Merge 8f78a2470c2b46560855c577453d247241ba6999 on remote branch

Change-Id: Iaaf83c8b5cd631007a24ade414f2468ac8915e11
diff --git a/avb/VtsSecurityAvbTest.cpp b/avb/VtsSecurityAvbTest.cpp
index 2fb98ce..f5892d6 100644
--- a/avb/VtsSecurityAvbTest.cpp
+++ b/avb/VtsSecurityAvbTest.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "VtsSecurityAvbTest"
 
+#include <sys/utsname.h>
 #include <unistd.h>
 
 #include <array>
@@ -364,6 +365,11 @@
   return std::string(reinterpret_cast<const char *>(descriptor.hash_algorithm));
 }
 
+// Converts descriptor.hash_algorithm to std::string.
+static std::string GetHashAlgorithm(const AvbHashDescriptor &descriptor) {
+  return std::string(reinterpret_cast<const char *>(descriptor.hash_algorithm));
+}
+
 // Checks whether the public key is an official GSI key or not.
 static bool ValidatePublicKeyBlob(const std::string &key_blob_to_validate) {
   if (key_blob_to_validate.empty()) {
@@ -452,6 +458,79 @@
   return descriptor;
 }
 
+TEST(AvbTest, Boot) {
+  /* Skip for devices running kernels older than 5.4. */
+  struct utsname buf;
+  int ret, kernel_version_major, kernel_version_minor;
+  ret = uname(&buf);
+  ASSERT_EQ(ret, 0) << "Failed to get kernel version.";
+  char dummy;
+  ret = sscanf(buf.release, "%d.%d%c", &kernel_version_major,
+               &kernel_version_minor, &dummy);
+  ASSERT_GE(ret, 2) << "Failed to parse kernel version.";
+  if (kernel_version_major < 5 ||
+      (kernel_version_major == 5 && kernel_version_minor < 4)) {
+    return;
+  }
+
+  /* load vbmeta struct from boot, verify struct integrity */
+  std::string out_public_key_data;
+  android::fs_mgr::VBMetaVerifyResult out_verify_result;
+  std::string boot_path = "/dev/block/by-name/boot" + fs_mgr_get_slot_suffix();
+  std::unique_ptr<android::fs_mgr::VBMetaData> vbmeta =
+      android::fs_mgr::LoadAndVerifyVbmetaByPath(
+          boot_path, "boot", "" /* expected_key_blob */,
+          true /* allow verification error */, false /* rollback_protection */,
+          false /* is_chained_vbmeta */, &out_public_key_data,
+          nullptr /* out_verification_disabled */, &out_verify_result);
+
+  ASSERT_TRUE(vbmeta) << "Verification of GKI vbmeta fails.";
+  ASSERT_FALSE(out_public_key_data.empty()) << "The GKI image is not signed.";
+  EXPECT_TRUE(ValidatePublicKeyBlob(out_public_key_data))
+      << "The GKI image is not signed by an official key.";
+  EXPECT_EQ(out_verify_result, android::fs_mgr::VBMetaVerifyResult::kSuccess)
+      << "Verification of the GKI vbmeta structure failed.";
+
+  /* verify boot partition according to vbmeta structure */
+  std::unique_ptr<android::fs_mgr::FsAvbHashDescriptor> descriptor =
+      android::fs_mgr::GetHashDescriptor("boot", std::move(*vbmeta));
+  const std::string &salt_str = descriptor->salt;
+  const std::string &expected_digest_str = descriptor->digest;
+
+  android::base::unique_fd fd(open(boot_path.c_str(), O_RDONLY));
+  ASSERT_GE(fd, 0) << "Fail to open boot partition. Try 'adb root'.";
+
+  const std::string hash_algorithm(GetHashAlgorithm(*descriptor));
+  ALOGI("hash_algorithm = %s", hash_algorithm.c_str());
+
+  std::unique_ptr<ShaHasher> hasher = CreateShaHasher(hash_algorithm);
+  ASSERT_TRUE(hasher);
+
+  std::vector<uint8_t> salt, expected_digest, out_digest;
+  bool ok = HexToBytes(salt_str, &salt);
+  ASSERT_TRUE(ok) << "Invalid salt in descriptor: " << salt_str;
+  ok = HexToBytes(expected_digest_str, &expected_digest);
+  ASSERT_TRUE(ok) << "Invalid digest in descriptor: " << expected_digest_str;
+  ASSERT_EQ(expected_digest.size(), hasher->GetDigestSize());
+
+  std::vector<char> boot_partition_vector;
+  boot_partition_vector.resize(descriptor->image_size);
+  ASSERT_TRUE(android::base::ReadFully(fd, boot_partition_vector.data(),
+                                       descriptor->image_size))
+      << "Could not read boot partition to vector.";
+
+  out_digest.resize(hasher->GetDigestSize());
+  ASSERT_TRUE(hasher->CalculateDigest(
+      boot_partition_vector.data(), descriptor->image_size,
+      salt.data(), descriptor->salt_len, out_digest.data()))
+      << "Unable to calculate boot image digest.";
+
+  ASSERT_TRUE(out_digest.size() == expected_digest.size())
+      << "Calculated GKI boot digest size does not match expected digest size.";
+  ASSERT_TRUE(out_digest == expected_digest)
+      << "Calculated GKI boot digest does not match expected digest.";
+}
+
 // Loads contents and metadata of logical system partition, calculates
 // the hashtree, and compares with the metadata.
 TEST(AvbTest, SystemHashtree) {
diff --git a/system_property/VtsTrebleSysPropTest.py b/system_property/VtsTrebleSysPropTest.py
index 6480488..c998c42 100644
--- a/system_property/VtsTrebleSysPropTest.py
+++ b/system_property/VtsTrebleSysPropTest.py
@@ -96,7 +96,8 @@
 
     _SYSTEM_WHITELISTED_TYPES = [
             "vendor_default_prop",
-            "vendor_security_patch_level_prop"
+            "vendor_security_patch_level_prop",
+            "vendor_socket_hook_prop"
     ]
 
     _VENDOR_OR_ODM_WHITELISTED_TYPES = [
diff --git a/system_property/vts_treble_sys_prop_test.py b/system_property/vts_treble_sys_prop_test.py
index db69cd3..800599b 100644
--- a/system_property/vts_treble_sys_prop_test.py
+++ b/system_property/vts_treble_sys_prop_test.py
@@ -153,7 +153,8 @@
 
     _SYSTEM_WHITELISTED_TYPES = [
             "vendor_default_prop",
-            "vendor_security_patch_level_prop"
+            "vendor_security_patch_level_prop",
+            "vendor_socket_hook_prop"
     ]
 
     _VENDOR_OR_ODM_WHITELISTED_TYPES = [
@@ -327,11 +328,11 @@
             "Found %d property names in product property contexts",
             len(property_dict))
 
-        violation_list = filter(
+        violation_list = list(filter(
             lambda x: any(
                 x.startswith(prefix)
                 for prefix in self._VENDOR_OR_ODM_NAMESPACES),
-            property_dict.keys())
+            property_dict.keys()))
         self.assertEqual(
             len(violation_list), 0,
             ("product propertes (%s) have wrong namespace" %
@@ -371,6 +372,7 @@
         if (not self.dut.Exists(self._ODM_PROPERTY_CONTEXTS_FILE_PATH)):
             logging.info("Skip test for a device which doesn't have an odm "
                          "property contexts.")
+            return
         self._TestPropertyTypes(
             self._ODM_PROPERTY_CONTEXTS_FILE_PATH,
             lambda typename: typename.startswith(self._VENDOR_TYPE_PREFIX) or