ax-cap-access 技术文档
路径:
components/cap_access类型:库 crate 分层:组件层 / 能力位访问封装 版本:0.3.0文档依据:当前仓库源码、Cargo.toml、README.md、src/lib.rs、os/arceos/modules/axfs/src/fops.rs
ax-cap-access 的真实定位是一个能力位 bitmask + 包装器组件:它把“某个对象当前允许的访问权限”附着在对象句柄上,并在访问时做一次显式的 capability 子集检查。它不是完整的 capability 安全子系统,不做全局对象管理、权限传播、撤销、审计或命名空间隔离。
1. 架构设计分析
1.1 设计定位
这个 crate 的接口极小,核 心就两个类型:
CapWithCap<T>
其中:
Cap是能力位集合WithCap<T>是“对象 + 能力位”的组合包装
这说明它解决的不是“系统范围权限模型”,而是“单个对象句柄的本地访问约束”。
1.2 Cap:能力位集合
Cap 由 bitflags 生成,目前只有三个位:
READWRITEEXECUTE
这三个权限位对应的不是某种复杂策略语言,而是最基础的访问能力表达。它们的使用语义是:
- 请求的权限必须是已授予权限的子集
具体体现在 can_access() 内部使用的是:
self.cap.contains(requested_cap)
1.3 WithCap<T>:句柄包装模型
WithCap<T> 只保存两项数据:
inner: Tcap: Cap
对外提供的能力也很克制:
new(inner, cap)cap()can_access(cap)access_unchecked()access(cap)access_or_err(cap, err)
值得注意的是,它只返回:
&T
而不是 &mut T。这意味着它本身不承担“可变借用权限模型”的表达。若调用方需要修改对象,通常依赖的是:
- 被包装对象本身的内部可变性
- 或其底层句柄语义
1.4 unsafe 边界
access_unchecked() 是该 crate 唯一显式越过能力检查的入口:
- 调用者需自行保证不违反能力约束
当前仓库里的真实使用场景是在 ax-fs 的 Drop 实现中:
File/Directory在析构时通过access_unchecked()取出VfsNodeRef- 然后调用
release()
这类用法说明:ax-cap-access 的能力检查主要针对“正常业务访问”,而某些生命周期收尾路径需要由上层自己背书。
1.5 与 ax-fs 的真实关系
当前仓库内可确认的直接消费者是:
os/arceos/modules/axfs/src/fops.rs
在那里:
File和Directory都把VfsNodeRef包装成WithCap<VfsNodeRef>OpenOptions会被转换成Cap- 文件权限
FilePerm也会被映射成Cap - 读、写、执行目录遍历分别通过
Cap::READ、Cap::WRITE、Cap::EXECUTE做检查
例如:
read()/read_at()要求Cap::READwrite()/truncate()/flush()要求Cap::WRITE- 相对目录访问
access_at()要求Cap::EXECUTE get_attr()甚至允许用Cap::empty()访问元数据
这说明 ax-cap-access 在当前系统里承担的是文件句柄级权限防线,而不是 VFS 全局权限系统。
2. 核心功能说明
2.1 主要能力
- 用位标志表达对象可访问权限
- 在对象句柄外层附着权限集合
- 在访问时做显式能力检查
- 支持无检查访问,用于特殊受控路径
- 支持
Option和Result风格的访问返回
2.2 当前仓库中的典型调用链
真实调用链可概括为:
ax-fs根据OpenOptions和节点权限生成Cap- 用
WithCap::new(node, access_cap)封装已打开的节点 - 各操作通过
access_or_err()检查访问权限 - 失败时统一映射为
PermissionDenied
因此 ax-cap-access 处于“文件对象已获得”之后、“具体操作开始”之前这一层。
2.3 最关键的边界澄清
ax-cap-access 不提供:
- 权限继承与传播
- 全局 capability 表
- capability 撤销
- 对象命名、查找和授权委托
- 安全审计日志
它就是一个本地对象包装器。
3. 依赖关系图谱
3.1 直接依赖
| 依赖 | 作用 |
|---|---|
bitflags | 生成 Cap 能力位集合 |