Android SELinux开发入门指南之权限解决万能规则
前言
Android的妈咪谷歌为了解决Android系统一直让人诟病的安全问题,在Android 4.4以后强制引入了SELinux安全管理。SELinux虽然可以将安全提升一个层级,但是有时候的实际效果确实杀敌一千,自损八百给开开发造成许多的困难。今天将带领读者一起看看的是Android开启SELinux后,有没有一种通用万能规则解决SELinux中绝大部分的avc denied问题。当然这个是有的,不然也不会有这篇博客了,在接下来的篇章中我会以实际案例来进行扩展和说明。
注意:注意这里的实际操作都是在Android 8上面进行的。
一.万能规则
Android 5.x开始,引入了非常严格的SELinux权限管理机制,我们经常会遇到因为SELinux权限问题造成的各种avc denied困扰。本文结合具体案例,讲解如何根据log来快速解决90%的权限问题。遇到权限问题,在logcat或者kernel的log中一定会打印avc denied提示缺少什么权限,如下:
//通过kernel中的log查看
cat /proc/kmsg | grep avc 或 dmesg | grep avc
//或者通过logcat查看,如下
logcat -b events | grep avc
解决原则是:缺什么补什么,一步一步补到没有avc denied为止。下面我以实际案例来说明。好吗不多说啥了,直接开说?
1.1 实践案例分析一
这是一个典型的SELinux权限问题,下面让我们一步步的来破解分析。
分析过程:
- 缺少什么权限: { write }权限
- 谁缺少权限: scontext=u:r:kernel:s0
- 对哪个文件缺少权限: tcontext=u:object_r:block_device
- 什么类型的文件: tclass=blk_file
- 解决方法:添加对应的规则,这里建议添加在对应的kernel.te里面
allow kernel block_device:blk_file write;
1.2 实际案例分析二
解决方法:添加对应的规则,这里建议添加在对应的platform_app.te里面添加对应的规则。
allow platform_app app_data_file:file execute;
1.3 实际案例分析三
解决方法:添加对应的规则,这里建议添加在对应的engsetmacaddr.te里面添加对应的规则。
allow engsetmacaddr vfat:dir { search write add_name create }; 或者 allow engsetmacaddr vfat:dir create_dir_perms;
1.4 实际案例分析四
解决方法:添加对应的规则,这里建议添加在对应的sdcardd.te里面添加对应的规则。
allow sdcardd system_data_file:dir read; 或者
allow sdcardd system_data_file:dir rw_dir_perms
其中(rw_dir_perms包含read write可以参考external/sepolicy/global_macros的定义声明)。
1.5 万能规则总结
通过前面的这四个案例,可以总结出如下的规律这里以第2.4章节为例说明,允许某个scontext对某个tcontext拥有某个权限。我们对log重新排列一下,如下:
scontext=u:r:sdcardd
tcontext=u:object_r:system_data_file:s0
tclass=dir
avc: denied { read }
得到的万能公式如下:
在scontext所指的te文件中加入类似如下内容:
以上以.te为后缀的文件都在external/sepolicy/或者device/softwinner/xxxx-commm/sepolicy/下,修改之后,都要重刷boot.img。(重点,在Android 7和Android 8上面.te后缀的文件都在system/sepolicy或者device/softwinner/xxxx-commm/sepolicy/下面这个需要注意,且此时需要烧录system.img或者vendor.img)
1.6 补充说明
有如下几点需要特别注意的,如下:
- 有时候avc denied的log不是一次性显示所有问题,要等你解决一个权限问题之后,才会提示另外一个权限问题。比如提示确实某个目录的read权限,你加入read之后,再显示缺少write权限,要你一次次一次试,一次一次加。这时你可以简单粗暴写个rw_dir_perms,这个权限包含了{open search write …}等等很多权限。可以查看external/sepolicy/global_macros来了解更多权限声明 (相对应的在Android 7和Android 8对应的就是external/sepolicy/global_macros,如果有定义的话 );
- 要加入的权限很多时,可以用中括号,比如:
allow engsetmacaddr vfat:dir { search write add_name create};
- 遇到问题不确定是否由于selinux问题造成,可先在adb shell 下,输入setenforce 0,让selinux失效,看是否问题还出现。以此可以澄清是非selinux造成的问题。
后话
有一个开源的工具audit2allow,没有具体使用过,网上流程如下而对于如何解决该类权限问题,一般的做法是,缺少什么就补什么,先介绍一下简化方法:
- 提取所有的avc LOG. 如 adb shell “cat /proc/kmsg | grepavc” > avc_log.txt
- 使用 audit2allow tool 直接生成policy. audit2allow -i avc_log.txt 即可自动输出生成的policy
还是建议不要使用这个工具,最好自己手动编写相关的策略。因为上面这个工具知识机械的转化,不一定符合具体的要求
写在最后
各位读者看官朋友们,Android SELinux开发入门指南之权限解决万能规则篇章已经全部完毕,希望能吸引你,激活发你的学习欲望和斗志。在最后麻烦读者朋友们如果本篇对你有帮助,关注和点赞一下,当然如果有错误和不足的地方也可以拍砖。