Snap for 5611628 from 31f5f91352e67fab78b21442d2779789fdd5af87 to sdk-release
Change-Id: I736b3eda724f3838414db8faf720fb3a546f3349
diff --git a/libavb/avb_descriptor.c b/libavb/avb_descriptor.c
index 4f8e925..cfc2aac 100644
--- a/libavb/avb_descriptor.c
+++ b/libavb/avb_descriptor.c
@@ -91,7 +91,11 @@
const AvbDescriptor* dh = (const AvbDescriptor*)p;
avb_assert_aligned(dh);
uint64_t nb_following = avb_be64toh(dh->num_bytes_following);
- uint64_t nb_total = sizeof(AvbDescriptor) + nb_following;
+ uint64_t nb_total = 0;
+ if (!avb_safe_add(&nb_total, sizeof(AvbDescriptor), nb_following)) {
+ avb_error("Invalid descriptor length.\n");
+ goto out;
+ }
if ((nb_total & 7) != 0) {
avb_error("Invalid descriptor length.\n");
@@ -107,7 +111,10 @@
goto out;
}
- p += nb_total;
+ if (!avb_safe_add_to((uint64_t*)(&p), nb_total)) {
+ avb_error("Invalid descriptor length.\n");
+ goto out;
+ }
}
ret = true;
diff --git a/libavb/avb_slot_verify.c b/libavb/avb_slot_verify.c
index 8cfd80d..eb474ec 100644
--- a/libavb/avb_slot_verify.c
+++ b/libavb/avb_slot_verify.c
@@ -390,16 +390,22 @@
// used later.
AvbSHA256Ctx sha256_ctx;
AvbSHA512Ctx sha512_ctx;
+ size_t image_size_to_hash = hash_desc.image_size;
+ // If we allow verification error and the whole partition is smaller than
+ // image size in hash descriptor, we just hash the whole partition.
+ if (image_size_to_hash > image_size) {
+ image_size_to_hash = image_size;
+ }
if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha256") == 0) {
avb_sha256_init(&sha256_ctx);
avb_sha256_update(&sha256_ctx, desc_salt, hash_desc.salt_len);
- avb_sha256_update(&sha256_ctx, image_buf, hash_desc.image_size);
+ avb_sha256_update(&sha256_ctx, image_buf, image_size_to_hash);
digest = avb_sha256_final(&sha256_ctx);
digest_len = AVB_SHA256_DIGEST_SIZE;
} else if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha512") == 0) {
avb_sha512_init(&sha512_ctx);
avb_sha512_update(&sha512_ctx, desc_salt, hash_desc.salt_len);
- avb_sha512_update(&sha512_ctx, image_buf, hash_desc.image_size);
+ avb_sha512_update(&sha512_ctx, image_buf, image_size_to_hash);
digest = avb_sha512_final(&sha512_ctx);
digest_len = AVB_SHA512_DIGEST_SIZE;
} else {
@@ -1162,7 +1168,8 @@
}
}
- if (rollback_index_location >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) {
+ if (rollback_index_location < 0 ||
+ rollback_index_location >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) {
avb_errorv(
full_partition_name, ": Invalid rollback_index_location.\n", NULL);
ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
diff --git a/test/avb_slot_verify_unittest.cc b/test/avb_slot_verify_unittest.cc
index e03c37e..d27e6e0 100644
--- a/test/avb_slot_verify_unittest.cc
+++ b/test/avb_slot_verify_unittest.cc
@@ -478,6 +478,74 @@
avb_slot_verify_data_free(slot_data);
}
+TEST_F(AvbSlotVerifyTest, LoadSmallerPartitionIfAllowingVerificationError) {
+ const size_t boot_partition_size = 16 * 1024 * 1024;
+ const size_t boot_image_size = 5 * 1024 * 1024;
+ const size_t new_boot_image_size = 1 * 1024 * 1024;
+ base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
+
+ // If we're allowing verification errors then check that the whole
+ // partition is loaded. This is needed because in this mode for
+ // example the "boot" partition might be flashed with another
+ // boot.img that is larger than what the HashDescriptor in vbmeta
+ // says.
+ EXPECT_COMMAND(
+ 0,
+ "./avbtool add_hash_footer"
+ " --image %s"
+ " --rollback_index 0"
+ " --partition_name boot"
+ " --partition_size %zd"
+ " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
+ " --salt deadbeef"
+ " --internal_release_string \"\"",
+ boot_path.value().c_str(),
+ boot_partition_size);
+
+ GenerateVBMetaImage(
+ "vbmeta_a.img",
+ "SHA256_RSA2048",
+ 4,
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ base::StringPrintf(
+ "--include_descriptors_from_image %s"
+ " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
+ " --internal_release_string \"\"",
+ boot_path.value().c_str()));
+
+ // Now replace the boot partition with something bigger and
+ // different. Because FakeOps's get_size_of_partition() operation
+ // just returns the file size it means that this is what is returned
+ // by get_size_of_partition().
+ //
+ // Also make sure this image will return a different digest by using
+ // a non-standard starting byte. This is to force avb_slot_verify()
+ // to return ERROR_VERIFICATION below.
+ GenerateImage("boot_a.img", new_boot_image_size, 1 /* start_byte */);
+
+ ops_.set_expected_public_key(
+ PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
+
+ AvbSlotVerifyData* slot_data = NULL;
+ const char* requested_partitions[] = {"boot", NULL};
+ EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
+ avb_slot_verify(ops_.avb_ops(),
+ requested_partitions,
+ "_a",
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
+ &slot_data));
+ EXPECT_NE(nullptr, slot_data);
+
+ // Check that the loaded partition is actually
+ // |new_boot_image_size|.
+ EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
+ EXPECT_EQ("boot",
+ std::string(slot_data->loaded_partitions[0].partition_name));
+ EXPECT_EQ(new_boot_image_size, slot_data->loaded_partitions[0].data_size);
+ avb_slot_verify_data_free(slot_data);
+}
+
TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMeta) {
const size_t boot_partition_size = 16 * 1024 * 1024;
const size_t boot_image_size = 5 * 1024 * 1024;