Android 快速配置 SELinux 权限的方法

SELinux Overview


快速配置方法

最近在修改 audio 相关资源时,碰到了 SELinux 问题,log 显示读取ro.serialno被拦住了,log信息如下:

Access denied finding property "ro.serialno"
avc: denied { read } for name="u:object_r:serialno_prop:s0" dev="tmpfs" ino=2297 scontext=u:r:mtk_hal_audio:s0 tcontext=u:object_r:serialno_prop:s0 tclass=file permissive=0
avc: denied { search } for name="audioserver" dev="dm-2" ino=540707 scontext=u:r:mtk_hal_audio:s0 tcontext=u:object_r:audioserver_data_file:s0 tclass=dir permissive=0
avc: denied { open } for path="/dev/__properties__/u:object_r:serialno_prop:s0" dev="tmpfs" ino=6681 scontext=u:r:mtk_hal_audio:s0 tcontext=u:object_r:serialno_prop:s0 tclass=file permissive=0
avc: denied { getattr } for path="/dev/__properties__/u:object_r:serialno_prop:s0" dev="tmpfs" ino=6632 scontext=u:r:mtk_hal_audio:s0 tcontext=u:object_r:serialno_prop:s0 tclass=file permissive=0

如何根据这些 log 配置相应的权限呢?

借老大发的一张图说一下:
这里写图片描述

根据这张图,第一个 avc 异常:

avc: denied { read } for name="u:object_r:serialno_prop:s0" dev="tmpfs" ino=2297 scontext=u:r:mtk_hal_audio:s0 tcontext=u:object_r:serialno_prop:s0 tclass=file permissive=0

配置的权限应该就是:

allow mtk_hal_audio serialno_prop:file { read };

若只需要read权限,则可省略{},写成:

allow mtk_hal_audio serialno_prop:file read;

那么要修改的文件应该就是mtk_hal_audio.te,这个文件在:
device/mediatek/sepolicy/basic/non_plat/
如果device/mediatek/sepolicy/下有多个 mtk_hal_audio.te,那么随便修改一个就可以,不过个人建议改basic/下面的。(原因请看补充部分)

剩下的几个 avc 配置类比即可,最后要配置的权限就是这样的:

allow mtk_hal_audio serialno_prop:file { read };
allow mtk_hal_audio audioserver_data_file:dir { search };
allow mtk_hal_audio serialno_prop:file { open };
allow mtk_hal_audio serialno_prop:file { getattr };

不难发现,除了第二个,其余3个只有最后面的权限定义不一样,于是我们就可以把它们整合一下,顺便也就把{}的用处体现出来了:

allow mtk_hal_audio serialno_prop:file { read open getattr };
allow mtk_hal_audio audioserver_data_file:dir { search };

一般权限配置到这里就差不多 OK 了,但这里修改了serialno_prop的访问权限,编译会报neverallow的错误,错误指向了system/sepolicy/public/domain.te文件。
根据错误信息,找到了如下代码:

# Do not allow reading device's serial number from system properties except form
# a few whitelisted domains.
neverallow {
  domain
  -adbd
  -dumpstate
  -hal_drm
  -hal_cas
  -init
  -mediadrmserver
  -recovery
  -shell
  -system_server
} serialno_prop:file r_file_perms;

需要说明的是,这里面的是白名单,只有这里面列出的才能访问serialno_prop

这里我们需要把mtk_hal_audio加到白名单,但直接加进去,会报文件找不到。
我们回过来检查mtk_hal_audio.te文件的定义,发现前2行有如下配置:

type mtk_hal_audio, domain;
hal_server_domain(mtk_hal_audio, hal_audio)

虽然没看明白是在干啥,不过可以看出来mtk_hal_audiohal_audio是有联系的;这里mtk_hal_audio明显是MTK加的,那hal_audio应该就是 Android 原生存在的,neverallow里面配置的应该也是Android原生的。
基于这些分析和猜测,将hal_audio加入了白名单,编译验证果然OK了。

小结

1、这里的配置只是简易方法,并不一定所有情况都适用。
2、一定要注意冒号:、分号;的使用。
3、最后面权限声明的{}类似于数组,可以添加多种权限,但是各个权限之间要用空格隔开。
4、要基于已有的信息和经验,大胆假设,小心求证!
(20180703 更新)
5、经验证,修改 neverallow,会导致 CTS Fail !!!
6、当确认权限添加无误后,还是没效果的时候,请检查 scontext,若出现如下c512,c768信息

scontext=u:r:untrusted_app_25:s0:c512,c768
tcontext=u:object_r:sysfs_ir:s0

则说明,mls 检测未通过,还需要配置其它权限。


补充

在 Android KK 4.4 版本后,Google 正式有限制的启用 SELinux,来增强 android 的安全保护。但随着版本的迭代和调整 sepolicy 文件的存放路径,配置方法,单编方式也在调整,下面简单介绍一下各版本的差异。
(L以前的版本已成为历史,此处不再列出,如需要,可查[FAQ11483] 如何快速验证 SELinux Policy 问题

L / M 版本

sepolicy 文件主要放在下面几个目录:
1). Google 原生目录 external/sepolicy
2). MTK 配置目录 device/mediatek/common/sepolicy
3). MTK 配置目录 device/mediatek/{platform}/sepolicyM版本后才添加,主要是针对平台客制化

在编译时, 系统会以合并的方式(union),将 MTK 配置目录下的 policy 附加到 Google 原生的 policy 上,而非替换(KK版本).

如果在device/mediatek/common/sepolicy下面新增 SELinux Policy file,在 L 版本需要更新device/mediatek/common/BoardConfig.mk中的BROAD_SEPOLICY_UNION增加对应的xxxx.te,M 版本已经取消了这个宏,无需再操作。

单编方法:

mmm external/sepolicy
make -j24 ramdisk-nodeps
make -j24 bootimage-nodeps
N 版本

sepolicy 文件主要在如下目录:
1). Google 原生目录 system/sepolicy
2). MTK 配置目录 device/mediatek/common/sepolicy/,需要注意的是里面有3个子目录:
basic,所有的版本都会吃到;
bsp,bsp 版本 + Turnkey 版本都会吃到;
full, 只有Turnkey 版本会吃到。

单编方法:

mmm system/sepolicy
make -j24 ramdisk-nodeps
make -j24 bootimage-nodeps
O 版本

sepolicy 文件主要在如下目录:
1). Google 原生目录 system/sepolicy
2). MTK 配置目录 device/mediatek/sepolicy,大体上还是与N一致的3个子目录,但设定已经大改, 需要大家参考 MOL 上的 sepolicy O 版本更新。

单编方法:

mmm system/sepolicy

然后再根据对应的 sepolicy 是存放在system image, 还是 vendor image 对 system、vendor image 分别打包。


此笔记已同步推送到微信公众号:灰灰的Rom笔记

猜你喜欢

转载自blog.csdn.net/ShawnXiaFei/article/details/80833167