RFC-0150:选择停用更新

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

面向产品所有者的政策和功能,可让用户选择停用软件更新。

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

总结

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

设计初衷

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

利益相关方

教员

pascallouis@google.com

审核者

  • kevinwells@google.com - 软件交付 (SWD)
  • ampearce@google.com - 安全
  • pascallouis@google.com - Fuchsia 工程委员会 (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 Blocks (RPMB))的设备上启用此功能。我们没有要求在没有防篡改存储空间的设备上启用此功能,但如果日后需要,我们可以再次访问此 RFC。
    • 注意:提议的设计并不限制我们只能采用安全的存储实现,但如果按照要求移除防篡改存储,产品所有者就需要在安全性方面做出妥协。

设计

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

我们提议产品所有者可以通过在 Software Delivery 配置中的标志中静态构建功能,在产品上启用此功能。

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

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

必须通过功能路由和审查验证严格保护 fuchsia.update.config.OptOutAdmin API,以确保未经授权的组件无法访问该 API。

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

选择停用持久性和安全性

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

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

更新检查

在每次计划更新时,检查 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”的数据中公开选择停用设置

固件 / 安全

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

更新服务器

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

性能

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

工效学设计

我们为此设置提供的读取 API 有助于减少可能对开发者或用户的困惑,以及 Inspect 和 Cobalt 对停用状态的日志记录。

向后兼容性

此 RFC 中没有我们所知的向后兼容性问题。

安全注意事项

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

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

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

以下风险仍然存在:

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

以下安全改进目前未涵盖在内,但有可供未来的迭代考虑:

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

隐私注意事项

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

测试

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

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

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

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

文档

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

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

“Tombstone”版本

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

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

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

这也有一些值得注意的缺点:

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

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

我们可以通过将停用值存储在 minfs 中来避免一些复杂性,以便将此功能部署到更多产品中。但是,这使得拥有提权的攻击者如果可以获得对 minfs 的写入权限,就很难无限期地持续进行攻击。与修改已验证执行的可信应用的状态相比,获得对 minfs 的写入访问权限要容易得多,因为就表面积而言,VX TA 比 minfs 小得多,而且更易于审核。

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

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

早期技术和参考资料

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

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