Andorid 官网相关SELinux说明:
SELinux 概念
Android 中的安全增强型 Linux
验证 SELinux
开发应用报错,提示
avc: denied { write } for comm="com.test" name="/" dev="dm-5" ino=2 scontext=u:r:system_app:s0 tcontext=u:object_r:system_data_root_file:s0 tclass=dir permissive=0
那就是缺少 SELinux 权限,那就加上。
在 Android aosp 源码上,需要先执行过 source build/envsetup
、lunch
命令,
如果不执行 ,会提示
ANDROID_HOST_OUT not set. Have you run lunch?
所以,得先执行。执行后,在根目录就可以直接使用 audit2allow 工具了。
audit2allow
audit2allow 工具路径是 external/selinux/prebuilts/bin/audit2allow
。
把 avc 的 log 写入到 avc_log.txt 中,
注意,抓到的 log 可能是这样的,
09-28 09:30:06.221 5734 5734 W Thread-20: type=1400 audit(0.0:2346): avc: denied { write } for comm=“com.test” name=“/” dev=“dm-5” ino=2 scontext=u:r:system_app:s0 tcontext=u:object_r:system_data_root_file:s0 tclass=dir permissive=0
写入文件时要去掉前面的部分,只保留从 avc: denied 开头的部分,即
avc: denied { write } for comm=“com.test” name=“/” dev=“dm-5” ino=2 scontext=u:r:system_app:s0 tcontext=u:object_r:system_data_root_file:s0 tclass=dir permissive=0
文件名可以自己修改,把 avc_log.txt 拷贝到根目录,
然后执行 audit2allow -i avc_log.txt
,就会得到如下结果
#============= system_app ==============
allow system_app system_data_root_file:dir write;
如果没有执行出结果,可以把 avc_log.txt 中的内容复制多行后再执行
执行 get_build_var BOARD_SEPOLICY_DIRS
找到写 Selinux 权限的目录,然后根据目录找对应的 te 文件(因为权限是写在 te 文件里的),然后写入这个结果。
结果可能有好几个,写入到任意一个就行。
不过还是建议遵循归类原则。
比如,我们要加的是 system_app 的权限,就找已经加过 system_app 相关的 te ;要加的是 vendor_app 的权限,就找已经加过 vendor_app 相关的 te。
本例是加到了 device/xxx/common/sepolicy/system_app.te 中.
修改后报错,
out/target/product/xxx/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows.tmp out/target/product/xxx/obj/FAKE/sepolicy_neverallows_intermediates/policy.conf ) && (out/host/linux-x86/bin/sepolicy-analyze out/target/product/xxx/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows.tmp neverallow -w -f out/target/product/xxx/obj/FAKE/sepolicy_neverallows_intermediates/policy_2.conf || ( echo \"\" 1>&2; echo \"sepolicy-analyze failed. This is most likely due to the use\" 1>&2; echo \"of an expanded attribute in a neverallow assertion. Please fix\" 1>&2; echo \"the policy.\" 1>&2; exit 1 ) ) && (touch out/target/product/xxx/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows.tmp ) && (mv out/target/product/xxx/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows.tmp out/target/product/xxx/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows )"
libsepol.report_failure: neverallow on line 634 of system/sepolicy/public/init.te (or line 21764 of policy.conf) violated by allow system_app system_data_root_file:dir { write };
libsepol.check_assertions: 1 neverallow failures occurred
Error while expanding policy
按照提示修改 system/sepolicy/public/init.te
,
-neverallow { domain -init -toolbox -vendor_init -vold } system_data_root_file:dir { write add_name remove_name };
+neverallow { domain -init -toolbox -vendor_init -vold } system_data_root_file:dir { add_name remove_name };
然后任选如下任一方式单编:
- 到 system/sepolicy/ 下执行 mma -j12 编译,适用于只修改了这个目录的情况。
- 在根目录执行
make -j12 sepolicy
:推荐做法,修改了原生 sepolicy 和厂商 sepolicy 都可以这样验证。
单编通过的话说明语法没问题,也没有触发 neverallow 。然后再全编译验证即可。
编译问题
Match operation ‘empty’ is not valid
编译的时候碰到了一个奇怪的问题,
Could not read line from 'out/target/product/xxx/vendor/etc/selinux/vendor_property_contexts': Match operation 'empty' is not valid: must be either 'prefix' or 'exact'
百度搜索之后找到答案:
是因为 te,context 文件结尾必须要有空行。检查 context 文件后,在末尾加上空行就好了。
x_x_perms
添加权限是,可能需要同时加多个权限,如,
allow system_app hidraw_device:chr_file { read open getattr};
挨个加是没问题的,简便方法是通过宏定义 x_x_perms 全部加上,如,
allow system_app hidraw_device:chr_file rw_file_perms;
rw_file_perms 的定义在 system/sepolicy/prebuilts/api/28.0/public/global_macros
,
#####################################
# Common groupings of permissions.
#
define(`x_file_perms', `{ getattr execute execute_no_trans map }')
define(`r_file_perms', `{ getattr open read ioctl lock map }')
define(`w_file_perms', `{ open append write lock map }')
define(`rx_file_perms', `{ r_file_perms x_file_perms }')
define(`ra_file_perms', `{ r_file_perms append }')
define(`rw_file_perms', `{ r_file_perms w_file_perms }')
define(`rwx_file_perms', `{ rw_file_perms x_file_perms }')
define(`create_file_perms', `{ create rename setattr unlink rw_file_perms }')
define(`r_dir_perms', `{ open getattr read search ioctl lock }')
define(`w_dir_perms', `{ open search write add_name remove_name lock }')
define(`ra_dir_perms', `{ r_dir_perms add_name write }')
define(`rw_dir_perms', `{ r_dir_perms w_dir_perms }')
define(`create_dir_perms', `{ create reparent rename rmdir setattr rw_dir_perms }')
define(`r_ipc_perms', `{ getattr read associate unix_read }')
define(`w_ipc_perms', `{ write unix_write }')
define(`rw_ipc_perms', `{ r_ipc_perms w_ipc_perms }')
define(`create_ipc_perms', `{ create setattr destroy rw_ipc_perms }')