用例

本文档包含 AVF 的常见用例。

隔离编译

作为软件安全隔区,受保护的虚拟机可提供安全环境来编译安全敏感代码。此环境可实现将 bootclasspath 和系统服务器 JAR(由 APEX 更新触发)的编译从前期启动移至重新启动之前,并显著缩短 APEX 更新后的启动时间。

该实现位于 com.android.compos APEX 中。此组件是可选的,可以使用 makefile 将其包含在内。

隔离编译

图 1. 在 Mainline 更新上编译 JAR

安全目标是如实编译经过验证的输入并单独生成输出;将 Android 作为不受信任的客户端无法以任何其他方式更改编译输出,除非使编译过程失败(Android 回退到启动时编译)。

仅当整个编译期间没有错误时,虚拟机中的编译服务才会生成签名。Android 可以从虚拟机中检索公钥以进行签名验证。

虚拟机的密钥是通过虚拟机的 DICE 配置文件生成的,该配置文件由装载到虚拟机的 APEX 和 APK 以及其他虚拟机参数(例如可调试性)定义。

为了确定公钥并非来自未知虚拟机,Android 会启动虚拟机以确定密钥是否正确。每次 APEX 更新后,虚拟机都会在前期启动时启动。

借助受保护的虚拟机的“启动时验证”功能,编译服务仅运行经过验证的代码。因此,代码可以决定仅接受满足特定条件的输入,例如,仅接受许可名单中指定了其名称和 fs-verity 摘要的输入文件。

虚拟机中的任何公开 API 都是攻击面。系统会假定所有输入文件和参数都来自不受信任的客户端,且在处理之前必须经过验证和审查。

虚拟机会验证输入/输出文件的完整性,并将文件作为不受信任的文件服务器存储在 Android 上,如下所示:

  • 在使用 fs-verity 算法之前,必须先验证输入文件的内容。为使输入文件可在虚拟机中使用,其根哈希必须在构成虚拟机 DICE 配置文件的容器 (APK) 中提供。有了受信任的根哈希,攻击者就无法在不会被检测到的情况下篡改输入文件。
  • 必须在虚拟机中维护输出文件的完整性。即使输出文件存储在 Android 上,其生成期间的完整性也会使用相同的 fs-verity 树格式进行维护,但可以进行动态更新。最终输出文件可以使用根哈希进行标识,此文件将在虚拟机中被隔离。虚拟机中的服务通过签名来保护输出文件。