RFC-0150:选择停用更新

RFC-0150:更新选择停用
状态已接受
领域
  • 软件交付
说明

供产品所有者选择不接收软件更新的政策和功能。

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2022-01-14
审核日期(年-月-日)2022-01-31

摘要

我们介绍了一项新功能,供产品所有者允许其产品的用户选择不接收软件更新。我们介绍了与此机制相关的政策、其使用方式,以及与存储该设置相关的安全机制。最后,我们将介绍系统中的其他组件如何观察系统是否已选择停用更新。

设计初衷

根据我们的要求,客户必须允许 Fuchsia 设备用户选择不接收更新。我们必须以尽可能确保所有用户安全的方式满足该要求,无论这些用户的选择停用状态如何。

利益相关方

教员

pascallouis@google.com

审核者

  • kevinwells@google.com - 软件交付 (SWD)
  • ampearce@google.com - 安全
  • pascallouis@google.com - Fuchsia Engineering Council (FEC)

咨询人员

  • borthakur@google.com
  • marvinpaul@google.com - 服务器实施
  • gtsai@google.com - 服务器实现
  • enoharemaien@google.com - 隐私权
  • hjfreyer@google.com - 组件平台 / FEC
  • 软件交付团队

社交

此 RFC 经过了软件交付团队、安全和隐私团队以及客户的设计阶段。

要求

本文档中的关键字“必须”“不得”“必需”“会”“不会”“应”“不应”“建议”“可以”和“可选”应按 IETF RFC 2119 中的描述进行解释。

  • 产品所有者可以允许用户选择停用更新,这意味着除了产品所有者指定的关键更新(包括关键安全更新)以外,用户设备上不会下载或安装任何更新。
  • 如果设备已选择退出更新,并且正在运行恢复出厂设置 (FDR),则应选择重新启用更新。
  • 该设置必须在重新启动后保留,而不必每次启动时都由产品级组件重新设置(这会导致产品级组件和更新检查之间出现竞态条件)。
  • 此设置的启用和存储必须尽可能安全,以防止攻击者发现权限提升、为设备停用更新,以及无限期地保留该漏洞。
  • 如果产品所有者未决定将该选项包含在 build 中,那么其他人就不能在运行时启用该选项(必须有一个静态编译时标志来完全停用该功能)。
  • 我们必须设置相关指标,说明选择不更新更新的用户数量(但不是特定用户),以确保此选项不会被攻击者利用来保留漏洞。
  • 如果系统处于恢复模式,应始终允许更新。
  • 如果用户手动请求更新(即使在更新被停用的情况下),则应允许该更新。
  • 该功能应仅在具有防篡改存储空间(例如 Replay Protected Memory Block (RPMB))的设备上启用此功能。我们不要求在没有防篡改存储空间的设备上启用此功能,但如果日后需要,我们可以重新参阅此 RFC。
    • 注意:虽然提议的设计并不限制我们只能实现安全的存储实现,但移除防篡改存储是一项要求,会导致产品所有者在安全性方面做出妥协。

设计

omaha-client 是正式版系统更新检查工具。它与产品所有者或代理运行的 Omaha 服务器进行通信。Omaha 客户端和服务器会定期协商要安装的系统或软件包版本。

我们提议产品所有者可以通过在软件交付配置中的标志中静态构建此功能,为产品启用该功能。

读取和写入拒绝联系选项值

一个名为 update-settings-storage 的新 SWD 组件将提供一个名为 fuchsia.update.config.OptOut 的 FIDL API 来读取此选项,并提供一个名为 fuchsia.update.config.OptOutAdmin 的 API 来编写此选项。此 API 需要在 SDK 中公开,以允许产品级组件开启和关闭该选项的值。

fuchsia.update.config.OptOutAdmin API 必须受到功能路由和审查验证的严格保护,以确保未经授权的组件不会获得访问权限。

应允许使用 fuchsia.update.config.OptOut 读取停用设置的值,以便将系统列入许可名单内控件比 OptOutAdmin 宽松的组件列入许可名单。这样一来,系统和产品级的组件就能根据设备是否已选择停用更新来做出决策,并提供此选项的设置和问题排查视图。

选择停用持久性和安全性

提供 OptOut API 的组件 update-settings-storage 必须在重新启动后保留选择停用设置的值,并且必须将该设置保留在受完整性保护的存储空间中。例如,如果 minfs 存储对此设置没有附带的哈希和签名,则会不安全,因此是不允许的。

我们提议使用防硬件篡改的存储空间(目前在 Fuchsia 设备上唯一的选项是 RPMB)来存储此停用设置。我们希望防篡改存储空间具有如下特点:除非经过签名的可信应用,否则无法写入该存储;或者可检测到恶意写入。

更新检查

在每次计划更新时,检查 omaha-client 应使用 OptOut FIDL API 从 update-settings-storage 中读取,并使用 Omaha 协议中的现有 updatedisabled 字段向 Omaha 发送“停用”值。

如果系统在 recovery 分区上运行,updatedisabled 应始终为 false。同样,如果更新检查是由用户发起的,则 updatedisabled 应始终为 false

如果 Omaha 服务器收到 updatedisabled 等于 true 的更新检查,则应针对该 Omaha 应用的响应返回 NoUpdate,但产品所有者指定的关键更新除外。

此处有一种替代方案,那就是如果设备选择停用更新,则不发送任何 Omaha 更新检查。但是,该替代方法会拒绝产品所有者关于选择不接收更新的用户数量的指标,并拒绝产品所有者推送关键更新(根据需要在服务器上替换 updatedisabled 字段)。

