Android 14 sepolicy 分区模型的核心。
一、总览
alps_u0(AOSP/Google 框架)提供 public(共用) 与 private(私有) 两层策略 + prebuilts/api/34.0 冻结快照;
alps_s0(MTK 工程)的 device/mediatek/sepolicy/basic/ 提供 plat_public / plat_private(并入 system 侧) 与 non_plat(vendor 侧)。编译时各分区独立生成 .cil,设备启动时由 init 合并成单一内核策略。
二、每个文件的角色
|---------------------------------------------------------------------|------|------------------|-----------------------------------------------------------------------|
| 文件 | 归属树 | 层 | 管理内容 |
| alps_s0/device/mediatek/sepolicy/basic/non_plat/kernel.te | MTK | vendor(non_plat) | kernel 域对 MTK 硬件/dm 设备的访问 ota_metadata_file/dm_user_device |
| alps_u0/system/sepolicy/public/init.te | AOSP | public(共用) | init 的全局公开约束(如 neverallow init execute_no_trans,放 public 才能约束所有分区的规则) |
| alps_u0/system/sepolicy/private/init.te | AOSP | private(私有) | init 域定义与详细授权(type init, domain; + 对文件/属性的 allow) |
| alps_u0/system/sepolicy/private/domain.te | AOSP | private | 通用 domain 属性、全局 neverallow的 execute 例外-ota_metadata_file |
| alps_u0/system/sepolicy/private/snapuserd.te | AOSP | private | snapuserd 域(A/B OTA COW 合并守护进程,Android 14 新增私有域) |
| alps_u0/system/sepolicy/prebuilts/api/34.0/private/{domain,init}.te | AOSP | 冻结快照 | API 34 冻结的 private 镜像,与当前 private 目录必须保持同步 |
三、它们如何形成 SELinux 规则(构建链)
te 源文件(各分区)
└─ checkpolicy -C -M -c 30 → 中间 conf
└─ build_sepolicy / secilc -m -M true -G -c 30 → 各分区 .cil
├─ plat_sepolicy.cil (system: AOSP public+private + MTK plat_public/plat_private)
├─ system_ext_sepolicy.cil (system_ext: 含 MTK plat_private 的 postinstall.te)
├─ vendor_sepolicy.cil (vendor: MTK non_plat + OEM vendor 规则)
└─ product_sepolicy.cil
init 启动时 security_load_policy 合并加载 → 内核单一策略
secilc 链接时会校验引用 ------vendor 的 .cil 只能引用 plat 的 public 类型;若引用了 private 类型,链接直接报 unknown type。这就是"哪些可见"的强制机制。
四、public / private / 快照 的可见性规则
|------------------------------------------------------|--------------------------------------------|------------------------------------------------|------------------------------------------------|
| 层 | 谁可见 | 谁不可见 | 典型内容 |
| public(system/sepolicy/public/+ MTK plat_public/) | 所有分区(system/system_ext/product/vendor)都可引用 | --- | init的公开约束、跨分区共用的 type/attribute/neverallow |
| private(system/sepolicy/private/+ MTKplat_private/ ) | 仅 system 分区自身 | vendor/product 不可见 ;vendor 引用即编译/链接失败 | snapuserd域、ota_metadata_file、init 详细授权 |
| non_plat(MTK basic/non_plat/) | vendor 侧(含自己的 type 定义) | system 的 private 规则看不到 vendor 私有类型 | kernel.te、vendor_init.te 、postinstall 的 MTK 部分 |
| prebuilts/api/34.0 | 构建期的校验基线 | 修改 public/影响 API 的 private 必须同步,否则 freeze 校验失败 | API 34 冻结快照 |
判定方法 :需要让 vendor 引用也能system引用定义在public;只给 system 引用定义在private;约束必须压住 vendor 规则的 neverallow 必须定义放 public(或同时出现在快照);涉及 MTK 硬件/vendor 服务定义在non_plat。
五、域与彼此关系
kernel(内核态,规则在 MTK non_plat/kernel.te)
│ 启动
▼
init(public+private 两层管理;所有进程的祖先)
│ domain_trans(exec 触发域转换)
├─► snapuserd (A/B OTA COW 合并,private/snapuserd.te)
├─► postinstall (system_ext 分区 OTA 阶段进程,MTK plat_private/postinstall.te)
└─► vendor_init → vendor 服务(MTK non_plat/vendor_init.te)
- domain_trans:init 执行 snapuserd_exec 时把子进程转入 snapuserd 域------所以 init 的 allow 与 snapuserd 的 allow 必须配套;
- neverallow:编译期强约束,全局生效;放 public 的 neverallow 连 vendor 规则也不能违反;
- 属性(attribute):如 domain、file_type,规则按属性批量生效,减少规则爆炸。