blob: 6e700c545016140c687bd825c7bac34aadc087d5 [file] [log] [blame]
<html devsite><head>
<title>验证启动</title>
<meta name="project_path" value="/_project.yaml"/>
<meta name="book_path" value="/_book.yaml"/>
</head>
<body>
<!--
Copyright 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
//www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<p>验证启动要求在使用前以加密形式验证要启动的 Android 版本包含的所有可执行代码和数据,其中包括内核(从 <code>boot</code> 分区加载)、设备树(从 <code>dtbo</code> 分区加载)、<code>system</code> 分区和 <code>vendor</code> 分区等。
</p>
<p>仅读取一次的小分区(例如 <code>boot</code><code>dtbo</code>)通常是通过将整个内容加载到内存中,然后计算相应哈希值来进行验证的。接下来,系统会比较这个计算出的哈希值与预期哈希值。<em></em>如果值不一致,则 Android 将无法加载。如需了解详情,请参阅<a href="/security/verifiedboot/boot-flow">启动流程</a>
</p>
<p>内存装不下的较大分区(如文件系统)可以使用哈希树;此时,验证流程会在将数据加载到内存时持续进行。在这种情况下,系统会在运行时计算哈希树的根哈希值,并对照预期根哈希值进行检查。<em></em>Android 包含用于验证较大分区的 <a href="/security/verifiedboot/dm-verity">dm-verity 驱动程序</a>。如果在某个时间点计算出的根哈希值与预期根哈希值不一致<em></em>,系统便不会使用相应数据,而且 Android 会出现错误。如需了解详情,请参阅 <a href="/security/verifiedboot/boot-flow#dm-verity-corruption">dm-verity 损坏</a>
</p>
<p>预期哈希值<em></em>通常存储在每个经过验证的分区的末尾或开头、专用分区中,或同时位于以上两个位置。最重要的是,这些哈希值是由信任根以直接或间接的方式签名的。举个例子,AVB 实现就支持这两种方式;要了解详情,请参阅 <a href="/security/verifiedboot/avb">Android 验证启动</a>
</p>
<h2 id="rollback-protection">回滚保护</h2>
<p>即使更新流程完全安全,攻击者仍可能会利用非永久性 Android 内核漏洞来手动安装更易受攻击的旧版 Android 系统,重新启动进入易受攻击的版本,然后通过该 Android 版本来安装永久性漏洞。在这种情况下,攻击者可通过这种漏洞永久拥有相应设备,并可以执行任何操作(包括停用更新)。
</p>
<p>防范这类攻击的保护措施称为“回滚保护”<em></em>。“回滚保护”通常通过以下方式实现:使用防篡改的存储空间来记录最新的 Android 版本,并在 Android 版本低于记录的版本时拒绝启动 Android。系统通常会针对每个分区来跟踪版本。
</p>
<p>要详细了解 AVB 处理回滚保护的方式,请参阅 <a href="https://android.googlesource.com/platform/external/avb/+/master/README.md#Rollback-Protection" class="external">AVB README</a></p>
<h2 id="handling-verification-errors">处理验证错误</h2>
<p>验证在启动时(例如,如果在 <code>boot</code> 分区上计算出的哈希值与预期哈希值不一致)和运行时(例如,如果 dm-verity 在 <code>system</code> 分区上遇到验证错误)都可能会失败。如果验证在启动时失败,设备则无法启动,而且最终用户需要执行相关步骤才能恢复设备使用。
</p>
<p>如果验证在运行时失败,恢复流程就会更复杂一些。如果设备使用的是 dm-verity,则应在 <code>restart</code> 模式下进行配置。在 <code>restart</code> 模式下,如果遇到验证错误,设备会立即重启,并设置特定标记以表明错误原因。引导加载程序应该会注意到该标记,并将 dm-verity 切换为使用 I/O 错误 (<code>eio</code>) 模式并保持该模式,直到安装新的更新为止。
</p>
<p><code>eio</code> 模式下启动时,设备会显示错误屏幕,以通知用户系统已检测到损坏,而且设备可能无法正常使用。该屏幕会持续显示,直到用户将其关闭为止。在 <code>eio</code> 模式下,如果遇到验证错误,则 dm-verity 驱动程序将不会重启设备,而是会返回 EIO 错误,并且相应的应用需要处理该错误。
</p>
<p>这样做的目的是,让系统更新程序能够正常运行(以便安装不含损坏错误的新操作系统),或者让用户能够从设备上获取尽可能多的数据。安装新的操作系统后,引导加载程序会注意到新安装的操作系统,并切换回 <code>restart</code> 模式。
</p>
</body></html>