SEAndroid

SEAndroid是在Android系统中基于SELinux推出的强制访问控制模型,来完善自主访问模型中只要取得root权限就可以为所欲为的情况。

SEAndroid工作大致分为两部分:打标签和根据标签做权限控制

打标签

SeAndroid会给所有的文件(包括进程贴上标签),这些标签称为Security Context。我们可以通过ls -Z来查看文件的Security Context或者通过ps -Z来查看进程的Security Context.

Security Context由四部分组成,每一部分用冒号隔开,来看一个例子
u:r:init:s0
u:object_r:rootfs:s0

第一部分u代表用户,在SeAndroid中只有一个用户,就是u
第二部分r或者object_r代表用户的角色,如果角色是r代表的是进程,如果角色是object_r代表的是文件
第三部分init或者rootfs代表类型或者域,一般管文件的这个叫类型,管进程的这个叫域。不同的域拥有不同的权限
第四部分s0代表安全等级,我们不用关注

根据标签做权限控制

这一部分主要是编写Policy文件了,举个栗子

allow netd proc:file write
简单说一下语法
action domain type:object_class operation
allow是TE中定义的动作词,表示允许,类似的还有neverallow表示不允许

netd表示域,就是进程所属的域,代表某一类进程

proc表示type,就是file的type,表示一类文件

file表示object class,是type下的某一个具体类型,是具体给进程操作的东西,这些object class是操作系统预定义好的,在security_class文件中,每一个object class都用class关键字声明

write表示操作,允许进行的操作也是系统定义好的,在access_vector文件中,每一种object class都对应一组操作,比如common file {write read},或者class bind {read write},其中common和class的区别是common可以被继承,而class定义的操作就是针对于某种object class的,不能被继承

上面的te语句的意思是:允许标签为netd的进程去向标签为proc的file写入数据

接下来看一下如何定义type或者domain,使用type关键字定义
type type_name, attribute_name,attribute_name表示type所属的属性组,一个type可以属于多个属性组。这样我们在编译SeLinux策略的时候通过对属性组编写,就可以应用到该属性组之下的所有type了
Android系统定义的属性组一般都放在attribute文件中

SeLinux中用户和角色的定义

在roles文件下定义了角色,每一个角色都有不同的功能,所以每一个角色都和一个域相关联,比如
role r types domain
就把r这个角色和名称为domain的这个域关联起来了

一个用户可以拥有多个角色
user u roles {r}
这样就把用户u和角色r关联起来了

多个角色之间有层级关系,比如老板比总经理大,SeLinux用dominance来表示,比如
dominance{role 老板 {role 总经理;role 总监}}
这就表明老板比总经理和总监都大,从type来说就是老板会继承总经理和总监所关联的属性组

基于角色的控制

在SeAndroid中定义的ur是怎么做到基于角色的控制呢?
使用constrain关键字,形式如下
constrain object_class operation expression
比如constrain file write (u1 == u2 and r1 == r2)
表示只有用户相同并且角色相同的时候,才允许对file这个class执行write操作
其中expression中可以使用的符号有==,!=,dom,domby(就是前面说的上下级关系)

打标签以及transition

这涉及到两个话题:一个是系统是如何给文件还有进程打标签的。另一个是我们知道进程是一个可执行文件的执行过程,系统可以给某个可执行文件打标签,但是当这个可执行文件运行起来变成进程的时候,这个进程的标签是怎么样的。另外,进程都可以fork,那么一个进程fork出来的进程的标签是怎么样的?这就需要transition了

给进程和文件打标签涉及到两个内核文件:initial_sids和initial_sid_context.

initial_sids算是给我们的标签起别名,因为我们知道一个标签是由四部分组成的字符串,直接使用起来不方便,这个就是给标签起别名,举个栗子

sid security
sid init

然后initial_sid_context是把标签的别名和标签联系起来,举个栗子

sid security u:object_r:kernel:s0
sid init u:object_r:unlabeled:s0

接下来重点看一下transition,使用tryp_transition关键字
type_transition source_type target_type:object_class result_type,举个栗子
type_transition init_t apache_exec_t : process apache_t;
这句话是说当一个type为init_t的进程去执行一个type为apache_exec_t的文件时,生成的object_class为process,这个process的类型为apache_t。这样当我们的init进程去执行apache文件的时候,生成的进程type就是apache_t.

理想是美好的,但是要达到上述目的,还需要额外三条语句来配合
allow init_t apache_exec_t : file execute;
允许type为init_t的进程去执行type为apache_exec_t的文件

allow init_t apache_t : process transition;
允许type为init_t的进程切换为type为apache_t的

allow apache_t apache_exec_t : file entrypoint;
允许type为apache_t的进程由type为apache_exec_t的文件生成

由于这样使用起来很麻烦,所以SeAndroid在te_macros中定义了很多宏来帮助我们实现,
比如上面的四句就可以用以下一句宏来实现
domain_auto_trans(init_t, apache_exec_t, apache_t)

SeAndroid中还有一个常见的宏就是给一个目录下的新建的文件打标签的宏,比如
file_type_auto_trans(appdomain, download_file, download_file)

Android系统预先给哪些文件打了标签

Android预先打的标签在XXX_context文件中,比如
/dev/binder u:object_r:binder_device:s0
给/dev/binder文件大的标签是u:object_r:binder_device:s0

一般XXX_context文件都是与预置好的给某些文件或者目录打标签。

apk以及其使用的data目录是如何被SeAndroid打标签的

在PMS启动的时候会去读取mac_permissions.xml文件,该文件中保留了签名和seinfo的对应关系,比如platform签名对应的seinfo是platform,这个seinfo信息在安装app的时候会用到。

然后在安装app的时候,PMS会根据app的签名,给该app赋予一个seinfo.这个seinfo就是Selinux给这个app打标签时候的第三个参数:type

在启动app的时候,PMS会使用到seapp_contexts文件,这个文件定义了不同seinfo的app启动之后的domin, SeLinux就是根据这个文件为app进程和其使用的data目录打标签

在有源码的情况下可以去看一下这两个文件,注释的非常详细

这样就结束了

你可能感兴趣的:(SEAndroid)