目录
- 前言
- 一、 通用AV规则语法
- 1.1 allow source target:class permissions;
- 1.2 neverallow source target:class permissions;
- 二、type
- 三、attribute
- 四、typeattribute
- 五、alias
- 六、typealias
- 七、init_daemon_domain
- 7.1 `init_daemon_domain` 宏概述
- 7.2 宏展开与实现
- 7.2.1 展开后规则详解
- 7.2.2 总结
- 八、xxx_contexts
- 8.1 **什么是安全上下文?**
- 8.2 **常见的 xxx_contexts 文件及其功能**
- (1) **file_contexts**
- (2) **property_contexts**
- (3) **service_contexts**
- (4) **seapp_contexts**
- (5) **hwservice_contexts**
- (6) **vndservice_contexts**
- (7) **genfs_contexts**
- (8) **fs_use_xxx**
- 8.3 **如何使用和修改 xxx_contexts 文件**
- 8.4 **Android SELinux 上下文文件的模块化**
- 九、其他
- domain
- coredomain
- init_daemon_domain()
- coredomain和init_daemon_domain()
- SELinux安全上下文
- SELinux文件属性
- SELinux权限
前言
关于安卓Selinux之前写过一篇文章,安卓SELinux策略,最近这方面的工作比较多,完成之后准备再写一篇,不过这篇文章将重点描述SELinux的语法规则
一、 通用AV规则语法
• 规则名称: allow,dontaudit,auditallow和neverallow• 源类型:授予访问的类型,通常是进程的域类型• 目标类型:客体的类型,它被授权可以访问的类型• 客体类别:客体的类别• 许可:表示主体对客体访问时允许的操作类型(也叫做访问向量)。一个简单的AV规则有一个源类型,目标类型,客体类别和许可。
1.1 allow source target:class permissions;
allow规则中可以看到许多AV规则,如:
allow user_t bin_t : file execute;
这个allow规则的源类型为user_t,目标类型为bin_t,客体类别file,许可execute,这个规则可以解读为"允许user_t执行类型为bin_t的文件"
上面的规则示例中,直接引用了源类型(user_t)
和目标类型(bin_t)
,其实在源类型或目标类型中要引用多个类型也是很方便的,其中一个方法就是使用属性,在AV规则中能使用类型的地方都可以使用属性(类型组)。
例如,假设我们定义了一个属性(exec_type)
,打算将其与所有的普通用户程序(通过域类型user_t标记)
都可以执行的文件类型关联,那么就可以将上面的例子改为引用属性exec_type
,而不用再明确地指定类型bin_t
了,如:
allow user_t exec_type : file execute;
1.2 neverallow source target:class permissions;
这个规则来指定永远不会被allow规则执行的访问
neverallow user_t shadow_t : file write;
这条neverallow规则可以有效地阻止我们在策略中添加一条允许user_t对类型为shadow_t的文件进行写操作的规则,如果添加了这样的规则在编译时就会报错,这条规则不会移除访问权,它只是会产生编译错误。我们在编写策略时,neverallow规则往往放在allow规则前面,首先声明哪些访问是明确地被拒绝的,然后再声明哪些访问是可以接受的,这样就可以预防我们人为出错了。
二、type
- 作用:
类型声明
- 语法:
type 类型名称 [alias 别名集] [,属性集];
- 定义:type 是 SELinux 策略中最基本的类型声明,用于定义一个具体的 SELinux 类型(type),表示资源(如文件、进程、属性)或主体(如进程域)的安全上下文。
每个 type 是一个独立的标签,用于标识特定资源或进程的 SELinux 上下文,供权限规则使用。
注意
:
- 别名集:如果指定的不止一个别名标识符,要在一对大括号中用空格将各个别名区别开来,如:alias {aliasa_t aliasb_t}。
- 属性集:是一个或多个预先声明的属性标识符,如果同时指定多个属性标识符,属性之间使用逗号进行分隔,如:type bin_t, file_type, exec_type;
- 类型声明在整个策略中,以及基础载入模块和非基础载入模块中都是有效的。但在有条件的语句中无效。
示例:
type serial_device, dev_type;
定义 serial_device 类型,表示串口设备(如 /dev/ttyS0),并关联 dev_type 属性(表示设备类型)。
三、attribute
- 定义:
attribute 是 SELinux 中的属性声明,用于定义一个类型集合(group),可以将多个 type 归类到一个抽象标签下,简化权限规则的编写。它本身不直接与资源或进程关联,而是为 type 提供分组机制。 - 作用:
允许在规则中使用单个 attribute 替代多个 type,减少重复规则。
常用于分类类似资源(如所有 sysfs 文件、所有属性类型)。 - 语法:
attribute 属性名称;
注意
:
- 属性和类型,别名都在同一个命名空间,因此不能与其他类型或别名重名。
- 属性声明在整个策略,基础载入模块和非基础载入模块中都有效,但在有条件的语句中无效。
示例:
attribute sysfs_odm_server;
定义 sysfs_odm_server属性(在 attributes 文件中添加),用于标记与 odm_server相关的类型(如 sysfs 节点)。
四、typeattribute
- 定义:
typeattribute 是 SELinux 的语句,用于将一个已定义的 type 与一个或多个 attribute 关联,将该 type 加入属性集合。
它是连接 type 和 attribute 的桥梁。 - 作用:
允许一个 type 继承某个 attribute 的权限规则,简化策略管理。
当 allow 规则使用 attribute 时,所有关联该属性的 type 都会受到影响。 - 语法:
typeattribute 类型名 属性名;
示例:
type odm_server, domain;
typeattribute odm_server sysfs_odm_server;
将 odm_server 类型关联到 sysfs_odm_server 属性,表示 odm_server 具有 sysfs_odm_server 的权限特性。
五、alias
(为确保兼容性而存在)别名是引用类型时的一个备选的名字,能够使用类型名的地方就可以使用别名,包括TE规则,安全上下文和标记语句,别名通常用于策略改变时保证一致性,例如:一个旧策略可能引用了类型netscape_t,更新后的策略可能将类型名改为mozilla_t了,但同时提供了一个别名netscape_t以保证与旧模块能够正确兼容。
type mozilla_t alias netscape_t, domain;
注意别名声明是放在属性的前面的。
六、typealias
- 语法:
typealias 类型名称 alias 别名名称
- 类型名称:要添加别名的类型的名称,类型必须使用type语句单独声明,而且这里只能指定一个类型名称。
- 别名名称:如果同时指定多个别名,别名之间用空格分开,并使用大括号将所有别名括起来,如{aliasa_t aliasb_t}。
- typealias语句在单个策略,基础载入模块和非基础载入模块中都有效,只有在条件语句中无效。
# 这两条语句等同于
type mozilla_t, domain;
typealias mozilla_t alias netscape_t; #下面这一条语句
type mozilla_t alias netscape_t, domain;
七、init_daemon_domain
7.1 init_daemon_domain
宏概述
- 定义:
init_daemon_domain
是 Android SELinux 策略中的一个宏,定义在system/sepolicy/public/te_macros
(或prebuilts/api/34.0/public/te_macros
)中,用于为由init
进程启动的守护进程(daemon)配置 SELinux 域。- 它为指定的进程类型(
xx
)分配一个 SELinux 域, 由init启动的进程,默认和init有相同的权限,所以需要用init_daemon_domain()将进程的域切换到自己的进程域,确保守护进程在安全的环境中运行。
- 作用:
- 将一个进程标记为
init
启动的守护进程,分配一个独立的 SELinux 域。 - 配置必要的权限,允许进程与
init
交互、访问资源,并限制其行为以符合安全策略。 - 常用于系统服务或供应商服务。
- 将一个进程标记为
- 语法:
init_daemon_domain(<domain_name>)
<domain_name>
:要定义的 SELinux 域类型(如xx
),通常是一个type
(如odm_server
)。
7.2 宏展开与实现
init_daemon_domain
是一个宏,展开后包含一系列 SELinux 规则。其在 Android 12(system/sepolicy/public/te_macros
)中的定义:
# system/sepolicy/public/te_macros
macro init_daemon_domain(domain)type $1, domain;type $1_exec, exec_type, file_type;domain_auto_trans(init, $1_exec, $1)allow $1 self:capability { setuid setgid };allow $1 init:unix_stream_socket { connectto };allow $1 init:fd use;allow $1 self:process { execmem };allow $1 kernel:security { read_policy load_policy };allow $1 self:capability2 { logging };# Allow init to relabel the daemonallow init $1:process { transition sigchld };# Allow the daemon to relabel itselfallow $1 self:process { setcurrent };# Allow init to send signals to the daemonallow init $1:process { signal };
endmacro
7.2.1 展开后规则详解
假设你调用 init_daemon_domain(odm_server)
,宏会展开为以下规则:
-
定义类型:
type odm_server, domain; type odm_server_exec, exec_type, file_type;
- 定义
odm_server
作为 SELinux 域类型(domain
),表示进程的运行上下文。 - 定义
odm_server_exec
作为可执行文件类型(exec_type
和file_type
),通常对应守护进程的可执行文件(如/system/bin/odm_server
)。
- 定义
-
域转换:
domain_auto_trans(init, odm_server_exec, odm_server)
- 定义域转换规则:当
init
进程执行odm_server_exec
文件时,进程上下文自动转换为odm_server
域。 - 等价于:
allow init odm_server_exec:file { execute }; allow init odm_server:process { transition }; type_transition init odm_server_exec:process odm_server;
- 定义域转换规则:当
7.2.2 总结
init_daemon_domain(odm_server)
将odm_server
定义为一个由init
启动的守护进程域,配置其执行文件(odm_server_exec
)和基本权限,确保安全运行。- 它简化了守护进程的 SELinux 配置,适用于系统或供应商服务。
八、xxx_contexts
在 Android 的 SELinux(Security-Enhanced Linux)中,xxx_contexts
文件是用来定义 SELinux 安全策略的上下文文件,它们指定了系统资源(如文件、进程、属性等)的安全上下文(security context)。这些文件通常位于 /etc/selinux/targeted/contexts
目录下,用于配置 SELinux 的安全标签和权限规则。以下是对常见 xxx_contexts
文件的详细解析:
8.1 什么是安全上下文?
安全上下文是 SELinux 用来标识资源(文件、进程、端口等)安全属性的标签,格式为:
user:role:type[:range]
- user: SELinux 用户(如
system_u
,u
)。 - role: 角色(如
object_r
表示对象角色)。 - type: 类型,是 SELinux 类型强制访问控制(TE)的核心(如
app_data_file
)。 - range: MLS(多级安全)或 MCS(多类安全)级别(可选,通常 Android 不使用 MLS)。
xxx_contexts
文件的作用是为不同类型的资源分配初始的安全上下文。
8.2 常见的 xxx_contexts 文件及其功能
以下是 Android SELinux 中常见的 xxx_contexts
文件及其详细说明:
(1) file_contexts
- 作用: 定义文件系统对象的 SELinux 安全上下文,指定文件、目录或符号链接的默认标签。
- 位置: 通常位于
/etc/selinux/targeted/contexts/files/file_contexts
。 - 格式:
示例:<路径正则表达式> <上下文>
/system/bin/sh u:object_r:shell_exec:s0 /data/data/.* u:object_r:app_data_file:s0
/system/bin/sh
的上下文被设置为u:object_r:shell_exec:s0
,表示它是可执行的 shell 文件。/data/data/.*
表示所有应用数据目录的上下文为app_data_file
。
- 用途:
- 在系统启动或文件创建时,
file_contexts
决定文件的初始标签。 - 用于
restorecon
命令来修复或设置文件的安全上下文。
- 在系统启动或文件创建时,
- 注意:
- 正则表达式匹配路径时,优先级从上到下,匹配最具体的规则。
- Android 的
file_contexts
通常被拆分成多个文件(如/system/etc/selinux/plat_file_contexts
、/vendor/etc/selinux/vendor_file_contexts
)以支持模块化。
(2) property_contexts
- 作用: 定义系统属性的 SELinux 安全上下文(
property
是 Android 的键值对配置,如ro.build.version
)。 - 位置:
/etc/selinux/targeted/contexts/property_contexts
。 - 格式:
示例:<属性前缀> <上下文>
ro.build.* u:object_r:build_prop:s0 persist.sys.* u:object_r:system_prop:s0
ro.build.*
表示所有以ro.build
开头的只读属性使用build_prop
上下文。persist.sys.*
表示持久化系统属性使用system_prop
上下文。
- 用途:
- 控制哪些进程可以读取或修改特定属性。
- 防止未经授权的进程篡改关键系统属性。
- 注意:
- 属性上下文对系统属性的访问控制非常严格,进程必须具有对应的类型和权限才能访问。
(3) service_contexts
- 作用: 定义 Android Binder 服务(或 AIDL 服务)的 SELinux 安全上下文。
- 位置:
/etc/selinux/targeted/contexts/service_contexts
。 - 格式:
示例:<服务名称> <上下文>
activity_service u:object_r:activity_service:s0 wifi_service u:object_r:wifi_service:s0
activity_service
是 ActivityManagerService 的 Binder 服务,上下文为activity_service
。
- 用途:
- 控制哪些进程可以调用特定的 Binder 服务。
- 确保只有授权的进程可以访问关键服务(如 ActivityManager 或 Wi-Fi 服务)。
- 注意:
- 服务名称通常由系统定义,开发者需要确保自定义服务的上下文正确配置。
(4) seapp_contexts
- 作用: 定义 Android 应用进程的 SELinux 安全上下文,决定应用的 SELinux 域(domain)。
- 位置:
/etc/selinux/targeted/contexts/seapp_contexts
。 - 格式:
示例:user=<SELinux用户> isPrivApp=<true/false> name=<包名> domain=<域> type=<文件类型> levelFrom=<级别来源>
user=system isPrivApp=true domain=system_app type=system_data_file user=_app seInfo=platform domain=platform_app type=app_data_file
user=system
表示系统应用的 SELinux 用户为system
,域为system_app
。user=_app
表示普通应用的域为platform_app
(如果是平台签名应用)。
- 用途:
- 根据应用的 UID、签名、包名等分配不同的 SELinux 域。
- 控制应用的权限范围(如系统应用、平台应用、普通应用)。
- 注意:
seapp_contexts
是动态分配上下文的关键,决定了应用的隔离级别。- 支持的字段包括
isPrivApp
(是否预装)、seInfo
(签名信息)、name
(包名)等。
(5) hwservice_contexts
- 作用: 定义硬件抽象层(HAL)服务的 SELinux 安全上下文。
- 位置:
/etc/selinux/targeted/contexts/hwservice_contexts
。 - 格式:
示例:<HAL服务名称> <上下文>
android.hardware.wifi@1.0-service u:object_r:hal_wifi_default:s0
- 用途:
- 控制对硬件服务的访问,特别是在 Android 8.0+ 的 Treble 架构中。
- 确保 HAL 服务运行在独立的 SELinux 域中,防止越权访问。
- 注意:
- HAL 服务通常运行在独立的进程中,上下文严格隔离。
(6) vndservice_contexts
- 作用: 定义 Vendor(供应商)特定的 Binder 服务上下文。
- 位置:
/vendor/etc/selinux/vndservice_contexts
。 - 格式: 与
service_contexts
类似。 - 用途:
- 为供应商自定义的 Binder 服务分配上下文。
- 通常由设备制造商(OEM)定义。
- 注意:
- 与
service_contexts
类似,但专用于/vendor
分区。
- 与
(7) genfs_contexts
- 作用: 为不支持扩展属性的文件系统(如 proc、sysfs、tmpfs)定义 SELinux 上下文。
- 位置:
/etc/selinux/targeted/contexts/genfs_contexts
。 - 格式:
示例:<文件系统类型> <路径> <上下文>
proc /proc/sys u:object_r:proc_sys:s0 sysfs /sys/devices u:object_r:sysfs_devices:s0
- 用途:
- 为特殊文件系统(如
/proc
、/sys
)分配上下文。 - 弥补文件系统不支持扩展属性的不足。
- 为特殊文件系统(如
- 注意:
- 仅适用于非标准文件系统,普通文件系统使用
file_contexts
。
- 仅适用于非标准文件系统,普通文件系统使用
(8) fs_use_xxx
- 作用: 定义文件系统的 SELinux 挂载方式(
fs_use_task
,fs_use_trans
,fs_use_xattr
)。 - 位置: 通常与
genfs_contexts
一起使用。 - 类型:
fs_use_xattr
: 使用扩展属性存储上下文(常见于 ext4)。fs_use_task
: 为任务分配上下文(常用于管道或套接字)。fs_use_trans
: 动态转换上下文(常用于 tmpfs)。
- 用途:
- 控制文件系统如何与 SELinux 交互。
- 注意:
- 这些规则较少直接修改,通常由系统开发者配置。
8.3 如何使用和修改 xxx_contexts 文件
- 查看上下文:
- 使用
ls -Z
查看文件或目录的上下文。 - 使用
getprop
查看属性上下文。
- 使用
- 修改上下文:
- 使用
restorecon
重新应用file_contexts
中的上下文:restorecon /path/to/file
- 自定义上下文需要修改对应的
xxx_contexts
文件,并重新编译系统镜像。
- 使用
- 调试:
- 使用
audit2allow
分析 SELinux 拒绝日志(avc: denied
),生成允许规则。
- 使用
- 注意事项:
- 修改
xxx_contexts
文件需要深入了解 SELinux 策略,否则可能导致安全漏洞或系统不稳定。 - Android 的 AOSP 和 Vendor 分区分离后,需分别修改
/system
和/vendor
下的上下文文件。
- 修改
8.4 Android SELinux 上下文文件的模块化
从 Android 8.0 开始,Google 引入了 Project Treble,SELinux 策略被模块化,xxx_contexts
文件被拆分为:
- Platform:
/system/etc/selinux/
(AOSP 部分) - Vendor:
/vendor/etc/selinux/
(供应商部分) - ODM:
/odm/etc/selinux/
(设备制造商部分)
例如:
plat_file_contexts
:平台相关的文件上下文。vendor_file_contexts
:供应商相关的文件上下文。
这些文件在系统启动时由 init
合并为完整的 file_contexts
。
九、其他
参考链接:
domain
https://www.cnblogs.com/ly565911158/p/3622942.html
coredomain
https://www.cnblogs.com/liwugang/p/12433028.html
init_daemon_domain()
由于切换进程域的,进程都是init启动的,默认和init是相同的权限,所以需要用init_daemon_domain()将进程的域切换到自己的进程域;
https://blog.csdn.net/shell812/article/details/58596377
coredomain和init_daemon_domain()
https://blog.51cto.com/u_2559640/2365798
SELinux安全上下文
https://blog.csdn.net/weixin_34257076/article/details/92710226
SELinux文件属性
https://blog.csdn.net/weixin_32218919/article/details/116559662
SELinux权限
https://blog.csdn.net/jaczen/article/details/73028302