配套系列教学视频链接:
说明
系统:Android10.0
设备: FireFly RK3399 (ROC-RK3399-PC-PLUS)
前言
本章节重点介绍selinux 策略文件te中经常用到的type和attribute。
一, Type
Selinux实现的是强制类型访问模型, 可以简单理解一切都是类型, 不管是主体还是客体,都必须类型化, 如客体和客体和主体都需要设置安全上下文, 客体格式为u:r:xxx:s0, 主体为u:object_r:yyy:s0, 其中xxx和yyy是可以自定义的, 但是需要通过type进行类型化声明, 你可以理解type为一个动词,为xxx取名,客体一般声明type, 主体一般声明为domain。type的完整格式:
type type_id [, attribute_id,][attribute_id,] …;
方括号表示可选, attribute_id表示和type_id进行关联的属性,可以是多个,之间用逗号隔开
例子如下:
type device, dev_type, fs_type;
此处表示声明(或理解新建)一个device类型, 该类型关联文件系统属性,以及设备属性。在比如以下例子:
type graphics_device, dev_type;
此处表示声明(或理解新建)一个graphics_device类型, 该类型关联另外一个设备属性
定义好之后, 在设置安全上下文的时候就可以做如下操作:
system/sepolicy/private/file_contexts:74:
/dev/adf[0-9]* u:object_r:graphics_device:s0
进程的allow的语句就可以出现:
system/sepolicy/public/charger.te:32:allow charger graphics_device:dir r_dir_perms;
通俗一点可以这么理解:
type 张三, 男人, 律师;
意思是:取了一个新名字叫张三, 属于男人, 也属于律师
type一般会在以下几个文件中出现:
system/sepolicy/public/file.te | 系统中各种文件类型的声明, 如type sockfs, fs_type; # Default type for anything under /system. type system_file, system_file_type, file_type; |
system/sepolicy/public/device.te | 系统中各种设备类型的声明, 如type camera_device, dev_type; 很多时候我们在开发驱动的时候,会新建设备节点如一个串口设备,这个设备节点的type一般都习惯放在device.te中声明 |
system/sepolicy/public/service.te | 声明系统中各种后台服务, 如type audioserver_service, service_manager_type; |
各个进程的te文件 | 如zygote.te,init.te等文件, 主要是用于声明domain, 如type vold, domain; |
二, Attribute
attribute直接翻译过来叫属性, 主要用于在声明type的时候进行关联。 属性类似一个组,type关联属性之后, 新增的type就可以加入到这个属性组中,这个属性(组)拥有的权限, 新增的type也就自然拥有了这个权限),举例:
type system_server, coredomain, domain;
type performanced, domain, coredomain;
{ system_server performanced }都关联(加入)了domain属性组
文件public/domain.te +66
# Device accesses.
allow domain device:dir search;
就可以等同于(伪代码):
allow { system_server performanced } device:dir search;
属性语法:
attribute attribute_id;
声明属性的文件system/sepolicypublic/attributes:
attribute dev_type;
attribute domain;
其实attribute也可以理解成一种type,意味着属性也是可以用在上下文和策略中的, 如:
u:object_r:某属性:s0
allow 某属性 device:dir search;
allow adbd 某属性:dir search;
不同属性所拥有的权限会在不同的te的文件中声明, 比如属性domain会在以下文件中定义
system/sepolicy/public/domain.te:
allow domain self:fd use;
allow domain proc:dir r_dir_perms;
allow domain proc_net_type:dir search;
r_dir_file(domain, self)
allow domain self:{ fifo_file file } rw_file_perms;
allow domain self:unix_dgram_socket { create_socket_perms sendto };
allow domain self:unix_stream_socket { create_stream_socket_perms connectto };
dev_type属性的权限会在文件system/sepolicy/public/file.te +486中定义
allow file_type tmpfs:filesystem associate;
allow file_type rootfs:filesystem associate;
allow dev_type tmpfs:filesystem associate;
除了使用type语句关联类型和属性外,还可以使用typeattribute语句,这个语句允许我们在声明类型之后,再单独关联属性.
如: system/sepolicy/public/mediaserver.te文件中:
# mediaserver - multimedia daemon
type mediaserver, domain; #此处并没有关联mlstrustedsubject属性
type mediaserver_exec, system_file_type, exec_type, file_type;
type mediaserver_tmpfs, file_type;
typeattribute mediaserver mlstrustedsubject; #此处可以添加新的关联属性
三,常见宏
大部分宏都是在system/sepolicy/public/te_macros中定义:
type_transition source_type target_type : class default_type 例子: type_transition vold storage_file:dir storage_stub_file; | 当主体进程域source_type对target_type类型的文件进行class定义的操作时,进程会切换到default_type域中。此时指的是主体进程域的type切换(上下文切换), 注意:此时只是描述了从哪里切换到哪里的问题。 |
domain_trans(olddomain, target_type, newdomain) 缩写: DT 例子: domain_trans(vold, shell_exec, blkid); | 定义允许在olddomain操作target_type时,从olddomain到newdomain转化规则。主要针对进程上下文的转换,大部分进程都是从init进程调动fork和execv,此时子进程就需要从init的进程安全上下文切换到对应的子进程自己应有的进程安全上下文。此时就需要用该宏来切换。注意点, 该宏重点只是申请允许切换。也可以理解为type_transition() 申请权限。 |
domain_auto_trans(olddomain, target_type, newdomain) 例子: domain_auto_trans(init, charger_exec, charger) 当init进程在执行charger_exec可执行程序时,自动切换到charger进程上下文。 | 等同于type_transition和domain_trans两个,既描述从哪里切换到哪里, 也描述切换所需要的允许规则。 |
init_daemon_domain(domain) | 等同于domain_auto_trans, 在定义后台服务serivice的时候,我们经常用这个宏, 后台服务器由init进程启动, 并启动后需要切换到对应的进程安全上下文上去。 |
file_type_trans(domain, dir_type, file_type) 缩写: TT | 在某个domain(进程)在安全上下文为dir_type类型的目录下创建子文件, 子文件会自动继承父目录的文件安全上下文,如果想子文件的上下文创建时变为file_type, 可通过 file_type_trans申请权限, 注意,该宏重点是也只是申请允许切换。 |
file_type_auto_trans(domain, dir_type, file_type) 例子:一般在实际例子用的少 | 等同于type_transition和file_type_trans两个,既描述从哪里切换到哪里, 也描述切换所需要的允许规则。 |
r_dir_file(domain, type) | 允许domain访问安全上下文为type的目录下的文件和符号连接文件 |
unconfined_domain(domain) | 使指定的doamin获得更多的许可(这一宏只是让指定的进程安全上下文继承mlstrustedsubject(在作为主体时, 能绕过MLS检查相关)和unconfineddomain属性(在作为客体时, 能绕过MLS检查相关)) |
binder_use(domain) | 允许domain使用binder通信 |
binder_call(clientdomain, serverdomain) | 允许clientdomain通过binder调用serverdomain |
binder_service(domain) | 定义domain作为binder service的相关许可 |
app_domain(domain) | 为domain定义所有android app所需的基本许可(实际上是继承appoamin属性) |
net_domain(domain) | 为doamin定义访问网络所需的基本许可(实际上是继承netdoamin属性) |
set_prop(domain, prop) | 允许domain对prop属性有设置权限 |
get_prop(domain, prop) | 允许domain对prop属性有获取权限 |