工作好几年了,基本上从事Android 上层开发,都是在别人基础上修改改的,因为公司一个需求,改动代码,发现开不了机了,通过别人指点发现是因为selinux 权限的原因,导致代码无法执行,又发现了一个自己的短板,决心系统性学习Android selinux 的原理和实现方式,我的学习习惯是先知道怎么做,如何做,然后在了解为什么,直奔主题.
目前工作在做 Android 12 项目,所有修改位置都是基于此.
关于如何编译selinux ,在andriod 编译小知识点_xss534890437的博客-优快云博客 已经有介绍,就不重复啰嗦了.
1,关闭selinux
在调试selinux 的时候,如果是手动运行的,可以adb shell setenforce 0, 关闭selinux 进行调试
或者在Selinux.cpp 中直接关闭selinux 配置,这样开机就是关闭状态了
void SelinuxSetEnforcement() {
bool kernel_enforcing = (security_getenforce() == 1);
bool is_enforcing = IsEnforcing();
//加这段就可以了
is_enforcing = false;
//加这段就可以了
if (kernel_enforcing != is_enforcing) {
if (security_setenforce(is_enforcing)) {
PLOG(FATAL) << "security_setenforce(" << (is_enforcing ? "true" : "false")
<< ") failed";
}
}
}
编译替换init 即可.参考andriod 编译小知识点_xss534890437的博客-优快云博客
复现问题,然后抓取dmesg log,,通过auditallow2 -i log.txt,即可获取对应的selinux 改动,清晰易懂哈
添加SystemProperty
a,type xxxxxxx, property_type; //property.te中定义标签
b,xxxxxx u:object_r:xxxxxx:s0;//property_contexts中给属性打上对应标签,也可以蹭下系统标签
c,get_prop(system_server, xxxxxx);//这里举个例子,允许Systemserver 访问该属性
set_prop(system_server, xxxxxx);
这两个相当于allow xxx,只不多系统帮我们封装好了而已
添加文件类型
a,可执行脚本
定义域
type xxxx, domain,mlstrustedsubject;
type xxxx_exec, exec_type, file_type,vendor_file_type;
init_daemon_domain(copy_bootanimation) //单独进程标签
定义标签
/vendor/bin/copy_bootanimation\.sh u:object_r:xxxxx_exec:s0
注意xxxx 和 xxxx_exec 的区别
剩下的就是通过dmesg 获取对应标签的权限了,可以通过xxxx 来查找
b,节点类型
参考系统LED 节点,蹭一下LED 的标签,自定义的应该也是一样,我也没加过哈
genfscon sysfs /devices/platform/soc/xxxx u:object_r:sysfs_leds:s0
注意这个路径是绝对路径
新增分区文件系统
device.te 声明类型
type vendor_xxx_device, dev_type;
file_context 定义上下文
/dev/block/platform/soc/4744000.sdhci/by-name/分区 u:object_r:vendor_xxx_device:s0
未完待续
参考:
https://source.android.com/docs/security/selinux