1 /*
2 * Copyright (C) 2016 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 "fs_avb/fs_avb.h"
18
19 #include <fcntl.h>
20 #include <libgen.h>
21 #include <string.h>
22 #include <sys/ioctl.h>
23 #include <sys/types.h>
24
25 #include <algorithm>
26 #include <sstream>
27 #include <string>
28 #include <vector>
29
30 #include <android-base/file.h>
31 #include <android-base/parseint.h>
32 #include <android-base/stringprintf.h>
33 #include <android-base/strings.h>
34 #include <libavb/libavb.h>
35 #include <libdm/dm.h>
36 #include <libgsi/libgsi.h>
37
38 #include "avb_ops.h"
39 #include "avb_util.h"
40 #include "fs_avb/fs_avb_util.h"
41 #include "sha.h"
42 #include "util.h"
43
44 using android::base::Basename;
45 using android::base::ParseUint;
46 using android::base::ReadFileToString;
47 using android::base::Split;
48 using android::base::StringPrintf;
49
50 namespace android {
51 namespace fs_mgr {
52
53 template <typename Hasher>
VerifyVbmetaDigest(const std::vector<VBMetaData> & vbmeta_images,const uint8_t * expected_digest)54 std::pair<size_t, bool> VerifyVbmetaDigest(const std::vector<VBMetaData>& vbmeta_images,
55 const uint8_t* expected_digest) {
56 size_t total_size = 0;
57 Hasher hasher;
58 for (const auto& vbmeta : vbmeta_images) {
59 hasher.update(vbmeta.data(), vbmeta.size());
60 total_size += vbmeta.size();
61 }
62
63 bool matched = (memcmp(hasher.finalize(), expected_digest, Hasher::DIGEST_SIZE) == 0);
64
65 return std::make_pair(total_size, matched);
66 }
67
68 template <typename Hasher>
CalculateVbmetaDigest(const std::vector<VBMetaData> & vbmeta_images)69 std::pair<std::string, size_t> CalculateVbmetaDigest(const std::vector<VBMetaData>& vbmeta_images) {
70 std::string digest;
71 size_t total_size = 0;
72
73 Hasher hasher;
74 for (const auto& vbmeta : vbmeta_images) {
75 hasher.update(vbmeta.data(), vbmeta.size());
76 total_size += vbmeta.size();
77 }
78
79 // Converts digest bytes to a hex string.
80 digest = BytesToHex(hasher.finalize(), Hasher::DIGEST_SIZE);
81 return std::make_pair(digest, total_size);
82 }
83
84 // class AvbVerifier
85 // -----------------
86 // Reads the following values from kernel cmdline and provides the
87 // VerifyVbmetaImages() to verify AvbSlotVerifyData.
88 // - androidboot.vbmeta.hash_alg
89 // - androidboot.vbmeta.size
90 // - androidboot.vbmeta.digest
91 class AvbVerifier {
92 public:
93 // The factory method to return a unique_ptr<AvbVerifier>
94 static std::unique_ptr<AvbVerifier> Create();
95 bool VerifyVbmetaImages(const std::vector<VBMetaData>& vbmeta_images);
96
97 protected:
98 AvbVerifier() = default;
99
100 private:
101 HashAlgorithm hash_alg_;
102 uint8_t digest_[SHA512_DIGEST_LENGTH];
103 size_t vbmeta_size_;
104 };
105
Create()106 std::unique_ptr<AvbVerifier> AvbVerifier::Create() {
107 std::unique_ptr<AvbVerifier> avb_verifier(new AvbVerifier());
108 if (!avb_verifier) {
109 LERROR << "Failed to create unique_ptr<AvbVerifier>";
110 return nullptr;
111 }
112
113 std::string value;
114 if (!fs_mgr_get_boot_config("vbmeta.size", &value) ||
115 !ParseUint(value.c_str(), &avb_verifier->vbmeta_size_)) {
116 LERROR << "Invalid hash size: " << value.c_str();
117 return nullptr;
118 }
119
120 // Reads hash algorithm.
121 size_t expected_digest_size = 0;
122 std::string hash_alg;
123 fs_mgr_get_boot_config("vbmeta.hash_alg", &hash_alg);
124 if (hash_alg == "sha256") {
125 expected_digest_size = SHA256_DIGEST_LENGTH * 2;
126 avb_verifier->hash_alg_ = HashAlgorithm::kSHA256;
127 } else if (hash_alg == "sha512") {
128 expected_digest_size = SHA512_DIGEST_LENGTH * 2;
129 avb_verifier->hash_alg_ = HashAlgorithm::kSHA512;
130 } else {
131 LERROR << "Unknown hash algorithm: " << hash_alg.c_str();
132 return nullptr;
133 }
134
135 // Reads digest.
136 std::string digest;
137 fs_mgr_get_boot_config("vbmeta.digest", &digest);
138 if (digest.size() != expected_digest_size) {
139 LERROR << "Unexpected digest size: " << digest.size()
140 << " (expected: " << expected_digest_size << ")";
141 return nullptr;
142 }
143
144 if (!HexToBytes(avb_verifier->digest_, sizeof(avb_verifier->digest_), digest)) {
145 LERROR << "Hash digest contains non-hexidecimal character: " << digest.c_str();
146 return nullptr;
147 }
148
149 return avb_verifier;
150 }
151
VerifyVbmetaImages(const std::vector<VBMetaData> & vbmeta_images)152 bool AvbVerifier::VerifyVbmetaImages(const std::vector<VBMetaData>& vbmeta_images) {
153 if (vbmeta_images.empty()) {
154 LERROR << "No vbmeta images";
155 return false;
156 }
157
158 size_t total_size = 0;
159 bool digest_matched = false;
160
161 if (hash_alg_ == HashAlgorithm::kSHA256) {
162 std::tie(total_size, digest_matched) =
163 VerifyVbmetaDigest<SHA256Hasher>(vbmeta_images, digest_);
164 } else if (hash_alg_ == HashAlgorithm::kSHA512) {
165 std::tie(total_size, digest_matched) =
166 VerifyVbmetaDigest<SHA512Hasher>(vbmeta_images, digest_);
167 }
168
169 if (total_size != vbmeta_size_) {
170 LERROR << "total vbmeta size mismatch: " << total_size << " (expected: " << vbmeta_size_
171 << ")";
172 return false;
173 }
174
175 if (!digest_matched) {
176 LERROR << "vbmeta digest mismatch";
177 return false;
178 }
179
180 return true;
181 }
182
183 // class AvbHandle
184 // ---------------
AvbHandle()185 AvbHandle::AvbHandle() : status_(AvbHandleStatus::kUninitialized) {
186 slot_suffix_ = fs_mgr_get_slot_suffix();
187 other_slot_suffix_ = fs_mgr_get_other_slot_suffix();
188 }
189
LoadAndVerifyVbmeta(const std::string & partition_name,const std::string & ab_suffix,const std::string & ab_other_suffix,const std::string & expected_public_key_path,const HashAlgorithm & hash_algorithm,bool allow_verification_error,bool load_chained_vbmeta,bool rollback_protection,std::function<std::string (const std::string &)> custom_device_path)190 AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta(
191 const std::string& partition_name, const std::string& ab_suffix,
192 const std::string& ab_other_suffix, const std::string& expected_public_key_path,
193 const HashAlgorithm& hash_algorithm, bool allow_verification_error,
194 bool load_chained_vbmeta, bool rollback_protection,
195 std::function<std::string(const std::string&)> custom_device_path) {
196 AvbUniquePtr avb_handle(new AvbHandle());
197 if (!avb_handle) {
198 LERROR << "Failed to allocate AvbHandle";
199 return nullptr;
200 }
201
202 avb_handle->slot_suffix_ = ab_suffix;
203 avb_handle->other_slot_suffix_ = ab_other_suffix;
204
205 std::string expected_key_blob;
206 if (!expected_public_key_path.empty()) {
207 if (access(expected_public_key_path.c_str(), F_OK) != 0) {
208 LERROR << "Expected public key path doesn't exist: " << expected_public_key_path;
209 return nullptr;
210 } else if (!ReadFileToString(expected_public_key_path, &expected_key_blob)) {
211 LERROR << "Failed to load: " << expected_public_key_path;
212 return nullptr;
213 }
214 }
215
216 auto android_by_name_symlink = [](const std::string& partition_name_with_ab) {
217 return "/dev/block/by-name/" + partition_name_with_ab;
218 };
219
220 auto device_path = custom_device_path ? custom_device_path : android_by_name_symlink;
221
222 auto verify_result = LoadAndVerifyVbmetaByPartition(
223 partition_name, ab_suffix, ab_other_suffix, expected_key_blob, allow_verification_error,
224 load_chained_vbmeta, rollback_protection, device_path, false,
225 /* is_chained_vbmeta */ &avb_handle->vbmeta_images_);
226 switch (verify_result) {
227 case VBMetaVerifyResult::kSuccess:
228 avb_handle->status_ = AvbHandleStatus::kSuccess;
229 break;
230 case VBMetaVerifyResult::kErrorVerification:
231 avb_handle->status_ = AvbHandleStatus::kVerificationError;
232 break;
233 default:
234 LERROR << "LoadAndVerifyVbmetaByPartition failed, result: " << verify_result;
235 return nullptr;
236 }
237
238 // Validity check here because we have to use vbmeta_images_[0] below.
239 if (avb_handle->vbmeta_images_.size() < 1) {
240 LERROR << "LoadAndVerifyVbmetaByPartition failed, no vbmeta loaded";
241 return nullptr;
242 }
243
244 // Sets the MAJOR.MINOR for init to set it into "ro.boot.avb_version".
245 avb_handle->avb_version_ = StringPrintf("%d.%d", AVB_VERSION_MAJOR, AVB_VERSION_MINOR);
246
247 // Checks any disabled flag is set.
248 std::unique_ptr<AvbVBMetaImageHeader> vbmeta_header =
249 avb_handle->vbmeta_images_[0].GetVBMetaHeader();
250 bool verification_disabled = ((AvbVBMetaImageFlags)vbmeta_header->flags &
251 AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
252 bool hashtree_disabled =
253 ((AvbVBMetaImageFlags)vbmeta_header->flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
254 if (verification_disabled) {
255 avb_handle->status_ = AvbHandleStatus::kVerificationDisabled;
256 } else if (hashtree_disabled) {
257 avb_handle->status_ = AvbHandleStatus::kHashtreeDisabled;
258 }
259
260 // Calculates the summary info for all vbmeta_images_;
261 std::string digest;
262 size_t total_size;
263 if (hash_algorithm == HashAlgorithm::kSHA256) {
264 std::tie(digest, total_size) =
265 CalculateVbmetaDigest<SHA256Hasher>(avb_handle->vbmeta_images_);
266 } else if (hash_algorithm == HashAlgorithm::kSHA512) {
267 std::tie(digest, total_size) =
268 CalculateVbmetaDigest<SHA512Hasher>(avb_handle->vbmeta_images_);
269 } else {
270 LERROR << "Invalid hash algorithm";
271 return nullptr;
272 }
273 avb_handle->vbmeta_info_ = VBMetaInfo(digest, hash_algorithm, total_size);
274
275 LINFO << "Returning avb_handle with status: " << avb_handle->status_;
276 return avb_handle;
277 }
278
IsAvbPermissive()279 static bool IsAvbPermissive() {
280 if (IsDeviceUnlocked()) {
281 // Manually putting a file under metadata partition can enforce AVB verification.
282 if (!access(DSU_METADATA_PREFIX "avb_enforce", F_OK)) {
283 LINFO << "Enforcing AVB verification when the device is unlocked";
284 return false;
285 }
286 return true;
287 }
288 return false;
289 }
290
IsPublicKeyMatching(const FstabEntry & fstab_entry,const std::string & public_key_data,const std::vector<std::string> & preload_avb_key_blobs)291 bool IsPublicKeyMatching(const FstabEntry& fstab_entry, const std::string& public_key_data,
292 const std::vector<std::string>& preload_avb_key_blobs) {
293 // At least one of the following should be provided for public key matching.
294 if (preload_avb_key_blobs.empty() && fstab_entry.avb_keys.empty()) {
295 LERROR << "avb_keys=/path/to/key(s) is missing for " << fstab_entry.mount_point;
296 return false;
297 }
298
299 // Expected key shouldn't be empty.
300 if (public_key_data.empty()) {
301 LERROR << "public key data shouldn't be empty for " << fstab_entry.mount_point;
302 return false;
303 }
304
305 // Performs key matching for preload_avb_key_blobs first, if it is present.
306 if (!preload_avb_key_blobs.empty()) {
307 if (std::find(preload_avb_key_blobs.begin(), preload_avb_key_blobs.end(),
308 public_key_data) != preload_avb_key_blobs.end()) {
309 return true;
310 }
311 }
312
313 // Performs key matching for fstab_entry.avb_keys if necessary.
314 // Note that it is intentional to match both preload_avb_key_blobs and fstab_entry.avb_keys.
315 // Some keys might only be available before init chroots into /system, e.g., /avb/key1
316 // in the first-stage ramdisk, while other keys might only be available after the chroot,
317 // e.g., /system/etc/avb/key2.
318 // fstab_entry.avb_keys might be either a directory containing multiple keys,
319 // or a string indicating multiple keys separated by ':'.
320 std::vector<std::string> allowed_avb_keys;
321 auto list_avb_keys_in_dir = ListFiles(fstab_entry.avb_keys);
322 if (list_avb_keys_in_dir.ok()) {
323 std::sort(list_avb_keys_in_dir->begin(), list_avb_keys_in_dir->end());
324 allowed_avb_keys = *list_avb_keys_in_dir;
325 } else {
326 allowed_avb_keys = Split(fstab_entry.avb_keys, ":");
327 }
328 return ValidatePublicKeyBlob(public_key_data, allowed_avb_keys);
329 }
330
IsHashtreeDescriptorRootDigestMatching(const FstabEntry & fstab_entry,const std::vector<VBMetaData> & vbmeta_images,const std::string & ab_suffix,const std::string & ab_other_suffix)331 bool IsHashtreeDescriptorRootDigestMatching(const FstabEntry& fstab_entry,
332 const std::vector<VBMetaData>& vbmeta_images,
333 const std::string& ab_suffix,
334 const std::string& ab_other_suffix) {
335 // Read expected value of hashtree descriptor root digest from fstab_entry.
336 std::string root_digest_expected;
337 if (!ReadFileToString(fstab_entry.avb_hashtree_digest, &root_digest_expected)) {
338 LERROR << "Failed to load expected root digest for " << fstab_entry.mount_point;
339 return false;
340 }
341
342 // Read actual hashtree descriptor from vbmeta image.
343 std::string partition_name = DeriveAvbPartitionName(fstab_entry, ab_suffix, ab_other_suffix);
344 if (partition_name.empty()) {
345 LERROR << "Failed to find partition name for " << fstab_entry.mount_point;
346 return false;
347 }
348 std::unique_ptr<FsAvbHashtreeDescriptor> hashtree_descriptor =
349 android::fs_mgr::GetHashtreeDescriptor(partition_name, vbmeta_images);
350 if (!hashtree_descriptor) {
351 LERROR << "Not found hashtree descriptor for " << fstab_entry.mount_point;
352 return false;
353 }
354
355 // Performs hashtree descriptor root digest matching.
356 if (hashtree_descriptor->root_digest != root_digest_expected) {
357 LERROR << "root digest (" << hashtree_descriptor->root_digest
358 << ") is different from expected value (" << root_digest_expected << ")";
359 return false;
360 }
361
362 return true;
363 }
364
LoadAndVerifyVbmeta(const FstabEntry & fstab_entry,const std::vector<std::string> & preload_avb_key_blobs)365 AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta(const FstabEntry& fstab_entry,
366 const std::vector<std::string>& preload_avb_key_blobs) {
367 // Binds allow_verification_error and rollback_protection to device unlock state.
368 bool allow_verification_error = IsAvbPermissive();
369 bool rollback_protection = !allow_verification_error;
370
371 std::string public_key_data;
372 bool verification_disabled = false;
373 VBMetaVerifyResult verify_result = VBMetaVerifyResult::kError;
374 std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
375 fstab_entry.blk_device, "" /* partition_name, no need for a standalone path */,
376 "" /* expected_public_key_blob, */, allow_verification_error, rollback_protection,
377 false /* not is_chained_vbmeta */, &public_key_data, &verification_disabled,
378 &verify_result);
379
380 if (!vbmeta) {
381 LERROR << "Failed to load vbmeta: " << fstab_entry.blk_device;
382 return nullptr;
383 }
384
385 AvbUniquePtr avb_handle(new AvbHandle());
386 if (!avb_handle) {
387 LERROR << "Failed to allocate AvbHandle";
388 return nullptr;
389 }
390 avb_handle->vbmeta_images_.emplace_back(std::move(*vbmeta));
391
392 switch (verify_result) {
393 case VBMetaVerifyResult::kSuccess:
394 avb_handle->status_ = AvbHandleStatus::kSuccess;
395 break;
396 case VBMetaVerifyResult::kErrorVerification:
397 avb_handle->status_ = AvbHandleStatus::kVerificationError;
398 break;
399 default:
400 LERROR << "LoadAndVerifyVbmetaByPath failed, result: " << verify_result;
401 return nullptr;
402 }
403
404 // Verify vbmeta image checking by either public key or hashtree descriptor root digest.
405 if (!preload_avb_key_blobs.empty() || !fstab_entry.avb_keys.empty()) {
406 if (!IsPublicKeyMatching(fstab_entry, public_key_data, preload_avb_key_blobs)) {
407 avb_handle->status_ = AvbHandleStatus::kVerificationError;
408 LWARNING << "Found unknown public key used to sign " << fstab_entry.mount_point;
409 if (!allow_verification_error) {
410 LERROR << "Unknown public key is not allowed";
411 return nullptr;
412 }
413 }
414 } else if (!IsHashtreeDescriptorRootDigestMatching(fstab_entry, avb_handle->vbmeta_images_,
415 avb_handle->slot_suffix_,
416 avb_handle->other_slot_suffix_)) {
417 avb_handle->status_ = AvbHandleStatus::kVerificationError;
418 LWARNING << "Found unknown hashtree descriptor root digest used on "
419 << fstab_entry.mount_point;
420 if (!allow_verification_error) {
421 LERROR << "Verification based on root digest failed. Vbmeta image is not allowed.";
422 return nullptr;
423 }
424 }
425
426 if (verification_disabled) {
427 LINFO << "AVB verification disabled on: " << fstab_entry.mount_point;
428 avb_handle->status_ = AvbHandleStatus::kVerificationDisabled;
429 }
430
431 LINFO << "Returning avb_handle for '" << fstab_entry.mount_point
432 << "' with status: " << avb_handle->status_;
433 return avb_handle;
434 }
435
LoadAndVerifyVbmeta(const std::string & slot_suffix)436 AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta(const std::string& slot_suffix) {
437 // Loads inline vbmeta images, starting from /vbmeta.
438 auto suffix = slot_suffix;
439 if (suffix.empty()) {
440 suffix = fs_mgr_get_slot_suffix();
441 }
442 auto other_suffix = android::fs_mgr::OtherSlotSuffix(suffix);
443 return LoadAndVerifyVbmeta("vbmeta", suffix, other_suffix,
444 {} /* expected_public_key, already checked by bootloader */,
445 HashAlgorithm::kSHA256,
446 IsAvbPermissive(), /* allow_verification_error */
447 true, /* load_chained_vbmeta */
448 false, /* rollback_protection, already checked by bootloader */
449 nullptr /* custom_device_path */);
450 }
451
452 // TODO(b/128807537): removes this function.
Open()453 AvbUniquePtr AvbHandle::Open() {
454 bool allow_verification_error = IsAvbPermissive();
455
456 AvbUniquePtr avb_handle(new AvbHandle());
457 if (!avb_handle) {
458 LERROR << "Failed to allocate AvbHandle";
459 return nullptr;
460 }
461
462 FsManagerAvbOps avb_ops;
463 AvbSlotVerifyFlags flags = allow_verification_error
464 ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
465 : AVB_SLOT_VERIFY_FLAGS_NONE;
466 AvbSlotVerifyResult verify_result =
467 avb_ops.AvbSlotVerify(avb_handle->slot_suffix_, flags, &avb_handle->vbmeta_images_);
468
469 // Only allow the following verify results:
470 // - AVB_SLOT_VERIFY_RESULT_OK.
471 // - AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION (UNLOCKED only).
472 // Might occur in either the top-level vbmeta or a chained vbmeta.
473 // - AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED (UNLOCKED only).
474 // Could only occur in a chained vbmeta. Because we have *no-op* operations in
475 // FsManagerAvbOps such that avb_ops->validate_vbmeta_public_key() used to validate
476 // the public key of the top-level vbmeta always pass in userspace here.
477 //
478 // The following verify result won't happen, because the *no-op* operation
479 // avb_ops->read_rollback_index() always returns the minimum value zero. So rollbacked
480 // vbmeta images, which should be caught in the bootloader stage, won't be detected here.
481 // - AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX
482 switch (verify_result) {
483 case AVB_SLOT_VERIFY_RESULT_OK:
484 avb_handle->status_ = AvbHandleStatus::kSuccess;
485 break;
486 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
487 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
488 if (!allow_verification_error) {
489 LERROR << "ERROR_VERIFICATION / PUBLIC_KEY_REJECTED isn't allowed ";
490 return nullptr;
491 }
492 avb_handle->status_ = AvbHandleStatus::kVerificationError;
493 break;
494 default:
495 LERROR << "avb_slot_verify failed, result: " << verify_result;
496 return nullptr;
497 }
498
499 // Sets the MAJOR.MINOR for init to set it into "ro.boot.avb_version".
500 avb_handle->avb_version_ = StringPrintf("%d.%d", AVB_VERSION_MAJOR, AVB_VERSION_MINOR);
501
502 // Verifies vbmeta structs against the digest passed from bootloader in kernel cmdline.
503 std::unique_ptr<AvbVerifier> avb_verifier = AvbVerifier::Create();
504 if (!avb_verifier || !avb_verifier->VerifyVbmetaImages(avb_handle->vbmeta_images_)) {
505 LERROR << "Failed to verify vbmeta digest";
506 if (!allow_verification_error) {
507 LERROR << "vbmeta digest error isn't allowed ";
508 return nullptr;
509 }
510 }
511
512 // Checks whether FLAGS_VERIFICATION_DISABLED is set:
513 // - Only the top-level vbmeta struct is read.
514 // - vbmeta struct in other partitions are NOT processed, including AVB HASH descriptor(s)
515 // and AVB HASHTREE descriptor(s).
516 AvbVBMetaImageHeader vbmeta_header;
517 avb_vbmeta_image_header_to_host_byte_order(
518 (AvbVBMetaImageHeader*)avb_handle->vbmeta_images_[0].data(), &vbmeta_header);
519 bool verification_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags &
520 AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
521
522 // Checks whether FLAGS_HASHTREE_DISABLED is set.
523 // - vbmeta struct in all partitions are still processed, just disable
524 // dm-verity in the user space.
525 bool hashtree_disabled =
526 ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
527
528 if (verification_disabled) {
529 avb_handle->status_ = AvbHandleStatus::kVerificationDisabled;
530 } else if (hashtree_disabled) {
531 avb_handle->status_ = AvbHandleStatus::kHashtreeDisabled;
532 }
533
534 LINFO << "Returning avb_handle with status: " << avb_handle->status_;
535 return avb_handle;
536 }
537
SetUpStandaloneAvbHashtree(FstabEntry * fstab_entry,bool wait_for_verity_dev)538 AvbHashtreeResult AvbHandle::SetUpStandaloneAvbHashtree(FstabEntry* fstab_entry,
539 bool wait_for_verity_dev) {
540 auto avb_handle = LoadAndVerifyVbmeta(*fstab_entry);
541 if (!avb_handle) {
542 return AvbHashtreeResult::kFail;
543 }
544
545 return avb_handle->SetUpAvbHashtree(fstab_entry, wait_for_verity_dev);
546 }
547
SetUpAvbHashtree(FstabEntry * fstab_entry,bool wait_for_verity_dev)548 AvbHashtreeResult AvbHandle::SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait_for_verity_dev) {
549 if (!fstab_entry || status_ == AvbHandleStatus::kUninitialized || vbmeta_images_.size() < 1) {
550 return AvbHashtreeResult::kFail;
551 }
552
553 if (status_ == AvbHandleStatus::kHashtreeDisabled ||
554 status_ == AvbHandleStatus::kVerificationDisabled) {
555 LINFO << "AVB HASHTREE disabled on: " << fstab_entry->mount_point;
556 return AvbHashtreeResult::kDisabled;
557 }
558
559 if (!LoadAvbHashtreeToEnableVerity(fstab_entry, wait_for_verity_dev, vbmeta_images_,
560 slot_suffix_, other_slot_suffix_)) {
561 return AvbHashtreeResult::kFail;
562 }
563
564 return AvbHashtreeResult::kSuccess;
565 }
566
TearDownAvbHashtree(FstabEntry * fstab_entry,bool wait)567 bool AvbHandle::TearDownAvbHashtree(FstabEntry* fstab_entry, bool wait) {
568 if (!fstab_entry) {
569 return false;
570 }
571
572 const std::string device_name(GetVerityDeviceName(*fstab_entry));
573
574 // TODO: remove duplicated code with UnmapDevice()
575 android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance();
576 std::string path;
577 if (wait) {
578 dm.GetDmDevicePathByName(device_name, &path);
579 }
580 if (!dm.DeleteDevice(device_name)) {
581 return false;
582 }
583 if (!path.empty() && !WaitForFile(path, 1000ms, FileWaitMode::DoesNotExist)) {
584 return false;
585 }
586
587 return true;
588 }
589
GetSecurityPatchLevel(const FstabEntry & fstab_entry) const590 std::string AvbHandle::GetSecurityPatchLevel(const FstabEntry& fstab_entry) const {
591 if (vbmeta_images_.size() < 1) {
592 return "";
593 }
594 std::string avb_partition_name =
595 DeriveAvbPartitionName(fstab_entry, slot_suffix_, other_slot_suffix_);
596 auto avb_prop_name = "com.android.build." + avb_partition_name + ".security_patch";
597 return GetAvbPropertyDescriptor(avb_prop_name, vbmeta_images_);
598 }
599
IsDeviceUnlocked()600 bool AvbHandle::IsDeviceUnlocked() {
601 return android::fs_mgr::IsDeviceUnlocked();
602 }
603
604 } // namespace fs_mgr
605 } // namespace android
606