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