Android8.0 SELinux详解

该文档意译自Android官方 《SELinux for Android 8.0》,主要描述了SELinux策略在AndroidO版本上发生的一些变化,在AndroidO版本上,SELinux的客制化设计支持SELinux策略的模块化和可更新性。其设计目标是为了芯片厂商和ODM厂商在能够独立的客制化SELinux配置。

官方文档请移步:http://download.csdn.net/download/huangyabin001/10241242


  • Android8.0 AndroidSELinux设计目标
Android4.4到Android7.0,SELinux策略的构建流程是将所有的策略(平台和非平台)合并在一起,最后将合并生成的文件统一放在root目录下(即boot.img)。但这种方式有悖于Android 8.0的预定设计目标;Android8.0设计的初衷是允许合作方可以独立的更新他们自有的策略,即在Android8.0之后Google允许合作方将自有的策略部分与系统原有的进行分离,如合作方可以将自有的部分解耦到vendor.img分区中,在需要更新的情况下只需更新vendor部分即可实现;

SELinux在Android8.0上的设计目标包含以下:
  1. 策略模块化。在Android4.4到Android7.0,大部分SELinux策略文件都打包在根文件系统中,这样的话,策略文件改变的情况下,芯片厂商和ODM厂商需要同时更新boot.img和system.img(system.img只针对ab系统,因为ab系统的话,boot.img是打包在system.img镜像中的)。Android8.0之后,Google为SoC和ODM提供了新的方式,这种方式在他们自有的SELinux策略发生变化时仅需要修改他们自有的分区即可,如vendor.img;
  2. 策略兼容性。

关于Android8.0架构如下图:
图1.Android分区
  1. system.img 包含Android 框架部分;
  2. boot.img 包含kernel和ramdisk;
  3. vendor.img 包含芯片厂商客制化代码和配置
  4. odm.img 包含dom厂商客制化代码和配置
  5. oem.img 包含oem厂商客制化部分代码和配置;
  6. bootloader 引导部分
  7. radio modem部分

在Androird8.0之前,vendor、odm和omd镜像都是可选的;在这些镜像中的配置都是通过symlinks被放在boot.img和system.img中的(如/vendor>/system/vendor)。在Android8.0之后,vendor镜像被强制以镜像的形式分离出来了。

这种模化设计体现在Android分区定义上,它使得平台在升级时(system.img)不会对SoC和ODM厂商自有部分的代码和配置产生影响。

  • 关于SELinux

SELinux是通过标签系统来控制主体对客体的读写等访问权限的。每个进程或者其他主体都有一个相关联的标签;我们称之为安全上下文。这个上下文是有user,role,type,MLS四部分组成;
  1. type我们也称之为domain(域),这个域必须要在SELinux策略中进行定义;
  2. 一个主体的标签常常由对应的安全上下文文件所决定;
SELinux策略也包含角色,一个角色声明了哪些域可以访问哪些客体;在Andoird4.4到Android7.0的版本中,SELinxu策略文件(sepolicy,file_context.bin,property_context等)都是打包在根文件系统中的,如下:
这些文件包含了SELinxu策略规则和所有的标签,包括ODM,SOC和AOSP。但是在Android8.0,这些文件将以模块的形式存在在不同的分区中;

  • Android7.x的SELinux架构

a.SELinux源文件
SELinux源文件目录结构如下:
external/selinux 外部SELinux工程
external/selinux/libselinux
external/selinux/libsepol
chkcon
libsepol 
external/selinux/checkpolicy

system/sepolicy Android SELinux策略核心配置,包含contexts和策略文件

b.SELinux编译流程
SELinux策略的创建实际上就是将AOSP 策略文件和设备制造商自定义的策略文件合并到一起,然后通过策略编译器编译,再通过各种策略校验机制校验,最终生成的一些如root/file_contexts.bin的文件,被打包到镜像中去。
设备制造商可以通过在Boardconfig.mk文件,使用BOARD_SEPOLICY_DIRS宏定义,将自有客制化部分的策略文件包含进去。如:
BOARD_SEPOLICY_DIRS += device/$SoC/common/sepolicy
BOARD_SEPOLICY_DIRS += device/$SoC/$DEVICE/sepolicy

