RFC-0064:Box <Knox>

RFC-0064:Box <Knox>
状态已拒绝
领域
  • FIDL
说明

引入了一种机制,用于通过与 FIDL 消息关联的辅助 VMO 传输大型结构化数据对象。

作者
提交日期(年-月-日)2018-09-27
审核日期(年-月-日)2020-06-17

遭拒原因

通过 FIDL 在对等方之间传输大型消息的问题非常重要, 以及当前 FIDL 存在的不足。 综合运用了渠道限制, 可能会超出这些限制的消息,以及 但消息大小本身难以确定(例如,max out 分页),使得在应用中无法解决这个问题 代码(至少是大规模的)。解决方案必须由 FIDL 提供

简而言之,FIDL 需要为图书馆作者提供一种途径, 由于协议限制(例如 字节数和句柄(对于 Zircon 通道),以及 FIDL 开发者 需要依靠绑定来实现 大型邮件。

此 RFC 文档包含许多可取的要素,可作为参考 。具体而言:

  • 问题陈述和动机。
  • 支持静态验证,以保证 不满足协议限制,或选择启用由 使用绑定关系(可能会产生一些额外费用)
  • 区分值类型与资源类型来提供内容 在便利性与性能之间权衡的多个不同点。

尽管如此,该 RFC 仍被拒绝,原因如下:

  • 消息的显示方式将字节和句柄从一个对等端传输到另一个对等端时, 无需考虑线缆格式,并且无需对线缆进行修改 格式。
  • 引入 box<T> 表示法有助于识别消息中的地点 出现拳击的情况,即表明拳击是一种精细的机制, 消息中(几乎)任意位置的行为。相反,当前的 认为最好在方法级别提供注解, 即使用现场(而不是声明)的较粗略的说明机制 网站。
  • 随着 FIDL 的逐步泛化,以支持 Zircon 通道上,我们必须考虑到,每次 有自己的局限性。例如,我们打算将 FIDL 扩展到 Zircon, fifos,那么大小限制将有所不同,并且不允许使用任何句柄。 这样可进一步提供方法级注解(而不是以类型为中心)的视图, 注释)。

如今,在应用中解决这一问题的方法使用 fuchsia.mem/Data 类型,表示数据的并集 或 VMO 中将此方法泛化到任何请求和/或响应 使用语法糖(像处理错误一样)以及绑定 支持,是目前在这一主题方面处于领先地位的有力竞争者。

摘要

并引入一种通过 与 FIDL 消息关联的辅助 VMO。

设计初衷

可发送的 FIDL 消息的大小上限 通过 Zircon 通道在进程之间传输, ZX_CHANNEL_MAX_MSG_BYTES.在撰写本文时, 上限为 64 KB(包括 FIDL 标头)。

尽管该限制对许多应用来说已经足够,但偶尔还是会遇到 传输更大型的对象。这给 FIDL API 带来了挑战 因为他们必须设计出 对象,例如:

  • 分页:在传输对象集合(通常为矢量)时, 分批分批提供对象,而不是一次性交付所有对象。
    • 只要每个对象小于上限就能正常运行 (将标头和其他字段纳入考虑范围)。
    • 对开发者来说有点难确定如何打包对象 有效传送至邮件中,而又不会超出限制,因为 目前还没有用于估算 FIDL 消息大小或 逐步构建容器
  • VMO 封装:而不是在 FIDL 中传输大型对象 请将它们复制到 VMO 中。这通常表示为 fuchsia.mem/Buffer
    • 非常适合字节矢量 (blob)。
    • 结构化数据对象很麻烦,因为由开发者负责 调用序列化/反序列化的方法。
    • 需要系统加强防范因共享内存导致的安全威胁。

未能预测到此问题是导致运行时不稳定的主要原因。

我们认为 FIDL 应以静态安全 可验证高效传输大型数据对象的机制。

设计

产品简介

Box 是一个容器,用于存储可能需要 当邮件总大小(包括标头)超过时,通过带外方式传输 Zircon 频道1的限制。

box 仅存放数据对象;它不能存储 标识名2

设计时,FIDL 协议作者。

  • 将数据对象封装到框中 包含这些对象的可能超出渠道限制

在编译时,FIDL 编译器会...

  • 解析声明
  • 静态验证每个框仅包含数据对象(没有句柄)
  • 静态验证每条 FIDL 消息的最大可能大小是否 不超过通道限制(强制执行静态邮件大小时) 模式) <ph type="x-smartling-placeholder">
      </ph>
    • 假定矢量和字符串在边界允许范围内的最大大小
    • 假设可扩展联合体和结构体(表)与它们一样大 有可能变成
    • 拒绝递归结构,除非递归被方框破坏

编译时,每个 FIDL 代码生成器都会...

  • 生成足以对盒装数据进行序列化和反序列化的代码

运行时,FIDL 编码器...

  • 将任意多盒装对象打包到邮件正文中, 其他行外对象
  • 打包所有不适合放入 VMO 的盒装对象

运行时,FIDL 解码器。

  • 在访问包含盒装对象(如果有)的 VMO 之前,可确保 具有该 VMO 的唯一句柄(该 VMO 未共享)
  • 从消息正文和 VMO 中提取盒装对象

