以Android L读取系统所有logcat并写入文件为例分析Android 添加系统服务,通过系统服务申请selinux的权限执行shell脚本,以及avc:dined应该怎么申请权限
来源:互联网 发布:matlab与java混合编程 编辑:程序博客网 时间:2024/05/08 11:41
首先说说环境:
基于Android L的aosp修改(修改对于此文基本无影响)过的sorce code.
本来的思路是通过setenforcing permissive来开启宽容模式,可是宽容模式就是selinux的debug模式就相当于关掉了seliux毫无安全可言,而下面说到的,是以我的读取系统logcat并写入文件为例,来讲在selinux中申请我们所需的权限。
系统服务:
在init.rc里面声明service,用我启动logcat的服务为例:
首先为了格式,找到声明service的地方。然后添加:
service start_logcat /system/bin/start_logcat.sh oneshot disabled on property:service.start_logcat=1 start start_logcat
看看代码。
第一段:
第一行:service代表声明,start_logcat是service的名字 /system/bin/start_logcat.sh是指的这个service指向的(要执行的脚本的路径) 注意了,这个路径指的是安卓系统也就是build之后的路径,而我放在system/bin下是因为这里的start_logcat.sh被我赋予了可执行的权限(后面会说怎么赋予),我第一次做的时候创建了脚本用chmod 777给的权限,实际是毫无意义的。
第二行代码的oneshot指的是只执行一次。
第三行代码的disabled指的是开机不启动。
第二段:
第一行代码的on跟java代码的if同意 后面用property关键字声明了一个key为 service.start_logcat的property。整行的意思就是 声明一个key是service.start_logcat的property并且在其value是1的时候执行下一行代码。
第二行代码显然易见启动 start_logcat service。
也就是说 我们在安卓程序里 只要调用( 其中SystemProperties可能需要用到反射来调用set方法):
SystemProperties.set("service.start_logcat", "1");
系统监听到key为service.start_logcat的property的value变为1的时候就会去启动这个service去执行脚本.
还有一种启动方式 是不需要上面的第二段代码只声明一个service 然后在调用的时候通过这种方式:
SystemProperties.set("ctl.start", "start_logcat");这种方式也会启动我们的系统服务去执行指向的脚本。
好,接下来说重点,重点是,我这个脚本执行(别忘记将脚本在.mk文件中cp到system/bin下)的内容是:
logcat -v time -f /sdcard/logcat -r 600000-n 1
也就是在sdcard下创建名为logcat的文件,大小为600M。一共2个文件交替着去记录logcat 超过600M就交替。
上篇文章说到了Android L之后selinux相关的权限限制,有兴趣的可以去看看。
接下来就说说遇到的问题。
首先,会报一个叫service:start_logcat selinux needs a domian 是这个错,大致是这么写的。
然后下面会报avc:dined的错误(待会会详细说这个错误怎么解决)。
后面会着重讲解avc:dined的错误,先看第一个错。第一个错的意思呢就是我们的service在执行脚本的时候selinux约束必须有domain
具体做法就是去device/xx/common/sepolicy 里面添加 一个.te文件(同级目录下有一个system_app.te,如果在这儿添加是不需要用system service的方式的,但是会开放对所有systemapp的权限,请谨慎处理),以logcat为例,创建start_logcat.te 并且在 file_contexts 下添加:
/system/bin/start_logcat.sh u:object_r:start_logcat_exec:s0
这个就是上面说到的让 /system/bin/start_logcat.sh具备可以执行的权限。
接下来看看.te文件,同样以logcat为例:
#Additional rules for shell type start_logcat, domain; type start_logcat_exec, exec_type, file_type; init_daemon_domain(start_logcat) # allow shell to run dmesg allow start_logcat kernel:system syslog_read; allow start_logcat toolbox_exec:file { read getattr open execute execute_no_trans }; allow start_logcat logcat_exec:file { read getattr open execute execute_no_trans }; allow start_logcat serial_device:chr_file rw_file_perms; allow start_logcat shell_exec:file read; allow start_logcat self:capability dac_override; allow start_logcat system_data_file:dir { write add_name }; allow start_logcat system_data_file:file { create open append }; allow start_logcat logd:unix_stream_socket {connectto}; allow start_logcat vfat:dir { search write add_name create }; allow start_logcat logdr_socket:sock_file {create write}; allow start_logcat vfat:file create_file_perms; allow start_logcat system_file:file execute_no_trans;
将一个类型设置为另一个类型的属性可以通过type语句实现,type start_logcat, domain; 表示将类型 domain设置为start_logcat的属性。这样就可以表明start_logcat描述的类型是用来描述进程的安全上下文的。
对于type start_logcat_exec, exec_type, file_type; 同理。
在# allow shell to run dmesg 这行注释下面的代码都是为start_logcat这个服务在selinux申请的权限。当然logcat可能不需要这么多权限, 我是考别的文件 然后在基础上添加需要的。
接下来问题来了,我们怎么知道都需要哪些权限。
有趣的是,我并不知道我需要什么权限,wtf。
能想到的唯一答案就是通过avc:dined的报错来分析我需要什么样的权限。
那么首先就要会看avc:dined的错误。
还是以logcat为例:
avc: denied { connectto } for pid=1712 comm="logcat" path="/dev/socket/logdr" scontext=u:r:start_logcat:s0 tcontext=u:r:logd:s0 tclass=unix_stream_socket permissive=0
这个呢 就是selinux在enforcing模式下的安全策略的限制报出的错。
接下来看看这个log我们应该怎么看:
denied {} 代表缺少什么 connectto
scontext 代表谁缺少 start_logcat
tcontext 代表对哪个文件 logd
tclass 代表文件类型 unix_stream_socket
现在再来看看上面的报错。 也就是说 我们的start_logcat的服务 对unix_stream_socket类型的logd文件缺少connectto的权限。
那么我们自然知道.te的规则文件怎么写了,在start_logcat.te中添加 :
allow start_logcat logd:unix_stream_socket {connectto};
允许start_logcat对unix_stream_socket类型的logd文件有connectto的操作。
酱紫(继续build,然后如果报错,按上所述添加需要的权限),我们就完成了安卓向selinux申请所需权限并执行所需脚本从0到有的整个过程。
ps:如果有更好的可以知道做什么需要什么权限的办法 ,欢迎告知,学习为主。
顺便附上查看kernellog的命令:
adb shell cat /proc/kmsg
这个是以我自己的logcat为例来讲述的整个selinux申请所需权限的过程,如果有不对,欢迎指出,共同进步。
- 以Android L读取系统所有logcat并写入文件为例分析Android 添加系统服务,通过系统服务申请selinux的权限执行shell脚本,以及avc:dined应该怎么申请权限
- 【系统服务】系统权限的申请
- 【备忘】Android向系统申请权限的
- android向系统申请的权限
- Android系统中如何添加权限-----以TP为例
- Android系统下在te文件中为指定服务添加sepolicy权限
- android程序可以向系统申请的权限一览表
- android手机系统 6.0后的权限申请问题
- 为Android系统添加服务
- Android 申请运行时权限 以camera为例
- 安卓6.0系统权限申请android.permission.WRITE_SETTINGS
- 安卓6.0系统权限申请android.permission.WRITE_SETTINGS
- Android中使用系统api申请开启权限
- 关于android 7.0系统怎么添加自定义的系统服务
- android系统服务及权限设置
- 推荐一款以Rest服务方式的通用权限系统\智能权限系统\Java权限系统\j2ee权限系统
- Android 添加系统服务
- Android 添加系统服务
- NumPy实战:Chapter-2(Matplotlib入门)
- 基本数据类型 自动装箱拆箱
- Entity Framework连接MySQL,出现报错:由于出现以下异常,无法生成模型:“表“TableDetails”中列“IsPrimaryKey”的值为DBNull
- javascript中=,==,与===的区别;以及特殊值NaN的讲解
- 7.1编译报错 "-Xmx<size>"
- 以Android L读取系统所有logcat并写入文件为例分析Android 添加系统服务,通过系统服务申请selinux的权限执行shell脚本,以及avc:dined应该怎么申请权限
- 调用Android系统分享功能(可分享纯文本信息)
- 迭代器(关键词:Python/iterator/iterable/__iter__/next)
- Android编程权威指南(第2版)—第14章挑战练习
- 线程的优先级
- 呈现数据
- 阿里云|Centos7及以上|REDIS 安装教程
- matlab启动时,命令行中出现“java.lang.ClassNotFoundException”错误代码
- 相关sql语句的练习