最近在一个Android 7.0 PDA项目中遇到如下需求:初始化一配置文件,此配置文件需要存储到data分区供系统服务和第三方应用进行读写操作,另外此配置文件在系统重启后保持文件内容不变,除非恢复出厂才可以恢复成默认配置参数 。因为初始化的配置参数为了方便其它同事修改,这里就直接将配置文件直接编译到系统内的方式实现。大概思路如下:自从Android 增加SELINUX安全机制后,系统文件权限为了满足系统服务和第三方应用都能读写的要求,因此我们需要修改SeLinux安全策略相关内容,首先想到在init.rc内拷贝初始化配置文件到Data分区,但是AIL语言没有判断文件存在的功能,因此考虑init.rc内调用shell脚本的方式来满足需求(shell脚本语言可以满足文件判断功能)。
这里只列出需要修改的相关代码,本文基于MT6735 Android7.0 软件平台,不再累述所遇到的坑,具体如下:
一、创建配置文件并修改Makefile编译到系统
创建配置原文件到如下路径alps/device/mediatek/mt6735/my_cfg
alps/device/mediatek/mt6735/device.mk 文件中添加如下一行,系统将会此配置文件编译到系统分区
PRODUCT_COPY_FILES += $(LOCAL_PATH)/my_cfg:system/etc/my_cfg
二、创建一个Shell脚本文件myshell.sh用于拷贝my_cfg配置文件到data分区,myshell.sh同样按照上述方法将其编译入系统内
创建脚本原文件myshell.sh到如下路径alps/device/mediatek/mt6735/myshell.sh 其内容如下:
三、init.rc内添加执行myshell.sh,这里我们没有直接放到init.rc,为了方便直接放入init.rc调用到平台初始化AIL文件内,如下所示:#!/system/bin/sh mkdir /data/mycfg/ chown system.system /data/mycfg chmod 0777 /data/apkins if [ -f /data/mycfg/my_cfg ]; then echo "my_cfg already exist" else cp /system/etc/my_cfg /data/my/my_cfg fi chmod 0777 /data/mycfg/my_cfg
alps/device/mediatek/mt6735/device.mk 文件中添加如下一行,将myshell.sh文件编译到系统分区
PRODUCT_COPY_FILES += $(LOCAL_PATH)/myshell.sh:system/bin/myshell.sh
alps/device/mediatek/mt6735/init.mt6735.rc 由于需要初始化到data分区,这里添加如下代码到on post-fs-data 后四、init.rc内执行shell脚本需要SeLinux为其放权限,这里不累述调试过程,只列出所需添加的安全策略的相关修改on post-fs-data
……
exec /system/bin/sh /system/bin/apkins.sh
为了给自己在开机状态下也可以初始化此文件,添加了service到init.mt6735.rc内,如下所示:
service myshell /system/bin/myshell.sh class late_start user root oneshot seclabel u:r:myshell:s0 on property:persist.sys.mycfg=true start myshell
五 、为配置文件赋值权限,允许其为系统服务和第三方应用读写操作在文件 alps/device/mediatek/common/sepolicy/full/file_contexts 内定义file context 如下所示
/system/bin/ myshell .sh u:object_r: myshell _exec:s0
然后添加myshell_exec相对的安全策略文件device/mediatek/common/sepolicy/full/myshell.te,其内容如下所示
除 此之外,由于在 alps/d evice/mediatek/common/sepolicy/full/shell.te 文件内添加如下一行type myshell, domain; type myshell_exec,exec_type, file_type; init_daemon_domain(myshell) allow myshell system_file:file { read open getattr }; allow myshell self:capability{ chown fowner fsetid setuid setgid dac_override }; allow myshell mycfg_file:dir { write getattr setattr search create add_name remove_name }; allow myshell shell_exec:file { read open getattr }; allow myshell toolbox_exec:file { read open getattr execute execute_no_trans }; allow myshell mycfg_file:file {create write read append open getattr setattr };
allow shell myshell_exec:file rx_file_perms;
首先为配置文件my_cfg添加file context,如下所示
alps/device/mediatek/common/sepolicy/full/file_contexts
/data/ mycfg / my _cfg u:object_r: mycfg _file:s0
然后为系统服务添加对mycfg配置文件的权限,如下所示:
alps/device/mediatek/common/sepolicy/full/system_server.te
allow system_server mycfg_file:dir { search };
allow system_server mycfg_file:file { write read append open getattr };
接着 为其添加第三方应用访问mycfg的权限,所需添加到的文件及其内容如下所示:
alps/ device/mediatek/common/sepolicy/full/untrusted_app.te
allow untrusted_app mycfg_file:dir { search };
allow untrusted_app mycfg_file:file { write read append open getattr };