RFC-0150:更新停用 | |
---|---|
状态 | 已接受 |
区域 |
|
说明 | 面向产品所有者的政策和功能,可让用户选择停用软件更新。 |
问题 | |
Gerrit 更改 | |
作者 | |
审核人 | |
提交日期(年-月-日) | 2022-01-14 |
审核日期(年-月-日) | 2022-01-31 |
摘要
我们介绍了一种新功能,可让产品所有者允许其产品的用户选择不接收软件更新。我们将介绍与此机制相关的政策、应采用的使用方式,以及与存储设置相关的安全机制。最后,我们将介绍系统上的其他组件如何观察系统是否已停用更新。
设计初衷
客户要求我们允许 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 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 必须通过 capability 路由和审核验证进行严格保护,以确保任何未经授权的组件都无法访问该 API。
系统应允许使用 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) 将 API 公开给 RPMB,仅在受支持的设备上静态包含该 API
- 修改 VX TA,以便在恢复出厂设置期间清除停用标志(它已在调解该操作)
更新服务器
- 修改了 Omaha 规则的生成方式,如果相应应用的
updatedisabled
为 true,则为所有应用更新检查请求返回NoUpdate
。
性能
对系统或更新检查性能应该没有明显影响。更新检查频率较低(以小时为单位),对延迟时间不太敏感。
工效学设计
我们为此设置提供的读取 API 有助于减少可能出现的开发者或用户困惑,Inspect 和 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。
- 实际应用停用功能需要 OTA 更新,这违反了我们的要求。
将停用值存储在可变存储空间中
通过在 minfs 中存储停用值,我们可以避免一些复杂性,从而将此功能部署到更多产品。不过,这使得具有特权提升能力的攻击者可以轻松地获得对 minfs 的写入权限,从而无限期地持续攻击。获得对 minfs 的写入访问权限可能比修改 Verified Execution Trusted Application 的状态要容易得多,因为 VX TA 的攻击面要比 minfs 小得多,并且更容易进行审核。
如果用户选择停用,则完全忽略更新检查
如果用户选择停用,我们可以修改 omaha-client
以完全不检查更新。这有两个缺点:我们无法通过 Omaha 获取有关有多少用户选择停用该功能的指标,并且具有足够授权的应用无法要求设备接受关键更新。
在先技术和参考文档
Omaha 协议包含 updatedisabled
标志,其根本原因在于:客户端设备告知服务器它正在检查更新,但不应执行下载和安装。
Chrome 浏览器支持通过企业政策停用更新。这可能适用于潜在的 Fuchsia 设备,但我们目前没有企业政策要求。