libfs_avb: verifying vbmeta digest early

We should check FLAGS_VERIFICATION_DISABLED is set or not
after verifying the vbmeta digest against `androidboot.vbmeta.digest`
from bootloader. This is to ensure the /vbmeta content is not
changed since the bootloader has verified it.

We still allow vbmeta digest verification error if the device is
unlocked. Note that this change will introduce a limitation that
the device will not boot if:

  1. The image is signed with FLAGS_VERIFICATION_DISABLED is set
  2. The device state is locked

However, it should not be a concern as we shouldn't boot a locked
device without verification.

Bug: 179452884
Test: build image with BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --flag 2,
      boot the device, then `adb shell touch /metadata/gsi/dsu/avb_enforce`.
      Reboot the device, checks the device does not boot because
      `androidboot.vbmeta.digest` is empty but AVB is enforced.

Change-Id: Id15a25403d16b36d528dc3b8998910807e801ad2
This commit is contained in:
Bowgo Tsai 2021-02-05 14:44:05 +08:00
parent e1ee7873b3
commit ec10d3cf6e

View file

@ -433,6 +433,16 @@ AvbUniquePtr AvbHandle::Open() {
// Sets the MAJOR.MINOR for init to set it into "ro.boot.avb_version".
avb_handle->avb_version_ = StringPrintf("%d.%d", AVB_VERSION_MAJOR, AVB_VERSION_MINOR);
// Verifies vbmeta structs against the digest passed from bootloader in kernel cmdline.
std::unique_ptr<AvbVerifier> avb_verifier = AvbVerifier::Create();
if (!avb_verifier || !avb_verifier->VerifyVbmetaImages(avb_handle->vbmeta_images_)) {
LERROR << "Failed to verify vbmeta digest";
if (!allow_verification_error) {
LERROR << "vbmeta digest error isn't allowed ";
return nullptr;
}
}
// Checks whether FLAGS_VERIFICATION_DISABLED is set:
// - Only the top-level vbmeta struct is read.
// - vbmeta struct in other partitions are NOT processed, including AVB HASH descriptor(s)
@ -443,26 +453,16 @@ AvbUniquePtr AvbHandle::Open() {
bool verification_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags &
AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
// Checks whether FLAGS_HASHTREE_DISABLED is set.
// - vbmeta struct in all partitions are still processed, just disable
// dm-verity in the user space.
bool hashtree_disabled =
((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
if (verification_disabled) {
avb_handle->status_ = AvbHandleStatus::kVerificationDisabled;
} else {
// Verifies vbmeta structs against the digest passed from bootloader in kernel cmdline.
std::unique_ptr<AvbVerifier> avb_verifier = AvbVerifier::Create();
if (!avb_verifier) {
LERROR << "Failed to create AvbVerifier";
return nullptr;
}
if (!avb_verifier->VerifyVbmetaImages(avb_handle->vbmeta_images_)) {
LERROR << "VerifyVbmetaImages failed";
return nullptr;
}
// Checks whether FLAGS_HASHTREE_DISABLED is set.
bool hashtree_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags &
AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
if (hashtree_disabled) {
avb_handle->status_ = AvbHandleStatus::kHashtreeDisabled;
}
} else if (hashtree_disabled) {
avb_handle->status_ = AvbHandleStatus::kHashtreeDisabled;
}
LINFO << "Returning avb_handle with status: " << avb_handle->status_;