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 开发团队或在本页面留言。