RFC-0150:选择停用更新

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

政策和功能:产品所有者可允许用户选择停用软件更新。

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

摘要

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

设计初衷

客户要求我们允许 Fuchsia 设备的用户选择不接收更新。我们必须以尽可能安全的方式满足该要求,无论用户是否选择不接收此类电子邮件。

利益相关方

辅导员

pascallouis@google.com

审核者

  • kevinwells@google.com - 软件交付 (SWD)
  • ampearce@google.com - Security
  • pascallouis@google.com - Fuchsia 工程委员会 (FEC)

已咨询

  • borthakur@google.com
  • marvinpaul@google.com - 服务器实现
  • gtsai@google.com - 服务器实现
  • enoharemaien@google.com - Privacy
  • hjfreyer@google.com - Component Platform / 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 必须受到功能路由和 Scrutiny 验证的严格保护,以确保没有未经授权的组件可以访问它。

应允许使用 fuchsia.update.config.OptOut 读取选择停用设置的值,以便在系统上允许列表中的组件具有比 OptOutAdmin 更宽松的控制权。这样一来,系统级和产品级组件便可根据设备是否选择不接收更新来做出决策,并提供此选项的设置和问题排查视图。

选择退出的持久性和安全性

提供 OptOut API 的组件 update-settings-storage 必须在重启后保留选择退出设置的值,并且必须将该设置保留在受完整性保护的存储空间中。例如,如果仅存储此设置,而未在存储中附带相应的哈希和签名,则是不安全的,因此不允许这样做。minfs

我们建议使用硬件防篡改存储空间(目前在 Fuchsia 设备上,唯一可用的选项是 RPMB)来存储此选择停用设置。我们希望防篡改存储空间具备的属性是,除了经过签名的可信应用之外,任何其他应用都无法写入该存储空间,或者可以检测到恶意写入。

这些存储 API 存在于必需的 产品中,并且应通过经过验证的执行可信应用 (VX TA) 公开,该应用在启动时通过硬件措施进行签名和身份验证。

更新检查

在每次预定的更新检查中,omaha-client 应使用 OptOut FIDL API 从 update-settings-storage 读取数据,并使用 Omaha 协议中现有的 updatedisabled 字段将选择退出值发送到 Omaha。

如果系统在恢复分区上运行,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 以在恢复出厂设置期间清除选择退出标志(它已在其中介导)

更新服务器

  • 修改了 Omaha 规则的生成,以针对所有应用更新检查请求返回 NoUpdate(如果相应应用的 updatedisabled 为 true)。

性能

不应对系统或更新检查性能产生明显影响。 更新检查不频繁(以小时为单位),对延迟不特别敏感。

工效学设计

我们针对此设置的读取 API 以及选择退出的检查和 Cobalt 日志记录将有助于减少开发者或用户可能出现的困惑。

向后兼容性

据我们所知,此 RFC 不存在向后兼容性问题。

安全注意事项

更新是 Fuchsia 最重要的安全功能。如果没有更新,Fuchsia 团队就无法修补平台中的漏洞。更重要的是,无论用户是否选择不接收更新,设备上存在此代码对所有用户来说都是一种风险:如果攻击者获得足够的权限,他们可以更改不接收更新的设置,并增加永久保持存在的可能性。

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

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

仍存在以下风险:

  • 我们无法控制将调用选择退出 API 的产品级代码,并且必须确保只有高权限组件才能访问该 API
  • 如果攻击者获得了足够的内核权限,仍然可以控制 update-settings-storage 或 VX TA,并要求它们修改设置

以下安全改进目前不在范围内,但未来迭代时可以考虑:

  • 添加了实体存在要求(用户必须以某种方式与设备互动,而不仅仅是通过产品级组件互动)
  • 使设置只能从引导加载程序写入。这会牺牲用户体验和跨平台一致性,以防御内核遭到入侵

隐私注意事项

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

测试

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

我们将通过经过验证的执行可信应用来集成测试 RPMB API。

我们还将单独对每个组件中的实现进行单元测试。

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

文档

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

缺点、替代方案和未知因素

“Tombstone”build

我们可以通过向设备推送“墓碑”build 来实现选择不更新,该 build 表明设备将不再更新。

这有一个显著的优势:

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

这种方法也有一些明显的缺点:

  • 对于启用此功能的每款产品,我们都需要为推送的每个正常 build 生成一个特定的“墓碑”build。
  • 实际应用选择退出功能需要 OTA 更新,这违反了我们的要求。

将选择停用的值存储在可变存储空间中

我们可以通过将选择退出值存储在 minfs 中来避免一些复杂性,这样就可以将此功能部署到更广泛的产品中。不过,如果攻击者能够获得对 minfs 的写入权限,那么他们就可以通过提升权限来无限期地持续攻击。获取对 minfs 的写入访问权限可能比修改经过验证的执行可信应用的状态容易得多,因为就表面积而言,VX TA 比 minfs 小得多,并且更易于审核。

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

如果用户选择停用,我们可以修改 omaha-client 以完全不检查更新。这存在一些缺点:我们无法获得基于奥马哈的有关有多少用户选择不接收更新的指标,并且具有足够授权的 产品所有者无法要求设备接收关键更新。

在先技术和参考资料

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

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