“选择停用”选项必须应用于 omaha-client 正在为其检查更新(包括系统更新和单个软件包)的所有应用。

实现

实现将在 SWD、固件、安全和更新服务器团队之间进行。任务细分大致如下所示,应与要提交的 CL 链相对应。

软件交付

  • 创建 fuchsia.update.config.OptOut FIDL API
  • 实现 update-settings-storage 组件
  • 在更新检查时从 omaha-client 读取 fuchsia.update.config.OptOut,以 updatedisabled 标志转发到 Omaha 服务器(除非设备处于恢复状态或检查是由用户发起的)
  • 在 SDK 中公开 fuchsia.update.config,并将这两个协议列入许可名单。
  • omaha-client 添加了 Cobalt 指标,以统计选择停用的设备的数量
  • 在“检查数据”中公开 omaha-client 的停用设置

固件 / 安全

  • 通过已验证的执行可信应用 (VX TA) 向 RPMB 公开 API,仅在支持的设备上静态包含该 API
  • 修改 VX TA 以清除恢复出厂设置期间的停用标志(此 TA 已进行调解)

更新服务器

  • 修改了 Omaha 规则的生成,以便在所有应用更新检查请求的 updatedisabled 为 true 时针对该应用返回 NoUpdate

性能

系统或更新检查性能应该不会受到明显影响。 更新检查不频繁(大约几小时),并且对延迟不是特别敏感。

工效学设计

此设置的读取 API 有助于减少可能对开发者或用户的困惑,正如 Inspect 和 Cobalt 记录选择停用状态一样。

向后兼容性

此 RFC 不存在已知的向后兼容性问题。

安全注意事项

更新是 Fuchsia 最重要的安全功能。如果没有更新,Fuchsia 团队将无法修补平台中的漏洞。更重要的是,无论是否选择停用更新,设备上根本存在此代码都会给所有用户带来风险:如果攻击者获得足够的权限,则可以更改停用更新的设置,从而增加永久保留应用的机率。

此设计尝试通过以下方式降低风险:

  • 将设置存储在防篡改内存 (RPMB) 中
  • 仅允许特定的已验证执行可信应用 (TA) 修改设置
    • 仅当设备处于锁定模式且已通过身份验证的用户登录(在 OOBE 之后)时,才可访问 TA
    • VX TA 比例如 minfs 小得多、也更简单,而且几乎完全由安全和固件团队修改
  • 审核 TA 的路由并将其列入许可名单
  • 保留向设备推送重要更新(由产品所有者定义)的功能
    • 定义绝对必要更新的标准不在本 RFC 的范围内
  • 我们会持续了解有多少设备已选择停用,并在该数量变得可疑时创建提醒

以下风险仍然存在:

  • 我们无法控制会调用停用 API 的产品级代码,并且我们必须确保只有具有较高特权的组件才能访问该 API。
  • 已获得足够内核特权的攻击者仍可控制 update-settings-storage 或 VX TA,并要求其修改此设置

以下安全性改进目前尚未纳入考虑范围,但可以考虑用于未来的迭代:

  • 添加实际在线状态要求(用户必须以某种方式与设备互动,而不仅仅是通过产品级组件互动)
  • 使设置仅可从引导加载程序写入。这样可以保护设置免受内核危害,但代价是用户体验和跨平台一致性

隐私注意事项

此设计不会对用户隐私产生重大影响,因为所有记录或传播选择停用状态的日志记录服务都将通过受隐私保护的日志记录服务(即通过 Inspect 提供的崩溃数据库或 Cobalt)进行。

测试

我们将在各种选择停用状态下对 update-settings-storage 组件、它与 omaha-client 的交互以及 omaha-client 生成的向 Omaha 服务器生成的最终请求进行集成测试。

我们将通过 Verified Execution 可信应用对 RPMB API 进行集成测试。

此外,我们还将分别对每个组件中的实现进行单元测试。

最后,我们将与测试团队互动,确保启用了此功能的产品必须对其整个集成进行端到端测试(与其他更新功能类似)。

文档

我们需要向新的 FIDL API 添加文档,以及我们的 OTA 流程文档

缺点、替代方案和问题

“Tombstone”build

我们可以通过将“tombstone”build 推送到设备(表明其将不再更新)来实现“停用更新”功能。

这样做有一个显著的优势:

  • 停用设置将存储在启动时验证元数据中,该元数据不可变。这意味着具有更好的安全属性。

这样做也有一些缺点:

  • 对于我们推送的每个常规 build,我们需要为启用了这一功能的每个产品生成一个特定的“tombstone”build。
  • 停用的实际应用需要 OTA 更新,这违反了我们的要求。

将“拒绝联系”值存储在可变存储空间中

我们可以通过将拒绝联系值存储在 minfs 中来避免一些复杂性,以便将该功能部署到更广泛的产品中。但是,对于进行提权的攻击者来说,如果可以获得对 minfs 的写入权限,那么就轻而易举地无限期地保持攻击。获得对 minfs 的写入访问权限可能比修改已验证执行可信应用的状态容易得多,因为就表面积而言,VX TA 比 minfs 小得多,而且更易于审核。

如果用户已选择停用,请完全省略更新检查

如果用户选择停用,我们可以修改 omaha-client,完全不检查更新。

现有艺术和参考资料

Omaha 协议包含 updatedisabled 标志,主要是出于这个原因:客户端设备会告知服务器它正在检查更新,但不应该执行下载和安装。

Chrome 浏览器支持通过企业政策停用更新。这可能适用于潜在的 Fuchsia 设备,但我们目前没有企业政策要求。