Loading fs_mgr/fs_mgr.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -851,7 +851,8 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode) return FS_MGR_MNTALL_FAIL; } } if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) { if (avb_handle->SetUpAvbHashtree(&fstab->recs[i], true /* wait_for_verity_dev */) == SetUpAvbHashtreeResult::kFail) { LERROR << "Failed to set up AVB on partition: " << fstab->recs[i].mount_point << ", skipping!"; /* Skips mounting the device. */ Loading Loading @@ -1071,7 +1072,8 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device, return FS_MGR_DOMNT_FAILED; } } if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) { if (avb_handle->SetUpAvbHashtree(&fstab->recs[i], true /* wait_for_verity_dev */) == SetUpAvbHashtreeResult::kFail) { LERROR << "Failed to set up AVB on partition: " << fstab->recs[i].mount_point << ", skipping!"; /* Skips mounting the device. */ Loading fs_mgr/fs_mgr_avb.cpp +63 −44 Original line number Diff line number Diff line Loading @@ -114,7 +114,6 @@ static std::pair<size_t, bool> verify_vbmeta_digest(const AvbSlotVerifyData& ver // Reads the following values from kernel cmdline and provides the // VerifyVbmetaImages() to verify AvbSlotVerifyData. // - androidboot.vbmeta.device_state // - androidboot.vbmeta.hash_alg // - androidboot.vbmeta.size // - androidboot.vbmeta.digest Loading @@ -123,7 +122,6 @@ class FsManagerAvbVerifier { // The factory method to return a unique_ptr<FsManagerAvbVerifier> static std::unique_ptr<FsManagerAvbVerifier> Create(); bool VerifyVbmetaImages(const AvbSlotVerifyData& verify_data); bool IsDeviceUnlocked() { return is_device_unlocked_; } protected: FsManagerAvbVerifier() = default; Loading @@ -138,7 +136,6 @@ class FsManagerAvbVerifier { HashAlgorithm hash_alg_; uint8_t digest_[SHA512_DIGEST_LENGTH]; size_t vbmeta_size_; bool is_device_unlocked_; }; std::unique_ptr<FsManagerAvbVerifier> FsManagerAvbVerifier::Create() { Loading @@ -161,9 +158,7 @@ std::unique_ptr<FsManagerAvbVerifier> FsManagerAvbVerifier::Create() { const std::string& key = pieces[0]; const std::string& value = pieces[1]; if (key == "androidboot.vbmeta.device_state") { avb_verifier->is_device_unlocked_ = (value == "unlocked"); } else if (key == "androidboot.vbmeta.hash_alg") { if (key == "androidboot.vbmeta.hash_alg") { hash_alg = value; } else if (key == "androidboot.vbmeta.size") { if (!android::base::ParseUint(value.c_str(), &avb_verifier->vbmeta_size_)) { Loading Loading @@ -478,6 +473,16 @@ static bool get_hashtree_descriptor(const std::string& partition_name, return true; } // Orange state means the device is unlocked, see the following link for details. // https://source.android.com/security/verifiedboot/verified-boot#device_state static inline bool IsDeviceUnlocked() { std::string verified_boot_state; if (fs_mgr_get_boot_config("verifiedbootstate", &verified_boot_state)) { return verified_boot_state == "orange"; } return false; } FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const fstab& fstab) { FsManagerAvbOps avb_ops(fstab); return DoOpen(&avb_ops); Loading @@ -493,12 +498,7 @@ FsManagerAvbUniquePtr FsManagerAvbHandle::Open(ByNameSymlinkMap&& by_name_symlin } FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) { // Gets the expected hash value of vbmeta images from kernel cmdline. std::unique_ptr<FsManagerAvbVerifier> avb_verifier = FsManagerAvbVerifier::Create(); if (!avb_verifier) { LERROR << "Failed to create FsManagerAvbVerifier"; return nullptr; } bool is_device_unlocked = IsDeviceUnlocked(); FsManagerAvbUniquePtr avb_handle(new FsManagerAvbHandle()); if (!avb_handle) { Loading @@ -506,8 +506,7 @@ FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) { return nullptr; } AvbSlotVerifyFlags flags = avb_verifier->IsDeviceUnlocked() ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR AvbSlotVerifyFlags flags = is_device_unlocked ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR : AVB_SLOT_VERIFY_FLAGS_NONE; AvbSlotVerifyResult verify_result = avb_ops->AvbSlotVerify(fs_mgr_get_slot_suffix(), flags, &avb_handle->avb_slot_data_); Loading @@ -526,62 +525,81 @@ FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) { // for more details. switch (verify_result) { case AVB_SLOT_VERIFY_RESULT_OK: avb_handle->status_ = kFsManagerAvbHandleSuccess; avb_handle->status_ = kAvbHandleSuccess; break; case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: if (!avb_verifier->IsDeviceUnlocked()) { if (!is_device_unlocked) { LERROR << "ERROR_VERIFICATION isn't allowed when the device is LOCKED"; return nullptr; } avb_handle->status_ = kFsManagerAvbHandleErrorVerification; avb_handle->status_ = kAvbHandleVerificationError; break; default: LERROR << "avb_slot_verify failed, result: " << verify_result; return nullptr; } // Verifies vbmeta images against the digest passed from bootloader. if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) { LERROR << "VerifyVbmetaImages failed"; return nullptr; } // Sets the MAJOR.MINOR for init to set it into "ro.boot.avb_version". avb_handle->avb_version_ = android::base::StringPrintf("%d.%d", AVB_VERSION_MAJOR, AVB_VERSION_MINOR); // Checks whether FLAGS_HASHTREE_DISABLED is set. // Checks whether FLAGS_VERIFICATION_DISABLED is set: // - Only the top-level vbmeta struct is read. // - vbmeta struct in other partitions are NOT processed, including AVB HASH descriptor(s) // and AVB HASHTREE descriptor(s). AvbVBMetaImageHeader vbmeta_header; avb_vbmeta_image_header_to_host_byte_order( (AvbVBMetaImageHeader*)avb_handle->avb_slot_data_->vbmeta_images[0].vbmeta_data, &vbmeta_header); bool verification_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED); if (verification_disabled) { avb_handle->status_ = kAvbHandleVerificationDisabled; } else { // Verifies vbmeta structs against the digest passed from bootloader in kernel cmdline. std::unique_ptr<FsManagerAvbVerifier> avb_verifier = FsManagerAvbVerifier::Create(); if (!avb_verifier) { LERROR << "Failed to create FsManagerAvbVerifier"; return nullptr; } if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) { LERROR << "VerifyVbmetaImages failed"; return nullptr; } // Checks whether FLAGS_HASHTREE_DISABLED is set. bool hashtree_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED); if (hashtree_disabled) { avb_handle->status_ = kFsManagerAvbHandleHashtreeDisabled; avb_handle->status_ = kAvbHandleHashtreeDisabled; } } LINFO << "Returning avb_handle with status: " << avb_handle->status_; return avb_handle; } bool FsManagerAvbHandle::SetUpAvb(struct fstab_rec* fstab_entry, bool wait_for_verity_dev) { if (!fstab_entry) return false; if (!avb_slot_data_ || avb_slot_data_->num_vbmeta_images < 1) { return false; SetUpAvbHashtreeResult FsManagerAvbHandle::SetUpAvbHashtree(struct fstab_rec* fstab_entry, bool wait_for_verity_dev) { if (!fstab_entry || status_ == kAvbHandleUninitialized || !avb_slot_data_ || avb_slot_data_->num_vbmeta_images < 1) { return SetUpAvbHashtreeResult::kFail; } if (status_ == kFsManagerAvbHandleUninitialized) return false; if (status_ == kFsManagerAvbHandleHashtreeDisabled) { if (status_ == kAvbHandleHashtreeDisabled || status_ == kAvbHandleVerificationDisabled) { LINFO << "AVB HASHTREE disabled on: " << fstab_entry->mount_point; return true; return SetUpAvbHashtreeResult::kDisabled; } std::string partition_name(basename(fstab_entry->mount_point)); if (!avb_validate_utf8((const uint8_t*)partition_name.c_str(), partition_name.length())) { LERROR << "Partition name: " << partition_name.c_str() << " is not valid UTF-8."; return false; // Derives partition_name from blk_device to query the corresponding AVB HASHTREE descriptor // to setup dm-verity. The partition_names in AVB descriptors are without A/B suffix. std::string partition_name(basename(fstab_entry->blk_device)); if (fstab_entry->fs_mgr_flags & MF_SLOTSELECT) { auto ab_suffix = partition_name.rfind(fs_mgr_get_slot_suffix()); if (ab_suffix != std::string::npos) { partition_name.erase(ab_suffix); } } AvbHashtreeDescriptor hashtree_descriptor; Loading @@ -589,13 +607,14 @@ bool FsManagerAvbHandle::SetUpAvb(struct fstab_rec* fstab_entry, bool wait_for_v std::string root_digest; if (!get_hashtree_descriptor(partition_name, *avb_slot_data_, &hashtree_descriptor, &salt, &root_digest)) { return false; return SetUpAvbHashtreeResult::kFail; } // Converts HASHTREE descriptor to verity_table_params. if (!hashtree_dm_verity_setup(fstab_entry, hashtree_descriptor, salt, root_digest, wait_for_verity_dev)) { return false; return SetUpAvbHashtreeResult::kFail; } return true; return SetUpAvbHashtreeResult::kSuccess; } fs_mgr/fs_mgr_avb_ops.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,15 @@ static AvbIOResult dummy_get_unique_guid_for_partition(AvbOps* ops ATTRIBUTE_UNU return AVB_IO_RESULT_OK; } static AvbIOResult dummy_get_size_of_partition(AvbOps* ops ATTRIBUTE_UNUSED, const char* partition ATTRIBUTE_UNUSED, uint64_t* out_size_num_byte) { // The function is for bootloader to load entire content of AVB HASH partitions. // In user-space, returns 0 as we only need to set up AVB HASHTHREE partitions. *out_size_num_byte = 0; return AVB_IO_RESULT_OK; } void FsManagerAvbOps::InitializeAvbOps() { // We only need to provide the implementation of read_from_partition() // operation since that's all what is being used by the avb_slot_verify(). Loading @@ -101,6 +110,7 @@ void FsManagerAvbOps::InitializeAvbOps() { avb_ops_.validate_vbmeta_public_key = dummy_validate_vbmeta_public_key; avb_ops_.read_is_device_unlocked = dummy_read_is_device_unlocked; avb_ops_.get_unique_guid_for_partition = dummy_get_unique_guid_for_partition; avb_ops_.get_size_of_partition = dummy_get_size_of_partition; // Sets user_data for GetInstanceFromAvbOps() to convert it back to FsManagerAvbOps. avb_ops_.user_data = this; Loading fs_mgr/include/fs_mgr_avb.h +37 −19 Original line number Diff line number Diff line Loading @@ -25,11 +25,10 @@ #include "fs_mgr.h" enum FsManagerAvbHandleStatus { kFsManagerAvbHandleUninitialized = -1, kFsManagerAvbHandleSuccess = 0, kFsManagerAvbHandleHashtreeDisabled = 1, kFsManagerAvbHandleErrorVerification = 2, enum class SetUpAvbHashtreeResult { kSuccess = 0, kFail, kDisabled, }; class FsManagerAvbOps; Loading @@ -40,8 +39,8 @@ using FsManagerAvbUniquePtr = std::unique_ptr<FsManagerAvbHandle>; using ByNameSymlinkMap = std::map<std::string, std::string>; // Provides a factory method to return a unique_ptr pointing to itself and the // SetUpAvb() function to extract dm-verity parameters from AVB metadata to // load verity table into kernel through ioctl. // SetUpAvbHashtree() function to extract dm-verity parameters from AVB HASHTREE // descriptors to load verity table into kernel through ioctl. class FsManagerAvbHandle { public: // The factory method to return a FsManagerAvbUniquePtr that holds Loading @@ -65,12 +64,22 @@ class FsManagerAvbHandle { // - nullptr: any error when reading and verifying the metadata, // e.g., I/O error, digest value mismatch, size mismatch, etc. // // - a valid unique_ptr with status kFsMgrAvbHandleHashtreeDisabled: // - a valid unique_ptr with status kAvbHandleHashtreeDisabled: // to support the existing 'adb disable-verity' feature in Android. // It's very helpful for developers to make the filesystem writable to // allow replacing binaries on the device. // // - a valid unique_ptr with status kFsMgrAvbHandleSuccess: the metadata // - a valid unique_ptr with status kAvbHandleVerificationDisabled: // to support 'avbctl disable-verification': only the top-level // vbmeta is read, vbmeta structs in other partitions are not processed. // It's needed to bypass AVB when using the generic system.img to run // VTS for project Treble. // // - a valid unique_ptr with status kAvbHandleVerificationError: // there is verification error when libavb loads vbmeta from each // partition. This is only allowed when the device is unlocked. // // - a valid unique_ptr with status kAvbHandleSuccess: the metadata // is verified and can be trusted. // static FsManagerAvbUniquePtr Open(const fstab& fstab); Loading @@ -79,14 +88,15 @@ class FsManagerAvbHandle { // Sets up dm-verity on the given fstab entry. // The 'wait_for_verity_dev' parameter makes this function wait for the // verity device to get created before return. // Returns true if the mount point is eligible to mount, it includes: // - status_ is kFsMgrAvbHandleHashtreeDisabled or // - status_ is kFsMgrAvbHandleSuccess and sending ioctl DM_TABLE_LOAD // to load verity table is success. // Otherwise, returns false. bool SetUpAvb(fstab_rec* fstab_entry, bool wait_for_verity_dev); bool hashtree_disabled() const { return status_ == kFsManagerAvbHandleHashtreeDisabled; } // // Return value: // - kSuccess: successfully loads dm-verity table into kernel. // - kFailed: failed to setup dm-verity, e.g., vbmeta verification error, // failed to get the HASHTREE descriptor, runtime error when set up // device-mapper, etc. // - kDisabled: hashtree is disabled. SetUpAvbHashtreeResult SetUpAvbHashtree(fstab_rec* fstab_entry, bool wait_for_verity_dev); const std::string& avb_version() const { return avb_version_; } FsManagerAvbHandle(const FsManagerAvbHandle&) = delete; // no copy Loading @@ -102,11 +112,19 @@ class FsManagerAvbHandle { }; private: FsManagerAvbHandle() : avb_slot_data_(nullptr), status_(kFsManagerAvbHandleUninitialized) {} enum AvbHandleStatus { kAvbHandleSuccess = 0, kAvbHandleUninitialized, kAvbHandleHashtreeDisabled, kAvbHandleVerificationDisabled, kAvbHandleVerificationError, }; FsManagerAvbHandle() : avb_slot_data_(nullptr), status_(kAvbHandleUninitialized) {} static FsManagerAvbUniquePtr DoOpen(FsManagerAvbOps* avb_ops); AvbSlotVerifyData* avb_slot_data_; FsManagerAvbHandleStatus status_; AvbHandleStatus status_; std::string avb_version_; }; Loading init/init_first_stage.cpp +23 −19 Original line number Diff line number Diff line Loading @@ -310,12 +310,12 @@ bool FirstStageMountVBootV1::SetUpDmVerity(fstab_rec* fstab_rec) { case FS_MGR_SETUP_VERITY_SKIPPED: case FS_MGR_SETUP_VERITY_DISABLED: LOG(INFO) << "Verity disabled/skipped for '" << fstab_rec->mount_point << "'"; break; return true; case FS_MGR_SETUP_VERITY_SUCCESS: // The exact block device name (fstab_rec->blk_device) is changed to "/dev/block/dm-XX". // Needs to create it because ueventd isn't started in init first stage. // The exact block device name (fstab_rec->blk_device) is changed to // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init // first stage. return InitVerityDevice(fstab_rec->blk_device); break; default: return false; } Loading Loading @@ -406,13 +406,17 @@ ListenerAction FirstStageMountVBootV2::UeventCallback(const Uevent& uevent) { bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) { if (fs_mgr_is_avb(fstab_rec)) { if (!InitAvbHandle()) return false; if (avb_handle_->hashtree_disabled()) { LOG(INFO) << "avb hashtree disabled for '" << fstab_rec->mount_point << "'"; } else if (avb_handle_->SetUpAvb(fstab_rec, false /* wait_for_verity_dev */)) { // The exact block device name (fstab_rec->blk_device) is changed to "/dev/block/dm-XX". // Needs to create it because ueventd isn't started in init first stage. InitVerityDevice(fstab_rec->blk_device); } else { SetUpAvbHashtreeResult hashtree_result = avb_handle_->SetUpAvbHashtree(fstab_rec, false /* wait_for_verity_dev */); switch (hashtree_result) { case SetUpAvbHashtreeResult::kDisabled: return true; // Returns true to mount the partition. case SetUpAvbHashtreeResult::kSuccess: // The exact block device name (fstab_rec->blk_device) is changed to // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init // first stage. return InitVerityDevice(fstab_rec->blk_device); default: return false; } } Loading Loading
fs_mgr/fs_mgr.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -851,7 +851,8 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode) return FS_MGR_MNTALL_FAIL; } } if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) { if (avb_handle->SetUpAvbHashtree(&fstab->recs[i], true /* wait_for_verity_dev */) == SetUpAvbHashtreeResult::kFail) { LERROR << "Failed to set up AVB on partition: " << fstab->recs[i].mount_point << ", skipping!"; /* Skips mounting the device. */ Loading Loading @@ -1071,7 +1072,8 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device, return FS_MGR_DOMNT_FAILED; } } if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) { if (avb_handle->SetUpAvbHashtree(&fstab->recs[i], true /* wait_for_verity_dev */) == SetUpAvbHashtreeResult::kFail) { LERROR << "Failed to set up AVB on partition: " << fstab->recs[i].mount_point << ", skipping!"; /* Skips mounting the device. */ Loading
fs_mgr/fs_mgr_avb.cpp +63 −44 Original line number Diff line number Diff line Loading @@ -114,7 +114,6 @@ static std::pair<size_t, bool> verify_vbmeta_digest(const AvbSlotVerifyData& ver // Reads the following values from kernel cmdline and provides the // VerifyVbmetaImages() to verify AvbSlotVerifyData. // - androidboot.vbmeta.device_state // - androidboot.vbmeta.hash_alg // - androidboot.vbmeta.size // - androidboot.vbmeta.digest Loading @@ -123,7 +122,6 @@ class FsManagerAvbVerifier { // The factory method to return a unique_ptr<FsManagerAvbVerifier> static std::unique_ptr<FsManagerAvbVerifier> Create(); bool VerifyVbmetaImages(const AvbSlotVerifyData& verify_data); bool IsDeviceUnlocked() { return is_device_unlocked_; } protected: FsManagerAvbVerifier() = default; Loading @@ -138,7 +136,6 @@ class FsManagerAvbVerifier { HashAlgorithm hash_alg_; uint8_t digest_[SHA512_DIGEST_LENGTH]; size_t vbmeta_size_; bool is_device_unlocked_; }; std::unique_ptr<FsManagerAvbVerifier> FsManagerAvbVerifier::Create() { Loading @@ -161,9 +158,7 @@ std::unique_ptr<FsManagerAvbVerifier> FsManagerAvbVerifier::Create() { const std::string& key = pieces[0]; const std::string& value = pieces[1]; if (key == "androidboot.vbmeta.device_state") { avb_verifier->is_device_unlocked_ = (value == "unlocked"); } else if (key == "androidboot.vbmeta.hash_alg") { if (key == "androidboot.vbmeta.hash_alg") { hash_alg = value; } else if (key == "androidboot.vbmeta.size") { if (!android::base::ParseUint(value.c_str(), &avb_verifier->vbmeta_size_)) { Loading Loading @@ -478,6 +473,16 @@ static bool get_hashtree_descriptor(const std::string& partition_name, return true; } // Orange state means the device is unlocked, see the following link for details. // https://source.android.com/security/verifiedboot/verified-boot#device_state static inline bool IsDeviceUnlocked() { std::string verified_boot_state; if (fs_mgr_get_boot_config("verifiedbootstate", &verified_boot_state)) { return verified_boot_state == "orange"; } return false; } FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const fstab& fstab) { FsManagerAvbOps avb_ops(fstab); return DoOpen(&avb_ops); Loading @@ -493,12 +498,7 @@ FsManagerAvbUniquePtr FsManagerAvbHandle::Open(ByNameSymlinkMap&& by_name_symlin } FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) { // Gets the expected hash value of vbmeta images from kernel cmdline. std::unique_ptr<FsManagerAvbVerifier> avb_verifier = FsManagerAvbVerifier::Create(); if (!avb_verifier) { LERROR << "Failed to create FsManagerAvbVerifier"; return nullptr; } bool is_device_unlocked = IsDeviceUnlocked(); FsManagerAvbUniquePtr avb_handle(new FsManagerAvbHandle()); if (!avb_handle) { Loading @@ -506,8 +506,7 @@ FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) { return nullptr; } AvbSlotVerifyFlags flags = avb_verifier->IsDeviceUnlocked() ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR AvbSlotVerifyFlags flags = is_device_unlocked ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR : AVB_SLOT_VERIFY_FLAGS_NONE; AvbSlotVerifyResult verify_result = avb_ops->AvbSlotVerify(fs_mgr_get_slot_suffix(), flags, &avb_handle->avb_slot_data_); Loading @@ -526,62 +525,81 @@ FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) { // for more details. switch (verify_result) { case AVB_SLOT_VERIFY_RESULT_OK: avb_handle->status_ = kFsManagerAvbHandleSuccess; avb_handle->status_ = kAvbHandleSuccess; break; case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: if (!avb_verifier->IsDeviceUnlocked()) { if (!is_device_unlocked) { LERROR << "ERROR_VERIFICATION isn't allowed when the device is LOCKED"; return nullptr; } avb_handle->status_ = kFsManagerAvbHandleErrorVerification; avb_handle->status_ = kAvbHandleVerificationError; break; default: LERROR << "avb_slot_verify failed, result: " << verify_result; return nullptr; } // Verifies vbmeta images against the digest passed from bootloader. if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) { LERROR << "VerifyVbmetaImages failed"; return nullptr; } // Sets the MAJOR.MINOR for init to set it into "ro.boot.avb_version". avb_handle->avb_version_ = android::base::StringPrintf("%d.%d", AVB_VERSION_MAJOR, AVB_VERSION_MINOR); // Checks whether FLAGS_HASHTREE_DISABLED is set. // Checks whether FLAGS_VERIFICATION_DISABLED is set: // - Only the top-level vbmeta struct is read. // - vbmeta struct in other partitions are NOT processed, including AVB HASH descriptor(s) // and AVB HASHTREE descriptor(s). AvbVBMetaImageHeader vbmeta_header; avb_vbmeta_image_header_to_host_byte_order( (AvbVBMetaImageHeader*)avb_handle->avb_slot_data_->vbmeta_images[0].vbmeta_data, &vbmeta_header); bool verification_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED); if (verification_disabled) { avb_handle->status_ = kAvbHandleVerificationDisabled; } else { // Verifies vbmeta structs against the digest passed from bootloader in kernel cmdline. std::unique_ptr<FsManagerAvbVerifier> avb_verifier = FsManagerAvbVerifier::Create(); if (!avb_verifier) { LERROR << "Failed to create FsManagerAvbVerifier"; return nullptr; } if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) { LERROR << "VerifyVbmetaImages failed"; return nullptr; } // Checks whether FLAGS_HASHTREE_DISABLED is set. bool hashtree_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED); if (hashtree_disabled) { avb_handle->status_ = kFsManagerAvbHandleHashtreeDisabled; avb_handle->status_ = kAvbHandleHashtreeDisabled; } } LINFO << "Returning avb_handle with status: " << avb_handle->status_; return avb_handle; } bool FsManagerAvbHandle::SetUpAvb(struct fstab_rec* fstab_entry, bool wait_for_verity_dev) { if (!fstab_entry) return false; if (!avb_slot_data_ || avb_slot_data_->num_vbmeta_images < 1) { return false; SetUpAvbHashtreeResult FsManagerAvbHandle::SetUpAvbHashtree(struct fstab_rec* fstab_entry, bool wait_for_verity_dev) { if (!fstab_entry || status_ == kAvbHandleUninitialized || !avb_slot_data_ || avb_slot_data_->num_vbmeta_images < 1) { return SetUpAvbHashtreeResult::kFail; } if (status_ == kFsManagerAvbHandleUninitialized) return false; if (status_ == kFsManagerAvbHandleHashtreeDisabled) { if (status_ == kAvbHandleHashtreeDisabled || status_ == kAvbHandleVerificationDisabled) { LINFO << "AVB HASHTREE disabled on: " << fstab_entry->mount_point; return true; return SetUpAvbHashtreeResult::kDisabled; } std::string partition_name(basename(fstab_entry->mount_point)); if (!avb_validate_utf8((const uint8_t*)partition_name.c_str(), partition_name.length())) { LERROR << "Partition name: " << partition_name.c_str() << " is not valid UTF-8."; return false; // Derives partition_name from blk_device to query the corresponding AVB HASHTREE descriptor // to setup dm-verity. The partition_names in AVB descriptors are without A/B suffix. std::string partition_name(basename(fstab_entry->blk_device)); if (fstab_entry->fs_mgr_flags & MF_SLOTSELECT) { auto ab_suffix = partition_name.rfind(fs_mgr_get_slot_suffix()); if (ab_suffix != std::string::npos) { partition_name.erase(ab_suffix); } } AvbHashtreeDescriptor hashtree_descriptor; Loading @@ -589,13 +607,14 @@ bool FsManagerAvbHandle::SetUpAvb(struct fstab_rec* fstab_entry, bool wait_for_v std::string root_digest; if (!get_hashtree_descriptor(partition_name, *avb_slot_data_, &hashtree_descriptor, &salt, &root_digest)) { return false; return SetUpAvbHashtreeResult::kFail; } // Converts HASHTREE descriptor to verity_table_params. if (!hashtree_dm_verity_setup(fstab_entry, hashtree_descriptor, salt, root_digest, wait_for_verity_dev)) { return false; return SetUpAvbHashtreeResult::kFail; } return true; return SetUpAvbHashtreeResult::kSuccess; }
fs_mgr/fs_mgr_avb_ops.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,15 @@ static AvbIOResult dummy_get_unique_guid_for_partition(AvbOps* ops ATTRIBUTE_UNU return AVB_IO_RESULT_OK; } static AvbIOResult dummy_get_size_of_partition(AvbOps* ops ATTRIBUTE_UNUSED, const char* partition ATTRIBUTE_UNUSED, uint64_t* out_size_num_byte) { // The function is for bootloader to load entire content of AVB HASH partitions. // In user-space, returns 0 as we only need to set up AVB HASHTHREE partitions. *out_size_num_byte = 0; return AVB_IO_RESULT_OK; } void FsManagerAvbOps::InitializeAvbOps() { // We only need to provide the implementation of read_from_partition() // operation since that's all what is being used by the avb_slot_verify(). Loading @@ -101,6 +110,7 @@ void FsManagerAvbOps::InitializeAvbOps() { avb_ops_.validate_vbmeta_public_key = dummy_validate_vbmeta_public_key; avb_ops_.read_is_device_unlocked = dummy_read_is_device_unlocked; avb_ops_.get_unique_guid_for_partition = dummy_get_unique_guid_for_partition; avb_ops_.get_size_of_partition = dummy_get_size_of_partition; // Sets user_data for GetInstanceFromAvbOps() to convert it back to FsManagerAvbOps. avb_ops_.user_data = this; Loading
fs_mgr/include/fs_mgr_avb.h +37 −19 Original line number Diff line number Diff line Loading @@ -25,11 +25,10 @@ #include "fs_mgr.h" enum FsManagerAvbHandleStatus { kFsManagerAvbHandleUninitialized = -1, kFsManagerAvbHandleSuccess = 0, kFsManagerAvbHandleHashtreeDisabled = 1, kFsManagerAvbHandleErrorVerification = 2, enum class SetUpAvbHashtreeResult { kSuccess = 0, kFail, kDisabled, }; class FsManagerAvbOps; Loading @@ -40,8 +39,8 @@ using FsManagerAvbUniquePtr = std::unique_ptr<FsManagerAvbHandle>; using ByNameSymlinkMap = std::map<std::string, std::string>; // Provides a factory method to return a unique_ptr pointing to itself and the // SetUpAvb() function to extract dm-verity parameters from AVB metadata to // load verity table into kernel through ioctl. // SetUpAvbHashtree() function to extract dm-verity parameters from AVB HASHTREE // descriptors to load verity table into kernel through ioctl. class FsManagerAvbHandle { public: // The factory method to return a FsManagerAvbUniquePtr that holds Loading @@ -65,12 +64,22 @@ class FsManagerAvbHandle { // - nullptr: any error when reading and verifying the metadata, // e.g., I/O error, digest value mismatch, size mismatch, etc. // // - a valid unique_ptr with status kFsMgrAvbHandleHashtreeDisabled: // - a valid unique_ptr with status kAvbHandleHashtreeDisabled: // to support the existing 'adb disable-verity' feature in Android. // It's very helpful for developers to make the filesystem writable to // allow replacing binaries on the device. // // - a valid unique_ptr with status kFsMgrAvbHandleSuccess: the metadata // - a valid unique_ptr with status kAvbHandleVerificationDisabled: // to support 'avbctl disable-verification': only the top-level // vbmeta is read, vbmeta structs in other partitions are not processed. // It's needed to bypass AVB when using the generic system.img to run // VTS for project Treble. // // - a valid unique_ptr with status kAvbHandleVerificationError: // there is verification error when libavb loads vbmeta from each // partition. This is only allowed when the device is unlocked. // // - a valid unique_ptr with status kAvbHandleSuccess: the metadata // is verified and can be trusted. // static FsManagerAvbUniquePtr Open(const fstab& fstab); Loading @@ -79,14 +88,15 @@ class FsManagerAvbHandle { // Sets up dm-verity on the given fstab entry. // The 'wait_for_verity_dev' parameter makes this function wait for the // verity device to get created before return. // Returns true if the mount point is eligible to mount, it includes: // - status_ is kFsMgrAvbHandleHashtreeDisabled or // - status_ is kFsMgrAvbHandleSuccess and sending ioctl DM_TABLE_LOAD // to load verity table is success. // Otherwise, returns false. bool SetUpAvb(fstab_rec* fstab_entry, bool wait_for_verity_dev); bool hashtree_disabled() const { return status_ == kFsManagerAvbHandleHashtreeDisabled; } // // Return value: // - kSuccess: successfully loads dm-verity table into kernel. // - kFailed: failed to setup dm-verity, e.g., vbmeta verification error, // failed to get the HASHTREE descriptor, runtime error when set up // device-mapper, etc. // - kDisabled: hashtree is disabled. SetUpAvbHashtreeResult SetUpAvbHashtree(fstab_rec* fstab_entry, bool wait_for_verity_dev); const std::string& avb_version() const { return avb_version_; } FsManagerAvbHandle(const FsManagerAvbHandle&) = delete; // no copy Loading @@ -102,11 +112,19 @@ class FsManagerAvbHandle { }; private: FsManagerAvbHandle() : avb_slot_data_(nullptr), status_(kFsManagerAvbHandleUninitialized) {} enum AvbHandleStatus { kAvbHandleSuccess = 0, kAvbHandleUninitialized, kAvbHandleHashtreeDisabled, kAvbHandleVerificationDisabled, kAvbHandleVerificationError, }; FsManagerAvbHandle() : avb_slot_data_(nullptr), status_(kAvbHandleUninitialized) {} static FsManagerAvbUniquePtr DoOpen(FsManagerAvbOps* avb_ops); AvbSlotVerifyData* avb_slot_data_; FsManagerAvbHandleStatus status_; AvbHandleStatus status_; std::string avb_version_; }; Loading
init/init_first_stage.cpp +23 −19 Original line number Diff line number Diff line Loading @@ -310,12 +310,12 @@ bool FirstStageMountVBootV1::SetUpDmVerity(fstab_rec* fstab_rec) { case FS_MGR_SETUP_VERITY_SKIPPED: case FS_MGR_SETUP_VERITY_DISABLED: LOG(INFO) << "Verity disabled/skipped for '" << fstab_rec->mount_point << "'"; break; return true; case FS_MGR_SETUP_VERITY_SUCCESS: // The exact block device name (fstab_rec->blk_device) is changed to "/dev/block/dm-XX". // Needs to create it because ueventd isn't started in init first stage. // The exact block device name (fstab_rec->blk_device) is changed to // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init // first stage. return InitVerityDevice(fstab_rec->blk_device); break; default: return false; } Loading Loading @@ -406,13 +406,17 @@ ListenerAction FirstStageMountVBootV2::UeventCallback(const Uevent& uevent) { bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) { if (fs_mgr_is_avb(fstab_rec)) { if (!InitAvbHandle()) return false; if (avb_handle_->hashtree_disabled()) { LOG(INFO) << "avb hashtree disabled for '" << fstab_rec->mount_point << "'"; } else if (avb_handle_->SetUpAvb(fstab_rec, false /* wait_for_verity_dev */)) { // The exact block device name (fstab_rec->blk_device) is changed to "/dev/block/dm-XX". // Needs to create it because ueventd isn't started in init first stage. InitVerityDevice(fstab_rec->blk_device); } else { SetUpAvbHashtreeResult hashtree_result = avb_handle_->SetUpAvbHashtree(fstab_rec, false /* wait_for_verity_dev */); switch (hashtree_result) { case SetUpAvbHashtreeResult::kDisabled: return true; // Returns true to mount the partition. case SetUpAvbHashtreeResult::kSuccess: // The exact block device name (fstab_rec->blk_device) is changed to // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init // first stage. return InitVerityDevice(fstab_rec->blk_device); default: return false; } } Loading