TE规则语法: 规则名称源类型目标类型:客体类别许可
规则名称 allow,dontaudit,auditallow和neverallow。
源类型 授予访问的类型,通常是进程尝试访问的域类型。
目标类型 客体的类型,它被授权可以访问源类型。
客体类别 客体的类别。
许可 表示主体对客体访问时允许的操作类型(也叫做访问向量)。
1允许规则:allow
allow 源类型 目标类型:客体类别许可
allow domain device:fileread;(来自domain.te45) |
这个allow规则的源类型为domain,目标类型为device,客体类别file,许可read,这个规则可以解读为"允许domain读取类型为device的文件"。
2审核规则:audit
默认情况下,SELinux不会记录任何允许的访问检查,只会记录被拒绝的访问检查。
dontaudit规则,它指出哪一个访问尝试被拒绝时不审核,这样就覆盖了SELinux默认的审核所有拒绝的访问尝试的行为。
auditallow规则
记录允许的访问
暂时没发现SEAndroid中有这种规则
Neverallow规则
指定永远不会被allow规则执行的访问,主要是以防万一的作用。因为在载入规则时,neverallow规则会先于allow规则载入,所以,当规则冲突时(同时存在neverallow禁止规则和allow允许规则),会产生编译错误。
使用type语句进行声明:type类型名称[,属性集];
type adbd, domain,mlstrustedsubject;来自adbd.te3
seandroid的20个attributes在 文件:attributes 中定义
源类型和目标类型都可以是attribute,并且没有数量限制,可以在源和目标字段处列出多个类型和属性,如果有多个类型或属性时,它们之间使用空格进行分隔,并使用大括号将它们括起来,如:
allow bluetooth { tun_device uhid_device hci_attach_dev}:chr_filerw_file_perms; 来自bluetooth.te13
l 特殊类型self:
关键字self说明目标类型使用的源类型自身,即目标类型等于源类型。只能出现在目的类型的位置。
allow domain self:dir r_dir_perms;来自domain.te19
等同于 allowdomain domain:dir r_dir_perms
l “非”特殊操作符
用于从一个属性中移除某个类型
allow domain { exec_type -sbin_t } : fileexecute;
allow domain { -sbin_t exec_type } : fileexecute;
客体类别可以是多个,使用大括号括起来
allow appdomain domain:{ file lnk_file }r_file_perms; 来自cts.te14
等同于:
allow appdomain domain:file r_file_perms;
allow appdomain domain:lnk_file r_file_perms;
许可可以是多个,使用大括号括起来,用空格隔开
Line 8: allow domain tmpfs:file { read getattr };来自domain.te8
特殊许可操作符
l 通配符*
包括了客体类别的所有许可
allow adbd self:tcp_socket *; 来自adbd.te9
l 求补算操作符~
除了类出的许可外,其它的许可都包括
类型规则在创建客体或在运行过程中重新标记时指定其默认类型
type_transition 在域转换过程中标记行为发生时以及创建客体时,指定其默认的类型。
用户joe的进程在user_t域,他想要修改密码,于是fork出一个新的process企图去修改密码。密码们都存在/etc/shadow当中,规则说,只有passwd_t类型的进程才可以去修改这个文件,joe同学fork出来的新进程继承了父进程的user_t域怎么办?得找个方法完成域转换,方法就是,运行/usr/bin/passwd文件,这是一个可执行文件,它的类型是passwd_exec_t,运行了它,就可以把自己的域转换到passwd_t了。这个过程中,包括了三个许可规则。
1、 进程的新域类型对可执行文件类型有entrypoint 访问权
只有运行了passwd_exec_t类型的file(/usr/bin/passwd),进程才能转到passwd_t域
allow passwd_t passwd_exec_t : file entrypoint;
passwd_t域将passwd_exec_t类型的file(/usr/bin/passwd)作为entrypoint
2、进程的当前(或旧的)域类型对入口文件类型有execute访问权
user_t类型的进程有权去运行passwd_exec_t类型的file(/usr/bin/passwd)
allow user_t passwd_exec_t : file {getattr execute};
user_t域对passwd_exec_t类型的file(/usr/bin/passwd)有execute权限
3、进程当前的域类型对新的域类型有transition访问权
user_t域有权转换到passwd_t域
allow user_t passwd_t : process transition;
user_t域对passwd_t类型的process有transition权限
特别的dyntransition
process客体类别许可dyntransition,引入这个许可主要是为了和其它系统保持兼容,它允许进程在请求时转换它的域类型,而不是在刚刚执行时,这种进程转换不安全,因为它允许域在新的域中执行任何代码,这样就消除了两个域之间的距离。
默认域转换:type_transition
type_transition user_t passwd_exec_t : process passwd_t;
在上面的例子中的三个许可,只是保证了修改密码时需要的域转换能够成功,可是用户才不懂什么域转换,更不会知道修改一下密码都要转来转去的。好吧,用户既然不知道,那就让计算机知道吧。。。
当一个类型为user_t的进程执行一个类型为passwd_exec_t的文件时,进程类型将会尝试转换,除非有其它请求,默认是换到passwd_t。这是一个默认转换规则,有了它,计算机在发现用户想要改密码时,就会根据这条规则进行必要的域转换。
规则中可以同时指定多个源类型,只要使用大括号将它们括起来,并用空格进行分隔就可以了,同样,我们还可以使用属性,在类型规则中列出类型和属性集,如:
type_transition { user_t sysadm_t }passwd_exec_t : process passwd_t; |
这条type_transition规则在源列表中包括两个类型:user_t和sysadm_t。这条规则将会展开为两条规则,前面这条规则与下面这两条规则的含义完全一样:
#这两条规则. |
客体转换规则为新创建的客体指定一个默认的类型,实际上,我们通常是在与文件系统有关的客体(如file,dir,lnk_file等)上使用这种type_transition规则,和域转换一样,这些规则只会引发一个默认客体标记尝试,也只有策略允许了有关的访问权时,尝试才会成功。
这条type_transition规则指出当一个类型为wpa的进程在一个类型为wifi_data_file的目录下创建一个sock_file文件时,默认情况下,新创建的文件类型应该为wifi_data_file,这条规则使得新建的文件从wifi_data_file转到wpa_socket域。
在这个例子中,wifi_data_file隐含关联了dir客体类别,因为它是唯一能够容纳文件的客体类别,同样,和前面一样,策略必须允许对默认标记的访问,对于这个例子,对类型为wifi_data_file的目录的访问权需要包括add_name,write和search,对类型为wpa_socket的文件要有read和write访问权。
useru roles { r }
将用户u和角色r关联起来,这条语句告诉用户u和角色r在安全上下文中是可以共存的,如果没有这条语句,用户u和角色r进程安全上下文将是无效的,SELinux将会拒绝创建它们,最后拒绝进行域转换。
SEAndroid只有一个用户u。
SEAndroid当中只有两个角色:r和object_r
role语句声明角色标识符以及与声明的角色有关的类型,前面的语句声明角色r以及与这个角色关联的类型domain,这个关联意味着domain类型在安全上下文中允许与角色r共存,如果没有这个role语句,就不能创建新的上下文u:r:domain,
domain是一个attribute,所以u:r:xxx,xxx是属于domain的就可以创建。(关于attribute,参看文件 attributes)
与user语句类似,要使进程安全上下文有效,role语句也是必需要有的,如果没有role语句关联类型domain,即使TE策略允许,域转换也会失败。
客体都有特殊的角色object_r,它是所有客体代表性的角色,这个角色是硬编码进SELinux的,它是不需要声明的,对于所有类型都是隐含允许的,你不要尝试声明角色object_r。