From: Eric Biggers Date: Mon, 6 Jul 2020 20:46:38 +0000 (-0700) Subject: vold: only allow emmc_optimized on eMMC storage X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=006eed8e3a;p=android-x86%2Fsystem-vold.git vold: only allow emmc_optimized on eMMC storage The emmc_optimized encryption flag is specifically designed for the limitations of inline encryption hardware that follows the eMMC standard. It isn't appropriate to use on other types of storage. So, make vold enforce that it's not used on other types of storage. Bug: 160639344 Test: - Enabled emmc_optimized on Cuttlefish and verified it no longer boots - Using a modified version of this change, verified that IsEmmcStorage() works as expected on various devices including Cuttlefish, Cuttlefish booted in GSI image mode, a device with eMMC storage, and a device with UFS storage. - Verified that VtsKernelEncryptionTest still passes Change-Id: Ie27b80658db53b1a4207b3cbb4e309d05130812e Merged-In: Ie27b80658db53b1a4207b3cbb4e309d05130812e --- diff --git a/FsCrypt.cpp b/FsCrypt.cpp index 4d5cd33..e21524a 100644 --- a/FsCrypt.cpp +++ b/FsCrypt.cpp @@ -52,6 +52,7 @@ #include #include +#include #include #include @@ -60,6 +61,9 @@ #include #include +using android::base::Basename; +using android::base::Realpath; +using android::base::StartsWith; using android::base::StringPrintf; using android::fs_mgr::GetEntryForMountPoint; using android::vold::BuildDataPath; @@ -73,6 +77,7 @@ using android::vold::SetQuotaInherit; using android::vold::SetQuotaProjectId; using android::vold::writeStringToFile; using namespace android::fscrypt; +using namespace android::dm; namespace { @@ -203,6 +208,26 @@ static bool read_and_fixate_user_ce_key(userid_t user_id, return false; } +static bool IsEmmcStorage(const std::string& blk_device) { + // Handle symlinks. + std::string real_path; + if (!Realpath(blk_device, &real_path)) { + real_path = blk_device; + } + + // Handle logical volumes. + auto& dm = DeviceMapper::Instance(); + for (;;) { + auto parent = dm.GetParentBlockDeviceByPath(real_path); + if (!parent.has_value()) break; + real_path = *parent; + } + + // Now we should have the "real" block device. + LOG(DEBUG) << "IsEmmcStorage(): blk_device = " << blk_device << ", real_path=" << real_path; + return StartsWith(Basename(real_path), "mmcblk"); +} + // Retrieve the options to use for encryption policies on the /data filesystem. static bool get_data_file_encryption_options(EncryptionOptions* options) { auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT); @@ -215,6 +240,12 @@ static bool get_data_file_encryption_options(EncryptionOptions* options) { << entry->encryption_options; return false; } + if ((options->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) && + !IsEmmcStorage(entry->blk_device)) { + LOG(ERROR) << "The emmc_optimized encryption flag is only allowed on eMMC storage. Remove " + "this flag from the device's fstab"; + return false; + } return true; } @@ -248,6 +279,11 @@ static bool get_volume_file_encryption_options(EncryptionOptions* options) { LOG(ERROR) << "Unable to parse volume encryption options: " << options_string; return false; } + if (options->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) { + LOG(ERROR) << "The emmc_optimized encryption flag is only allowed on eMMC storage. Remove " + "this flag from ro.crypto.volume.options"; + return false; + } return true; }