diff --git a/MetadataCrypt.cpp b/MetadataCrypt.cpp index cf7c5f7..24c7476 100644 --- a/MetadataCrypt.cpp +++ b/MetadataCrypt.cpp @@ -41,6 +41,8 @@ #include "Keymaster.h" #include "Utils.h" #include "VoldUtil.h" +#include "fs/Ext4.h" +#include "fs/F2fs.h" namespace android { namespace vold { @@ -202,8 +204,11 @@ static bool parse_options(const std::string& options_string, CryptoOptions* opti } bool fscrypt_mount_metadata_encrypted(const std::string& blk_device, const std::string& mount_point, - bool needs_encrypt) { - LOG(DEBUG) << "fscrypt_mount_metadata_encrypted: " << mount_point << " " << needs_encrypt; + bool needs_encrypt, bool should_format, + const std::string& fs_type) { + LOG(DEBUG) << "fscrypt_mount_metadata_encrypted: " << mount_point + << " encrypt: " << needs_encrypt << " format: " << should_format << " with " + << fs_type; auto encrypted_state = android::base::GetProperty("ro.crypto.state", ""); if (encrypted_state != "" && encrypted_state != "encrypted") { LOG(DEBUG) << "fscrypt_enable_crypto got unexpected starting state: " << encrypted_state; @@ -250,8 +255,24 @@ bool fscrypt_mount_metadata_encrypted(const std::string& blk_device, const std:: if (!create_crypto_blk_dev(kDmNameUserdata, blk_device, key, options, &crypto_blkdev, &nr_sec)) return false; - // FIXME handle the corrupt case - if (needs_encrypt && !encrypt_inplace(crypto_blkdev, blk_device, nr_sec, false)) return false; + if (needs_encrypt) { + if (should_format) { + status_t error; + + if (fs_type == "ext4") { + error = ext4::Format(crypto_blkdev, 0, mount_point); + } else if (fs_type == "f2fs") { + error = f2fs::Format(crypto_blkdev); + } else { + LOG(ERROR) << "Unknown filesystem type: " << fs_type; + return false; + } + LOG(DEBUG) << "Format (err=" << error << ") " << crypto_blkdev << " on " << mount_point; + if (error != 0) return false; + } else { + if (!encrypt_inplace(crypto_blkdev, blk_device, nr_sec, false)) return false; + } + } LOG(DEBUG) << "Mounting metadata-encrypted filesystem:" << mount_point; mount_via_fs_mgr(mount_point.c_str(), crypto_blkdev.c_str()); diff --git a/MetadataCrypt.h b/MetadataCrypt.h index 7341a08..e482765 100644 --- a/MetadataCrypt.h +++ b/MetadataCrypt.h @@ -26,7 +26,8 @@ namespace android { namespace vold { bool fscrypt_mount_metadata_encrypted(const std::string& block_device, - const std::string& mount_point, bool needs_encrypt); + const std::string& mount_point, bool needs_encrypt, + bool should_format, const std::string& fs_type); bool defaultkey_volume_keygen(KeyGeneration* gen); diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp index 864a6f0..332fc63 100644 --- a/VoldNativeService.cpp +++ b/VoldNativeService.cpp @@ -681,15 +681,18 @@ binder::Status VoldNativeService::mountFstab(const std::string& blkDevice, ENFORCE_SYSTEM_OR_ROOT; ACQUIRE_LOCK; - return translateBool(fscrypt_mount_metadata_encrypted(blkDevice, mountPoint, false)); + return translateBool( + fscrypt_mount_metadata_encrypted(blkDevice, mountPoint, false, false, "null")); } binder::Status VoldNativeService::encryptFstab(const std::string& blkDevice, - const std::string& mountPoint) { + const std::string& mountPoint, bool shouldFormat, + const std::string& fsType) { ENFORCE_SYSTEM_OR_ROOT; ACQUIRE_LOCK; - return translateBool(fscrypt_mount_metadata_encrypted(blkDevice, mountPoint, true)); + return translateBool( + fscrypt_mount_metadata_encrypted(blkDevice, mountPoint, true, shouldFormat, fsType)); } binder::Status VoldNativeService::createUserKey(int32_t userId, int32_t userSerial, diff --git a/VoldNativeService.h b/VoldNativeService.h index 0a55af4..8fd6261 100644 --- a/VoldNativeService.h +++ b/VoldNativeService.h @@ -111,7 +111,8 @@ class VoldNativeService : public BinderService, public os::Bn binder::Status initUser0(); binder::Status isConvertibleToFbe(bool* _aidl_return); binder::Status mountFstab(const std::string& blkDevice, const std::string& mountPoint); - binder::Status encryptFstab(const std::string& blkDevice, const std::string& mountPoint); + binder::Status encryptFstab(const std::string& blkDevice, const std::string& mountPoint, + bool shouldFormat, const std::string& fsType); binder::Status createUserKey(int32_t userId, int32_t userSerial, bool ephemeral); binder::Status destroyUserKey(int32_t userId); diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl index ef4f89a..eb012a0 100644 --- a/binder/android/os/IVold.aidl +++ b/binder/android/os/IVold.aidl @@ -88,7 +88,7 @@ interface IVold { void initUser0(); boolean isConvertibleToFbe(); void mountFstab(@utf8InCpp String blkDevice, @utf8InCpp String mountPoint); - void encryptFstab(@utf8InCpp String blkDevice, @utf8InCpp String mountPoint); + void encryptFstab(@utf8InCpp String blkDevice, @utf8InCpp String mountPoint, boolean shouldFormat, @utf8InCpp String fsType); void createUserKey(int userId, int userSerial, boolean ephemeral); void destroyUserKey(int userId); diff --git a/vdc.cpp b/vdc.cpp index 1aaeb5a..47d98de 100644 --- a/vdc.cpp +++ b/vdc.cpp @@ -31,9 +31,10 @@ #include "android/os/IVold.h" #include +#include #include -#include #include +#include #include #include @@ -107,8 +108,12 @@ int main(int argc, char** argv) { checkStatus(args, vold->reset()); } else if (args[0] == "cryptfs" && args[1] == "mountFstab" && args.size() == 4) { checkStatus(args, vold->mountFstab(args[2], args[3])); - } else if (args[0] == "cryptfs" && args[1] == "encryptFstab" && args.size() == 4) { - checkStatus(args, vold->encryptFstab(args[2], args[3])); + } else if (args[0] == "cryptfs" && args[1] == "encryptFstab" && args.size() == 6) { + auto shouldFormat = android::base::ParseBool(args[4]); + if (shouldFormat == android::base::ParseBoolResult::kError) exit(EINVAL); + checkStatus(args, vold->encryptFstab(args[2], args[3], + shouldFormat == android::base::ParseBoolResult::kTrue, + args[5])); } else if (args[0] == "checkpoint" && args[1] == "supportsCheckpoint" && args.size() == 2) { bool supported = false; checkStatus(args, vold->supportsCheckpoint(&supported));