SEAndroid基础

1.前言
    安全是在移动终端普及下,移动互联网应用需要解决的重头戏。当然,有了网络安全的保障下,还需要设备自身的安全保证,因此,Android集成了基于SELinux的SEAndroid。
2.SEAndroid、SELinux与Android
    SEAndroid(Security-Enhanced Android,Security Enhancements for Android™ (SE for Android))是将Linux操作系统上的MAC强制存取管控套件SELinux移植到Android平台上,用于增强Android系统对APP等的存取管控,用于确保每个APP的独立运行,防止恶意APP对系统或其他应用程序的攻击。
    那么什么是MAC?其与传统的DAC区别在哪?在SELinux出现之前,Linux上使用的安全模型为DAC(Discretionary Access Control,自主访问控制),其思想为:进程理论上所拥有的权限与执行它的用户的权限相同,而MAC(Mandatory Access Control,强制访问控制)的思想为:任何进程想在SELinux系统中干任何事情,都必须先在安全策略配置文件中赋予权限,凡是没有出现在该文件中的权限,进程就没有相应的权限。从而在DAC下,ROOT用户能进行所有的操作,但在MAC下则不行,特殊人物也需按规则来办事了,有提前在MAC里申请配置的才能进行相应权限的操作。
    综上所述,SEAndroid=SELinux+Android,下图可以看出传统Android和使用了SELinux的SEAndroid之间对权限操作的区别:
    左边和右边分别是未使用和使用SELinux的Android系统对于数据操作的区别,未使用SELinux的Android系统下,ROOT用户权限拥有最高权限,能对用户区与系统区进行操作,而普通用户只能对用户区进行操作,而使用了SELinux的Android系统下,不管是普通用户权限还是ROOT权限的程序,对用户区和系统区操作时,都必须通过SEAndroid的验证,拥有相应权限才能对相应文件进行操作,否则只能被拒门外。
    SEAndroid实现的是“白名单”的安全机制,只有在安全策略文件中设置相应权限才能进行操作,否则默认为拒绝状态,即默认没有权限。
3.Policy
    SELinux拥有自己的规则来编写安全策略文件,称为SELinux Policy语言。Linux下有两种东西:一种是静止的(Inactive),一种是活跃的(Active)。静止的是文件(Linux下一切皆文件),活跃的是进程。进程能发起动作,如打开文件并操作它,而文件只能被进程操作。那么SELinux里也必然针对这些东西来进行权限的配置,只有活跃的进程和静止的文件在权限相符时活跃的进程才能进行相应的操作。
    SELinux中,每种东西都会被赋予一个安全属性,叫作Security Context(下用SContext表示),是一个字符串,主要由3部分组成。
    1)活跃的进程
        使用ps -Z命令可以看到有如下输出:
        u:r:init:s0                    media     172   1     /system/bin/MtkCodecService
        u:r:dm_agent_binder:s0         system    182   1     /system/bin/dm_agent_binder
        u:r:init:s0                    system    184   1     /system/bin/ppl_agent
        u:r:mtkbt:s0                   bluetooth 199   1     /system/bin/mtkbt
        其中,第一列为相应进程的SContext,下面以MtkCodecService的u:r:init:s0来说明:
        u:user,SEAndroid中定义的唯一一个SELinux用户,在external/sepolicy/users文件中定义;
        r:role,对应SELinux中的一种比较高层次的机制:RBAC(Role Based Access Control,基于角色的访问控制),其提供更方便的权限管理思路,一个u可以属于多个role,不同的role具有不同的权限,其在external/sepolicy/roles文件中定义;
        init:代表该进程所属的Domain为init。MAC的基础管理思路是基于Type Enforecement Access Control(TEAC,一般用TE表示);
        s0:其与SELinux为了满足军用和教育行业而设计的MLS(Multi-Level Security)机制有关,MLS将进程和文件进行分组,不同级别的资源需要对应级别的进程才能访问,在external/sepolicy/mls文件中会调用gen_sens(mls_num_sens)宏,该宏在external/sepolicy/mls_macros文件中定义,其最终只使用sensitivity关键字定义了s0这一级别,即在目前的Android下只定义了一个级别。
    2)静止的文件
        使用ls -Z命令(在/目录下执行)可以看到有如下的输出:
        drwx------ root     root              u:object_r:rootfs:s0 root
        drwxr-x--- nvram    system            u:object_r:rootfs:s0 sbchk
        drwxr-x--- root     root              u:object_r:rootfs:s0 sbin
        倒数第2列为相应文件的SContext信息,以第一行root的u:object_r:rootfs:s0说明如下:
        u:user,代表创建该文件的SELinux user;
        object_r:文件是静止的,在SELinux下,静止的东西都用object_r来表示role;
        rootfs:静止的东西的Type,与活跃的东西的Domain是对应的。
        从上面对于Inactive和Active两类SContext的分析,可以了解到SContext的基本格式:
        user:role:type[:range]
        其中最核心的就前3部分。
        MAC的基本管理单元是TEAC,然后是高一级别的RBAC,RBAC是基于TE的,故而TE也是SELinux中最主要的部分。下面以一个TE例子说明下在TE(*.te)文件中对于SContext配置时的语法规则:
        allow netd proc:file write
        解析如下:
        allow:规则名字,表示授权。TE的rule_name有如下4种:
                allow:赋予某项权限;
                allowaudit:audit含义就是记录某项操作,默认情况下SELinux只记录那些权限检查失败的操作,而allowaudit则包含检查成功的操作也记录,这只允许记录,与上面提到的赋予权限无关,赋予权限只能使用allow;
                dontaudit:对那些权限检查失败的操作不做记录;
                nerverallow:禁用某项权限,上面提到如果没有在安全策略文件中赋予权限的,都是被禁止的,那么该关键字不是多此一举?当然不是了,用它主要是检查安全策略文件中有没有违反该项规则的allow语句,即一般情况下使用allow语句太多,怕误操作允许了某项权限,而使用nerverallow来定义我们明确不允许的权限,这样必然会有冲突出现,那么检查的效果就生效了。
        netd:source type,也称subject、domain;
        proc:target type,代表其后的file所对应的Type;
        file:Object Class,代表能够给subject操作的一类东西,如File、Dir、Socket等;
        write:在该Object Class中所定义的操作。
        该句总的意思是:允许netd进程对proc类型file进行write操作。
        从上面可以看出SELinux对应该配置的语句格式为:
        rule_name source_type target_type:class perm_set
        其中,当source_type、target_type、class、perm_set为多项时,可以使用花括号“{}”将起括起来,其可与如下的操作符结合使用:
        ~:相当于“取反”操作,即除了指定的项外的所有项;
        -:去除指定项;
        *:表示所有项。
