[Android Framework]Android 11 SELinux avc权限解决方法
2021/11/20 7:13:09
本文主要是介绍[Android Framework]Android 11 SELinux avc权限解决方法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1.SELinux与Android的关系
SELinux(Security-Enhanced Linux)是由美国国家安全局开发的一种安全增强型Linux内核模块,从Android5.0(API 21)开始被Google引入并强制集成,用于最大限度地减小系统中服务进程可访问的资源,从而增强系统安全性,也就是说即使系统漏洞被Hacker钻了空子,也不容易为所欲为。对于开发者来说,也就意味着即使你开发的服务拥有root权限,你开发的系统服务也并不能任意访问系统资源。
2.在Android中与SELinux有关的命令:
前提:处于root模式下
1.adb shell getenforce 获取系统当前SELinux运行模式
2.adb shell setenforce 0 设置运行模式为Permissive
3.adb shell setenforce 1 设置运行模式为Enforcing
Permissive:只打印log,不进行限制
Enforcing:打印log+限制权限
Disabled:不打印log,不进行限制(无法通过ADB设置)
3.如何定位和理解SELinux权限问题
在进行系统开发时,容易遇到开发定制的系统级服务运行时功能不正常的情况,比如获取不到系统属性和cmdline的节点值,这种时候可以优先排查avc权限问题。即在kernel日志或者logcat中通过过滤功能有问题的服务名称或者avc或者audit和找到如下的Log输出。
avc: denied { read } for service=csdn scontext=u:r:csdn:s0 tcontext=u:object_r:sysfs:s0 tclass=file
如果出现了该Log,那么说明当前的系统服务是存在SELinux权限受限的,此时,我们需要理解这句Log对我们来说意味着什么。
首先,我们可以通过以下几个关键词来"肢解"该Log:
denied:read : 被拒绝的权限是read
scontext:csdn : 被拒绝权限的服务是csdn
tcontext:sysfs : csdn被拒之门外的文件未sysfs
tclass:file : 文件类型为file
再整合成我们自己的话,也就是说我们开发的csdn服务被SELinux拒绝读取file类型的sysfs这个文件的权限。
4.如何解决SELinux权限问题
我们再次回到上述的关键词
denied:read : 被拒绝的权限是read
scontext:csdn : 被拒绝权限的服务是csdn
tcontext:sysfs : csdn被拒之门外的文件未sysfs
tclass:file : 文件类型为file
此时,我们需要在源码的根目录下寻找我们开发的服务所需要的策略文件csdn.te,例如我们项目中位于device/qcom/sepolicy/目录下。在里面加入如下代码:
allow csdn sysfs:file { read };
有一点需要注意的地方是,SELinux权限报错并不会一次全部输出在log中,一次可能只会输出一条,所以需要一个权限一个权限去解决,比如在该例子中,假设后面又报了对sysfs的open权限,只需要在上述代码的花括号中加入open即可,即:
allow csdn sysfs:file { read open };
如果是一般的权限问题,可能到这里就解决了,只需要再重新编译刷机即可。
至此,感谢阅读。
BUT,对于有的幸运玩家来说,在Android的SELinux机制中,有的文件是不允许通过这种方式来放开权限的,比如该例中的sysfs,如果像上面那样加了代码并编译,会提示neverallow错误,顾名思义,就是这种操作是从来不被允许的。
#1 neverallow on line XXX of system/sepolicy/csdn.te (or line XXX of XXX) violated by allow system_app sysfs:file { read }; #2 1 neverallow failures occurred #3 Error while expanding policy
对于neverallow错误的解决方法,可以去另外百度,有直接修改neverallow规则,或者去提示violate的策略文件中加上我们需要的例外服务,但这些方法都违反了Google定义的强制规则,并可能导致CTS报错,故在这里我只分享一种比较安全但是稍显复杂的方法。
共需要修改3个文件:
1.在csdn.te同级目录的file.te中,加入一个域的别名,如在该例中,我们原本需要访问的是sysfs域中的一个文件,所以我们在file.te中定义一个新的域,名字可以随便取,如:
type csdn_sysfs, fs_type, sysfs_type;
该语句的意思是,定义一个叫做csdn_sysfs的域(domain),该域具有fs_type和sysfs_type属性(attribute),关于更多domain和attribute的语法和定义可以百度SELinux关键字和语法。
2.在同目录中的file_contexts中加入对需要操作权限的文件路径与我们定义的域进行映射,如:
/sys/devices/sensors_info/sensors_prop/sensor_dir u:object_r:csdn_sysfs:s0
这样即可将sensor_dir与我们定义的域csdn_sysfs映射起来。
3.最后一步,在我们定义的csdn.te策略文件中,把之前的sysfs替换为我们新定义的域,即
allow csdn csdn_sysfs:file { open read };
完成后,编译刷机,对于这部分幸运玩家来说,大部分问题也可以解决了。
BUT, 在这部分幸运玩家中,还有极少数幸运玩家中的幸运玩家,会碰到一个情况,就是编译通过了,刷机成功了,但是仍然在log中打出缺少对sysfs操作权限的错误。
有一个概率较大的原因,是由于我们在file_contexts中映射的路径并不是它实际存在的路径,导致了映射失败,从而添加权限失败。
确定该问题的方法是,adb shell中通过ls -Z
取查看该文件的域,如果映射成功了,会变为csdn_sysfs,但是如果失败,仍然为sysfs。
-r--r--r-- 1 root root u:object_r:sysfs:s0 4096 2021-11-17 08:05 sensor_dir
此时,我们需要在adb shell中到我们需要访问的节点通过ls -l
检查一下该节点的真实路径
lrwxrwxrwx 1 root root 0 2021-11-17 08:05 subsystem -> /sys/devices/virtual/sensors_info/sensors_prop/sensor_dir
然后将第2个文件file_contexts中的代码改为
/sys/devices/virtual/sensors_info/sensors_prop/sensor_dir u:object_r:csdn_sysfs:s0
至此,编译刷机,问题解决。
这篇关于[Android Framework]Android 11 SELinux avc权限解决方法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法