• Android系统10 RK3399 init进程启动(三十二) SeAndroid策略更新和验证


     配套系列教学视频链接:

          安卓系列教程之ROM系统开发-百问100ask

    说明

    系统:Android10.0

    设备: FireFly RK3399 (ROC-RK3399-PC-PLUS)

    前言

    上一个章节介绍了如何定义策略, 并编译得到目标文件, 这些目标文件需要在开发上进行更新验证。


    一, 更新开发板策略

    编译得到的目标文件需要更新到开发板的/vendor/bin中:

    out/target/product/qh100_rk3399/vendor/bin/myse_test

    生成的策略文件目标文件:

    ls out/target/product/qh100_rk3399/vendor/etc/selinux/

    plat_pub_versioned.cil   vendor_file_contexts        vendor_property_contexts  vndservice_contexts

    plat_sepolicy_vers.txt   vendor_hwservice_contexts   vendor_seapp_contexts

    selinux_denial_metadata  vendor_mac_permissions.xml  vendor_sepolicy.cil

    ls out/target/product/qh100_rk3399/odm/etc/selinux/

    precompiled_sepolicy                                   precompiled_sepolicy.product_sepolicy_and_mapping.sha256

    precompiled_sepolicy.plat_sepolicy_and_mapping.sha256

    将以上文件,以文件夹为单位从源码中拷贝出来, 需要替换根文件系统中的vendor和odm分区的selinux文件, 这样的好处就是不用重新烧录整个镜像,局部更新安全策略就可以了。

    操作开发板, 通过adb执行如下:

    adb root

    adb remount

    adb push  myse_test   /vendor/bin

    adb push  vendor/selinux   /vendor/etc/

    adb push  odm/selinux   /odm/etc/

     

    二,运行验证

     提个问题:在不使用selinux规则文件的情况下, 直接在root用户下, 通过命令启动myse_test,发现是可以正常运行的, 是为什么呢?

    permissive模式下,并切换到root用户,测试更新了策略文件的效果:

    adb root

    adb remount

    adb push  vendor/selinux   /vendor/etc/

    adb push  odm/selinux   /odm/etc/

    adb shell

    qh100_rk3399:/ # getenforce

    Permissive

    qh100_rk3399:/ # ls -lZ /vendor/bin/myse_test

    -rwxr-xr-x 1 root shell u:object_r:vendor_file:s0 11384 2022-05-09 09:58 /vendor/bin/myse_test

    qh100_rk3399:/ # restorecon  /vendor/bin/myse_test

    SELinux: Loaded file_contexts

    qh100_rk3399:/ # ls -lZ /vendor/bin/myse_test

    -rwxr-xr-x 1 root shell u:object_r:myse_test_dt_exec:s0 11384 2022-05-09 09:58 /vendor/bin/myse_test

    启动myse_test进程:

    qh100_rk3399:/ # /vendor/bin/myse_test

    在另外一个终端上查看:

    qh100_rk3399:/ # ps -elfZ | grep myse

    u:r:su:s0                      root          6760  6524 95 14:53:46 pts/3 00:00:05 myse_test

     以上可以看到, 在不进行restorecon的时候, 我们更新的文件会自动继承父目录的安全上下文, 而执行restorecon之后, 文件的安全上下文就发生了变化了。变成了u:object_r:vendor_file:s0和u:object_r:myse_test_dt_exec:s0, 说明我们定义的安全上下文是生效了的。

    三, domain域转换

    上面可以看到myse_test的domain是为shell或者su, 并没有变成u:r:myse_test_dt:s0,此时需要修改myse_test.te文件, 使其能够domain切换:

    # subject context in proccess status

    type  myse_test_dt, domain;

    # object context as a file

    type myse_test_dt_exec, exec_type, vendor_file_type, file_type;

    #grant perm as domain

    init_daemon_domain(myse_test_dt)

    domain_auto_trans(shell, myse_test_dt_exec, myse_test_dt)

    重新编译策略文件,并重新更新vendor和odm中的策略。注意,想要看到进程域的切换, 需要更新好了策略文件之后, 进行重启,重启之后,才可以看到:

    一个终端下启动myse_test

    qh100_rk3399:/ $ ls -lZ /vendor/bin/myse_test

    -rwxr-xr-x 1 root shell u:object_r:myse_test_dt_exec:s0 11384 2022-05-09 09:58 /vendor/bin/myse_test

    qh100_rk3399:/ $ myse_test

    在另外一个终端下查看:

    qh100_rk3399:/ $ ps -elfZ | grep myse

    u:r:myse_test_dt:s0            shell         1595  1412 96 15:07:24 pts/0 00:00:11 myse_test

    以上说明策略文件生效了的, 注意,此时selinux模式是permissive模式, 并且也是在非root模式启动的进程

    四,selinux调试和enforcing模式下运行

       同样的代码,我们将selinux模式切换到enforce模式之后, 启动myse_test的时候会出现如下情况:

    qh100_rk3399:/ $ getenforce

    Permissive

    qh100_rk3399:/ $ su

    :/ # setenforce  1

    :/ # exit

    qh100_rk3399:/ $ getenforce

    Enforcing

    再运行myse_test会出现崩溃:

    qh100_rk3399:/ $ myse_test

    Segmentation fault

    同样的代码在permissive模式运行正常, 而在enforce模式下有问题,那应该就是权限问题了。此时需要调试,通过logcat来收集avc日志:

    qh100_rk3399:/ $ logcat | grep avc | grep myse

    02-24 15:07:25.694  1595  1595 I myse_test: type=1400 audit(0.0:77): avc: denied { use } for path="/dev/pts/0" dev="devpts" ino=3 scontext=u:r:myse_test_dt:s0 tcontext=u:r:adbd:s0 tclass=fd permissive=1

    02-24 15:07:25.694  1595  1595 I myse_test: type=1400 audit(0.0:78): avc: denied { read write } for path="/dev/pts/0" dev="devpts" ino=3 scontext=u:r:myse_test_dt:s0 tcontext=u:object_r:devpts:s0 tclass=chr_file permissive=1

    02-24 15:07:25.694  1595  1595 I myse_test: type=1400 audit(0.0:79): avc: denied { use } for path="/vendor/bin/myse_test" dev="dm-1" ino=49473 scontext=u:r:myse_test_dt:s0 tcontext=u:r:shell:s0 tclass=fd permissive=1

    02-24 15:07:25.720  1595  1595 I myse_test: type=1400 audit(0.0:80): avc: denied { read write } for name="myse_dev" dev="tmpfs" ino=43383 scontext=u:r:myse_test_dt:s0 tcontext=u:object_r:device:s0 tclass=file permissive=1

    02-24 15:07:25.720  1595  1595 I myse_test: type=1400 audit(0.0:81): avc: denied { open } for path="/dev/myse_dev" dev="tmpfs" ino=43383 scontext=u:r:myse_test_dt:s0 tcontext=u:object_r:device:s0 tclass=file permissive=1

    02-24 15:11:04.956  1906  1906 I myse_test: type=1400 audit(0.0:86): avc: denied { use } for path="/dev/pts/0" dev="devpts" ino=3 scontext=u:r:myse_test_dt:s0 tcontext=u:r:adbd:s0 tclass=fd permissive=1

    02-24 15:11:04.956  1906  1906 I myse_test: type=1400 audit(0.0:87): avc: denied { read write } for path="/dev/pts/0" dev="devpts" ino=3 scontext=u:r:myse_test_dt:s0 tcontext=u:object_r:devpts:s0 tclass=chr_file permissive=1

    02-24 15:11:04.957  1906  1906 I myse_test: type=1400 audit(0.0:88): avc: denied { use } for path="/vendor/bin/myse_test" dev="dm-1" ino=49473 scontext=u:r:myse_test_dt:s0 tcontext=u:r:shell:s0 tclass=fd permissive=1

    02-24 15:11:04.984  1906  1906 I myse_test: type=1400 audit(0.0:89): avc: denied { read write } for name="myse_dev" dev="tmpfs" ino=43383 scontext=u:r:myse_test_dt:s0 tcontext=u:object_r:device:s0 tclass=file permissive=1

    02-24 15:11:04.984  1906  1906 I myse_test: type=1400 audit(0.0:90): avc: denied { open } for path="/dev/myse_dev" dev="tmpfs" ino=43383 scontext=u:r:myse_test_dt:s0 tcontext=u:object_r:device:s0 tclass=file permissive=1

    将以上内容新建到一个文件: avc_log.txt

    audit2allow -i  avc_log.txt

    audit2allow一般在android源码中自带, 也可以通过apt进行安装, 得到如下结果:

    #============= myse_test_dt ==============

    allow myse_test_dt adbd:fd use;

    allow myse_test_dt device:file { read write open };

    allow myse_test_dt devpts:chr_file { read write };

    allow myse_test_dt shell:fd use;

    以上结果就表示myse_test_dt.te缺少权限, 需要在该文件添加权限,如下所示:

    # subject context in proccess status
    type  myse_test_dt, domain;
    # object context as a file
    type myse_test_dt_exec, exec_type, vendor_file_type, file_type;
    #grant perm as domain
    init_daemon_domain(myse_test_dt)

    domain_auto_trans(shell, myse_test_dt_exec, myse_test_dt)

    #============= myse_test_dt ==============

    allow myse_test_dt adbd:fd use;

    allow myse_test_dt device:file { read write open };

    allow myse_test_dt devpts:chr_file { read write };

    allow myse_test_dt shell:fd use;

    重新编译策略文件,更新根文件系统,重新编译,按照之前的方法, 将模式切换到enforcing模式下, 发现myse_test程序是可以正常运行的,说明我们给的权限是够的。

  • 相关阅读:
    2022unity超简单课设-模拟太阳系的Unity小游戏
    DSA之查找(1):线性表的查找
    SSM学习52:SSM三大技术整合案例
    matlab 使用激光雷达检测、分类和跟踪车辆
    汇总区间(C++解法)
    如何搭建android源代码repo仓库
    每个设计师都应该有的五个性格,你具备几个?
    Python脚本2 打印文本内两个日期之间的所有小时
    RS232电路设计
    期末前端web大作业:餐饮美食网站设计与实现——美食菜品网页(16页)
  • 原文地址:https://blog.csdn.net/ldswfun/article/details/125900112