4.SELinux模式
    在SELinux开启下,可以支持以下两种模式:
    1)permissive mode
         宽容模式,在该模式下,SELinux仅警告并记录失败的事件,而不会产生实际的限制效果。
    2)enforcing mode
         强制模式,在该模式下,SELinux会根据安全策略来做操作相关限制,不符时会拒绝访问,并产生相应的事件记录。
    在Android4.3,SELinux是permissive模式,而在Android4.4,SELinux可支持两种模式,但默认是enforcing模式(只对installd、netd、vold和zygote这4个root进程的Domain生效,其他都是permissive模式),如要切换为permissive模式,可在Kernel启动参数中加入androidboot.selinux=permissive。
    在Android运行状态时对模式进行操作:
            获得当前模式:adb shell getenforce
            切换为enforcing模式:adb shell su 0 setenforce 1
            切换为permissive模式:adb shell su 0 setenforce 0
    在Android的init.rc脚本中设置默认初始模式,在适当位置使用setenforce命令配置,参数功能同上。
5.编译及调试
    使用mmm external/sepolicy会在out/……/root目录下生成sepolicy文件,将其push到/data/security/current/目录下,然后setprop selinux.reload_policy 1,让init重新加载新的policy文件,默认情况下会先使用/data/security/current目录下的sepolicy文件,如果该文件不存在,再使用/目录下的同名文件。
6.实例
    在MTK8382平台下调试M Sensor时碰到串口有如下提示:
    [   78.031936].(3)[1283:akmd09911]type=1400 audit(1404911771.430:249): avc:  denied  { read } for  pid=1283 comm=”akmd09911″ path=”/system/bin/linker” dev=”mmcblk0p5″ ino=205 scontext=u:r:akmd09911:s0 tcontext=u:object_r:linker_exec:s0 tclass=file
    [   78.044496].(3)[1283:akmd09911]type=1400 audit(1404911771.440:250): avc:  denied  { read write } for  pid=1283 comm=”akmd09911″ name=”msensor” dev=”tmpfs” ino=3211 scontext=u:r:akmd09911:s0 tcontext=u:object_r:msensor_device:s0 tclass=chr_file
    [   78.047459].(3)[1283:akmd09911]type=1400 audit(1404911771.450:251): avc:  denied  { open } for  pid=1283 comm=”akmd09911″ name=”msensor” dev=”tmpfs” ino=3211 scontext=u:r:akmd09911:s0 tcontext=u:object_r:msensor_device:s0 tclass=chr_file
    那么该如何添加相应的权限到TE文件中呢?
    我们最终在mediatek/custom/common/sepolicy/akmd09911.te文件中添加了如下语句:
    allow akmd09911  linker_exec:file { read };
    allow akmd09911  msensor_device:chr_file { open read write };
    其中,source_type akmd09911与上面的提示scontext中的type对应(MTK的文档里说是与comm对应),target_type linker_exec和msensor_device与tcontext中的type对应,object_class file和chr_file与tclass对应,而相应的操作集{ read }和{ open read write }则一目了解了,与denied后的项对应。
    如果我们懒得去将一条条denied转换为allow,那么在Ubuntu下可以使用如下命令安装我们需要的audit2allow命令:
    sudo apt-get install policycoreutils
    安装好后,我们可以执行如下命令进行TE文件的生成:
    dmesg > dmesg.txt
    audit2allow -l -i dmesg.txt –o dmesg.te
    接下来打开dmesg.te就可以看到相应的规则了,直接将相应规则放到相应的TE文件即可。

评论

此博客中的热门博文

I/O映射之I/O端口

通过Netlink检测网线插拔

使用seq_file