手动添加开机服务:
1:做个独立文件夹,里面编辑要运行的bin,如下:
Android.mk---这里面要做c和h这些文件编辑出bin生成到指定目录:
csh.c---main函数在这里面
qmi_dms_client.c qmi_dms_client.h ---调用qmi去与底层沟通函数
2:bin服务文件做好了,开始把它加载到开机启动,
device/qcom/common/rootdir/etc/init.qcom.factory.rc---加这里是工厂模式启动
device/qcom/common/rootdir/etc/init.qcom.rc---加这里是正常模式启动
# csh service
service csh /system/bin/csh
class core 标识这个服务的类型:
#class core(手机最先启动的,如c,c++)
#class main(手机zygote已经启动起来了,假如服务多有可能起不来)
#late_star(最后启动,一般不用)
user root
#user 执行服务前切换到用户,此选项默认是root,因此可以不设置。
group root
#group [ ]*执行服务前切换到组,此选项默认是root,因此可以不设置
oneshot
#服务只启动一次,一旦关闭就不能再启动
disabled
#disabled 禁用服务,此服务开机时不会自动启动,但是可以在应用程序中手动启动它。
on property:sys.boot_completed=1--------检测到开机就启动
start csh
3:添加好了开机启动,我们就要先去做个独立运行它的te,文章最后有对te文件语法运用的解释(网络转载)
保证手机有权限执行这个bin,给bin一个运行的域:
device/qcom/sepolicy/common/csh.te----这个te文件按照需求和报错去修改,前面几号都是默认的添加域,
后面的都是报错和添加对应错误的权限:
#integrated process
type csh, domain, coredomain;
设置csh属于domain域,是一个进程的type,表明csh是用来描述进程的安全上下文的。
type csh_exec, exec_type, vendor_file_type, file_type;
设置csh_exec属于可执行文件的类型.表明csh_exec是用来描述可执行文件的安全上下文的。
#init_daemon_domain(csh)
设置之后,则当其从init进程fork出来之后,将被设置成shelld.te为shelld进程配置的安全上下文,
其拥有同init进程不一样的权限.
domain_auto_trans(init, csh_exec, csh);
设置csh_exec
allow csh csh:capability { dac_override dac_read_search };
#allow csh qmuxd_socket:dir { create read write open search getattr add_name };
#allow csh qmuxd_socket:sock_file { create write };
#allow csh qmuxd:unix_stream_socket { connectto };
allow csh property_socket:sock_file { write };
allow csh diag_device:chr_file rw_file_perms;
allow csh init:unix_stream_socket { connectto };
allow csh sysfs:file { read open };
#allow csh csh:socket { read create ioctl };
allow csh csh_prop:property_service set;
allow csh self:socket write;
allow csh rootfs:lnk_file {getattr};
#allow csh default_prop:property_service set;
allow语句解释:
[external/sepolicy/netd.te]
allow netd sysfs:file write;
如果没有在netd.te中使用上例中的权限配置语句,那么netd就无法往sys目录下的任何文件中写入数据,即使netd具有root权限。
上面这条表示允许(Allow)netd域(Domain)中的进程写(Write)sysfs类型(Type)的文件;
4,独立te文件做好了,我们就要去给对应模块授权和注册,类似解决编译错误,比如te里面定义的类型要去找到对应的模块te添加
csh_exec
执行文件定义bin所在的手机目录:
device/qcom/sepolicy/common/file_contexts: /system/bin/csh u:object_r:csh_exec:s0
csh_prop
te里面有定义prop属性,我们要去授权:
device/qcom/sepolicy/common/property.te: type csh_prop, property_type;
添加系统prop属性
服务的main函数里面有要去设置属性ro.nv.factory_csh,我们在这添加,因为main里面要去针对getprop的属性写值
property_set("ro.nv.factory_csh", (const char*)sn);
所以我们要先给手机系统写一个ro.nv.factory_csh值
device/qcom/sepolicy/common/property_contexts: ro.nv.factory_csh u:object_r:csh_prop:s0
其它的一些te权限错误,针对模块去一个一个添加:个人随性理解,不需要太关注,报什么错加什么权限
读取系统属性权限,property_service
device/qcom/sepolicy/common/init_shell.te: allow qti_init_shell csh_prop:property_service set;
system_app用户访问权限肯定要加的,我们手机正常应用都是system_app权限,不是root
device/qcom/sepolicy/common/system_app.te: allow system_app csh_prop:file r_file_perms;
shell权限,adb或者APK用到访问这个文件属性节点权限
device/qcom/sepolicy/common/shell.te: allow shell csh_prop:file r_file_perms;
APK有系统签名都会生成保存到对应的手机目录,给它读写这个目录权限,这个还是加在对应项目路径的好
device/qcom/sepolicy/项目目录/priv_app.te: allow priv_app csh_prop:file { open read getattr };
5,加的东西差不多了,先去make下代码,看看编译有没有错误,解决错误顺便看看我们的Bin有没有生成
system/bin
6,到此就结束了添加独立开机运行的服务,跟添加开机运行脚本类似(请查看我博客:Android 8.0 高通代码预制apk可卸载,恢复出厂设置apk可恢复)
我们再做一个读取这个自定义服务csh的方式,以方便调用:
String snVersion = SystemProperties.get("ro.nv.factory_csh", Build.UNKNOWN);
te文件网络转载“”
配置实例:
接下来我们以miui自带的服务shelld为例来描述如何给其配置安全上下文,使其能够正常工作。shelld: 这是一个使用binder通讯的binder服务,其是从init进程fork出来运行的进程.我们给shelld配置的相关SEAndroid的安全上下文如下te文件所示:
路径:miui/device/common/sepolicy/common/file_contexts
/system/xbin/shelld? ? u:object_r:shelld_exec:s0
如上所示te语句表明,将/system/xbin/shelld文件在打包system.img时设置安全上下文为u:object_r:shelld_exec:s0,用于保护其不被别的进程可以随意调用执行/system/xbin/shelld, 只有具有权限执行type为shelld_exec的进程才可以执行shelld.为了使其能够添加到servicemanager中去并且能够访问系统资源,我们作了如下配置:
路径:miui/device/common/sepolicy/common/shelld.te
# shelld
type shelld, domain;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 设置shelld属于domain域,是一个进程的type
type shelld_exec, exec_type, file_type;? ? ? # 设置shelld_exec属于可执行文件的类型.
typeattribute shelld mlstrustedsubject;? ? ? ? # 设置shelld是一个可信任的主题
# init_daemon_domain是定义在external/sepolicy/te_macros中的一个宏,如果没有设置该条语句当shelld 从init进程fork出来执行后,shelld会被设置成和init进程拥有一模一样的安全上下文,其拥有和init进程一样的权限
# 设置之后,则当其从init进程fork出来之后,将被设置成shelld.te为shelld进程配置的安全上下文,其拥有同init进程不一样的权限.
init_daemon_domain(shelld)
#domain_auto_trans 也是定义在external/sepolicy/te_macros中的一个宏,设置了如下语句之后,表明shelld进程fork出shell进程来通 过exec执行shell程序时,shell程序将使用其自身的安全上下文,而不是shelld的
domain_auto_trans(shelld, shell_exec, shell)
#unix_socket_connect同样是定义在external/sepolicy/te_macros中的一个宏,设置完如下语句,表明shelld进程可以通过socket同本地服务进行通讯.
unix_socket_connect(shelld, property, init);
#binder_use宏表明shelld可以使用Binder同servicemanager进程进行IPC通讯
binder_use(shelld)
#binder_call允许shelld同对应domain的Binder服务端进程进行binder IPC通讯
binder_call(shelld, binderservicedomain)
binder_call(shelld, appdomain)
#binder_service宏表明shelld是Binder通讯的服务端进程
binder_service(shelld)
#如下语句允许shelld进程来设置自身DAC控制系统权限
allow shelld self:capability
{ setgid setuid dac_override chown fowner fsetid };
...
#如下语句表明允许scontext=shelld的shelld进程来访问tcontext=system_app_data_file安全上下文的目录和文件
# /data/data subdirectory for system UID apps.
allow shelld system_app_data_file:dir create_dir_perms;
allow shelld system_app_data_file:file create_file_perms;
...
# shell
#如下语句表明允许shelld进程可以执行type为shell_exec的文件
allow shelld shell_exec:file { rx_file_perms };
...
#如下语句允许shelld进程将shelld_service添加到servicemanager进程中去
allow shelld shelld_service:service_manager add;
shelld_service是一种service的安全上下文,其定义如下所示:
路径:android/device/common/sepolicy/common/service_contexts
*.shell? ? ? ? u:object_r:shelld_service:s0 #该条语句将名称为miui.shell的binder进程设置安全上下文为 u:object_r:shelld_service:s0
在将shelld_service设置为service_manager_type属性
路径:android/device/common/sepolicy/common/service.te
type shelld_service,? ? ? ? service_manager_type; #该条语句将shelld_service表明为一个service_manager_type的属性,具有这个属性的service才能够添加到 servicemanager中去.
进行了如下配置之后,再将如下添加到Makefile中的变 量BOARD_SEPOLICY_UNION,并将这些te配置文件所在的目录名称添加到BOARD_SEPOLICY_DIRS变量中,则运行命令$ make bootimage, 就能将对应的安全策略文件build进boot.img中在重启之后就能够由init进程加载到内核中去.或者可以将生成的sepolicy文件push到/data/security/current/sepolicy之后接着调用
$ adb push sepolicy /data/security/current/sepolicy
$ setprop selinux.reload_policy 1
使得init重新加载sepolicy,由于/data目录下有了sepolicy,所以它将使用这个新的。
为违反SEAndroid策略的进程配置安全上下文:
一般如果有进程违反SEAndroid策略,我们将在logcat或者dmesg中发现如下类似的log:
<12>[? 12.835933] type=1400 audit(1325843.199:6): avc: denied { write } for pid=295 comm="installd" name="/" dev="mmcblk0p35" ino=2 scontext=u:r:installd:s0 tcontext=u:object_r:cache_file:s0 tclass=dir permissive=0
这样我们可以直接到对应的installd进程的安全策略文件中去添加如下类似语句就能够消除对应的违反规则:
路径:external/sepolicy/installd.te
allow installd cache_file:dir { write };
其中,installd就是log中scontext=u:r:installd:s0表明的domain主体安全上下文,cache_file就是log中tcontext=u:object_r:cache_file:s0的客体安全上下文,客体的类型是tclass=dir表明的dir类型,违反的规则是{ write }。