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 build 最初具有面向驱动程序的共享库许可名单。在 build 统一期间,此许可名单已被移除,以简化统一流程。一直以来,我们都打算重新实现它,但直到现在才成为优先事项。
驱动程序管理器目前有一个针对共享库许可名单的运行时实现,该实现从未开启。目前通过内核命令行选项 devmgr.devhost.strict-linking
启用。作为实施许可名单的一部分,此实现方式将会更新。