| RFC-0118:映像组装时的 SWD 政策 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 在映像组装时应用 SWD 政策的短期更改。 |
| 问题 | |
| Gerrit 更改 | |
| 作者 | |
| 审核人 | |
| 提交日期(年-月-日) | 2021-06-28 |
| 审核日期(年-月-日) | 2021-07-28 |
摘要
此 RFC 提出了一种临时解决方案,通过定义易于理解且范围明确的政策,让开发者能够更好地了解、理解和扩展软件交付 (SWD) 政策配置,从而确保他们不会意外交付安全性较低的配置。
当前提案旨在以当前形式存在,直到基于子组件的产品组装能够为不同的产品使用情形提供更清晰的政策。此提案中的中间工作将有助于更轻松地过渡到系统组装样式配置,因为集中应用 SWD 政策的工作已经完成。
设计初衷
SWD 配置对于强制执行已验证的执行至关重要。目前,SWD 配置分散在多个配置文件和软件包中,这些文件和软件包相互交互以确定设备上的实际 SWD 配置。此 RFC 旨在降低产品 SWD 状态的理解难度。添加明确且经过深思熟虑的政策还可以简化和安全地添加新产品和变体,从而减轻确保应用正确配置的负担。
设计
目前,此 RFC 提议了三项 SWD 政策。它们旨在通过语义化而非产品驱动的命名方式来规范化 SWD 政策配置。这些政策将应用于产品定义,以便更全面地定义 SWD 状态,并且 <
如有需要,我们可能会添加更多政策,但预计这些政策的数量远不及产品和 build 变体的增长速度。
政策定义
仅限基本组件
所有可执行代码都必须直接验证(在基本层中)。所有可配置的 SWD 限制都设置为其默认安全状态:不允许动态配置代码库,并且可执行性限制处于开启状态,这意味着只有基本组件和已列入许可名单的组件可解析和可执行。
本地动态配置
允许动态配置代码库,并手动解析间接验证的代码(universe 软件包/临时组件),前提是用户具有物理访问权限(例如开发者)。
无限制
对代码的可执行性或可见性没有任何限制。这是最宽松的 SWD 配置,允许外部代码和动态配置,并停用可执行性限制。
政策表
| POLICY_NAME | enable_dynamic_configuration | persisted_repos_dir | disable_executability_restrictions |
|---|---|---|---|
| base_components_only | 关闭 | 关闭 | 关闭 |
| local_dynamic_config | 开启 | 关闭 | 关闭 |
| 无限制 | 开启 | 开启 | 开启 |
实现
此 RFC 建议在映像组装级别实现此功能。由于 SWD 配置需要在 base_packages 和 system_image_deps 中设置值,因此建议修改相应的组目标,以包含对基于 policy_labels build 实参定义的 GN 组的新依赖项。policy_labels build 实参是一个字典,用于存储一组映像程序集可理解的键值对(在本例中为 swd)及其各自的政策标签。
这样一来,我们便可确保针对给定 build 始终只定义一个 SWD 政策配置。
举例来说,假设政策是在 //build/security/policies_swd.gni 中定义的:
policies_swd = [
{
name = "local_dynamic_config"
base_package_deps = [ /* ... */ ]
system_image_deps = [ /* ... */ ]
bootfs_deps = [ /* ... */ ]
},
{
name = "foo"
// ...
},
]
在产品定义文件中,产品所有者可以执行以下操作:
import("//build/images/policy.gni") # defines policy_labels = {} arg.
policy_labels.swd = "local_dynamic_config"
policy_labels.foo = "bar"
在映像组装步骤中:
group("base_packages") {
testonly = base_cache_packages_testonly
visibility = [ ":*" ]
public_deps = [
// ...
]
// Addition for this proposal
deps = []
foreach (policy, policies_swd) {
if (policy.name == policy_labels.swd) {
deps += policy.base_package_deps
}
}
}
请注意,这并不能完全解决从祖先 GNI 文件继承产品定义的问题。不过,它确实简化了 SWD 政策的配置和可审核性。
性能
此变更不会影响效果。
工效学设计
此更改通过抽象出配置设置,使 SWD 配置由单个 build 实参控制,从而更轻松地了解和审核设备上 SWD 的状态。
向后兼容性
此更改不会影响向后兼容性,应以易于还原的方式构建更改。
安全注意事项
此变更可提高 SWD 配置状态的简易性、可伸缩性和可读性,该状态决定了哪些软件可以在 Fuchsia 设备上运行。这样一来,开发者发布配置不安全产品的可能性就会降低,从而直接提升我们的安全状况。这种缩减的配置空间还将使产品负责人更轻松地进行审核。
隐私注意事项
此变更不会影响隐私权,也不会与用户数据互动。
测试
我们将对这项更改进行测试,以确保更改后的 build 具有预期的 SWD 政策配置。为此,我们需要在更改前后手动验证输出 build 是否具有(或不具有)预期文件(对于 disable_executability_restrictions)和 config-data 软件包(对于 enable_dynamic_configuration 和 persisted_repos_dir)。
文档
我们将添加更多文档来定义 SWD 政策配置。
缺点、替代方案和未知因素
此项更改旨在提供短期解决方案,直到平台子组件存在为止,以便我们更精细地控制 build 流程。这项工作已在子组件 (fxr/553664) 和结构化配置 (fxr/549661) 的正在进行的 RFC 中捕获。
此变更的主要注意事项是,它会从产品定义中抽象出软件包/依赖项包含。
我们调查了以下替代方案:
不进行任何更改
我们可以继续沿用当前的环境,其中每个产品都可以修改自己的配置,并且每个产品继续从其祖先的联合中随意继承。
但是,随着 Fuchsia 产品集的快速增长,我们提出了此提案,旨在主动改进 SWD 配置机制,以避免可能发生的事件,即向产品应用了错误的 SWD 状态,从而颠覆了 Fuchsia 平台的核心安全假设。
修改产品定义
这与目前的方式类似,但我们不会在产品定义的继承树中随意定义各种设置,而是在每个级别定义设置。我们认为这种方法不可行,因为它不仅让开发者有责任了解每个旋钮的功能,而且无法扩展到不断增长的产品集。此外,如果树的根级/祖先级发生任何更改,必然需要更改所有子级才能取消设置或重置关联的组件,这会带来额外的不利影响。
在 build 验证时进行断言
我们可以将确定 build 是否使用了正确配置的问题分流到 build 验证,断言正确的依赖项与每个 build 相关联。这解决了确保已构建的映像具有正确配置的问题,但并未解决可听性/可见性问题,也未改善在给定配置中了解 SWD 堆栈行为的人体工程学。
修改/减少 SWD 配置设置
我们调查了是否可以修改 SWD 逻辑,以将需要更改的设置数量减少到单个值。遗憾的是,由于 SWD 堆栈是在多个软件包的多个组件中实现的,并且 zbi 的配置分布在所有这些组件中,因此这种方法被认为不可行。