因为所有的进程均来自于文件,所以我们先从object开始介绍。 Object的type属性在哪里定义的? selinux为系统中的每个object(通常指文件,因为linux中一切皆文件)都静态地定义了一个security context,而这个security context即是上文所说的一个字符串:
user:role:type[:range]
定义各个object的security context的文件一般命名为***file_context,例如其中可能会包含netd binary文件的security context定义如下:
/dev/__properties__ u:object_r:properties_device:s0
...
/system/bin/vold u:object_r:vold_exec:s0
/system/bin/netd u:object_r:netd_exec:s0
/system/bin/wificond u:object_r:wificond_exec:s0
/system/bin/audioserver u:object_r:audioserver_exec:s0
由上述可以看到“/dev/properties ”的security context被定义为“u:object_r:properties_device:s0”, “/system/bin/netd”文件的security context被定义为“u:object_r:netd_exec:s0”。
Subject的domain(例如:“netd”)在哪里定义?如何与动态运行的进程相关联的? 在代码树种,会有很多的.te类型的文件,这些文件很多是以进程的名称命名,对subject domain的定义一般被包含在.te文件中。以“netd”为例: system/sepolicy/private/netd.te
1 typeattribute netd coredomain;
2 typeattribute netd domain_deprecated;
3
4 init_daemon_domain(netd)
5
6 # Allow netd to spawn dnsmasq in it's own domain
7 domain_auto_trans(netd, dnsmasq_exec, dnsmasq)
8
9 # Allow netd to start clatd in its own domain
10 domain_auto_trans(netd, clatd_exec, clatd)
其中第1,2行实现了对domain “netd”的定义: 第1行:声明“netd” domain,具有“coredomain”属性(attribute); 第2行:声明“netd” domain,具有“domain_deprecated”属性(attribute);
假设domain “init”已经被赋予给了init进程。因为所有进程都来自于init进程,那么domain “netd”关联到具体某个进程的过程其实只是一个domain transition的过程。而第4行“init_daemon_domain(netd)”使能了“netd”的domain transition。它是个宏定义,具体如下:
system/sepolicy/public/te_macros
1 #####################################
2 # domain_trans(olddomain, type, newdomain)
3 # Allow a transition from olddomain to newdomain
4 # upon executing a file labeled with type.
5 # This only allows the transition; it does not
6 # cause it to occur automatically - use domain_auto_trans
7 # if that is what you want.
8 #
9 define(`domain_trans', `
10 # Old domain may exec the file and transition to the new domain.
11 allow $1 $2:file { getattr open read execute map };
12 allow $1 $3:process transition;
13 # New domain is entered by executing the file.
14 allow $3 $2:file { entrypoint open read execute getattr map };
15 # New domain can send SIGCHLD to its caller.
17 # Enable AT_SECURE, i.e. libc secure mode.
18 dontaudit $1 $3:process noatsecure;
19 # XXX dontaudit candidate but requires further study.
20 allow $1 $3:process { siginh rlimitinh };
21 ')
22
23 #####################################
24 # domain_auto_trans(olddomain, type, newdomain)
25 # Automatically transition from olddomain to newdomain
26 # upon executing a file labeled with type.
27 #
28 define(`domain_auto_trans', `
29 # Allow the necessary permissions.
30 domain_trans($1,$2,$3)
31 # Make the transition occur by default.
32 type_transition $1 $2:process $3;
33 ')
...
161 #####################################
162 # init_daemon_domain(domain)
163 # Set up a transition from init to the daemon domain
164 # upon executing its binary.
165 define(`init_daemon_domain', `
166 domain_auto_trans(init, $1_exec, $1)
167 tmpfs_domain($1)
168 ')
按照上述定义,将“init_daemon_domain(netd)”做部分扩展以后如下:
allow init netd_exec:file { getattr open read execute map }; allow init netd:process transition;. allow netd netd_exec:file { entrypoint open read execute getattr map }; ifelse(init,
init',
', `allow netd init:process sigchld;') dontaudit init netd:process noatsecure; allow init netd:process { siginh rlimitinh }; type_transition init netd_exec:process netd;
由上述内容可以看到,domain transition包含如下几个方面的内容: 1)必须要允许init进程执行“netd” domain进程依赖的可执行文件; “allow init netd_exec:file { getattr open read execute map };” 2)允许从“init”到“netd”的domain transition; “allow init netd:process transition;” 2)声明“netd” domain进程的文件入口“entrypoint”; “allow netd netd_exec:file { entrypoint open read execute getattr map };” 3)声明从“netd_exec” object启动的daemon进程的domain,从“init”转变到“netd”。 “type_transition init netd_exec:process netd;”
目前为止,我们知道“netd” domain的进程已经被定义了其启动过程,意味着一旦系统启动,就可以创建一个security context为“u:r:netd:s0”的subject(进程)了。那么对这个domain声明权限中包含的各种操作是如何定义的呢?