1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <android-base/properties.h>
18 #include <fs_avb/fs_avb.h>
19 #include <fs_avb/fs_avb_util.h>
20 #include <fstab/fstab.h>
21 #include <gtest/gtest.h>
22 
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 using android::fs_mgr::AvbHandle;
27 using android::fs_mgr::AvbHandleStatus;
28 using android::fs_mgr::Fstab;
29 using android::fs_mgr::FstabEntry;
30 using android::fs_mgr::VBMetaData;
31 using android::fs_mgr::VBMetaVerifyResult;
32 
33 namespace fs_avb_device_test {
34 
35 // system vbmeta might not be at the end of /system when dynamic partition is
36 // enabled. Therefore, disable it by default.
TEST(FsAvbUtilTest,DISABLED_LoadAndVerifyVbmeta_SystemVbmeta)37 TEST(FsAvbUtilTest, DISABLED_LoadAndVerifyVbmeta_SystemVbmeta) {
38     Fstab fstab;
39     EXPECT_TRUE(ReadDefaultFstab(&fstab));
40 
41     FstabEntry* system_entry = GetEntryForMountPoint(&fstab, "/system");
42     EXPECT_NE(nullptr, system_entry);
43 
44     std::string out_public_key_data;
45     std::string out_avb_partition_name;
46     VBMetaVerifyResult out_verify_result;
47     std::unique_ptr<VBMetaData> vbmeta =
48             LoadAndVerifyVbmeta(*system_entry, "" /* expected_public_key_blob */,
49                                 &out_public_key_data, &out_avb_partition_name, &out_verify_result);
50 
51     EXPECT_NE(nullptr, vbmeta);
52     EXPECT_EQ(VBMetaVerifyResult::kSuccess, out_verify_result);
53     EXPECT_EQ("system", out_avb_partition_name);
54     EXPECT_NE("", out_public_key_data);
55 }
56 
TEST(FsAvbUtilTest,GetHashtreeDescriptor_SystemOther)57 TEST(FsAvbUtilTest, GetHashtreeDescriptor_SystemOther) {
58     // Non-A/B device doesn't have system_other partition.
59     if (fs_mgr_get_slot_suffix() == "") return;
60 
61     // Skip running this test if system_other is a logical partition.
62     // Note that system_other is still a physical partition on "retrofit" devices.
63     if (android::base::GetBoolProperty("ro.boot.dynamic_partitions", false) &&
64         !android::base::GetBoolProperty("ro.boot.dynamic_partitions_retrofit", false)) {
65         return;
66     }
67 
68     Fstab fstab;
69     EXPECT_TRUE(ReadFstabFromFile("/system/etc/fstab.postinstall", &fstab));
70 
71     // It should have two lines in the fstab, the first for logical system_other,
72     // the other for physical system_other.
73     EXPECT_EQ(2UL, fstab.size());
74 
75     // Use the 2nd fstab entry, which is for physical system_other partition.
76     FstabEntry* system_other = &fstab[1];
77     EXPECT_NE(nullptr, system_other);
78 
79     std::string out_public_key_data;
80     std::string out_avb_partition_name;
81     VBMetaVerifyResult out_verify_result;
82     std::unique_ptr<VBMetaData> system_other_vbmeta =
83             LoadAndVerifyVbmeta(*system_other, "" /* expected_public_key_blob */,
84                                 &out_public_key_data, &out_avb_partition_name, &out_verify_result);
85 
86     EXPECT_NE(nullptr, system_other_vbmeta);
87     EXPECT_EQ(VBMetaVerifyResult::kSuccess, out_verify_result);
88     EXPECT_EQ("system_other", out_avb_partition_name);
89     EXPECT_NE("", out_public_key_data);
90 
91     auto hashtree_desc =
92             GetHashtreeDescriptor(out_avb_partition_name, std::move(*system_other_vbmeta));
93     EXPECT_NE(nullptr, hashtree_desc);
94 }
95 
TEST(AvbHandleTest,LoadAndVerifyVbmeta_SystemOther)96 TEST(AvbHandleTest, LoadAndVerifyVbmeta_SystemOther) {
97     // Non-A/B device doesn't have system_other partition.
98     if (fs_mgr_get_slot_suffix() == "") return;
99 
100     // Skip running this test if system_other is a logical partition.
101     // Note that system_other is still a physical partition on "retrofit" devices.
102     if (android::base::GetBoolProperty("ro.boot.dynamic_partitions", false) &&
103         !android::base::GetBoolProperty("ro.boot.dynamic_partitions_retrofit", false)) {
104         return;
105     }
106 
107     Fstab fstab;
108     EXPECT_TRUE(ReadFstabFromFile("/system/etc/fstab.postinstall", &fstab));
109 
110     // It should have two lines in the fstab, the first for logical system_other,
111     // the other for physical system_other.
112     EXPECT_EQ(2UL, fstab.size());
113 
114     // Use the 2nd fstab entry, which is for physical system_other partition.
115     FstabEntry* system_other_entry = &fstab[1];
116     // Assign the default key if it's not specified in the fstab.
117     if (system_other_entry->avb_keys.empty()) {
118         system_other_entry->avb_keys = "/system/etc/security/avb/system_other.avbpubkey";
119     }
120     auto avb_handle = AvbHandle::LoadAndVerifyVbmeta(*system_other_entry);
121     EXPECT_NE(nullptr, avb_handle) << "Failed to load system_other vbmeta. Try 'adb root'?";
122     EXPECT_EQ(AvbHandleStatus::kSuccess, avb_handle->status());
123 }
124 
TEST(AvbHandleTest,GetSecurityPatchLevel)125 TEST(AvbHandleTest, GetSecurityPatchLevel) {
126     Fstab fstab;
127     EXPECT_TRUE(ReadDefaultFstab(&fstab));
128 
129     auto avb_handle = AvbHandle::LoadAndVerifyVbmeta();
130     EXPECT_NE(nullptr, avb_handle) << "Failed to load inline vbmeta. Try 'adb root'?";
131     EXPECT_EQ(AvbHandleStatus::kSuccess, avb_handle->status());
132 
133     // Gets security patch level with format: YYYY-MM-DD (e.g., 2019-04-05).
134     FstabEntry* system_entry = GetEntryForMountPoint(&fstab, "/system");
135     EXPECT_NE(nullptr, system_entry);
136     EXPECT_EQ(10UL, avb_handle->GetSecurityPatchLevel(*system_entry).length());
137 
138     FstabEntry* vendor_entry = GetEntryForMountPoint(&fstab, "/vendor");
139     EXPECT_NE(nullptr, vendor_entry);
140     EXPECT_EQ(10UL, avb_handle->GetSecurityPatchLevel(*vendor_entry).length());
141 
142     FstabEntry* product_entry = GetEntryForMountPoint(&fstab, "/product");
143     EXPECT_NE(nullptr, product_entry);
144     EXPECT_EQ(10UL, avb_handle->GetSecurityPatchLevel(*product_entry).length());
145 }
146 
147 }  // namespace fs_avb_device_test
148