您的位置:首页 > 运维架构 > Linux

Android之动态修改system/etc目录下文件的一种实现方式-SELinux

2018-02-27 10:25 1941 查看
在没有root的前提下,system分区为只读,若要动态修改该分区下的文件,可以按照下面流程实现:

1.写执行脚本,这里以修改system/etc/hosts文件为例,在/device/mediatek/mt67xx目录下创建名为modifyhosts.sh的文件,文件内容如下:

[python] view
plain copy

# 修改system分区为可读写  

mount -o remount,rw /system  

  

# 修改内容,可以执行拷贝、删除、写入等操作  

echo 127.0.0.1 localhost > /etc/hosts  

  

# 修改hosts文件权限  

chmod 644 /etc/hosts  

  

# 修改system分区为只读  

mount -o remount,ro /system  

2.配置脚本编译后的路径,在/device/mediatek/mt67xx/device.mk文件中配置脚本编译后的路径:注意:脚本文件后缀可以不要

[java] view
plain copy

PRODUCT_COPY_FILES += $(LOCAL_PATH)/modifyhosts.sh:system/bin/modifyhosts.sh  

3.配置启动脚本的服务,/system/core/rootdir/init.rc文件为系统启动初始化文件,最先加载,配置sh脚本启动服务:

[java] view
plain copy

service remount-sys /system/bin/modifyhosts.sh  

# 这个服务不能通过启动一类服务来启动,只能单独以名字来启动  

disabled  

# 服务只运行一次,退出后不再重启  

oneshot  

4.定义主体的type,在/external/sepolicy目录下新建一个modifyhosts.te文件,在该文件中定义一个名为modifyhosts的domain以及名为modifyhosts_exec的type:

[java] view
plain copy

# 将domain设置为modifyhosts的属性,表明modifyhosts是用来描述进程的安全上下文的  

type modifyhosts, domain;  

# 调试时先加上下面这一句,它会打印出所有需要申请的权限,调试完成后删除该语句。  

permissive modifyhosts;  

# 将exec_type和file_type设置为modifyhosts_exec的属性,表明modifyhosts_exec是用来描述可执行文件的安全上下文的  

type modifyhosts_exec, exec_type, file_type;  

init_daemon_domain(modifyhosts)  

5.定义客体的type,remount-sys进程对应的可执行文件是/system/bin/modifyhosts.sh,则在/external/sepolicy/file_contexts文件中添加/system/bin/modifyhosts.sh文件的安全上下文:

[java] view
plain copy

/system/bin/modifyhosts.sh u:object_r:modifyhosts_exec:s0  

也就是说,客体/system/bin/modifyhosts.sh文件的type是modifyhosts_exec。

6.添加SELinux权限,由于不知道需要添加哪些权限,故按上面5个步骤操作完后,可以先编译版本刷机,之后在adb shell 下执行:

[java] view
plain copy

setprop ctl.start remount-sys  

dmesg > /data/data/a.txt  

导出执行log到指定目录下,根据log内容添加指定权限,dmesg是打印kernel层log的命令。

log内容如下:

[java] view
plain copy

[  659.805760] .(0)[269:logd.auditd]type=1400 audit(1481859095.080:77): avc: denied { remount } for pid=5080 comm="mount" scontext=u:r:modifyhosts:s0 tcontext=u:object_r:labeledfs:s0 tclass=filesystem permissive=1  

从log可知,需要为modifyhosts.te文件添加权限,SELinux权限规则语句一般如下:

[java] view
plain copy

allow 主体的Type 客体的Type:操作 权限1;  

或者:  

allow 主体的Type 客体的Type:操作 { 权限1 权限2 };  

可以从log中获取四个参数得出最后的规则:

[java] view
plain copy

allow modifyhosts labeledfs:filesystem { remount };  

添加权限后再次编译版本,如果编译失败,且失败原因如下:

[java] view
plain copy

libsepol.report_failure: neverallow on line 284 of external/sepolicy/domain.te (or line 5613 of policy.conf) violated by allow modifyhosts labeledfs:filesystem { remount };  

libsepol.check_assertions: 1 neverallow failures occurred  

这是因为系统在domain.te文件中定义了全局的neverallow策略,与modifyhosts.te中allow的策略有冲突,此时请确认该权限是否是服务所必须的,如果是必须的可以在/external/sepolicy/domain.te文件中有冲突的neverallow语句中添加自己为例外:

[java] view
plain copy

neverallow { domain -kernel -init -recovery -vold -zygote  

    -modifyhosts # add by zhangyongfei  

 } { fs_type -sdcard_type }:filesystem { mount remount relabelfrom relabelto };  

7.通过前面6步之后就调试好了,下面该在系统代码中添加真正调用该服务的代码了,这里可以在系统服务(AMS、PMS等)中调用下面方法启动该服务:

[java] view
plain copy

// remount-sys是在init.rc中自定义的服务名  

SystemProperties.set("ctl.start","remount-sys");  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: