扩展:
在传统的 Linux 系统中,每一个应用程序都对应有一个可执行文件。在这种情况下,我们就可以在安全策略中设定一个规则:当一个可执行文件加载到一个进程中执行时,该进程的安全上下文就设置为指定值。
基础知识都已经学习完了,但是还不知道怎么样,下面从不同的场景,实现了几个例子,可以参考学习一下。
对于 /extern/sepolicy 的修改如下方法编译:
1. mmm external/sepolicy
2. make bootimg
不过对于 MTK 的 Android 系统,不建议修改 external/sepolicy,而是修改 device/mediatek/common/sepolicy,在 plicy 目录下,make relabel 可更新或创建标识映射。
一、添加一个系统服务的权限声明
情景:定义一个 init 启动的 service --- demo_service,对应的执行文件是 /system/bin/demo。
1、创建一个 demo.te 在 /device/mediatke/common/sepolicy 目录下
如果是 Android4.4 的源码,在 /device/mediatke/common/BoardConfig.mk 的 BOARD_SEPOLICY_UNION 宏中新增 demo.te。
如果是 Android5.0 以上的编译会自动包好了整个文件夹里的文件,则不用在 BoardConfig.mk 中添加文件声明。
2、在 demo.te 中添加:demo 的域(domain)类型定义
type demo, domain
3、在 demo.te 中添加:demo 的可执行文件(客体)的类型定义
type demo_exec, exec_type
4、在 demo.te 中添加:init 启动 service 时类型转换声明,直接用一个宏,主要是用于把 demo_exec(客体)转换成 demo(进程域)
init_daemon_domain(demo)
5、绑定执行档 file_contexts 类型(安全上下文),由这个可执行文件启动起来的进程都是 demo 域里的
/system/bin/demo u:object_r:demo_exec:s0
6、根据 demo 需要访问的文件以及设备,定义其它的权限在 demo.te 中
上面的例子最大的疑点就是 init_daemon_domain 这个宏,我们来看看。
下面所有的宏都在 /external/sepolicy/te_macros 文件里定义,具体的定义,请自行查看。
init_daemon_domain:
init_daemon_domain 宏的作用是:设置 init 转换到 daemon 域,可执行文件是 xxx_exec
上面的例子是这样子使用的:init_daemon_domain(demo)
把 $1 = demo 代换进去,相当于执行下面两条语句:
domain_auto_trans(init, demo_exec, demo)
声明 tmpfs 的读写和转换权限,tmpfs 是一些内存临时文件
tmpfs_domain(demo)
domain_auto_trans:
domain_auto_trans 的作用是:定义旧的域转换成新的域的声明,直接把上面的参数代入到 domain_auto_trans 里相当于执行:
# 这个宏应该就是上一篇文章里提到的域转换的权限声明
domain_trans(init, demo_exec, demo)
# 声明 init 域执行 demo_exec 可执行文件,新的域转换成 demo 域
type_transition init demo_exec:process demo;
已经大致完成了一个服务的权限声明,但是还有第 6 点没有完成,如果该服务需要对底层设备文件的读写,该如何声明权限?
二、添加一个进程服务对内核文件节点的读写权限
直接上例程:
情景:一个域(服务或者进程)需要访问一个专属的 char device /dev/demo
(1)定义 deivce 类型,创建一个 device.te 文件
type demo_device device_type;
(2)绑定 demo device 的上下文,在 file_contexts
/dev/demo u:object_r:demo_device:s0
(3)声明 demo 进行 (使用 demo device 的权限) 在 demo.te
allow demo demo_device:chr_file rw_file_perms;
rw_file_perms 是一个集合的宏定义:
define ( 'r_file_perms' , '{ getattr open read ioctl lock }' )
define ( 'w_file_perms' , '{ open append write }' )
define ( 'rw_file_perms' , '{ r_file_perms w_file_perms }' )
三、添加一个 Socket 访问权限
这个类似于文件的权限声明。
情景:一个 native service 通过 init 创建一个 socket 并绑定在 /dev/socket/demo,并且允许某些 process 访问。
(1)定义 socket 类型 file.te
type demo_socket , file_type
(2)绑定 socket 的类型 file_contexts
/dev/socket/demo_socket u:objcet_r:demo_socket:s0
(3)允许所有的 process 访问
# allow app connnectto & write
unix_socket_connect(appdomain, demo, demo)
四、添加一个进程服务对一个属性的访问权限
情景:允许一个进程域对一个属性 sys.poerctl 进行设置
# 声明一个 property_type 类型 powerctl_prop
type powerctl_prop,property_type
# 设置属性的上下文,把属性 sys.powerctl 的上下文设置成 powerctl_prop 类型
sys.powerctl u:object_r:powerctl_prop:s0
# 允许 adbd 进程对 powerctl_prop 上下文的属性进行设置
# set_prop 里面做了两个动作,允许进行对 property 的 socket 进行连接和写入,允许进程设置属性
set_prop(adbd, powerctl_prop)
五、添加一个服务的 binder,对外提供服务
type surfaceflinger_service, service_manager_type;
type surfaceflinger, domain;
surfaceflinger u:object_r:surfaceflinger_service:s0
type surfaceflinger_exec, exec_type, file_type;
/system/bin/surfaceflinger u:object_r:surfaceflinger_exec:s0
# 允许 surfaceflinger 读,写,调用 Binder IPC
binder_use(surfaceflinger)
# 允许 surfaceflinger 访问,调用 binderservicedomain 的 Binder IPC
binder_call(surfaceflinger, binderservicedomain)
binder_call(surfaceflinger, appdomain)
binder_call(surfaceflinger, bootdomain)
# 将 surfaceflinger 与 binder service 的属性域 binderservicedomain 相连
binder_service(surfaceflinger)
六、添加一个 APP 的节点访问权限
(有助于理解 SELinux/SEAndroid)
定义节点类型
device/mediatek/common/sepolicy/file.te
type demo_file, fs_type, sysfs_type;
定义文件上下文
device/mediatek/common/sepolicy/file_contexts
/dev/demo_file u:object_r:demo_file:s0
定义 App 权限
ps -Z 查看应用权限上下文,如 Setting 是 u:r:system_app:s0
rw_file_perms 是一组权限的集合,包含读与写权限
device/mediatek/common/sepolicy/system_app.te
allow system_app demo_file:file rw_file_perms;
定义服务权限,rw_file_perms 是权限集,包含读写权限
device/mediatek/common/sepolicy/system_server.te
allow system_server demo_file:file rw_file_perms;
七、添加一个 APP 的节点访问权限2
定义文件类型
device/mediatek/common/sepolicy/file.te
type proc_mtk_demo, fs_type;
定义虚拟文件系统的文件安全上下文
device/mediatek/common/sepolicy/genfs_contexts
genfscon proc /mtk_demo/current_demo u:object_r:proc_mtk_demo:s0
给予 shell 的进程读写权限, 由 /system/bin/sh 启动的命令会与 shell 有同样地进程权限域
device/mediatek/common/sepolicy/shell.te
allow shell proc_mtk_demo:file { open read write getattr };
APP 的读写权限
device/mediatek/common/sepolicy/system_app.te
allow system_app proc_mtk_demo:file rw_file_perms;
使用方法
App 使用方法之一:
string[ ] cmd = {
"/system/bin/sh", "-c", "echo" + st + " > " + "/proc/mtk_demo/current_demo",
};
Runtime.getRuntime().exec(cmd);
App 使用方法之二,可以直接使用 Jvav File 来读写该文件: