在 SELinux 出现之前,Linux 上的安全模型叫 DAC,全称是 Discretionary Access Control,翻译为自主访问控制。
DAC 的核心思想很简单,就是:进程理论上所拥有的权限与执行它的用户的权限相同。比如,以 root 用户启动 Browser,那么 Browser 就有 root 用户的权限,在 Linux 系统上能干任何事情。
显然,DAD 管理太过宽松,只要想办法在 Android 系统上获取到 root 权限就可以了。那么 SELinux 是怎么解决这个问题呢?在 DAC 之外,它设计了一种新的安全模型,叫 MAC(Mandatory Access Control),翻译为强制访问控制。
MAC 的理论也很简单,任何进程想在 SELinux 系统上干任何事情,都必须在《安全策略文件》中赋予权限,凡是没有出现在安全策略文件中的权限,就不行。
关于 DAC 和 MAC,可以总结几个知识点:
Linux中有两种东西,一种死的(Inactive),一种活的(Active)。死的东西就是文件(Linux哲学,万物皆文件。注意,万不可狭义解释为File),而活的东西就是进程。此处的 死 和 活 是一种比喻,映射到软件层面的意思是:进程能发起动作,例如它能打开文件并操作它。而文件只能被进程操作。
根据 SELinux 规范,完整的 Secure Context 字符串为:user:role:type[:range]
在 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
其中:
文件的 Secure Context 可以通过 ls -Z 来查看,如下
rk3288:/vendor/lib $ ls libOMX_Core.so -Z
u:object_r:vendor_file:s0 libOMX_Core.so
MAC 基本管理单位是 TEAC(Type Enforcement Accesc Control),然后是高一级别的 Role Based Accesc Control。RBAC 是基于 TE 的,而 TE 也是 SELinux 中最主要的部分。上面说的 allow 语句就是 TE 的范畴。
根据 SELinux 规范,完整的 SELinux 策略规则语句格式为:
allow domains types:classes permissions;
- Domain - 一个进程或一组进程的标签。也称为域类型,因为它只是指进程的类型。
- Type - 一个对象(例如,文件、套接字)或一组对象的标签。
- Class - 要访问的对象(例如,文件、套接字)的类型。
- Permission - 要执行的操作(例如,读取、写入)。
= allow : 允许主体对客体进行操作
= neverallow :拒绝主体对客体进行操作
= dontaudit : 表示不记录某条违反规则的决策信息
= auditallow :记录某项决策信息,通常 SElinux 只记录失败的信息,应用这条规则后会记录成功的决策信息。
使用政策规则时将遵循的结构示例:
语句:
allow appdomain app_data_file:file rw_file_perms;
这表示所有应用域都可以读取和写入带有 app_data_file 标签的文件
—> 相关实例
1. SEAndroid 中的安全策略文件 policy.conf
# 允许 zygote 域中的进程向 init 域中的进程(Object Class 为 process)发送 sigchld 信号
allow zygote init:process sigchld;
2. # 允许 zygote 域中的进程 search 或 getattr 类型为 appdomain 的目录。
# 注意,多个 perm_set 可用 {} 括起来
allow zygote appdomain:dir { getattr search };
3. # perm_set 语法比较奇特,前面有一个 ~ 号。
# 它表示除了{entrypoint relabelto}之外,{chr_file #file}这两个object_class所拥有的其他操作
allow unconfineddomain {fs_type dev_type file_type}:{ chr_file file } \
~{entrypoint relabelto};