android7.1增加一个开机自启动的bin应用遇到的权限问题
1. 增加开机自启动的bin应用
1.1 增加的源代码
新建external\study,编译生成study,编译方式有两种
(1) mmm external/study
(2) make systemimage,在 device/qcom/common/base.mk下增加LIBCAMERA += study
1.2 增加开机自启动study
device/qcom/msm8937_64/init.target.rc的
on boot
…
service study /system/bin/study
class main
user root
oneshot
第1个study是service名称,第2个study是可执行应用名称。
1.3 增加study的权限
(1) device/qcom/sepolicy/common/file_contexts下增加study
# System files
…
stem/bin/study u:object_r: study_exec:s0
file_contexts文件保存系统中所有文件的安全上下文定义,每行前半部分是文件的路径,后面是它的安全上下文的定义(study_exec)。
安全上下文的格式:USER:ROLE:TYPE[LEVEL],在安全上下文规则中最主要的定义是type,这里是study_exec。TYPE是定义主体和客体所属的类型,对于进程而言,它的类型也称为domian。
(2) 在device/qcom/sepolicy/common/或是其他sepolicy下增加study.te文件。
Te文件属于类型强制规则文件(TypeEnforcement),它主要由类型定义和规则定义两部分组成
#定义了study和study_exec两种类型,study用在进程的安全上下文中,study_exec用在文件的安全上下文中。属性domain表示域,属性是android预先在system\sepolicy\attributes中定义好,当然我们也可以定义,比如在device\qcom\sepolicy\common\attributes中。
#无论是主题还是客体的类型定义,都是通过type语句来完成,通常主体的type具有domian属性,因此,我们也把主体的type称为domain,将domain设置为study的属性,表明zygote是用来描述进程的安全上下文的。
type study, domain;
#表明类型study_exec具有属性exec_type和file_type,即它是用来描述文件的安全上下文的
type study_exec, exec_type, file_type;
init_daemon_domain(study)
allow study study:capability dac_override;
allow study rootfs:lnk_file { read getattr};
allow study system_data_file:dir {opengetattr read write add_name};
allow study system_data_file:file {opengetattr create read write};
allow study shell_exec:file {read openexecute execute_no_trans rx_file_perms};
allow study toolbox_exec:file {getattrexecute read open execute_no_trans};
这些内容是根据avc denied的log增加的。
1) init_daemon_domain(study)
程执行一个type为zygote_exec的文件时,将该子进程的domain设置为zygote,而不是继承父进程的domain。并且给与zygote这个domain,所有定义在tmpfs_domain宏中的权限。
# init_daemon_domain(domain)
# Set up a transition from init to thedaemon domain
# upon executing its binary.
define(`init_daemon_domain', `
domain_auto_trans(init, $1_exec, $1)
tmpfs_domain($1)
')
init_daemon_domain(study)是一个宏,声明当一个domain为init的进程创建一个子进程执行一个type为study_exec的文件时,将该子进程的domain设置为study,而不是继承父进程的domain。并且给与study这个domain,所有定义在tmpfs_domain宏中的权限。
2) allow语句
比如allow study system_data_file:file {opengetattr create read write};
rule_name source_type target_type : classperm_set
source_type:通常是某种属性为domain的类型(type),代表主体。
Target_type(目标类型):允许访问的客体的类型,目标类型可以同时指定多个,
Class(客体类别):允许访问的客户的目标类型可能会涵盖比较广的范围,客体类别可以对客体目标类型进行限制和明确化,例如这里目标类型是system_data_file可以代表文件(file)、目录(dir)及链接(lnk_file),通过file对它进行了限制,因此,在这条规则中只代表文件。
增加的内容需要编译生成新的boot.img和生成study,其中增加的study.te文件在make bootimage编译的时候生成在out\target\product\msm8937_64\root\sepolicy中,而file_contexts文件汇总生成为out\target\product\msm8937_64\root\file_contexts.bin,file_contexts.bin文件,file_contexts.bin 和 file_contexts可互转,见链接:
https://blog.cofface.com/archives/2255.html
sepolicy可用二进制工具bless查找里面的内容。
2. adb方式更新boot.img和study---OK
用fastboot烧录boot.img和adb push study到/system/bin下验证正常。
通过ls -z study方式得到结果:
u:object_r:study_exec:s0system/bin/study
3. 升级包update.zip方式更新boot.img和study---权限问题
更新后提示init: Service study does not have aSELinux domain defined.
通过ls -z study方式得到结果:
u:object_r:system_file:s0 system/bin/study
可见用adb的方式study的类型是study_exec,升级包的方式是system_file,为什么是system_file呢?见文件system\sepolicy\file.te下面的内容
# Default type for anything under /system.
type system_file, file_type;
为了解决init: Service study does not have aSELinux domain defined.问题,需要在升级包的META-INF\com\google\android\updater-script文件增加下面的内容:
set_metadata("/system/bin/study","uid", 0, "gid", 2000, "mode", 0755,"capabilities", 0x0, "selabel", "u:object_r:study_exec:s0");