之前这篇文章AOSP安全策略SElinux_android以及问题排查思路过于繁琐。因此直接来个相对实用的。
一、SElinux 规则修改
SDK 中已经配置有一套合理的 SElinux policy。在 SDK 开发过程中,可以根据需要,编辑规则文件,增加自定义规则。
1.查看违反规则的方法
dmesg | grep avc #或者在串口 log 中查找关键字 denied,即可看到有违反规则的行为。
2.生成规则
自动生成规则:使用 linux 工具 audit2allow 可以将违反规则的 avc 记录生成放行规则 (适合于 dmesg 所有输出,初期的开发阶段)。
手动生成规则: 比如违反 avc 记录如下:
type=1400 audit(1386760471.880:7): avc: denied { entrypoint } for pid=1227 comm=“init” path=“/sbin/healthd” dev=“rootfs” ino=4396 scontext=u:r:healthd:s0 tcontext=u:object_r:rootfs:s0 tclass=file
关键字对应的属性名:
scontext_name: healthd tcontext_name: rootfs tclass_type: file rules: entrypoint
放行公式:
allow scontext_name tcontext_name:tclass_type rules;
生成 rule 如下:
allow healthd rootfs:file entrypoint;
3.添加规则
编辑 device/{vendor-name}/common/sepolicy 目录下面 TE 格式文件,添加 Step 2 中生成的 rule 到以 scontext_name 命名的 TE 文件。
重新编译 Android 就可以生成新的 SElinux policy 固件。
如在编译过程出现类似如下错误,说明添加的规则和 system/sepolicy 设置的规则冲突。
neverallow on line 269 of system/sepolicy/domain.te (or line 5193 of policy.conf)
violated by allow platform_app unlabeled:dir { create };
4.解决规则冲突
system/sepolicy 定义通用规则,如果出现 device 规则与其冲突的问题,即 system/sepolicy定义 neverallow 规则,但是 device 规则又要允许访问。这种情况初学者本能的认为需要在system/sepolicy 中的 neverallow 中增加例外规则,如下实例。
实际上这种做法不妥,在添加 selinux 规则的时候尽量不要违背 system/sepolicy 的 neverallow, system/sepolicy 的neverallow 都是 google 工程师经过深思熟虑设置的规则检验关卡,违背了其规则,证明添加的device 规则不合理。这种情况下一般是没有为 scontext 或者 tcontext 定制化标签导致的,请检查 avc 报错中是否有 default 或者 unlabel 字样。
neverallow all_untrusted_apps {
hwservice_manager_type
-same_process_hwservice
-coredomain_hwservice
-hal_configstore_ISurfaceFlingerConfigs
-hal_graphics_allocator_hwservice
-hal_omx_hwservice
-untrusted_app_visible_hwservice
#相应加一条?
}:hwservice_manager find;
二、添加 sepolicy 示例
下面举例说明如何为 Android 的二进制程序 pz制定 sepolicy 规则,相关规则见
device/{vendor-name}/common/sepolicy/pz.te
type pz domain,domain_deprecated;为 pz进程定义专属 type pz,关联属性 domain。
type pz_exec,exec_type,file_type;为 pz 的二进制文件定义 type pz_exec。
init_daemon_domain(pz);进行进程的 domain transition,当 init 进程 fork 并执行pz_exec 标签对应的可执行文件 pz 时,进程的 domain 转为 pz。
-
在对 pz 进行 sepolicy 的策略配置时,发现 pz 会创建文件夹/dev/com.koushikdutta.superuser.daemon 和 sock:/dev/com.koushikdutta.superuser.daemon/server 用于通信。因此需要对这两个对象打上自定义标签,防止发生 neverallow 规则冲突。
type pz_daemon_device,dev_type 在 device.te 中定义 pz_daemon_device 用于给文件夹打标签。
type pz_socket,file_type,mlstrustedobject; 在 pz.te 中定义 pz_sock 用于给 server打标签。
file_type_auto_trans(pz,device,pz_daemon_device); 当 pz 在/dev(context: device)目录下创建文件夹 com.koushikdutta.superuser.daemon 时,给该文件夹打上qw_daemon_device 标签。
file_type_atuo_trans(pz,pz_daemon_device,qw_socket); 当 pz 在/dev/com.koushikdutta.superuser.daemon/(context:qw_daemon_device) 下创建文件 server 时,给server 打上 qw_socket 标签。
接下来编译出固件,根据 dmesg 中的一些 avc 报错添加一些 allow 规则,反复编译几次即可。
按照以上规则不出意外的话就可将 pz 的相关 sepolicy 配置起来。但事与愿违,在添加策略进行验证时,发现一些规则,如: allow pz pz_socket:sock_file create_file_perms;。这些规则添加后:
没有编译出错
没有 neverallow 冲突
成功编译进 policy.conf
但是在验证时,仍然报出相关的 avc denied。经过一番查找,发现该规则需要相应的 mls 权限才可以被授予对应权限。 mls 中:
mlsconstrain{sock_file} {write setattr...}(t2==app_data_file or l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject)
简单起见,在定义 pz 时,加上 type qw,domain,domain_deprecated,mlstrustedsubject.注: mlstrustedsubject 和 mlstrustedobject 在 mls 权限控制中拥有至高无上的权利。
三、SElinux 中的特殊符号
te 文件每行末尾以分号 “;” 结束
contexts 文件每行末尾没有分号 “;”
通配符• *:对应集合内的所有内容。• -:表示集合 A 内去除某项内容 b• ~:表示 ~ 后元素所在集合去除 ~ 后元素剩余的子集
注意:想要在深入了解的请移步至AOSP安全策略SElinux_android以及问题排查思路