system/sepolicy目录下的file_contexts和BOARD_SEPOLICY_DIRS定义的策略目录最终会编译生成file_contexts.bin文件。
图2.SELinux 编译流程


sepolicy策略文件是有多种源文件组成的,如:
图3.SELinux策略文件
policy.conf是由security_classes,initial_side,...*.te,genfs_contexts和port_contexts串联生成的。

c.SELinux文件

Android设备通常包含下面这些SELinux相关的文件
selinux_version
  1. sepolicy : binary output after combining policy files ( security_classes ,
  2. initial_sids , *. te , etc.)
  3. file_contexts
  4. property_contexts
  5. seapp_contexts
  6. service_contexts
  7. system/etc/mac_permissions.xml

d.SELinux初始化
当系统启动时,SELinux并不是强制模式(enforcing mode),而是宽容模式(permissive mode)。init进程会执行以下操作:
  1. 通过/sys/fs/selinux,从ramdisk中载入selinux策略文件到kernel中;
  2. 切换SELinux到强制模式
  3. re-exec(),将SELinux域规则运用自己身上,即init进程。



  • Android 8.0 SELinux设计思路
a.第一阶段 mount
    在Android8.0之前,SELinux文件是通过合并自定义策略和aosp的策略。在Android8.0之后,Android提供了一种方式可以将非平台的策略从aosp平台中分离出,这样合作方就可以独立的对自有部分的SELinux策略进行构建和更新。
    解耦之后的SELinux策略文件可以存储在合作方自有的分区中(如vendor),这样一来,init进程需要更早的将system、vendor分区挂在起来,这样才能保证在init初始化的时候可以尽早的读取加载SELinux文件,并与保存在system目录下的核心SELinux文件合并起来,之后再将合并之后的SELinux策略加载到内核中去。

b.SELinux上下文标签
1>文件上下文
Android8.0对file_contexts引入了以下修改:
file_contexts以二进制的形式打包在镜像中,这在Android7.0以及之前的版本都是以可读的文本的形式存在的。
Android8.0将file_contexts分离成了两个文件:
Plat_file_contexts:Android平台file_context除了对vendor分区进行标记之外,没有其他有关设备制造商自有的标签了。平台相关的file_context必须打包到system分区,如/system/etc/selinux/plat_file_context。说白了也就是从Android8.0开始,SELinux平台相关的策略文件将会打包到system分区,这个要与Android7.0进行区分,详细如下:
Android7.0图1

Android8.0 图1
Android8.0 图2
注!上面目录在Andrid8.0平台上的boot分区中etc目录会对system/etc目录进行映射,如下:
Android8.0 图3

Nonplat_file_contexts:设备制造商的file_context必须打包在vendor分区,如/vendor/etc/selinux/nonplat_file_contexts。将会在设备启动时与plat_file_contexts一起合并,并被加载到kernel中。详细如下:
Android8.0 图4

Android8.0 图5

2>属性上下文
同文件上下文

3>服务上下文
同文件上下文

4>seapp上下文
同文件上下文

5>mac权限
同文件上下文

c.主体或客体标签

    Android8.0 可以独立更新平台(system/boot分区)和设备制造商组件(vendor分区),意味着需要清楚的定义每一个客体的标签。举个例子,如果设备制造商组件(vendor分区)下有/dev/foo,平台组件也有/dev/foo,我们需要分别为不同的客体定义标签、属性、类型等其他内容;
例如:
1.针对platform和non-platform分别定义type或attribute
type foo, domain; → type np_foo, domain;

2.针对属性和进程分别不同的属性或其他内容;
foo.xxx → np.foo.xxx
ro.foo.xxx → ro.np.foo.xxx
persist.foo.xxx → persist.np.foo.xxx

3.针对文件分别定义不同的标签
由于平台(aosp)和非平台(vendor或device-specific)策略都可以为整个文件系统提供标签声明,因此我们要通过一些规则来解决SELinux冲突;这里Android8.0给我们提供了一些很好的建议;

