android SELinux 问题解决-如何用工具生成相关权限配置文件?
16lz
2021-01-26
转自http://blog.csdn.net/mcgrady_tracy/article/details/53217982
SELinux是什么?即Security-Enhanced Linux,是由美国国家安全局(NSA)发起,基于Linux开发的一个安全增强系统,旨在提高系统的安全性。
而SEAndroid基于SELinux,在Android5.0上被正式启用。
SELinux有3种操作模式,分别是Disabled、Permissive、Enforcing,在android中可以通过输入adb命令getenforce来获取当前系统的SELinux状态。Disabled表示SELinux是被禁止的,Permissive只发出警告但不拒绝访问,而Enforcing在发出警告的同时会拒绝访问。自Android5.0开始,默认模式为Enforcing,很多时候会带来一些权限问题。
那么怎么来确认是不是SELinux带来的权限问题呢?当Kernel log出现"avc: denied"这些字段时,那么这些问题都是这一类问题。
如何进一步确认呢,可以输入adb命令setenforce 0来改变当前SELinux的工作模式为Permissive,然后再重启相关服务,看是否还有这种问题,如果没有,说明的确是SELinux带来的问题。
如何编写te文件呢?
假设我有一个服务key,需要读取/dev/input/event0这个input设备,代码如下: [cpp] view plain copy
- int main(void)
- {
- int fd;
- struct input_event event;
- fd = open("/dev/input/event0", O_RDONLY);
- if (fd < 0) {
- exit(1);
- }
- while (1) {
- if (read(fd, &event, sizeof(struct input_event)) > 0) {
- if (event.type == EV_KEY) {
- printf("key %d %s\n", event.code,
- event.value ? "down" : "up");
- }
- }
- }
- }
最终这段代码将被编译生成一个bin文件,在/system/bin/目录下。
那么首先是需要在init.rc里面启动这个服务:
- service key /system/bin/key
- class core
服务启动之后,我们还需要为改服务创建一个domain。 [cpp] view plain copy
- # key.te
- type key, domain;
- type key_exec, exec_type, file_type;
- init_daemon_domain(key)
修改file_contexts,将key加入到新创建的domain中。 [cpp] view plain copy
- /system/bin/key u:object_r:key_exec:s0
我们可以通过ls -Z命令查看一下/system/bin/key文件的安全上下文: [cpp] view plain copy
- -rwxr-xr-x root shell u:object_r:key_exec:s0 key
现在key这个service还不能访问event0这个设备,甚至都影响到了service的启动,提示的错误信息如下: [cpp] view plain copy
- avc: denied { search } for pid=269 comm="key" name="input" dev="tmpfs" ino=176 scontext=u:r:key:s0 tcontext=u:object_r:input_device:s0 tclass=dir permissive=0
这类问题就是SELinux权限问题,那么怎么添加权限呢?
本来我们可以通过ps -Z命令来查看key这个service的安全上下文,但是现在由于权限问题service这个服务都不能启动,只能分析一下错误log了。
根据log来看,安全上下文为"u:r:key:s0"这个进程对安全上下文为"u:object_r:input_device:s0"的文件没有访问权限,我们通过ls -Z命令看一下/dev/input/event0这个文件: [cpp] view plain copy
- crw-rw---- root input u:object_r:input_device:s0 event0
它的安全上下文的确为"u:object_r:input_device:s0",再结合代码来看,也的确是这样的,再通过log来看,是没有search权限,那么我们把这个权限先加进去(加入到key.te文件中): [cpp] view plain copy
- allow key input_device:dir { search };
Ok,报的没有search权限问题没有,但是又报了新的权限问题: [cpp] view plain copy
- avc: denied { read } for pid=270 comm="key" name="event0" dev="tmpfs" ino=2352 scontext=u:r:key:s0 tcontext=u:object_r:input_device:s0 tclass=chr_file permissive=0
也的确是这样,代码里面对event0设备还有open、read操作,报权限问题是很正常的,加入open、read权限: [cpp] view plain copy
- allow key input_device:chr_file { open read };
没有再报权限问题了,key这个service也能够启动了,通过ps -Z命令可以看到这个service的安全上下文的确为"u:r:key:s0": [cpp] view plain copy
- u:r:key:s0 root 272 1 /system/bin/key
自己手动编写te语句有点麻烦,没关系,可以根据log然后通过工具自动生成te语句,这个工具就是audit2allow。
在ubuntu上,输入下面的命令来安装这个工具: [cpp] view plain copy
- sudo apt-get install policycoreutils
那么这个工具怎么使用呢,例子: [cpp] view plain copy
- adb shell dmesg | audit2allow
或者我还可以把前面的抓的错误信息单独拿出来,然后通过audit2allow工具来生成: [cpp] view plain copy
- echo "avc: denied { read } for pid=270 comm="key" name="event0" dev="tmpfs" ino=2352 scontext=u:r:key:s0 tcontext=u:object_r:input_device:s0 tclass=chr_file permissive=0" | audit2allow
生成的te语句如下: [cpp] view plain copy
- #============= key ==============
- allow key input_device:chr_file read;
语句是能够生成的,只是不全,手动补全就可以了。
参考:
https://source.android.com/security/selinux/validate.html
https://source.android.com/security/selinux/device-policy.html
更多相关文章
- Android游戏开发学习笔记(三):视频的播放
- Android(安卓)6.0 运行时权限封装之路
- android 编译命令
- Android(安卓)应用通知权限是否开启以及跳转到设置界面
- [置顶] android wifi调试总结 theros AR6K命令小结 android wifi
- [Android7.1] Gitolite + Repo 管理 Android(安卓)源码
- android简单的请求手机权限封装
- [PX3][Android7.1] 调试笔记 去除USB权限弹窗
- Android(安卓)8.0 适配安装未知来源权限 canRequestPackageInsta