diff --git a/MetadataCrypt.cpp b/MetadataCrypt.cpp index 2f11c8b..8b2b960 100644 --- a/MetadataCrypt.cpp +++ b/MetadataCrypt.cpp @@ -52,6 +52,7 @@ using android::fs_mgr::GetEntryForMountPoint; using android::fscrypt::GetFirstApiLevel; using android::vold::KeyBuffer; using namespace android::dm; +using namespace std::chrono_literals; // Parsed from metadata options struct CryptoOptions { @@ -81,6 +82,17 @@ const KeyGeneration makeGen(const CryptoOptions& options) { return KeyGeneration{options.cipher.get_keysize(), true, options.use_hw_wrapped_key}; } +void defaultkey_precreate_dm_device() { + auto& dm = DeviceMapper::Instance(); + if (dm.GetState(kDmNameUserdata) != DmDeviceState::INVALID) { + LOG(INFO) << "Not pre-creating userdata encryption device; device already exists"; + return; + } + if (!dm.CreateEmptyDevice(kDmNameUserdata)) { + LOG(ERROR) << "Failed to pre-create userdata metadata encryption device"; + } +} + static bool mount_via_fs_mgr(const char* mount_point, const char* blk_device) { // fs_mgr_do_mount runs fsck. Use setexeccon to run trusted // partitions in the fsck domain. @@ -173,8 +185,19 @@ static bool create_crypto_blk_dev(const std::string& dm_name, const std::string& table.AddTarget(std::move(target)); auto& dm = DeviceMapper::Instance(); - if (!dm.CreateDevice(dm_name, table, crypto_blkdev, std::chrono::seconds(5))) { - PLOG(ERROR) << "Could not create default-key device " << dm_name; + if (dm_name == kDmNameUserdata && dm.GetState(dm_name) == DmDeviceState::SUSPENDED) { + // The device was created in advance, populate it now. + std::string path; + if (!dm.WaitForDevice(dm_name, 5s, crypto_blkdev)) { + LOG(ERROR) << "Failed to wait for default-key device " << dm_name; + return false; + } + if (!dm.LoadTableAndActivate(dm_name, table)) { + LOG(ERROR) << "Failed to populate default-key device " << dm_name; + return false; + } + } else if (!dm.CreateDevice(dm_name, table, crypto_blkdev, 5s)) { + LOG(ERROR) << "Could not create default-key device " << dm_name; return false; } return true; diff --git a/MetadataCrypt.h b/MetadataCrypt.h index e482765..06131ad 100644 --- a/MetadataCrypt.h +++ b/MetadataCrypt.h @@ -25,6 +25,7 @@ namespace android { namespace vold { +void defaultkey_precreate_dm_device(); bool fscrypt_mount_metadata_encrypted(const std::string& block_device, const std::string& mount_point, bool needs_encrypt, bool should_format, const std::string& fs_type); diff --git a/main.cpp b/main.cpp index 1f85fb5..641d13a 100644 --- a/main.cpp +++ b/main.cpp @@ -16,6 +16,7 @@ #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER +#include "MetadataCrypt.h" #include "NetlinkManager.h" #include "VoldNativeService.h" #include "VoldUtil.h" @@ -247,6 +248,11 @@ static int process_config(VolumeManager* vm, VoldConfigs* configs) { PLOG(FATAL) << "could not find logical partition " << entry.blk_device; } + if (entry.mount_point == "/data" && !entry.metadata_encryption.empty()) { + // Pre-populate userdata dm-devices since the uevents are asynchronous (b/198405417). + android::vold::defaultkey_precreate_dm_device(); + } + if (entry.fs_mgr_flags.vold_managed) { if (entry.fs_mgr_flags.nonremovable) { LOG(WARNING) << "nonremovable no longer supported; ignoring volume";