>System(/system)
system镜像下的文件只允许通过system/sepolicy中的file_contexts、service_contexts进行定义;也就是说,nonplat_file_contexts 不可以对system镜像中的对象进行标记。

>Vendor(/vendor)
官方文档还列举了/data,/dev等,这里不再赘述,可以查看源码了解;

d.SELinux 策略构建和客制化
    在Android8.0中,SELinux策略分离成平台(platform)和非平台(non-platform)两部分,而平台策略为了给非平台作者导出特定的类型和属性,又分为平台私有(platform private)和平台公有(platform public)部分。

1.平台公有策略(platform public seoplicy)
平台共有策略全部定义在/system/sepolicy/public下,public下的type和attribute可以被non-platform中的策略所使用,也就是说,设备制造商的sepolicy作者在non-platform下可以对platform public sepolicy的策略进行扩展。

2.平台私有策略(platform private seoplicy)
与公有策略相反,被声明为私有策略的type或attribute对non-platform的策略作者是不可见的,这里有些费解,我们举例来说,这里以8.0版本的aosp源代码中的/system/sepolicy/private/目录下的atrace.te文件为例;
  1. 8.0版本的aosp中的/system/sepolicy/private/file_contexts定义了“/system/bin/atrace    u:object_r:atrace_exec:s0”
  2. 然后在/system/sepolicy/private/atrace.te中定义atrace相关的规则;
  3. 我们在device/qcom/sepolicy/common目录下新增一个atrace.te文件,并添加规则 "allow atrace sdcardfs:file read;"
当我们make进行编译时会在校验的时候失败,提示我们“device/qcom/sepolicy/common/atrace.te:2:ERROR 'unknown type atrace' at token ';' on line 23355”,那么也就是说private策略中的type和attribute对我们是不可见的。

3.平台私有映射
映射主要针对旧版本的映射,应用比较少,这里不作研究;


e.构建SELinux策略

Android8.0的SElinux策略是由/system和/vendor中的策略合并而来的。具体构建的逻辑声明在/platform/system/sepolicy/Android.mk中。
LocationContains
system/sepolicy/public平台策略
system/sepolicy/private平台策略
system/sepolicy/vendor平台对vendor相关的定义
BOARD_SEPOLICY_DIRSvendor 策略
平台编译系统采用这种逻辑将平台和非平台策略组件分别打包在system镜像和vendor镜像中去。


f.策略兼容性
Android8.0 SELinux的模块化设计鼓励供应商(vendor)将自有部分的selinux与system部分分离开来,从而使得平台ota时具备更好的兼容性,比如新版本的SELinux配置与旧版本的SELinux配置的差异等。
SELinux 策略是特定类型的对象(如file,dir,进程等),源域(主体)与目标域(客体)的交互;每个对象都受SELinux策略影响,每个对象至少要有一个type(类型),但这个类型(type)可以具备多个属性(attribute);

g.平台更新
下面列举了一些平台更新可能会遇到的场景:
1.相同类型
这种场景常常发生在selinux版本中没有对对象修改标签,怎么理解呢,当我们同时有很多个版本的SELinux时,而且多个版本均对"/dev/binder"进行type的定义。那就会发生冲突,解决冲突的办法就是在不同版本的SELinux,对type定义上添加版本后缀,如下:binder_device_v1 … binder_device_vN

2.新类型
这种场景常常发生在我们需要添加一个新功能时,需要添加一个新type时,平台已经添加了一个新类型(type)。

3.删除type

4.新类别和权限

