RFC-0102:禁止 CHILD_NO_WRITE 与 CHILD_RESIZABLE

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_create_child 传递 ZX_VMO_CHILD_NO_WRITEZX_VMO_CHILD_RESIZABLE 的组合视为错误。

设计初衷

使用 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_WRITEZX_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 等可变指令长度架构上,即使仅限于在页面边界上进行。

不进行任何操作

另一种方法是保持系统调用的原样,并记录以下事实:即使请求了可调整大小的句柄,成功创建的句柄也可能无法调整大小。