在 Android 系统中,SELinux 主要是通过一系列配置文件来进行管理和配置的。这些配置文件涵盖了策略定义、标签映射、签名信息等多个方面。
一、SeLinux文件体系
之前提到 Android 架构中大致包含 AOSP、厂商、Vendor 等部分。在 Android 8 以上的系统中,AOSP 和厂商、供应商的部分是独立配置的,方便 OTA 更新。针对这种架构,SELinux 的 Policy 文件体系包含以下目录:
- system/sepolicy/public:这部分策略是 AOSP 公开给厂商(vender)使用的,作为其基础 API。比如声明了 domain 的 attributes 就在这里。这部分策略需要做兼容处理,因为厂商(vender)引用了这里的策略,如果 OTA 单独升级了 AOSP,需要确保向后兼容性。
- system/sepolicy/private:这部分策略是 AOSP 内部使用的,即 system image 内部用的策略。这部分政策不应被厂商(vender)感知,因此不需要考虑向后兼容性。
- system/sepolicy/vendor:这部分策略是专门为厂商(vender)定制的部分,由厂商自行管理,不需要考虑 AOSP 升级的影响。
- device/{厂商}/{设备名称}/sepolicy:这部分策略是针对特定设备的,比如三星设备 device/samsung/tuna/sepolicy。这部分政策由设备制造商自行管理,不需要考虑 AOSP 升级的影响。
1、BoardConfig.mk
在 Android 源码中,BoardConfig.mk 文件用于指定 SELinux 策略文件路径的构建配置。对于 SELinux 策略文件,在配置 SELinux 策略文件路径的时候,通常使用以下几个系统变量进行指定:
- BOARD_PLAT_PUBLIC_SEPOLICY_DIR:平台公共 SELinux 策略文件路径,通常指向 system/sepolicy/public。
- BOARD_PLAT_PRIVATE_SEPOLICY_DIR:平台私有 SELinux 策略文件路径,通常指向 system/sepolicy/private。
- BOARD_VENDOR_SEPOLICY_DIRS:指定设备特定的 SELinux 策略文件路径(通常是厂商自定义的部分)。通常指向 device/{厂商}/{设备名称}/sepolicy/。
- BOARD_SEPOLICY_DIRS:指定设备特定的 SELinux 策略文件路径(通常用于系统部分),通常指向 device/{厂商}/{设备名称}/sepolicy/。
- BOARD_SYSTEM_SEPOLICY_DIRS:指定系统级别的 SELinux 策略文件路径,通常指向 system/sepolicy
AOSP 的 SELinux 策略文件一般不需要更改,或少量更改。厂商侧主要修改和定制的安全策略在 device/{厂商}/{设备名称}/sepolicy 下。
配置示例
源码位置:device/{厂商}/{设备名称}/sepolicy/BoardConfig.mk
# 指定平台公共 SELinux 策略文件路径
BOARD_PLAT_PUBLIC_SEPOLICY_DIR := $(DEVICE_PATH)/sepolicy/public# 指定平台私有 SELinux 策略文件路径
BOARD_PLAT_PRIVATE_SEPOLICY_DIR := $(DEVICE_PATH)/sepolicy/private# 指定设备特定的 SELinux 策略文件路径(厂商自定义部分)
BOARD_VENDOR_SEPOLICY_DIRS += $(DEVICE_PATH)/sepolicy# 指定设备特定的 SELinux 策略文件路径(系统部分)
BOARD_SEPOLICY_DIR := $(DEVICE_PATH)/sepolicy# 指定系统级别的 SELinux 策略文件路径
BOARD_SYSTEM_SEPOLICY_DIRS += $(DEVICE_PATH)/sepolicy/system
当构建系统运行时,会根据这些变量指定的路径合并 SELinux 策略文件。
2、system_ext和product
在 Android 11 及以上系统中,system_ext 和 product 分区也独立出单独的 SELinux 策略,并且区分了public 和 private。这些策略的版本兼容处理由各合作伙伴自行负责,而不是 AOSP 负责。
- SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS:指定 system_ext 分区的公共 SELinux 策略文件路径,通常指向 system_ext/sepolicy/public 或者设备特定的私有策略文件路径。
- SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS:指定 system_ext 分区的私有 SELinux 策略文件路径。通常指向 system_ext/sepolicy/private 或者设备特定的私有策略文件路径。
- PRODUCT_PUBLIC_SEPOLICY_DIRS:产品公共 SELinux 策略文件路径,通常指向 system/sepolicy/public 或者设备特定的公共策略文件路径。
- PRODUCT_PRIVATE_SEPOLICY_DIRS:产品私有 SELinux 策略文件路径,通常指向 system/sepolicy/private 或者设备特定的私有策略文件路径。
二、策略文件
把 SELinux 策略配置相关的文件统称为策略文件。这些文件包含了各种安全规则,决定了进程、文件、网络端口等资源的安全标签以及它们之间的访问控制规则。
1、TE文件
在 SELinux 中,.te 文件(Type Enforcement 文件)是非常重要的组成部分,它们定义了 SELinux 策略的核心规则。.te 文件主要用于定义类型(Types)、访问规则以及其他与安全相关的配置。
编写完TE文件后,将 TE 文件放在对应目录下,Android 系统编译后 .te 文件将被编译成 .cil 文件。在 init 进程启动阶段,会将 .cil 文件汇总统一编译成一个命名为 policy 的文件。cil 文件是可读的,policy 文件是二进制的。在系统运行时最终加载使用的是 policy 文件。
policy文件一般在/sys/fs/selinux/policy。一般每个进程单独声明一个 TE 文件。比如一个 dhcp 进程单独有一个 te 文件叫 dhcp.te。而文件的 te 统一整合在 file.te(比如 platform/system/sepolicy/public/file.te)中。
针对 Platform(AOSP 的部分)、Non-Platform(厂商、供应商的部分),TE 会有不同的放置目录。
文件示例
源码位置:/system/sepolicy/public/dhcp.te
type dhcp, domain;
type dhcp_exec, system_file_type, exec_type, file_type;net_domain(dhcp)allow dhcp cgroup:dir { create write add_name };
allow dhcp cgroup_v2:dir { create write add_name };
allow dhcp self:global_capability_class_set { setgid setuid net_admin net_raw net_bind_service };
allow dhcp self:packet_socket create_socket_perms_no_ioctl;
allow dhcp self:netlink_route_socket nlmsg_write;
allow dhcp shell_exec:file rx_file_perms;
allow dhcp system_file:file rx_file_perms;
not_full_treble(`allow dhcp vendor_file:file rx_file_perms;')# dhcpcd runs dhcpcd-hooks/*, which runs getprop / setprop (toolbox_exec)
allow dhcp toolbox_exec:file rx_file_perms;# For /proc/sys/net/ipv4/conf/*/promote_secondaries
allow dhcp proc_net_type:file write;allow dhcp dhcp_data_file:dir create_dir_perms;
allow dhcp dhcp_data_file:file create_file_perms;# PAN connections
allow dhcp netd:fd use;
allow dhcp netd:fifo_file rw_file_perms;
allow dhcp netd:{ dgram_socket_class_set unix_stream_socket } { read write };
allow dhcp netd:{ netlink_kobject_uevent_socket netlink_route_socket netlink_nflog_socket } { read write };
这段 .te 文件定义了与 DHCP 相关的安全策略, 下面我们来看一下这段代码的详细解析。
语法解析
type dhcp, domain
声明一个 type 名为 dhcp,属于 domain 类别,也就是说在声明时便继承了domain 所拥有的权限。domain 属性是进程专用的,很显然这是一个进程的 te 文件。
type dhcp_exec, system_file_type, exec_type, file_type;
声明一个 type 名为 dhcp_exec, 属于 system_file_type, exec_type, file_type 类别。也就是说同时继承三个 Attribute 所代表的文件。system_file_type 用于代表系统文件,exec_type 用于代表可执行文件,也就是进程的可执行文件入口,file_type 代表通用文件。从这里我们知道dhcp_exec 代表 dhcp 可执行文件的入口。
net_domain(dhcp)
这是一个宏,用于定义 dhcp 类型为网络域类型,可以进行通用的网络操作,比如读写 TCP 包,操作 socket 等。
allow dhcp cgroup:dir { create write add_name };
allow dhcp cgroup_v2:dir { create write add_name };
具体的规则描述,表示允许 dhcp 类型访问 cgroup 和 cgroup_v2 目录,执行创建、写入和添加名称的操作。下面几个同样是具体的规则描述,这里就不做一一介绍了。
not_full_treble(`allow dhcp vendor_file:file rx_file_perms;')
允许 dhcp 类型访问 vendor_file 文件,并具有读取和执行权限。not_full_treble 表示这是一个特殊的规则,不完全适用于所有情况。
2、Context文件
在 SELinux 中,Context 文件用于定义不同类型的上下文,以便将文件、进程和服务等资源与特定的安全标签(context)关联起来。以下是几种常见的 Context 文件及其用途:
- file_contexts:定义了文件和目录的上下文(context),用于将文件目录和文件的类型(type)关联起来。
- genfs_contexts:用于将文件系统(如 /proc 和 vfat)与类型(type)关联起来。
- property_contexts:用于将 Android 系统属性与类型(type)关联起来。
- service_contexts:用于将服务进程与类型(type)关联起来。
- seapp_contexts:用于将应用程序与类型(type)关联起来。
- mac_permissions.xml:根据应用程序的签名或包名,为应用程序分配一个 seinfo。seinfo 用于在应用程序没有明确关联一个类型时归属一个默认类型。
- keystore2_key_contexts :用于为 Keystore 2.0 namespaces 分配一个标签(label)。
通过这些 Context 文件,SELinux 可以将文件、进程和服务等资源与特定的安全标签(context)关联起来,从而实现细粒度的访问控制。
当然,在 SELinux 中,还有 Attribute 文件和 security_classes 文件等,分别用于定义安全标签中的属性部分和声明安全类(Class),在其他文章中经常使用,同时后面也会做详细分析,这里就不做过多介绍了。