diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp index 65f0eff55..eb737bba7 100644 --- a/fs_mgr/Android.bp +++ b/fs_mgr/Android.bp @@ -74,6 +74,7 @@ cc_library { "liblogwrap", "libdm", "libext2_uuid", + "libfscrypt", "libfstab", ], cppflags: [ diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index 328169092..b93872bfd 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,9 @@ #define SYSFS_EXT4_VERITY "/sys/fs/ext4/features/verity" +// FIXME: this should be in system/extras +#define EXT4_FEATURE_COMPAT_STABLE_INODES 0x0800 + #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) using android::base::Basename; @@ -412,25 +416,43 @@ static void tune_reserved_size(const std::string& blk_device, const FstabEntry& // Enable file-based encryption if needed. static void tune_encrypt(const std::string& blk_device, const FstabEntry& entry, const struct ext4_super_block* sb, int* fs_stat) { - bool has_encrypt = (sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_ENCRYPT)) != 0; - bool want_encrypt = entry.fs_mgr_flags.file_encryption; - - if (has_encrypt || !want_encrypt) { + if (!entry.fs_mgr_flags.file_encryption) { + return; // Nothing needs done. + } + std::vector features_needed; + if ((sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_ENCRYPT)) == 0) { + features_needed.emplace_back("encrypt"); + } + android::fscrypt::EncryptionOptions options; + if (!android::fscrypt::ParseOptions(entry.encryption_options, &options)) { + LERROR << "Unable to parse encryption options on " << blk_device << ": " + << entry.encryption_options; + return; + } + if ((options.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) != 0) { + // We can only use this policy on ext4 if the "stable_inodes" feature + // is set on the filesystem, otherwise shrinking will break encrypted files. + if ((sb->s_feature_compat & cpu_to_le32(EXT4_FEATURE_COMPAT_STABLE_INODES)) == 0) { + features_needed.emplace_back("stable_inodes"); + } + } + if (features_needed.size() == 0) { return; } - if (!tune2fs_available()) { LERROR << "Unable to enable ext4 encryption on " << blk_device << " because " TUNE2FS_BIN " is missing"; return; } - const char* argv[] = {TUNE2FS_BIN, "-Oencrypt", blk_device.c_str()}; + auto flags = android::base::Join(features_needed, ','); + auto flag_arg = "-O"s + flags; + const char* argv[] = {TUNE2FS_BIN, flag_arg.c_str(), blk_device.c_str()}; - LINFO << "Enabling ext4 encryption on " << blk_device; + LINFO << "Enabling ext4 flags " << flags << " on " << blk_device; if (!run_tune2fs(argv, ARRAY_SIZE(argv))) { LERROR << "Failed to run " TUNE2FS_BIN " to enable " - << "ext4 encryption on " << blk_device; + << "ext4 flags " << flags << " on " << blk_device; *fs_stat |= FS_STAT_ENABLE_ENCRYPTION_FAILED; } } diff --git a/init/Android.bp b/init/Android.bp index bd2d38c24..776a3a6c4 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -79,7 +79,6 @@ cc_defaults { "libdl", "libext4_utils", "libfs_mgr", - "libfscrypt", "libgsi", "libhidl-gen-utils", "libkeyutils", diff --git a/init/Android.mk b/init/Android.mk index 4e4c00210..997b2bc18 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -91,7 +91,6 @@ LOCAL_STATIC_LIBRARIES := \ libsquashfs_utils \ liblogwrap \ libext4_utils \ - libfscrypt \ libcrypto_utils \ libsparse \ libavb \