| RFC-0118:映像组装时的 SWD 政策 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 在映像组装时应用 SWD 政策的短期更改。 |
| 问题 | |
| Gerrit 更改 | |
| 作者 | |
| 审核人 | |
| 提交日期(年-月-日) | 2021-06-28 |
| 审核日期(年-月-日) | 2021-07-28 |
摘要
此 RFC 提出了一项临时解决方案,旨在通过定义易于理解且范围明确的政策,让开发者能够更好地了解和理解软件交付 (SWD) 政策配置,并提高其可伸缩性,以便任何开发者都能了解在运行 Fuchsia 的设备上可以运行哪些软件,并确保他们不会意外发布安全性较低的配置。
目前的提案旨在以当前形式存在,直到基于子组装的产品组装能够为不同的产品用例提供更明确定义的政策。此提案中的中间工作将有助于更轻松地过渡到系统组装样式的配置,因为集中应用 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 | 开启 | 关闭 | 关闭 |
| unrestricted | 开启 | 开启 | 开启 |
实现
此 RFC 建议在映像组装级别实现此功能。由于 SWD 配置需要在 base_packages 和 system_image_deps 中设置值,因此该提案建议修改相应的组目标,以包含对基于 policy_labels build 参数定义的 GN 组的新依赖项,该参数是一个字典,用于存储一组映像组装理解的键值对(在本例中为 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 状态的简易性,以便 SWD 配置由单个 build 实参控制。
向后兼容性
此更改不会影响向后兼容性,更改应以易于恢复的方式进行结构化。
安全注意事项
此更改提高了 SWD 配置状态的简单性、可伸缩性和可读性,从而确定可以在 Fuchsia 设备上运行哪些软件。这降低了开发者发布具有不安全配置的产品的可能性,直接提高了我们的安全态势。这种缩减的配置空间也让产品所有者更容易进行审核。
隐私注意事项
此更改不会影响隐私或与用户数据互动。
测试
我们将对此更改进行测试,以确保此更改后的 build 具有预期的 SWD 政策配置。为此,我们将手动验证输出 build 在更改前后是否具有(或不具有)预期文件(对于 disable_executability_restrictions)和 config-data 软件包(对于 enable_dynamic_configuration 和 persisted_repos_dir)。
文档
我们将添加其他文档来定义 SWD 政策配置。
缺点、替代方案和未知事项
此更改旨在作为短期解决方案,直到平台子组装存在,以便我们能够更精细地控制构建流程。这项工作已在子组装 (fxr/553664) 和结构化配置 (fxr/549661) 的进行中 RFC 中捕获。
此更改的主要注意事项是,它从产品定义中抽象出了软件包/依赖项包含。
我们调查了以下替代方案:
不进行任何更改
我们可以继续在当前环境中运行,每个产品都可以修改自己的配置,并且每个产品都会继续从其祖先的并集中随意继承。
但是,随着 Fuchsia 产品的快速增长,我们提出了此提案,以主动改进 SWD 配置机制,从而避免可能发生的突发事件,即不正确的 SWD 状态应用于产品,颠覆 Fuchsia 平台的核心安全假设。
修改产品定义
这与目前的做法类似,但我们不会在产品定义的继承树中随意定义各种设置,而是在每个级别定义设置。我们认为这是不可行的,因为它既将了解每个旋钮功能的责任推给了开发者,也无法扩展到不断增长的产品集。此外,树的根/祖先级别的任何更改都必然需要更改所有子级别,以取消设置或重置关联的组件,这也会带来额外的弊端。
在 build 验证时断言
我们可以将确定 build 是否使用正确配置的问题卸载到 build 验证中,断言正确的依赖项与每个 build 相关联。这解决了确保 build 映像具有正确配置的问题,但没有解决可审核性/可见性问题,也没有提高在给定配置中理解 SWD 堆栈行为的工效学。
修改/减少 SWD 配置设置集
我们调查了是否可以修改 SWD 逻辑,以便将要更改的设置数量减少到单个值。 遗憾的是,我们认为这是不可行的,因为 SWD 堆栈是在多个软件包和 zbi 中的多个组件中实现的,配置分布在所有这些组件中。