| RFC-0090:驱动程序共享库许可名单 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 为驱动程序共享库添加许可名单。 |
| Gerrit 更改 | |
| 作者 | |
| 审核人 | |
| 提交日期(年-月-日) | 2021-03-30 |
| 审核日期(年-月-日) | 2021-04-28 |
摘要
此 RFC 建议驱动程序框架添加驱动程序可以依赖的共享库的明确许可名单。此许可名单将在 Fuchsia 树的构建时进行检查,并在驱动程序管理器的运行时进行检查。依赖于不在许可名单中的共享库的驱动程序将不会运行。
此 RFC 将驱动程序作者与驱动程序框架之间长期存在的非正式协议正式化。驱动程序作者目前知道他们不应依赖于无关的共享库,但目前还没有明确的共享库许可名单。
问题陈述和动机
Fuchsia 中的驱动程序以共享库的形式实现。驱动程序会加载到驱动程序主机中。 驱动程序主机表示可以容纳多个驱动程序的单个进程。驱动程序本身可以依赖于其他共享库,这些共享库也需要加载到驱动程序主机中。
由于驱动程序及其共享库都存在于同一进程中,因此共享库可能会以微妙且未定义的方式发生冲突。树外构建的驱动程序可能会尝试链接到另一个驱动程序正在使用的同一共享库的较新或较旧版本。两个共享库中同一符号的多个实现使得符号解析不确定。此外,共享库中的全局变量可以被视为同一驱动程序主机中驱动程序之间意外的共享状态。如果没有许可名单,驱动程序可能会开始通过不受支持的共享库进行通信。出于安全性和正确性方面的考虑,驱动程序框架需要某种方式来阻止驱动程序使用不受支持的共享库。
此 RFC 提出的解决方案是为驱动程序提供构建时和运行时共享库许可名单。驱动程序将无法链接到不在许可名单中的共享库。此许可名单上的所有共享库都将由 Fuchsia 平台提供,而不是由各个驱动程序提供。
解决此问题的长期解决方案是使用命名空间动态链接器。借助此类链接器,每个驱动程序在进程中都有自己的“命名空间”,并且驱动程序的共享库不会发生冲突。如果驱动程序框架具有命名空间动态链接器,则不再需要共享库许可名单。
为何现在?
驱动程序框架正在实现两个需要严格许可名单的新功能:树外驱动程序和驱动程序软件包。这两个功能都从新位置加载驱动程序,这意味着系统如何处理驱动程序的共享库变得不明确。制定明确的政策,规定驱动程序的共享库将从 Fuchsia 平台加载,可以减少系统的不确定性,并确保每个驱动程序在运行时获得相同版本的共享库。拥有共享库许可名单是将所有驱动程序的共享库保留在 Fuchsia 映像中的先决条件。
设计
驱动程序框架将维护驱动程序可以链接到的共享库列表。此列表的初始内容将是驱动程序当前链接到的所有共享库。可以向列表中添加或从中移除库,但需要获得驱动程序框架团队的许可。
此许可名单上的所有共享库都将由 Fuchsia 平台提供。其中许多共享库将以 bootfs 项的形式存在于 ZBI 中的 /boot/lib/,以便驱动程序在前期启动时加载它们。驱动程序的加载器服务将仅加载许可名单中的共享库,而不会加载各个驱动程序提供的库。
驱动程序将无法链接到不在许可名单中的共享库。如果驱动程序尝试链接到不在列表中的共享库,驱动程序框架将创建构建时错误。如果已加载的驱动程序尝试访问不在列表中的共享库,驱动程序管理器将记录运行时错误。
考虑用于新共享库的标准
驱动程序框架团队将能够根据自己的需要向许可名单添加新的共享库。对于任何新的共享库,都必须考虑以下项:
- 库的大小。如果共享库将存储在 ZBI 中,则必须有空间。 如果库将存储在存储空间中,则这一点不太重要。
实现
许可名单将根据驱动程序当前使用的共享库列表生成。 然后,将实现用于在构建时检查许可名单的机制。之后,将实现用于在运行时检查许可名单的机制。由于初始列表将包含驱动程序当前使用的所有共享库,因此无需进行任何驱动程序更改。
运行时实现可以通过在驱动程序框架中使用自定义 fuchsia.ldsvc.Loader 实现来完成。此实现不需要对代码库的其他区域进行架构更改。
性能
这不会对性能产生任何影响。
安全注意事项
此提案对安全性有积极影响。它使驱动程序的共享库使用情况更易于审核,并减少了因共享库冲突而导致未定义行为的可能性。
隐私注意事项
这可能会对隐私产生积极影响,因为它减少了驱动程序之间共享状态的表面。
测试
将首先实现构建时检查,这意味着主要测试是树是否正确构建。目前没有树外驱动程序,因此如果树正确构建,则所有驱动程序都符合共享库许可名单。
实现构建时检查后,将实现运行时检查,以支持未来的树外驱动程序。这将进行集成测试。
文档
此 RFC 可作为我们创建许可名单的决定的文档。
有关许可名单的详细信息将添加到 fuchsia.dev 网站上的驱动程序教程中。 这将包括请求和批准对许可名单进行更改的过程。
缺点、替代方案和未知因素
一个缺点是,如果我们有命名空间动态链接器,则不需要此许可名单。 当该链接器存在时,我们将能够重新评估并可能移除许可名单。
许可名单限制了驱动程序可以链接到的共享库的数量,但可能不足以确保共享库是同一版本。树外驱动程序可能会尝试针对许可名单中的较新版本的共享库进行构建,但在运行时,当系统使用 bootfs 中的较旧版本的库时,构建会失败。确保树外驱动程序针对同一版本进行构建可能是实现许可名单后必要的后续工作。
另一个缺点是,驱动程序所有者可能会通过静态链接其库来响应共享库许可名单。使用静态链接的库会增加驱动程序的代码大小。 这是这种方法不幸但必要的副作用。如其他地方所述,解决此问题的长期解决方案是使用命名空间动态链接器,这将允许驱动程序在没有许可名单的情况下使用共享库。
在先技术和参考文档
Zircon 构建最初有一个驱动程序的共享库许可名单。在构建统一期间,此许可名单被移除,以简化统一过程。它一直打算重新实现,但直到现在才成为优先事项。
驱动程序管理器目前有一个共享库许可名单的运行时实现,但从未启用过。目前,它通过内核命令行选项 devmgr.devhost.strict-linking 启用。作为实现许可名单工作的一部分,此实现将进行更新。