• 属性问题展开的selinux权限介绍


    从android5.0开始,强制开启了SELinux,对系统属性的访问权限也由selinux进行限制。

    SELinux非常繁杂,8.0开始的Treble Project后,为了实现system、vendor分区的隔离,selinux的机制变的更加繁琐。本文不打算全面讲解android上selinux,通过概览全貌和常见案例分析,让大家在"不求甚解"的情况下,能够处理系统定制中80%的selinux权限问题。

    1.SELinux的基本介绍

    • 框架:Kernel中,SELinux通过Linux Security Modules实现。

      img

    kernel/fs/read_write.c:
    int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count)
    {
        ......
        /* 基础权限检查 */
        if (unlikely(!access_ok(VERIFY_READ, buf, count)))
            return -EFAULT;
        ......
        /* selinux权限检查 */
        retval = security_file_permission(file,
                    read_write == READ ? MAY_READ : MAY_WRITE);
        ......
    }
    
    • 语法:rule_name source_type target_type : class perm_set
      allow system_app misc_user_data_file:file create_file_perms;
      get_prop(system_app, system_prop) 其实是一个宏,展开如下:
      allow system_app system_prop:file r_file_perms; #/dev/properties/system_prop

    2.android上selinux相关文件

    • 源码:
      system/sepolicy:
      ├── private
      ├── public
      │ ├── property_contexts
      │ ├── property.te
      │ ├── file_contexts
      │ ├── file.te
      │ ├── su.te
      │ ├── system_app.te
      │ ├── system_server.te
      │ ├── untrusted_app.te
      │ ├── priv_app.te
      │ └── zygote.te
      └── vendor
    • ROM:
      selinux编译生成的策略文件sepolicy,8.0之前在boot.img中,8.0由于treble的原因,system和vendor分区各放置一部分,加载的时候会进行合并。8.0之后单刷userdebug版本的boot不再能获取root权限,要刷userdebug版的system.img才行。
      /system/etc/selinux:
      plat_file_contexts
      plat_property_contexts
      plat_sepolicy.cil
      /vendor/etc/selinux:
      vendor_file_contexts
      vendor_property_contexts
      vendor_sepolicy.cil

    3.my_system_prop定义

    property.te:
    type my_system_prop, property_type;
    property_contexts:
    persist.my. u:object_r:my_system_prop:s0
    system_app.te:
    set_prop(system_app, my_system_prop)

    案例

    模块编译selinux:make sepolicy
    关闭selinux:setenforce 0

    • 案例一:build.prop明明声明了属性,为什么通过APK和adb shell获取不到?
      属性组成:

      • /default.prop
      • /system/build.prop
      • /vendor/default.prop
      • /vendor/build.prop
      • 由代码通过set生成的属性

      首先,只要build.prop里声明了,就会被加载到系统属性中。属性是有权限控制的,所以APK是不能获取所有属性的。
      参照上文my_system_prop的定义,如果对应APK没有声明get_prop的权限,是获取不到相关权限的。
      例如:
      persist.my.test u:object_r:my_system_prop:s0
      com.android.myapp想要去读取这个属性,但是读不到,如何分析呢?

      1. 查看属性的安全上下文:getprop -Z persist.my.test

      2. 查看进程的安全上下文:ps -AZ | grep com.android.myapp
        u:r:platform_app:s0:c512,c768 com.android.myapp

      3. 给platform_app加权限,在platform_app.te中添加:
        get_prop(platform_app, my_system_prop)

      adb shell对应的身份是shell,也是受限的,只有adb root后getprop获取的属性才是最全的。

    • 案例二:新增allow xxx权限,编译报错Neverallow,如何处理?

      1. cts版本不能有任何neverallow,只能去掉添加的权限
      2. 国内版本可适当注释掉原生相关neverallow进行规避
        neverallow check failed at out/target/product/sailfish/obj/ETC/plat_sepolicy.cil_intermediates/plat_sepolicy.cil:6373 from system/sepolicy/public/domain.te:1133
      (neverallow base_typeattr_144 file_type (file (execmod)))
        <root>
        allow at out/target/product/sailfish/obj/ETC/vendor_sepolicy.cil_intermediates/vendor_sepolicy.cil:1396
          (allow platform_app_28_0 app_data_file_28_0 (file (execute execmod)))
    

    如上看出,具体是public/domain.te:1133的限制影响了新加权限,找到对应行数观察:

    neverallow { domain -untrusted_app_all } file_type:file execmod;
    

    解决方式:

    1. 直接注释到该行
    # neverallow { domain -untrusted_app_all } file_type:file execmod;
    
    1. 只规避受影响的platform_app
    neverallow { domain -untrusted_app_all -platform_app } file_type:file execmod;
    
    • 案例三:avc: denied { write }之类的缺少权限如何处理?

      audit(0.0:67): avc: denied { write } for path="/dev/block/vold/93:96" dev="tmpfs" ino=/1263 scontext=u:r:kernel:s0 tcontext=u:object_r:block_device:s0 tclass=blk_file permissive=0

      语法:rule_name source_type target_type : class perm_set**
      万能公式:
      缺少什么权限:{ write }权限
      谁缺少权限:scontext=u:r:kernel:s0
      对谁缺少权限:tcontext=u:object_r:block_device:s0
      什么类型:tclass=blk_file

      kernel.te:
      allow kernel block_device:blk_file write;
      写操作一般还伴随open、append等,所以一般使用w_file_perms宏替代单一的write

    • 案例四:avc: denied { execmod }如何处理?

      audit(0.0:51): avc: denied { execmod } for path="/system/app/education_student/lib/arm/libhpHandPends.so" dev="mmcblk0p24" ino=424 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:system_file:s0 tclass=file permissive=0

      按照万能公式可得如下策略语句,这是没问题的。但这不是最优解,也可能违反Neverallow。

      allow untrusted_app system_file:file execmod;

      目前android加载so的策略是强制使用地址无关代码的模式,execmod的本质是由于so不支持地址无关导致加载失败。
      地址无关可以在多个进程间共享so的代码指令,无需拷贝重定位,节省内存。

      目前的Android.mk、NDK都默认加有-fPIC,只有很早之前的编译的so存在此问题。
      因此最优解是重新编译so,GCC编译时加上-fPIC参数即可。

    链接:https://www.jianshu.com/p/88a92d101532
    参考:https://blog.csdn.net/qq_34211365/article/details/106056873

  • 相关阅读:
    【js】实现输入框不允许输入某些特殊字符
    springboot集成druid实现数据源监控
    SpringBoot整合Druid并配置数据源监控
    SpringBoot集成Druid实现数据源管理和监控
    同一个catch字句中捕获多个java异常
    【JWT】JSON Web Token原理与实现
    行级锁实验:sql语句条件中的索引对锁的影响
    什么是乐观锁,什么是悲观锁,如何实现
    Linux命令与文件的查找which、wheris、locate、find
    vi编辑器永久设置行号、缩进
  • 原文地址:https://www.cnblogs.com/lixuejian/p/15324551.html
Copyright © 2020-2023  润新知