🐧【Linux】SELinux介绍
Annan 2023年09月11日
1.历史背景
在 SELinux 出现之前,Linux 上的安全模型叫 DAC,全称是 Discretionary Access Control,翻译为自主访问控制。
DAC 的核心思想很简单,就是:进程理论上所拥有的权限与执行它的用户的权限相同。比如,以 root 用户启动 Browser,那么 Browser 就有 root 用户的权限,在 Linux 系统上能干任何事情。
显然,DAC 管理太过宽松,只要想办法在 Android 系统上获取到 root 权限就可以了。那么 SELinux 是怎么解决这个问题呢?在 DAC 之外,它设计了一种新的安全模型,叫 MAC(Mandatory Access Control),翻译为强制访问控制。
MAC 的理论也很简单,任何进程想在 SELinux 系统上干任何事情,都必须在《安全策略文件》中赋予权限,凡是没有出现在安全策略文件中的权限,就不行。
关于 DAC 和 MAC,可以总结几个知识点:
- Linux 系统先做 DAC 检查。如果没有通过 DAC 权限检查,则操作直接失败。通过 DAC 检查之后,再做 MAC 权限检查
- SELinux 有自己的一套规则来编写安全策略文件,这套规则被称之为 SELinux Policy 语言。
2. Secure Context
在 Android系统中,所有对象大致可以分为两类:
- 一种是
死的(文件、端口、系统属性等被调用对象),例如:u:object_r:proc:s0 - 一种是
活的(进程、App等调用资源的对象),例如:u:r:vendor_init:s0
此处的 死 和 活 是一种比喻,映射到软件层面的意思是:进程能发起动作,例如它能打开文件并操作它。而文件只能被进程操作。
根据 SELinux 规范,完整的 Secure Context 字符串为:user:role:type[:range]
2.1 进程的 Secure Context
在 SELinux 中,每种东西都会被赋予一个安全属性,官方说法叫做 Security Context,Security Context 是一个字符串,主要由三个部分组成,例如 SEAndroid 中,进程的 Security Context 可通过 ps -Z 命令查看:
rk3288:/ $ ps -AZ
u:r:hal_wifi_supplicant_default:s0 wifi 1816 1 11388 6972 0 0 S wpa_supplicant
u:r:platform_app:s0:c512,c768 u0_a14 1388 228 1612844 57396 0 0 S android.ext.services
u:r:system_app:s0 system 1531 228 1669680 119364 0 0 S com.android.gallery3d
u:r:kernel:s0 root 582 2 0 0 0 0 S [kworker/1:2]
u:r:radio:s0 radio 594 228 1634876 89296 0 0 S com.android.phone
u:r:system_app:s0 system 672 228 1686204 141716 0 0 S com.android.settings
u:r:platform_app:s0:c512,c768 u0_a18 522 223 1721656 152116 0 0 S com.android.systemui
上面的最左边的一列就是进程的 Security Context,以第一个进程 wpa_supplicant 为例
u:r:hal_wifi_supplicant_default:s0
其中:
- u 为 user 的意思,SEAndroid 中定义了一个 SELinux 用户,值为 u
- r 为 role 的意思,role 是角色之意,它是 SELinux 中一个比较高层次,更方便的权限管理思路。简单点说,一个 u 可以属于多个 role,不同的 role 具有不同的权限。
- hal_wifi_supplicant_default 代表该进程所属的 Domain 为 hal_wifi_supplicant_default。MAC(Mandatory Access Control)强制访问控制 的基础管理思路其实是 Type Enforcement Access Control(简称TEAC,一般用TE表示),对进程来说,Type 就是 Domain,比如 hal_wifi_supplicant_default 需要什么权限,都需要通过 allow 语句在 te 文件中进行说明。
- s0 是 SELinux 为了满足军用和教育行业而设计的 Multi-Level Security(MLS)机制有关。简单点说,MLS 将系统的进程和文件进行了分级,不同级别的资源需要对应级别的进程才能访问
2.2 文件的 Secure Context
文件的 Secure Context 可以通过 ls -Z 来查看,如下
rk3288:/vendor/lib $ ls libOMX_Core.so -Z
u:object_r:vendor_file:s0 libOMX_Core.so
- u:同样是 user 之意,它代表创建这个文件的 SELinux user
- object_r:文件是死的东西,它没法扮演角色,所以在 SELinux 中,死的东西都用 object_r 来表示它的 role
- vendor_file:type,和进程的 Domain 是一个意思,它表示 libOMX_Core.so 文件所属的 Type 是 vendor_file
- s0:MLS 的等级
3. TE规则
根据SELinux规范,完整的规则相关的语句格式为:
rule_name source_type target_type:class perm_set
rule_name 规则名allow: 允许主体对客体进行操作neverallow:拒绝主体对客体进行操作dontaudit: 表示不记录某条违反规则的决策信息auditallow:记录某项决策信息,通常 SElinux 只记录失败的信息,应用这条规则后会记录成功的决策信息
source_type 主体Domain:一个进程或一组进程的标签。也称为域类型。允许用户自定义。
target_type 客体Type:一个对象(例如,文件、套接字)或一组对象的标签。允许用户自定义。
class 类别- 要访问的对象的类型,例如文件、套接字等
- 在
system/sepolicy/private/security_classes中被定义
perm_set 动作集- 要执行的操作,例如读取、写入等。每个
class有自己被定义的perm_set - 在
system/sepolicy/private/access_vectors中被定义
- 要执行的操作,例如读取、写入等。每个
下面结合例子说明一下:
# 允许user域中的进程 读取 script标签中的file类型文件 allow user script:file {read};
# 不允许user域中的进程 写入 script标签中的file类型文件 neverallow user script:file {write};
source_type、target_type使用type、typeattribute、attribute定义。
**attribute定义一个代表具有某种相中属性的集合(即域)。
attribute dev_type;
type定义代表一个或一类资源类型,并分配至不同属性(域)中。
# 定义一个类型,属于dev_type属性
type ttyMT_device, dev_type;
以上定义可以拆分为两部分
# 仅定义一个类型
type ttyMT_device;
# 仅把ttyMT_device类型关联到dev_type属性
typeattribute ttyMT_device dev_type;
属性间使用逗号,一个类型可以关联至多个属性
type oem_lock_service, system_api_service, system_server_service, service_manager_type;
class字段使用comm和class定义,comm定义的class可以被class定义的对象继承。
common file {
ioctl read write create getattr setattr lock relabelfrom relabelto
append unlink link rename execute swapon quotaon mounton
}
class类型继承comm类型
class dir
inherits file
{
add_name
remove_name
reparent
search
rmdir
open
audit_access
execmod
}
contexts文件
contexts文件里定义了系统中所有的secure context。有如下的典型定义:
file_contexts //系统中所有file_contexts
seapp_contexts //app
property_contexts //属性
service_contexts //SA服务
genfs_contexts //虚拟文件系统
以上提到过的,linux系统中一切都有个安全属性定义,即secure context。这一切定义都在context文件中。当新增一个进程时,往往要在这里定义相关服务或文件的context(标签)。深入实例,查看509selinux问题记录中neverallow的问题解决方案。
参考文档:
相关笔记
- 509selinux问题记录
- 鸿蒙配置文件