5.删除类别和权限
......
  • 19
    点赞
  • 120
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
### 回答1: Android SELinuxAndroid操作系统中的一种安全机制,它可以限制应用程序的访问权限,保护用户数据的安全性。SELinux是一种强制访问控制(MAC)机制,它通过强制规则来限制应用程序的访问权限,即使应用程序本身存在漏洞,也可以保护系统的安全性。Android SELinux的实现基于Linux内核的SELinux模块,它通过定义安全策略来控制应用程序的访问权限,包括文件系统、网络、进程等方面。Android SELinux的实现需要在系统级别进行配置,因此需要一定的技术知识和经验。 ### 回答2: 安卓的SELinux是一项安全功能,做到了不同级别权限间的隔离。它与Linux的SELinux相似,都是基于Mandatary Access Control(MAC)的实现。MAC使用了定义好的安全策略来决定进程访问对象的许可。每个对象有一个或多个安全标签,决定了可访问这些对象的访问者。SELinux实现了一个高度定制化的MAC实现,以达到保护系统免受攻击的效果。 SELinux可以将任何应用程序、库或系统进程在安全上互相隔离。每个进程可以分配一个不同的安全上下文,用于决定该进程可以执行的操作。SELinux允许管理员定义一个策略集,以确保只有那些拥有特定权限的应用程序可以执行特定的操作。SELinux包括以下4个组件。 * Security-enhanced kernel:该内核支持SELinux,并且为应用程序和系统提供安全保护。通常,操作系统上的SELinux是直接编译到内核配置中的。 * SELinux policy:这是一组规则,它定义了哪些进程可以访问哪些资源,以及何时可以访问它们。这是SELinux的“脑”。SELinux策略通过使用安全标签来标识资源和进程,并使用规则来决定它们之间的安全关系。 * SELinux utilities:这些社区提供的工具用于安装、更新和管理SELinux策略。通常情况下,管理员会安装每个Linux发行版自带的安全工具。 * SELinux-aware applications:这是应用程序和守护进程,它们能够在SELinux的约束下运行。这些应用程序还懂得如何处理SELinux策略,以确保它们对系统的安全有积极贡献。 总的来说,SELinux是一项强大而高度定制化的MAC实现,能够确保安卓系统和应用程序免受攻击。它通过一组规则定义了可用资源和进程之间的安全关系,从而在操作系统和应用层上实现了分离和隔离。作为一项优秀的安全保护功能,它能够在各种安卓设备上为用户提供强大的保护措施,从而发挥关键的作用。 ### 回答3: Android操作系统是目前全球手机、平板等终端设备最常用的操作系统之一。Android系统架构中有一个非常重要的安全机制,即SE_LINUX(Security-Enhanced Linux)。SE_LINUX是由美国国家安全局(NSA)和Redhat合作研发的一种新型操作系统,它基于强制性访问控制(Mandatory Access Control)机制,是一种可扩展的安全模型,功能十分强大。 Android系统使用SE_LINUX来保障应用程序的安全。在Android的SE_LINUX中,安全策略旨在为每个进程提供最佳的资源保护。当应用程序尝试访问受限制的资源时,安全策略会检查该应用程序的标记是否具有访问受限制资源的许可权,以确保安全性。如果没有访问权限,访问请求就会被拒绝,在应用程序层面上保证了Android系统的安全。 其中,SE_LINUX的工作原理是在内核上增加了一个“SELinux子系统”,具体实现过程如下:(1)在内核源代码中添加SELinux子系统;(2)在Linux 内核上开发安全模块;(3)编写用户空间程序和共享代码,实现SELinux规则和策略以及管理SELinux权限的机制。Android系统的SE_LINUX是基于SMLS架构,即安全、多层、标签、安全。 同时,SE_LINUX还为Android系统中的进程、文件系统、系统服务进行了标记化管理。每个进程都有一个唯一的SELinux安全上下文标签进行标识,涉及到的对象都会增加一个SELinux标签,当某个进程尝试访问某个对象时,它的SELinux上下文标签需要满足该对象的SELinux上下文标签的安全策略,否则该进程就会被降级或者拒绝访问该对象。 总之,Android SE_LINUX是Android操作系统架构中的重要安全机制,它通过强制性访问控制(Mandatory Access Control)机制来保护应用程序的安全,在访问受限制的资源时会进行检查、获取许可证以保证安全。SE_LINUX的工作原理是标记化管理,确保每个进程、文件系统、系统服务都对应一个唯一的安全标签,实现了权限的有效、高效管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高桐@BILL

分享快乐,快乐分享...

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值