安卓SElinux(SEAndroid)
SELinux(Security-Enhanced Linux)是一种强制访问控制(MAC)安全模块,最初由美国国家安全局(NSA)开发,旨在增强Linux及Android系统的安全性。它通过为系统中的进程、文件和其他资源分配安全标签(Security Context),并依据预定义的安全策略来控制访问权限。从Android 4.3开始,Google开始在Android系统中引入SELinux,并将其命名为SEAndroid。
运行模式
安卓SELinux有两种运行模式,可以通过命令getenforce来查看SELinux模式,通过setenforce设置SELinux模式:
1.强制模式(Enforcing):这是Android系统默认的运行模式,策略规则生效,所有违反策略的行为都会被阻止,并记录到dmesg和logcat
2.宽容模式(Permissive):常用于策略调试,仅记录违规操作,不阻止实际访问;可通过setenforce 0临时切换;如果需要一直处于该模式,需要修改BOARD_SELINUX_ENFORCING值为false。
安全上下文
SELinux是通过标签系统来控制主体对客体的读写等访问权限的。套接字、文件和进程在 SELinux 中都有标签。每个进程或者其他主体都有一个相关联的标签,即安全上下文,这个上下文由user,role,type,level四部分组成。
标签采用格式:user:role:type[:level]
#user表示用户:SEAndroid中仅定义了一个SELinux用户,用u表示
#role表示角色:可以暂时理解为在SELinux用户可以有多个不同的role,不同role所具有的权限也不一样;一个角色声明了哪些域可以访问哪些客体
#type表示类型:不同的type所具有的权限也不一样,但跟role有本质的不同;type即demain(域),这个域必须要在SELinux策略中进行定义,type是访问决定的主要组成部分,可通过构成标签的其他组成部分进行修改。
#level表示安全级别:通常为s0,不用怎么关注
te术语&avc规则
SELinux的核心机制是类型强制(Type Enforcement),通过定义进程域和文件类型的匹配规则来控制访问。 SEAndroid就是通过一系列的te文件来管理所有进程和资源的权限,每个te文件里面都有无数条te语句,每条te语句对应一条安全策略。
(1)主体:SEAndroid中的主体就是指的进程,当然可能是单一的进程,也可以是一组具有相同权限的进程,但是它们都对应一个type。
(2)客体:SEAndroid中的客体就是指的资源(包括普通文件/特殊文件/套接字),当然可能是单一的资源,也可以是一组相同类型的资源,但是他们都对应一个type。
(3)客体类别:客体与客体类别的概念就类似于Java语言中的object和class,其中class表示一个类,object表示一个实例对象
(4)访问许可:代表对客体的访问权限,例如读写权限,查询发送等权限。
(5)AV规则:既然已经有了主体和客体,那么就有对应访问规则,又叫AV规则。属于SElinux策略语言的控制部分,即te文件中每一条AV规则语句都需要能够描述清楚:主体 对 客体 是否具有 访问许可。其实就是te文件里面的allow、neverallow、dontaudit、auditallow等语句。
allow规则:定义允许的访问权限。
auditallow规则:记录允许操作的审查事件。
dontaudit规则:屏蔽特定事件的日志记录。
neverallow规则:定义永远不允许的操作。
allow规则采用形式:allow 主体type 客体type:客体类别 {权限}
当SELinux拒绝访问权限的时候,将会打印如下日志:
avc:denied { map } for path="/data/local/data/mute.png" dev="mmcblk0p37" ino=5338 scontext=u:r:bootvideo:s0 tcontext=u:object_r:system_data_file:s0 tclass=file permissive=0
像这类日志都是以关键字avc开头,需要注意其中几个很重要的字段:
denied { 权限 }:找到denied字段,后面通常跟随大括号,里面的内部就表示被拒绝的操作,即什么操作权限被拒绝,例如读写查等权限
scontext=主体上下文:找到scontext字段,后面跟随的为主体安全上下文SContext,即代表主体进程
tcontext=客体上下文:找到tcontext字段,后面跟随的为客体安全上下文SContext,即代表被访问单个资源或一系列资源的上下文
tclass=客体类别:找到tclass字段,后面为客体类别
通过上面几个关键字,我们就可以为其配置专门的AV规则,安装allow语句的规则可以在对应主体进程的te文件下添加allow语句:
allow bootvideo system_data_file:file { map }
还可以通过audit2allow指令自动生成权限内容。
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
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的策略者是不可见的,定义在/system/sepolicy/private/下。
3.非平台策略
非平台策略即是上面所说的设备制造商自定义的策略,通常定义在device/soc/下。非平台策略下定义的所有type或attribute都是platform的策略者不可见的,但是非平台策略可以使用平台公有的type和attribute。sepolicy/vendor或者sepolicy/private下的策略可以使用public下的type和attribute,private和vendor不可互相使用。
Android设备通常包含下面这些SELinux相关的文件(只列举部分常用的):
(1)file_contexts – 该文件用于为文件分配标签,并且可供多种用户空间组件使用。在创建新政策时,请创建或更新该文件,以便为文件分配新标签。
(2)property_contexts – 该文件用于为 Android 系统属性分配标签,以便控制哪些进程可以设置这些属性。在启动期间,init 进程会读取此配置。
(3)service_contexts – 该文件用于为 Android Binder 服务分配标签,以便控制哪些进行可以为相应服务添加(注册)和查找(查询)Binder 引用。在启动期间,servicemanager 进程会读取此配置。
(4)vndservice_contexts被构建为vndservicemanager的设备特定的service_context。该文件必须位于/vendor/etc/selinux/vndservice_contexts的vendor分区中,并在启动时由vndservicemanager加载。
(5)genfs_contexts – 该文件用于为不支持扩展属性的文件系统(例如,proc 或 vfat)分配标签。此配置会作为内核政策的一部分进行加载,但更改可能对核心内 inode 无效。要全面应用更改,需要重新启动设备,或卸载后重新装载文件系统。此外,通过使用 context=mount 选项,还可以为装载的特定系统文件(例如 vfat)分配特定标签。
(6)seapp_contexts – 该文件用于为应用进程和 /data/data 目录分配标签。在每次应用启动时,zygote 进程都会读取此配置;在启动期间,installd 会读取此配置。
(7)各种.te文件 – 定义进程域(Domain)和文件类型(Type)以及allow、auditallow、dontaudit、neverallow等规则。
夜雨聆风