DEC 权限策略扩展功能 Wiki
一、功能概述
本次更新对 DEC 权限管理机制进行了全面扩展,主要包含以下四个核心能力:
| 序号 | 功能名称 | 一句话描述 |
|---|---|---|
| 1 | 忽略大小写规则下发 | 支持对特定目录设置"忽略/不忽略大小写"的权限规则 |
| 2 | 对外查询接口 | 提供标准 API 供其他模块查询 DEC 权限配置 |
| 3 | 规则数量扩展 | 单次支持的权限规则数量从原来的 8 条扩展到 64 条 |
| 4 | Symbol-link 支持 | 在权限挂载点中支持软链接操作 |
二、功能详解
2.1 忽略大小写规则下发
背景问题
在文件系统中,/storage/Users/Current 和 /storage/users/current 是否被视为同一目录?这取决于系统配置。不同应用对此有不同需求。
解决方案
新增 忽略大小写配置机制,可针对不同目录设置不同的匹配模式:
| 模式 | 说明 | 适用场景 |
|---|---|---|
DEC_MODE_IGNORE_CASE |
忽略大小写 | 用户目录,如 /storage/Users/currentUser |
DEC_MODE_NOT_IGNORE_CASE |
区分大小写 | 应用数据目录,如 /storage/Users/currentUser/appdata |
配置示例
// 当前默认配置
#define DEC_IGNORE_CASE_LIST \
{"/storage/Users/currentUser", DEC_MODE_IGNORE_CASE}, // 忽略大小写
{"/storage/Users/currentUser/appdata", DEC_MODE_NOT_IGNORE_CASE} // 区分大小写
工作流程
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ AppSpawn 启动 │───▶│ 读取配置文件 │───▶│ 下发规则到内核 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ 内核应用规则 │
└─────────────────┘
2.2 对外查询接口(dec_api)
接口说明
为方便其他模块(如 sandbox_manager_services)获取 DEC 权限配置,新增两个标准 API:
| 接口名称 | 返回值 | 用途 |
|---|---|---|
GetDecPathMap() |
map<权限名, 路径列表> |
获取所有权限对应的 DEC 路径 |
GetIgnoreCaseDirs() |
vector<路径, 模式> |
获取忽略大小写目录配置 |
使用场景
┌──────────────────────────────────────────────────────────────┐
│ sandbox_manager_services │
│ │
│ 当应用包发生变化时,需要清理相关的 DEC 路径 │
│ 调用 GetDecPathMap() 获取路径列表,然后执行清理操作 │
└──────────────────────────────────────────────────────────────┘
典型调用流程
// 获取某权限下的所有 DEC 路径
auto decPaths = GetDecPathMap();
for (const auto& [permission, paths] : decPaths) {
// permission: 权限名称,如 "ohos.permission.MANAGE_LOCAL_ACCOUNTS"
// paths: 该权限对应的所有 DEC 路径列表
}
// 获取忽略大小写配置
auto ignoreCaseDirs = GetIgnoreCaseDirs();
for (const auto& [path, mode] : ignoreCaseDirs) {
// path: 目录路径
// mode: DEC_MODE_IGNORE_CASE 或 DEC_MODE_NOT_IGNORE_CASE
}
2.3 规则数量扩展(8 → 64 条)
背景问题
原有实现中,单次只能下发 8 条权限规则(受内核单次批处理限制)。随着应用场景复杂化,8 条规则已无法满足需求。
解决方案
采用 分批下发机制:
┌────────────────────────────────────────────────────────────────┐
│ 64 条规则分批下发 │
├────────────────────────────────────────────────────────────────┤
│ │
│ 第 1 批: 规则 1-8 ──▶ 内核处理 │
│ 第 2 批: 规则 9-16 ──▶ 内核处理 │
│ 第 3 批: 规则 17-24 ──▶ 内核处理 │
│ ... │
│ 第 8 批: 规则 57-64 ──▶ 内核处理 │
│ │
└────────────────────────────────────────────────────────────────┘
关键参数
| 参数 | 值 | 说明 |
|---|---|---|
MAX_POLICY_NUM |
64 | 最大支持规则数 |
KERNEL_BATCH_SIZE |
8 | 每批下发的规则数 |
| 批次数 | 8 | 64 ÷ 8 = 8 次内核调用 |
时间戳一致性
为确保所有批次属于同一次操作,采用统一时间戳标识:
// 所有 8 批次使用相同的时间戳
uint64_t timestamp = clock_gettime(CLOCK_MONOTONIC);
for (each batch) {
batch.timestamp = timestamp; // 同一事务标识
}
2.4 Symbol-link(软链接)支持
背景问题
在 flags/permission 挂载点配置中,原来只支持目录挂载,不支持软链接操作。某些场景需要创建指向其他位置的软链接。
解决方案
在权限配置的 mount-paths 中新增 symbol-links 配置项:
配置示例(JSON 格式)
{
"permission": [
{
"ohos.permission.XXX": [
{
"mount-paths": [
{
"source": "/data/service",
"target": "/mnt/data/service"
}
],
"symbol-links": [
{
"target-name": "/data/external/share",
"link-name": "/mnt/share_link"
}
]
}
]
}
]
}
字段说明
| 字段 | 说明 |
|---|---|
target-name |
软链接指向的目标路径(真实存在的目录) |
link-name |
软链接的名称(在应用沙箱内可见的路径) |
效果示意
应用沙箱内:
/mnt/share_link ──────▶ /data/external/share
(软链接) (真实目录)
三、整体架构
┌─────────────────────────────────────────────────────────────────────┐
│ AppSpawn 进程 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ sandbox_dec.c │ │ dec_api.cpp │ │ sandbox_core │ │
│ │ (规则下发) │ │ (对外接口) │ │ (软链接处理) │ │
│ └───────┬───────┘ └───────┬───────┘ └───────┬───────┘ │
│ │ │ │ │
│ │ ┌───────────────┴───────────────┐ │ │
│ │ │ dec_config.h │ │ │
│ │ │ (配置定义中心) │ │ │
│ │ └───────────────┬───────────────┘ │ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ /dev/dec 设备节点 │ │
│ └─────────────────────────────┬───────────────────────────┘ │
│ │ │
└────────────────────────────────┼───────────────────────────────────┘
│
▼
┌─────────────────────────┐
│ 内核 DEC 模块 │
│ (权限校验与加密控制) │
└─────────────────────────┘
四、测试验证要点
4.1 忽略大小写规则
| 测试项 | 验证方法 | 预期结果 |
|---|---|---|
| 配置加载 | 启动 AppSpawn,检查日志 | 显示 "set dec ignore" 相关日志 |
| 规则生效 | 访问不同大小写的路径 | 按配置模式匹配 |
4.2 对外接口
| 测试项 | 验证方法 | 预期结果 |
|---|---|---|
| GetDecPathMap | 调用接口获取数据 | 返回正确的权限-路径映射 |
| GetIgnoreCaseDirs | 调用接口获取配置 | 返回正确的目录-模式列表 |
4.3 规则数量扩展
| 测试场景 | 规则数 | 预期批次数 | 验证点 |
|---|---|---|---|
| 少量规则 | 8 条 | 1 次 | 单次下发成功 |
| 中等规则 | 16 条 | 2 次 | 多批次下发成功 |
| 满载规则 | 64 条 | 8 次 | 全部下发成功 |
| 超限规则 | 65+ 条 | 拒绝 | 日志记录超限错误 |
4.4 软链接功能
| 测试项 | 验证方法 | 预期结果 |
|---|---|---|
| 软链接创建 | 配置 symbol-links 后启动应用 | 链接文件存在且指向正确 |
| 链接访问 | 通过链接访问目标目录 | 能正常读写目标目录内容 |
五、影响范围
5.1 受影响模块
| 模块 | 影响说明 |
|---|---|
| AppSpawn | 核心改动模块,新增规则下发逻辑 |
| Sandbox Manager | 可使用新接口获取 DEC 路径信息 |
| 内核 DEC 模块 | 需配合支持新的 ioctl 命令 |
5.2 配置文件变更
| 文件 | 变更说明 |
|---|---|
appdata-sandbox.json |
可选新增 symbol-links 配置项 |
dec_config.h |
可修改忽略大小写目录列表 |
5.3 兼容性说明
- 向后兼容:原有配置无需修改,新功能为可选扩展
- 内核依赖:需要内核支持
HM_SET_DEC_IGNORE_CASE_ID(12) ioctl 命令
六、常见问题
Q1: 如何添加新的忽略大小写目录?
A: 修改 dec_config.h 中的 DEC_IGNORE_CASE_LIST 宏定义:
#define DEC_IGNORE_CASE_LIST \
{"/storage/Users/currentUser", DEC_MODE_IGNORE_CASE}, \
{"/storage/Users/currentUser/appdata", DEC_MODE_NOT_IGNORE_CASE}, \
{"/your/new/path", DEC_MODE_IGNORE_CASE} // 新增条目
Q2: 规则超过 64 条怎么办?
A: 当前设计上限为 64 条。如需更多,需评估是否可以合并相似规则,或联系开发团队讨论扩展方案。
Q3: 软链接创建失败会影响应用启动吗?
A: 默认情况下,软链接失败不会阻止应用启动,仅记录日志。如需严格模式,可配置 checkErrorFlag。
七、版本信息
| 项目 | 内容 |
|---|---|
| 更新日期 | 2025年3月 |
| 相关 Issue | #1891 |
| 相关 MR | #2653 |
| 涉及文件 | sandbox_dec.c, sandbox_dec.h, dec_api.h, dec_api.cpp, dec_config.h, sandbox_core.cpp |
八、联系方式
如有问题或建议,请联系 AppSpawn 开发团队或在本页面留言。