selinux 记录

SEPolicy 语言:
    Linux中有两种东西,一种死的(Inactive),一种活的(Active)。死的东西就是文件(Linux哲学,万物皆文件。注意,万不可狭义解释为File),而活的东西就是进程。此处的 死 和 活 是一种比喻,映射到软件层面的意思是:进程能发起动作,例如它能打开文件并操作它。而文件只能被进程操作。

    根据 SELinux 规范,完整的 Secure Context 字符串为:user:role:type[:range]

进程的 Secure Context:
    在 SELinux 中,每种东西都会被赋予一个安全属性,官方说法叫做 Security Context,Security Context是一个字符串,主要由三个部分组成,例如 SEAndroid 中,进程的 Security Context 可通过 ps -Z 命令查看:

    上面的最左边的一列就是进程的 Security Context,以第一个进程 wpa_supplicant 为例
        u:r:hal_wifi_supplicant_default:s0
    其中 
    - u 为 user 的意思,SEAndroid 中定义了一个 SELinux 用户,值为 u 
    - r 为 role 的意思,role 是角色之意,它是 SELinux 中一个比较高层次,更方便的权限管理思路。简单点说,一个 u 可以属于多个 role,不同的 role 具有不同的权限。 
    - hal_wifi_supplicant_default 代表该进程所属的 Domain 为 hal_wifi_supplicant_default。MAC(Mandatory Access Control)强制访问控制 的基础管理思路其实是 Type Enforcement Access Control(简称TEAC,一般用TE表示),对进程来说,Type 就是 Domain,比如 hal_wifi_supplicant_default 需要什么权限,都需要通过 allow 语句在 te 文件中进行说明。 
    - s0 是 SELinux 为了满足军用和教育行业而设计的 Multi-Level Security(MLS)机制有关。简单点说,MLS 将系统的进程和文件进行了分级,不同级别的资源需要对应级别的进程才能访问

文件的 Secure Context:
    文件的 Secure Context 可以通过 ls -Z 来查看,如下

    ls libOMX_Core.so -Z
    u:object_r:vendor_file:s0 libOMX_Core.so

    u:同样是 user 之意,它代表创建这个文件的 SELinux user
    object_r:文件是死的东西,它没法扮演角色,所以在 SELinux 中,死的东西都用 object_r 来表示它的 role
    vendor_file:type,和进程的 Domain 是一个意思,它表示 libOMX_Core.so 文件所属的 Type 是 vendor_file
    s0:MLS 的等级


根据 SELinux 规范,完整的 SELinux 策略规则语句格式为:
    allow domains types:classes permissions;

    - Domain - 一个进程或一组进程的标签。也称为域类型,因为它只是指进程的类型。
    - Type - 一个对象(例如,文件、套接字)或一组对象的标签。
    - Class - 要访问的对象(例如,文件、套接字)的类型。
    - Permission - 要执行的操作(例如,读取、写入)。

    = allow : 允许主体对客体进行操作
    = neverallow :拒绝主体对客体进行操作
    = dontaudit : 表示不记录某条违反规则的决策信息
    = auditallow :记录某项决策信息,通常 SElinux 只记录失败的信息,应用这条规则后会记录成功的决策信息。

    使用政策规则时将遵循的结构示例:

    语句:
    allow appdomain app_data_file:file rw_file_perms;

    这表示所有应用域都可以读取和写入带有 app_data_file 标签的文件
    
    
SELinux 权限不足 avc-denied 问题解决:
    目前所有的 SELinux 权限检测失败,在 Kernel Log 或者 Android Log 中都有对应的 avc-denied Log 与之对应。反过来,有 avc-denied Log,并非就会直接失败,还需要确认当时 SELinux 的模式, 是 Enforcing 还是 Permissve。

    如果是 Enforcing 模式,就要检测对应的进程访问权限资源是否正常?是否有必要添加? 如果有必要添加,可以找下面的方式生成需要的 sepolicy 规则并添加到对应 te 文件。

    使用 audit2allow 简化方法 
    从 logcat 或串口中提取相应的 avc-denied log,下面的语句为提取所有的 avc- denied log
    $ adb shell "cat /proc/kmsg | grep avc" > avc_log.txt 
    使用 audit2allow 工具生成对应的 policy 规则
    // audio2allow 使用必须先 source build/envsetup.sh,导入环境变量
    $ audit2allow -i avc_log.txt -p $OUT/vendor/etc/selinux/precompiled_sepolicy
    将对应的policy 添加到 te 文件中
        = 一般添加在 /device/<company>/common/sepolicy 或者 /device/<company>/$DEVICE/sepolicy 目录下

    BOARD_SEPOLICY_DIRS += device/$SoC/common/sepolicy 通过这个命令添加厂家自定义的 sepolicy 规则


