因为所有的进程均来自于文件,所以我们先从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声明权限中包含的各种操作是如何定义的呢?