RFC-0090 - 驱动程序共享库许可名单

RFC-0090:驱动程序共享库许可名单
状态已接受
区域
  • 内核
说明

为驱动程序共享库添加了许可名单。

Gerrit 更改
作者
审核人
提交日期(年-月-日)2021-03-30
审核日期(年-月-日)2021-04-28

摘要

此 RFC 建议驱动程序框架添加一个包含驱动程序可以依赖的共享库的显式许可名单。系统会在 Fuchsia 树的构建时和驱动程序管理器的运行时检查此许可名单。系统不会运行依赖于许可名单中未包含的共享库的驱动程序。

此 RFC 旨在正式确认驱动程序作者与驱动程序框架之间长期以来的非正式协议。驱动程序作者目前知道他们不应依赖外部共享库,但目前还没有明确的共享库许可名单。

问题陈述和动机

Fuchsia 中的驱动程序是作为共享库实现的。驱动程序会加载到驱动程序主机。驱动程序主机表示一个可以包含多个驱动程序的单个进程。驱动程序本身可以依赖于其他共享库,这些库也需要加载到驱动程序主机中。

由于驱动程序及其共享库都存在于同一进程中,因此共享库可能会以细微且未定义的方式发生冲突。在树外构建的驱动程序可能会尝试与其他驱动程序正在使用的同一共享库的较新或较低版本进行关联。在两个共享库中实现同一符号的多个实现会导致符号解析变为非确定性。此外,共享库中的全局变量可能会被视为同一驱动程序主机中的驱动程序之间意外的共享状态。如果没有许可名单,驱动程序可能会开始通过不受支持的共享库进行通信。出于安全和正确性方面的原因,驱动程序框架需要某种方法来阻止驱动程序使用不受支持的共享库。

此 RFC 提出的解决方案是为驱动程序提供构建时和运行时共享库许可名单。驱动程序将无法链接到许可名单中未列出的共享库。此许可名单中的所有共享库都将由 Fuchsia 平台提供,而不是由各个驱动程序提供。

解决此问题的长期方案是使用命名空间型动态链接器。使用此类链接器时,每个驱动程序都会在进程中拥有自己的“命名空间”,并且驱动程序的共享库不会发生冲突。如果驱动程序框架具有命名空间型动态链接器,则不再需要共享库许可名单。

为何是现在?

驱动程序框架正在实现两项需要严格许可名单的新功能:树外驱动程序和驱动程序软件包。这两项功能都会从新位置加载驱动程序,这意味着系统如何处理驱动程序的共享库变得模糊不清。通过明确的政策指定从 Fuchsia 平台加载驱动程序的共享库,可以减少系统模糊性,并确保每个驱动程序在运行时都获得相同版本的共享库。若要在 Fuchsia 映像中保留所有驱动程序的共享库,必须先创建共享库许可名单。

设计

驱动程序框架将维护一个允许驱动程序关联到的共享库列表。此列表的初始内容将是驱动程序当前关联到的所有共享库。您可以向列表中添加或从中移除库,但需要获得驱动程序框架团队的许可。

此许可名单中的所有共享库都将由 Fuchsia 平台提供。其中许多共享库将作为 /boot/lib/ 中的 ZBI 中的 bootfs 项存在,以便驱动程序在早期启动时加载它们。驱动程序的加载器服务只会加载许可名单中的共享库,而不会加载各个驱动程序提供的库。

驱动程序将无法链接到许可名单中未列出的共享库。如果驱动程序尝试链接到列表中未包含的共享库,驱动程序框架将会创建构建时错误。如果加载的驱动程序尝试访问列表中未列出的共享库,驱动程序管理器会记录运行时错误。

考虑新共享库的标准

驱动程序框架团队将能够根据需要将新的共享库添加到许可名单中。对于任何新的共享库,都必须考虑以下事项:

  • 库的大小。如果共享库要存储在 ZBI 中,则必须有足够的空间。如果库将存储在存储空间中,则这一点不太重要。

实现

许可名单将根据驱动程序当前使用的共享库列表生成。然后,我们将实现在构建时检查许可名单的机制。之后,系统将实现在运行时检查许可名单的机制。无需进行任何驱动程序更改,因为初始列表将包含驱动程序当前使用的所有共享库。

您可以在驱动程序框架中使用自定义 fuchsia.ldsvc.Loader 实现来完成运行时实现。此实现不需要对代码库的其他部分进行架构更改。

性能

这不会影响广告效果。

安全注意事项

此提案对安全性有积极影响。这使得驱动程序的共享库使用情况更易于审核,并降低了因共享库冲突而导致未定义行为的可能性。

隐私注意事项

这可能会对隐私产生积极影响,因为它会减少驱动程序之间共享状态的范围。

测试

系统会先实现构建时检查,这意味着主要测试是树是否正确构建。目前没有树外驱动程序,因此如果树构建正确,则所有驱动程序都符合共享库许可名单。

实现构建时检查后,我们将实现运行时检查,以支持未来的非树型驱动程序。此模块将包含集成测试。

文档

此 RFC 旨在记录我们决定创建许可名单的决定。

我们将在 fuchsia.dev 网站上的驱动程序教程中添加有关许可名单的详细信息。 这将包括请求和批准对许可名单所做的更改的流程。

缺点、替代方案和未知情况

缺点之一是,如果我们使用命名空间型动态链接器,则无需此许可名单。当该链接存在时,我们将能够重新评估并可能移除许可名单。

许可名单会限制驱动程序可以关联的共享库数量,但可能不足以确保共享库是相同版本。外部驱动程序可能会尝试针对许可名单中的较新版本的共享库进行构建,但当系统使用来自 bootfs 的较低版本的库时,会在运行时失败。实现许可名单后,确保根据同一版本构建的非树内驱动程序可能是必要的后续工作。

另一个缺点是,驱动程序所有者可能会通过静态链接其库来响应共享库许可名单。使用静态链接的库会增加驱动程序的代码大小。这是这种方法的一种不幸但必要的副作用。如其他部分所述,解决此问题的长期方案是命名空间型动态链接器,它允许驱动程序在不使用许可名单的情况下使用共享库。

在先技术和参考文档

Zircon build 最初为驱动程序提供了共享库许可名单。在 build 合并期间,我们移除了此许可名单,以简化合并流程。我们一直打算重新实现该功能,但一直没有将其列为优先事项。

驱动程序管理器目前针对从未启用的共享库许可名单提供了运行时实现。目前,可使用内核命令行选项 devmgr.devhost.strict-linking 启用它。在实施许可名单的过程中,此实现将会更新。