| RFC-0102:禁止将 CHILD_NO_WRITE 与 CHILD_RESIZABLE 搭配使用 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 禁止将 ZX_VMO_CHILD_NO_WRITE 与 ZX_VMO_CHILD_RESIZABLE 搭配使用,并将其作为错误传递给 zx_vmo_create_child |
| 问题 | |
| Gerrit 更改 | |
| 作者 | |
| 审核人 | |
| 提交日期(年-月-日) | 2021-05-25 |
| 审核日期(年-月-日) | 2021-06-10 |
摘要
此 RFC 建议禁止将 ZX_VMO_CHILD_NO_WRITE 和 ZX_VMO_CHILD_RESIZABLE 组合使用,并将其作为错误传递给 zx_vmo_create_child。
设计初衷
使用 zx_vmo_create_child 创建子 VMO,并设置 ZX_VMO_CHILD_NO_WRITE 标志,会明确从生成的句柄中移除
ZX_RIGHT_WRITE。由于这是目前唯一指向新创建的 VMO 的句柄,并且其权限永远无法升级为包含
ZX_RIGHT_WRITE,因此永远无法生成具有 ZX_RIGHT_WRITE 的 VMO 的其他句柄。
使用 ZX_VMO_CHILD_RESIZABLE 创建的 VMO 子项可以执行调整大小操作 zx_vmo_set_size,该操作需要
ZX_RIGHT_WRITE,因为它可能会修改 VMO 数据。
如果将这两个标志都传递给 zx_vmo_create_child,则会成功创建 VMO,并返回一个句柄,如果调用
zx_vmo_set_size,则会出错。从用户的角度来看,成功创建具有 ZX_VMO_CHILD_RESZIABLE 的对象,但调整大小操作却失败,这非常令人困惑。不仅在立即生成的句柄上失败,而且无法生成此对象的句柄,因为句柄权限无法升级,因此无法调整大小。
设计
zx_vmo_create_child 系统调用会在开始时检查是否同时设置了 ZX_VMO_CHILD_NO_WRITE 和
ZX_VMO_CHILD_RESIZABLE 标志,如果是,则立即返回 ZX_ERR_INVALID_ARGS。
实现
所有更改都可以在单个 CL 中实现。
性能
不相关。
向后兼容性
目前尚无已知的使用此标志组合的情况。
安全注意事项
无。
隐私注意事项
无。
测试
添加了单元测试来验证限制。
文档
需要更新 zx_vmo_create_child 的 API 文档。
缺点、替代方案和未知事项
专用调整大小权限
ZX_RIGHT_WRITE 用于控制 zx_vmo_set_size 操作,因为调整大小会通过截断或零扩展来修改 VMO。这是一组非常有限且可预测的修改,因此可以拥有自己的专用权限,以将其与任意修改分开。
即使具有这种专用权限,ZX_VMO_CHILD_NO_WRITE 也几乎肯定会剥夺该权限,因为 ZX_VMO_CHILD_NO_WRITE
的目的是防止代码修改。截断和零扩展的组合可能会导致恶意指令的形成,尤其是在 x86 等可变指令长度架构上,即使仅限于在页面边界上执行也是如此。
不进行任何操作
另一种方法是保持系统调用不变,并记录以下事实:即使请求了,成功生成的句柄也可能无法调整大小。