SELinux avc 权限问题修改

前言

SELinux(Security-Enhanced Linux)是一套强制性的安全审查机制(强制访问控制)。Android从5.0(L)开始启用SELinux Enforce模式,即既打印异常log也拒绝请求。增强了系统及进程的安全性,最明显的一点是限制了ROOT权限,之前ROOT就能获取所有权限的导致非常混乱的情况得到很大改善。

下面主要记录下,一般情况下 碰到这类权限问题是如何处理的。

问题

在开发中,可能会遇到这类权限问题,通常搜索“avc”即可,如下:

avc: denied { create } for pid=503 comm="idmap" name="overlays.list" 
scontext=u:r:zygote:s0 tcontext=u:object_r:resource_cache_data_file:s0 tclass=file

确认问题

userdebug或eng软件,通过adb命令(adb shell setenforce 0)临时关闭SElinux(使进入Permissive模式) 使请求都能被执行,重启失效。
如果问题消失,这样就能确认是SELinux 权限导致的问题。如果问题依然在,则是其他原因而非SELinux权限导致。
SElinux模式:

  • Enforce模式:打印异常log,拒绝请求。没有权限的请求被拒绝后 执行就会有问题。
  • Permissive模式:打印异常log,不拒绝请求。请求没被拒绝,执行不会出现问题。

获取当前SELinux状态:

adb shell getenforce   //5.0开始 默认是开启Enforce模式,即获取的值为:Enforcing 

设置SELinux:

adb shell setenforce 0   //设置后即Permissive
adb shell setenforce 1   //设置后即Enforcing

分析

avc: denied { create } for pid=503 comm="idmap" name="overlays.list" scontext=u:r:zygote:s0 tcontext=u:object_r:resource_cache_data_file:s0 tclass=file

这一段log中,主要注意以下几个值(用不同颜色标记出来了):

  • denied -> create //缺少什么权限
  • scontext -> zygote //谁缺少权限
  • tcontext -> resource_cache_data_file //对哪个文件缺少权限
  • tclass -> file //什么类型的文件

上面log就是:zygote进程对resource_cache_data_file的file类型文件缺少create权限。

解决

权限拒绝,一般添加上需要的权限即可。

scontext.te添加:allow scontext tcontext:tclass denied

如上log就是在zygote.te文件中添加:
allow zygote resource_cache_data_file:file {create };

MTK平台SELinux Policy文件一般存放在:
Google原生目录:system/sepolicy
MTK配置目录:device/mediatek/sepolicy 或者 device/mediatek/{platform}}/sepolicy

快速确认是否编译成功
selinux policy的汇总:用grep在 out/target/product/project/obj/ETC/sepolicy_intermediates中搜索即可。

AndroidQ上ioctl变化

Google在Android Q上增强了对ioctl的审查,除保持对ioctl的审查/授权之外,对具体的ioctlcmd也需要进一步地审查/授权。
/kernel/security/selinux/hooks.c
...
error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd);
...

对于这样的一条avc log:
avc: denied { ioctl } for comm="BootAnimation" path="/proc/ged" dev="proc" ino=4026532249 ioctlcmd=0x6700 scontext=u:r:bootanim:s0 tcontext=u:object_r:proc_ged:s0 tclass=file permissive=0

在Android Q上,则需要:

allow bootanim proc_ged:file ioctl;            
allowxperm bootanim proc_ged:file ioctl 0x6700;

0x6700 即log中的ioctlcmd。

0x6700这个值一般在sepolicy目录下的ioctl_defines文件中配置。所以在Q上,上述log最终

ioctl_defines#
define(`GED_BRIDGE_IO_LOG_BUF_GET', `0x6700')
 
bootanim.te#
allow bootanim proc_ged:file ioctl;
allowxperm bootanim proc_ged:file ioctl GED_BRIDGE_IO_LOG_BUF_GET;
上一篇:iOS开发 点菜系统 使用UIPickerView


下一篇:IOCTL命令字的解析