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