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;