安卓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 上下文,供权限规则使用。

注意

  1. 别名集:如果指定的不止一个别名标识符,要在一对大括号中用空格将各个别名区别开来,如:alias {aliasa_t aliasb_t}。
  2. 属性集:是一个或多个预先声明的属性标识符,如果同时指定多个属性标识符,属性之间使用逗号进行分隔,如:type bin_t, file_type, exec_type;
  3. 类型声明在整个策略中,以及基础载入模块和非基础载入模块中都是有效的。但在有条件的语句中无效。

示例:

type serial_device, dev_type;

定义 serial_device 类型,表示串口设备(如 /dev/ttyS0),并关联 dev_type 属性(表示设备类型)。


三、attribute

  • 定义:
    attribute 是 SELinux 中的属性声明,用于定义一个类型集合(group),可以将多个 type 归类到一个抽象标签下,简化权限规则的编写。它本身不直接与资源或进程关联,而是为 type 提供分组机制。
  • 作用:
    允许在规则中使用单个 attribute 替代多个 type,减少重复规则。
    常用于分类类似资源(如所有 sysfs 文件、所有属性类型)。
  • 语法:attribute 属性名称;

注意

  1. 属性和类型,别名都在同一个命名空间,因此不能与其他类型或别名重名。
  2. 属性声明在整个策略,基础载入模块和非基础载入模块中都有效,但在有条件的语句中无效。

示例:

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 别名名称
    1. 类型名称:要添加别名的类型的名称,类型必须使用type语句单独声明,而且这里只能指定一个类型名称。
    2. 别名名称:如果同时指定多个别名,别名之间用空格分开,并使用大括号将所有别名括起来,如{aliasa_t aliasb_t}。
    3. 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 daemon
    allow init $1:process { transition sigchld };
    # Allow the daemon to relabel itself
    allow $1 self:process { setcurrent };
    # Allow init to send signals to the daemon
    allow init $1:process { signal };
endmacro
7.2.1 展开后规则详解

假设你调用 init_daemon_domain(odm_server),宏会展开为以下规则:

  1. 定义类型

    type odm_server, domain;
    type odm_server_exec, exec_type, file_type;
    
    • 定义 odm_server 作为 SELinux 域类型(domain),表示进程的运行上下文。
    • 定义 odm_server_exec 作为可执行文件类型(exec_typefile_type),通常对应守护进程的可执行文件(如 /system/bin/odm_server)。
  2. 域转换

    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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值