SELinux on Android(二)

好的,继续更新神作。


  • 如何把SELinux特性加入到安卓中


安卓中的SELinux目前是以enforcing mode存在的,而不是disable状态或者permissive状态(permissive状态可以作为指引,使测试和开发变得更加容易)。

尽管enforcingmode是全局的,请牢记着这种情况在基于单个domain的这种情况可是例外,就像在应用domain中一样。

SEAndroid拥有一切SELinux的特征。你只需要把最新的安卓内核整合进来,然后把~platform/external/sepolicy(你可以在该路径下找到许多例子)路径下的文件包含进来:

 https://android.googlesource.com/kernel/common/

 https://android.googlesource.com/platform/external/sepolicy/

这些文件在编译时会包含SELinux内核安全策略并兼容以前老版本的安卓操作系统。

把这些文件放置在 /device/manufacturer/device-name/sepolicy路径下。

然后修改BoardConfig.mk文件(该文件位于包含sepolicy的子路径),来引用sepolicy策略文件,方法如下:

BOARD_SEPOLICY_DIRS:= \ 
        <root>/device/manufacturer/device-name/sepolicy
BOARD_SEPOLICY_UNION:= \ 
        genfs_contexts \  
        file_contexts \  
        sepolicy.te


在重新编译整个工程之后,你的设备就具备SELinux功能了。

你现在可以定制自己的SELinux策略,来适应你自己对安卓系统的修改(这将会在定制段落说明),或者验证你的当前存在的配置(后面有介绍)。

 

 标签,规则和域

SELinux是由与动作或者策略匹配的标签所决定,而标签取决于你允许了什么。socket,file和process 都有SELinux各自对应的标签。SELinux的决定取决于对象所关联的标签和相互的策略。在SELinux中,标签是由user:role:type:mls_level 这样的形式定义的,其中的type(类型)是影响决策的重要组成部分,而这些对象(objects)则被他所属于的类和类型去匹配其他类的权限检查

策略规则的格式是allow domains types:classes permissions

·         Domain – 进程或者进程集合的标签

·         Type – 对象(e.g. file, socket)或者对象集合的标签

·         Class – 对象(e.g. file, socket)被允许(授权)访问的种类

·         Permission – 允许采取的操作(e.g. read, write

下面我们来看一个例子:

allow appdomain app_data_file:file rw_file_perms

这条策略的意思是说一个app可以去读写有app_data_file标签的file。注意到这条规则依赖于一个已经定义好的全局的宏文件,这些宏可以在 文件te_macros里面找到。宏是用来提供公共的类,权限,规则,是用来帮助减少由于相关权限缺少而导致失败的可能。在编译时这些这些使用宏的地方将会被宏中所使用的语句替换掉。

以上的格式是创建规则的重要组成部分,再来看一遍,一条规则有这么多

<rule variant> <source_type> <target_type> : <class> <permission>

这条rule表明当一个打着source type标签的对象尝试去以一个符合permission的动作去访问属于class类的有着target_type标签的对象的时候这条规则就会被触发。实际应用中,这条规则常常包含着几条permission比如说:

allow domain null_device:chr_file { getattr open read ioctl lock append write};


domain是所有进程都有的标签,null_device是chr_file类/dev/null的标签,这条策略的意思就是允许对/dev/null进行基本的读写操作。

一般说来一个domain都有与它匹配的打了标签的进程

比如一个APP是运行在自己的打untrusted_app标签的进程中的,所以只能获得对应于这个标签的受限的权限。

随着系统安装的原装APP是在另一个标签下的。而系统应用则是在system_app标签下的拥有另外的权限

下面这些标签可能会在以后出现:

·         socket_device

·         device

·         block_device

·         default_service

·         system_data_type

·         tmpfs


  • 客制化


一旦你在安卓系统中整合了这些基础功能,并且彻底地分析了结果,你就可以在你自己的策略设置中添加条目来对安卓系统做一些客制化的工作。

当然,你添加的这些策略必须满足安卓兼容性程序的需求,并且,你不能移除默认的SELinux设置。

设备生产商不应该移除现存的安卓安全设置。否则可能会破坏 SELinux在安卓上的部署,破坏受SELinux保护的应用的良好安全环境。这也包含了第三方应用(需要改进以变得更易用和更具操作性)。在具备 SELinux功能的设备上,如要应用正常工作,则绝不允许自身有任何修改。

参见内核安全特征段落,该段提供了安卓兼容性定义文档(针对特殊要求):

http://source.android.com/compatibility/index.html

SELinux使用白名单的方法,这意味着SELinux会向某些特殊的角色赋予特权。

因为目前安卓默认的SELinux策略已经支持整个AOSP,OEM实际上不需要再去修改SELinux的默认设置。但是,如果OEM做了SELinux策略的修改和定制,就应该特别注意,切勿破坏现存的应用。这里给出一些建议吧:

1.使用最新的安卓内核;

2.采用最少特权原则;

3.你只管处理你自己对安卓系统的添加和修改,其他的不用管。因为默认的安全策略会自动在AOSP的代码库中产生作用。也就是说,你对安卓原生态系统添加了什 么内容,你就写你所添加内容对应的策略配置就OK了,其他的就别管了,否则可能会出问题(这时我的理解);

4.把软件组件划分为不同的模块,由不同的模块分别执行单一的任务;

5.建立SELinux策略,该策略可以将这些任务从无关的功能中孤立开来;

6.将这些策略写入*.te(SELinux策略文件的扩展)文件中,该文件位于: /device/manufacturer/device-name/sepolicy;

7.发布你定制的SELinux版本时,先让其处在permissive mode中(因为还没经过测试噢);

8.分析结果,并不断改善策略配置。

一旦将自己的SELinux定制内容整合到安卓系统中,OEM安卓开发过程应该包含一个步骤来确认SELinux的兼容性。在一个理想的软件开发过程中,SELinux策略只有在软件模型改变时才会发生改变,而不是在实际的实现时(不是很懂)。

当设备生产商开始定制SELinux时,应该首先仔细审核对安卓的添加内容。如果他们添加了一个组件,用以实现一个新的功能,设备生产商必须确保该组件满足安卓安全策略的要求,同时也要(在开启为enforcement之前)满足OEM精心开发的相关安全策略。

为了阻止非必要的问题发生,最好能够做到足够的宽泛和兼 容,而不是过于限制和不兼容,结果是破坏了的设备功能。相反的,设备生产商对安卓系统的改变将会使其他人受益,它们应该提供一个针对默认SELinux策 略的修改补丁。如果该补丁可以直接打给默认安全策略,那么设备生产商将不再需要在每个安卓发布版中做相应的修改。



本文由Hack Blog原创,如需转载注明原文链接

作者:wesly 分类:Android 浏览:4442 评论:0
留言列表
发表评论
来宾的头像