[2/3] ext4: add support for INLINE_CRYPT_OPTIMIZED encryption policies
diff mbox series

Message ID 20191021230355.23136-3-ebiggers@kernel.org
State Not Applicable
Headers show
Series
  • fscrypt: support for inline-encryption-optimized policies
Related show

Commit Message

Eric Biggers Oct. 21, 2019, 11:03 p.m. UTC
From: Eric Biggers <ebiggers@google.com>

INLINE_CRYPT_OPTIMIZED encryption policies have special requirements
from the filesystem:

- Inode numbers must never change, even if the filesystem is resized
- Inode numbers must be <= 32 bits
- File logical block numbers must be <= 32 bits

ext4 has 32-bit inode and file logical block numbers.  However,
resize2fs can re-number inodes when shrinking an ext4 filesystem.

However, many people who want to use inline encryption don't care about
filesystem shrinking.  They'd be fine with a solution that just prevents
the filesystem from being shrunk.

Therefore, add a new feature flag EXT4_FEATURE_COMPAT_STABLE_INODES that
will do exactly that.  Then wire up the fscrypt_operations to expose
this flag to fs/crypto/, so that it allows INLINE_CRYPT_OPTIMIZED
policies when this flag is set.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/ext4/ext4.h  |  2 ++
 fs/ext4/super.c | 14 ++++++++++++++
 2 files changed, 16 insertions(+)

Comments

Theodore Y. Ts'o Oct. 22, 2019, 1:37 p.m. UTC | #1
On Mon, Oct 21, 2019 at 04:03:54PM -0700, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> INLINE_CRYPT_OPTIMIZED encryption policies have special requirements
> from the filesystem:
> 
> - Inode numbers must never change, even if the filesystem is resized
> - Inode numbers must be <= 32 bits
> - File logical block numbers must be <= 32 bits

You need to guarantee more than this; you also need to guarantee that
the logical block number may not change.  Fortunately, because the
original per-file key scheme used a logical block tweak, we've
prohibited this already, and we didn't relax this restriction for
files encrpyted using DIRECT_KEY.  So it's a requirement which we
already meet, but we should document this requirement explicitly ---
both here and also in Documentations/filesystems/fscrypt.rst.

Otherwise, looks good.  Feel free to add:

Reviewed-by: Theodore Ts'o <tytso@mit.edu>

						- Ted
Eric Biggers Oct. 22, 2019, 4:37 p.m. UTC | #2
On Tue, Oct 22, 2019 at 09:37:16AM -0400, Theodore Y. Ts'o wrote:
> On Mon, Oct 21, 2019 at 04:03:54PM -0700, Eric Biggers wrote:
> > From: Eric Biggers <ebiggers@google.com>
> > 
> > INLINE_CRYPT_OPTIMIZED encryption policies have special requirements
> > from the filesystem:
> > 
> > - Inode numbers must never change, even if the filesystem is resized
> > - Inode numbers must be <= 32 bits
> > - File logical block numbers must be <= 32 bits
> 
> You need to guarantee more than this; you also need to guarantee that
> the logical block number may not change.  Fortunately, because the
> original per-file key scheme used a logical block tweak, we've
> prohibited this already, and we didn't relax this restriction for
> files encrpyted using DIRECT_KEY.  So it's a requirement which we
> already meet, but we should document this requirement explicitly ---
> both here and also in Documentations/filesystems/fscrypt.rst.
> 
> Otherwise, looks good.  Feel free to add:
> 
> Reviewed-by: Theodore Ts'o <tytso@mit.edu>
> 

This is meant to list the requirements over the current policies.  If we wanted
to list all requirements on filesystems to support any fscrypt policy at all,
we'd also have to list a lot of other things like that the filesystem must
implement all the fscrypt_operations, must call all the needed hooks, must
support encrypted filenames and symlinks, etc...

I'll change the beginning of this commit message to
"INLINE_CRYPT_OPTIMIZED encryption policies have special requirements
from the filesystem, in comparison to the current encryption policies:"

... and in the previous patch I'll add a note in the "Contents encryption"
section of Documentation/filesystems/fscrypt.rst that the use of the file
logical block number means that filesystems must not allow operations that would
change it.

- Eric

Patch
diff mbox series

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 03db3e71676ce..b3a2cc7c0252f 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1678,6 +1678,7 @@  static inline bool ext4_verity_in_progress(struct inode *inode)
 #define EXT4_FEATURE_COMPAT_RESIZE_INODE	0x0010
 #define EXT4_FEATURE_COMPAT_DIR_INDEX		0x0020
 #define EXT4_FEATURE_COMPAT_SPARSE_SUPER2	0x0200
+#define EXT4_FEATURE_COMPAT_STABLE_INODES	0x0800
 
 #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER	0x0001
 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE	0x0002
@@ -1779,6 +1780,7 @@  EXT4_FEATURE_COMPAT_FUNCS(xattr,		EXT_ATTR)
 EXT4_FEATURE_COMPAT_FUNCS(resize_inode,		RESIZE_INODE)
 EXT4_FEATURE_COMPAT_FUNCS(dir_index,		DIR_INDEX)
 EXT4_FEATURE_COMPAT_FUNCS(sparse_super2,	SPARSE_SUPER2)
+EXT4_FEATURE_COMPAT_FUNCS(stable_inodes,	STABLE_INODES)
 
 EXT4_FEATURE_RO_COMPAT_FUNCS(sparse_super,	SPARSE_SUPER)
 EXT4_FEATURE_RO_COMPAT_FUNCS(large_file,	LARGE_FILE)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index dd654e53ba3d9..b3cbf8622eab6 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1345,6 +1345,18 @@  static bool ext4_dummy_context(struct inode *inode)
 	return DUMMY_ENCRYPTION_ENABLED(EXT4_SB(inode->i_sb));
 }
 
+static bool ext4_has_stable_inodes(struct super_block *sb)
+{
+	return ext4_has_feature_stable_inodes(sb);
+}
+
+static void ext4_get_ino_and_lblk_bits(struct super_block *sb,
+				       int *ino_bits_ret, int *lblk_bits_ret)
+{
+	*ino_bits_ret = 8 * sizeof(EXT4_SB(sb)->s_es->s_inodes_count);
+	*lblk_bits_ret = 8 * sizeof(ext4_lblk_t);
+}
+
 static const struct fscrypt_operations ext4_cryptops = {
 	.key_prefix		= "ext4:",
 	.get_context		= ext4_get_context,
@@ -1352,6 +1364,8 @@  static const struct fscrypt_operations ext4_cryptops = {
 	.dummy_context		= ext4_dummy_context,
 	.empty_dir		= ext4_empty_dir,
 	.max_namelen		= EXT4_NAME_LEN,
+	.has_stable_inodes	= ext4_has_stable_inodes,
+	.get_ino_and_lblk_bits	= ext4_get_ino_and_lblk_bits,
 };
 #endif