--------------------------------------------------------------------------------    
file_contexts //系统中所有file_contexts安全上下文
seapp_contexts //app安全上下文
property_contexts //属性的安全上下文
service_contexts    //service文件安全上下文
genfs_contexts //虚拟文件系统安全上下文
以上文件system/sepolicy中都有对应的内容

在Android8.0以上,SELinux策略分离成平台(platform)和非平台(non-platform)两部分,
而平台策略为了给非平台作者导出特定的类型和属性,又分为平台私有(platform private)和平台公有(platform public)部分。

1.平台公有策略(platform public seoplicy)平台共有策略全部定义在/system/sepolicy/public下,public下的type和attribute可以被non-platform中的策略所使用,也就是说,设备制造商的sepolicy作者在non-platform下可以对platform public sepolicy的策略进行扩展。
2.平台私有策略(platform private seoplicy)与公有策略相反,被声明为私有策略的type或attribute对non-platform的策略作者是不可见的。
-------------------------------------------------------------------------------


怎么抓取SELinux Log?
1.adb shell dmesg----抓kernel log
(特别说明:adb shell "cat /proc/kmsg | grep avc" > avc_log.txt  可以直接提出avc的log)
2.adb logcat –b events
关键字:
avc: denied
修改之后,怎么快速验证?
方法一:
mmm system/sepolicy
生成out目录下,注意有两个目录:
system/etc/sepolicy---Android 原生的,建议不动。如果修改,会影响CTS
vendor/etc/sepolicy---第三方厂家修改。
特别说明:system/sepolicy/Android.mk中定义了一些属性
BOARD_SEPOLICY_DIRS  ##此宏涉及到的目录,会编译到vendor/etc/sepolicy下
PLAT_PUBLIC_POLICY ##此宏涉及到的目录,会当成system/sepolicy/public
PLAT_PRIVATE_POLICY##此宏涉及到的目录,会当成system/sepolicy/private
另外,单独编译后,会发现都会有对应的生成目录
    /out/target/product/xxx/vendor/etc/selinux/
        vendor_file_contexts
        vendor_property_contexts
        vendor_sepolicy.cli   //allow语句会生成到这里面

方法二:
make sepolicy
怎么从log中提取有效信息?
举例1
    <36>[  103.972283] c0    484 type=1400 audit(1536907169.826:34): avc: denied { read } for pid=2591 comm="roid.qh_engmode" name="printk" dev="proc" ino=35544 scontext=u:r:radio:s0 tcontext=u:object_r:proc:s0 tclass=file permissive=0
普通提取:
allow radio proc:file read;
关键字:
avc: denied { read }  scontext=u:r:radio:s0 tcontext=u:object_r:proc:s0  tclass=file
格式:allow scontext tcontext:tclass {read}

深入提取:

1.观察原生:

#参考资料:
https://www.jianshu.com/p/e95cd0c17adc

解决avc-denied之设置SELinux策略
https://blog.csdn.net/eliot_shao/article/details/51859083

1). 简化方法
1.1 提取所有的avc LOG. 如 adb shell “cat /proc/kmsg | grep avc” > avc_log.txt 
1.2 使用 audit2allow tool 直接生成policy. audit2allow -i avc_log.txt 即可自动输出生成的policy 
1.3 将对应的policy 添加到selinux policy 规则中,对应MTK Solution, 您可以将它们添加在KK: mediatek/custom/common/sepolicy, L: device/mediatek/common/sepolicy 下面,如

  allow zygote resource_cache_data_file:dir rw_dir_perms;
  allow zygote resource_cache_data_file:file create_file_perms;
  ===> mediatek/custom/common/sepolicy/zygote.te (KK)
  ===> device/mediatek/common/sepolicy/zygote.te (L)

注意audit2allow 它自动机械的帮您将LOG 转换成policy, 而无法知道你操作的真实意图,有可能出现权限放大问题,经常出现policy 无法编译通过的情况。


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章