语言详情

我们引入了一种新的内置 FIDL 类型,以 box<T> 表示。T 用于指定 要放入盒子的对象的类型。

  • T 必须是不直接或间接包含 标识名。
  • T 不能是基元类型。
  • T 可能是可选类型。

新类型 box<T> 可用于任何引用类型,例如 structs, 可以接受联合体、矢量和字符串。

框类型示例

  • box<string>
    • 包含无界限字符串的框
  • box<int>
    • 错误:Box 不能包含基元类型的对象
  • box<vector<T>:100>
    • 包含 T 个有边界向量的框
  • box<vector<T>>
    • 包含 T 个对象的无界限矢量的框
  • vector<box<T>>:100
    • 一个有边界的 T 对象的有界向量。
  • box<string:100>
    • 包含有界字符串的方框
  • box<string>
    • 包含无界限字符串的框
  • box<MyStruct>
    • 包含结构的盒子
  • box<MyStruct?>
    • 包含可选结构的
  • box<MyStruct>?
    • 错误:框不得为可选项

声明示例

interface Database {
    // OK
    1: SelectTop(string:1000 query) -> (box<Record> record);

    // ERROR: reply may exceed message size limit
    // consider wrapping large objects in a box<>,
    // "Record" size is unbounded
    2: BadSelectTop(string:1000 query) -> (Record record);

    // OK
    3: SelectAll(string:1000 query) -> (box<vector<Record>> records);

    // ERROR: reply may exceed message size limit
    // consider wrapping large objects in a box<>,
    // "vector<Record>" size is unbounded
    4: BadSelectAll(string:1000 query) -> (vector<Record> records);
};

struct Record {
    string name;
    string address;
};

电汇格式

(此部分不完整。)

文案创意 1:在序列化深度优先遍历期间,添加遇到的所有框 完成后,先将包装好的物品按照 使这些对象超出行,直到没有剩余空间为止,然后计算剩余空间的大小 装箱对象,分配单个 VMO,并继续将包装箱内容从 那里

文案创意 2:与创意 1 类似,但将每个创意框放入各自的 VMO 中,稍微简单一些 但可能会受到更多限制

文案创意第 3 行:也许我们应该完全放弃箱子的概念, 方法级别,例如注解。[Huge]

绑定

(此部分不完整。)

增强型 VMO 系统调用

(此部分不完整。)

文案创意第 1 行:定义“确保不共享”标志,验证 VMO 是否只有一个句柄 不与其他 VMO 共享任何页面,并且未映射,可以将此标志传递给 zx_vmo_read/write/map 等

文案创意 2:定义一个新的系统调用以检查 VMO 是否未共享

文案创意第 3 行:实际检查对 VMO 进行反向 COW 快照(如果它已 不共享(应为空操作)

文案创意 4:在 VMO 上弃踢并改用 View

实施策略

(此部分不完整。)

工效学设计

(此部分不完整。)

文档和示例

(此部分不完整。)

向后兼容性

除了提供传输大型数据对象的机制外,Box 还提供了 旨在解决静态安全问题

目前,尝试传输超出信道的 FIDL 消息的节目 限制会在运行时失败,从而导致系统不稳定。将边界框 引入静态消息大小强制执行是可行的 ,确保在编译时 消息会超出渠道限制;可以简单地将违规内容 移到一个盒子里。

但是,一次性启用静态消息大小强制执行可能会破坏现有的 会阻碍迁移工作

我们建议按以下方式解决此问题:

  • 最初,请在宽容模式下启用静态邮件大小检查。
    • FIDL 编译器应检查消息大小, 可能会超过上限建议 FIDL 协议的作者 不妨改用方框
  • 继续迁移。
  • 完成后,请在强制执行模式下启用静态邮件大小检查。
    • FIDL 编译器应检查消息大小, 可能会超过上限暂停编译。

性能

(此部分不完整。)

安全

通过将现有的临时机制替换为由 Google 提供支持的官方解决方案, FIDL 语言绑定,我们有机会提高整体安全性 纪律。

例如,FIDL 语言绑定可确保包含方框的 VMO 数据只有一个所有者,然后才能尝试访问其内容。这个 可解决常见的共享内存威胁,如:

  • VMO 的提供程序会在客户端访问数据时修改数据。
  • VMO 的提供程序会在访问 VMO 时更改其大小 或以其他方式诱使客户端发生页面错误。

反过来,引入此功能可能会使大型语言模型 消息,从而增加发生其他威胁的可能性,例如:

  • VMO 的提供商向客户端发送大量回复,导致客户端 在反序列化时分配大量堆

测试

(此部分不完整。)

缺点、替代方案和未知之处

(此部分不完整。)

早期艺术作品和参考资料

(此部分不完整。)

编者注:被拒绝的RFC-0062:方法不可能, 禁止所有可能会超出协议限制的方法。这也是 会由于静态分析的局限性而限制 对消息进行正确分页或手动“装箱”。



  1. 假设,FIDL 可以通过其他通道传输, 可能具有不同的性质具体的实施方式不在讨论范围内 此提案 

  2. 编者注:由于此 RFC 是在 2018 年撰写的,因此 值类型和资源是 FIDL 语言的正式组成部分, RFC-0057。