blob: 41c96833e1e0073adffc900c89d84df637329183 [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <fs_mgr.h>
#include <fstab/fstab.h>
#include <gtest/gtest.h>
#include <string>
#include "utils.h"
static bool isExemptFromAVBTests() {
int first_api_level = getFirstApiLevel();
int vendor_api_level = getVendorApiLevel();
GTEST_LOG_(INFO) << "First API level is " << first_api_level;
GTEST_LOG_(INFO) << "Vendor API level is " << vendor_api_level;
if (first_api_level < __ANDROID_API_S__) {
GTEST_LOG_(INFO) << "Exempt from avb test due to old starting API level";
return true;
}
// This feature name check only applies to devices that first shipped with
// SC or later.
int min_api_level = (first_api_level < vendor_api_level) ? first_api_level : vendor_api_level;
if (min_api_level >= __ANDROID_API_S__ &&
!deviceSupportsFeature("android.hardware.security.model.compatible")) {
GTEST_LOG_(INFO) << "Skipping test: FEATURE_SECURITY_MODEL_COMPATIBLE missing.";
return true;
}
return false;
}
static std::set<std::string> getVerityMountPoints() {
std::set<std::string> verity_partitions;
android::fs_mgr::Fstab mounted_fstab;
if (!ReadFstabFromFile("/proc/mounts", &mounted_fstab)) {
ADD_FAILURE() << "Failed to read the mounted fstab";
return verity_partitions;
}
// Build a list of mount points that are either mounted or known to have
// importance.
std::set<std::string> mount_points = {"/", "/system"};
for (const auto& entry : mounted_fstab) {
mount_points.insert(entry.mount_point);
}
android::fs_mgr::Fstab fstab;
if (!ReadDefaultFstab(&fstab)) {
ADD_FAILURE() << "Failed to read default fstab";
return verity_partitions;
}
for (const auto& entry : fstab) {
if (!entry.fs_mgr_flags.avb) {
continue;
}
if (mount_points.find(entry.mount_point) == mount_points.end()) {
GTEST_LOG_(INFO) << entry.mount_point << " isn't mounted, skipping";
continue;
}
if (mount_points.find(entry.mount_point) == mount_points.end()) {
GTEST_LOG_(INFO) << entry.mount_point << " isn't mounted, skipping";
continue;
}
if (android::base::EqualsIgnoreCase(entry.fs_type, "emmc")) {
GTEST_LOG_(INFO) << entry.mount_point << " has emmc fs_type, skipping";
continue;
}
GTEST_LOG_(INFO) << "partition enabled verity " << entry.mount_point;
verity_partitions.insert(android::base::Basename(entry.mount_point));
}
return verity_partitions;
}
// As required by CDD, verified boot MUST use verification algorithms as strong
// as current recommendations from NIST for hashing algorithms (SHA-256).
// @CddTest = 9.10/C-1-5
TEST(VerifiedBootTest, avbHashtreeNotUsingSha1) {
GTEST_SKIP() << "Skipping due to broken test. See b/264937051";
if (isExemptFromAVBTests()) {
GTEST_SKIP();
}
auto verity_mount_points = getVerityMountPoints();
for (const auto& mount_point : verity_mount_points) {
// The verity sysprop use "system" as the partition name in the system as
// root case.
std::string partition = mount_point == "/" ? "system" : mount_point;
std::string alg_prop_name = "partition." + partition + ".verified.hash_alg";
std::string hash_alg = android::base::GetProperty(alg_prop_name, "");
ASSERT_FALSE(hash_alg.empty());
ASSERT_FALSE(android::base::StartsWithIgnoreCase(hash_alg, "sha1"));
}
}
// Ensure that protected partitions are being verified every time they are read
// from, rather than once per boot.
// @CddTest = 9.10/C-1-7
TEST(VerifiedBootTest, avbNotUsingCheckAtMostOnce) {
if (isExemptFromAVBTests()) {
GTEST_SKIP();
}
if (getFirstApiLevel() < __ANDROID_API_U__) {
GTEST_SKIP() << "Skipping test: Exempt due to old API level";
}
// Any device with sufficient RAM or a 64-bit CPU is not allowed to use
// check_at_most_once.
//
// Sufficiently performance limited devices are allowed to use it out of necessity.
if (android::base::GetBoolProperty("ro.config.low_ram", false) &&
android::base::GetProperty("ro.product.cpu.abilist64", "").empty())
GTEST_SKIP()
<< "Skipping test: Device is performance constrained (low ram or 32-bit)";
auto verity_mount_points = getVerityMountPoints();
for (const auto& mount_point : verity_mount_points) {
// The verity sysprop use "system" as the partition name in the system as
// root case.
std::string partition = mount_point == "/" ? "system" : mount_point;
std::string prop_name = "partition." + partition + ".verified.check_at_most_once";
ASSERT_FALSE(android::base::GetBoolProperty(prop_name, false));
}
}