在此做下一个笔记,以前其实也遇到过,没想到这次还是踩坑。
由于客户使用第三方APP需要访问/dev/snd/下的声卡节点,因此打开APP后,发现并不能正常访问,使用
cat /proc/kmsg | grep avc,报错以下信息:
[ 70.119120] type=1400 audit(1554076874.080:6):avc: denied { search } for pid=6383 comm="SpeechAudioReco" name="snd" dev="tmpfs" ino=4354 scontext=u:r:untrusted_app:s0:c512,c768
tcontext=u:object_r:audio_device:s0 tclass=dir permissive=0
同时进行确认是selinux的问题测试:
1、串口shell或者adb工具,使用
setenforce 0 (临时禁用掉 SELinux)
getenforce (得到结果为 Permissive)
2、给/dev/snd/下的节点0777权限
测试结果:Success
既然是这个问题,那么我们就来补selinux的策略,于是根据万能公式得到:
以及借助overlay机制,直接找到device下的策略文件untrusted_app.te,加入以下权限:
allow untrusted_app audio_device:dir search;
编译烧录后,给节点0777权限,再次打开APP访问,发现又报错:
[ 250.220688] type=1400 audit(1554077054.150:6): avc: denied { write } for pid=17838 comm="SpeechAudioReco" name="pcmC0D0c" dev="tmpfs" ino=312 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:audio_device:s0 tclass=chr_file permissive=0
于是在untrusted_app.te文件再加入以下权限:
allow untrusted_app audio_device:chr_file rwx_file_perms;
编译报错externl/selinux/app.te中的策略与我在untrusted_app.te中加入的权限allow untrusted_app audio_device:chr_file rwx_file_perms;冲突
找到app.te,注释掉冲突项audio_device:
# Access to any of the following character devices.
neverallow appdomain {
# audio_device
camera_device
dm_device
radio_device
gps_device
rpmsg_device
}:chr_file { read write };
# Note: Try expanding list of app domains in the future.
#neverallow { untrusted_app isolated_app shell } graphics_device:chr_file { read write };
编译烧录后,再给节点0777权限,再次打开APP访问,还是报错如下,为什么??
[ 250.220688] type=1400 audit(1554077054.150:6): avc: denied { write } for pid=17838 comm="SpeechAudioReco" name="pcmC0D0c" dev="tmpfs" ino=312 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:audio_device:s0 tclass=chr_file permissive=0
这就奇怪了,该给的权限都给了,可还是报没有write权限,记起来以前也是遇到过这个坑,第三方APP访问节点,要在定义type的时候加入mlstrustedobject才行。
那么就找到audio_device定义的地方external/device.te,修改如下:
diff --git a/device.te b/device.te
index b2f4f1d..c72d216 100644
--- a/device.te
+++ b/device.te
@@ -3,7 +3,7 @@ type device, dev_type, fs_type;
type alarm_device, dev_type, mlstrustedobject;
type adb_device, dev_type;
type ashmem_device, dev_type, mlstrustedobject;
-type audio_device, dev_type;
+type audio_device, dev_type, mlstrustedobject;
type binder_device, dev_type, mlstrustedobject;
type block_device, dev_type;
type camera_device, dev_type;
编译烧录后,成功了!!!
疑问: 为什么第三方APP访问节点加入mlstrustedobject ?
- 正常的avc 日志如下:
type=1400 audit(1632720237.902:52): avc: denied { write } for comm=“ip” scontext=u:r:update_route_table:s0 tcontext=u:r:update_route_table:s0 tclass=netlink_route_socket permissive=0 - 不太正常的avc 日志如下:
[ 250.220688] type=1400 audit(1554077054.150:6): avc: denied { write } for pid=17838 comm=“SpeechAudioReco” name=“pcmC0D0c” dev=“tmpfs” ino=312 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:audio_device:s0 tclass=chr_file permissive=0
先了解下安全上下文的组成格式:
SEAndroid的安全上下文与SELinux基本一致(除了MLS检测在SEAndroid中被强制执行),共有4个部分组成分别为user、role、type、sensitivity,以u:object_r:system_data_file:s0为例:
user:安全上下文的第一列为user,在SEAndroid中的user只有一个就是u。
role:第二列表示role,在SEAndroid中的role有两个,分别为r和object_r。
type:第三列为type,SEAndroid中共定义了139种不同的type。
security level:第四列是专为MLS访问机制所添加的安全上下文的扩展部分,格式为sensitivity[:category list][- sensitivity[:category list]] ,例如s0 - s15:c0.c1023,其中s0之后的内容可以不需要,冒号后面的内容是category,sensitivity和category组合一起声明了当前的安全级别(security level),“-”号左右分别标识了安全级别的最低和最高,这一列的参数将在MLS约束检查时用到,“15”、“1023”表示了sensitivity和category的最大值,这一参数可在Android.mk中定义。
总结:通过对比两种类型的avc log,以及对安全上下文的组成格式可以知道,这个不正常的恰好是 MLS 相关的。
目前只参考以下部分:
- 在SEAndroid中共定义了三个拥有巨大权限的attribute分别是mlstrustedsubject、mlstrustedobject、unconfineddomain,被分类到mlstrustedsubject的type在充当主体domain是可以越过MLS检查,被分类到mlstrustedobject的type在充当客体时可以越过MLS检查,被分到unconfineddomain的type则拥有所有权限可对客体进行任意操作。
在SEAndroid中: - 被分在mlstrustedsubject attribute中的type有adbd、debuggerd、drmserver、init、installd、kernel、mediaserver、netd、surfaceflinger、su、system、vold、zygote。
- 被分在mlstrustedobject attribute中的type有alarm_device、ashmem_device、binder_device、log_device、mtp_device、nv_device、powervr_device、ptmx_device、null_device、cgroup、sysfs、sysfs_writable、sysfs_writable、sysfs_writable、debugfs、apk_data_file、cache_file、dnsproxyd_socket。
- 被分在unconfineddomain的type有init、kernel、su
因此我们需要对 tty_device定义添加 mlstrustedobject !!!
参考链接:
https://blog.csdn.net/gnnulzy/article/details/52868696
https://www.cnblogs.com/mojl-cnblogs/p/11053174.html
MLS 可参考:https://blog.csdn.net/l173864930/article/details/17194899