* [PATCH 0/4] ext4: support encryption with block size larger than page size
@ 2026-11-03 15:31 Baokun Li
2026-11-03 15:31 ` [PATCH 1/4] fscrypt: Cap data units at the " Baokun Li
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Baokun Li @ 2026-11-03 15:31 UTC (permalink / raw)
To: linux-fscrypt
Cc: ebiggers, jaegeuk, tytso, linux-ext4, adilger.kernel, jack,
yi.zhang, ojaswin, ritesh.list, linux-kernel
Motivation
==========
Currently ext4 refuses encryption on a filesystem whose block size
is larger than page size. The reason is in the fallback path:
fscrypt takes the fs block size as the default data unit size,
while blk-crypto-fallback supports no data unit larger than a page.
fscrypt already supports a data unit size smaller than the block size.
So when none is specified, taking the smaller of the block size and the
page size as the data unit size is enough for fscrypt to support LBS.
Based on v7.4-rc1.
Patch Overview
==============
Patch 1: Caps the default data unit at the page size and rejects the
policies that would exceed it.
Patch 2: Validates the test_dummy_encryption policy before applying it.
Patch 3: Sends a folio that covers a DUN wraparound to the buffer_head
path.
Patch 4: Removes the block size > page size checks and enables large
folios for encrypted files.
Testing
=======
kvm-xfstests -c ext4/all -g auto has been executed with no new failures.
On ext4/32k, two groups of tests fail because they are not adapted, and
no other regressions were observed:
- the tests that use v1 policies: ext4/024, generic/395, 397, 398, 399,
419, 421, 429, 440, 576, 580, 581, 593, 613.
- the tests that don't explicitly set the data unit size (generic/582,
583, 584): the kernel gets a 4K data unit by default on a 4K-page
machine while the tests still use the block size.
With the xfstests fix, the first group is skipped and the second group
passes. The fix will be sent separately.
Benchmark
=========
Hardware: 96-core machine, 3.84T NVMe, 512G memory
Filesystem: ext4, encryption on the fallback path
Buffered sequential 1M writes and reads (1G, fsync) in MiB/s;
medians of 3 runs.
Base tree, 4k-block filesystem:
job 4k plain 4k enc
-------- -------- ------
seqwrite 1969 1418
seqread 1021 907
LBS enabled, encrypted 4k-block vs 32k-block filesystem:
job 4k enc 32k enc 32k plain 4k->32k
-------- ------ ------- --------- -------
seqwrite 1430 1958 2138 +37%
seqread 964 2004 1834 +108%
Buffered sequential writes (1G, fsync) of the encrypted 4k-block
filesystem across request sizes, base tree vs this series:
fio bs Before After gain
------ ------ ----- ----
4k 1272 1261 -1%
16k 1457 1803 +24%
64k 1499 2060 +37%
256k 1488 2103 +41%
1M 1418 1928 +36%
Comments and questions are, as always, welcome.
Thanks,
Baokun
Baokun Li (4):
fscrypt: Cap data units at the page size
fscrypt: Validate the test_dummy_encryption policy for new inodes
ext4: don't put a DUN wraparound in the middle of a read bio
ext4: allow large folios and bs > ps encryption
Documentation/filesystems/fscrypt.rst | 19 +++++++++++++++----
fs/crypto/fscrypt_private.h | 4 +++-
fs/crypto/keysetup.c | 8 ++++++++
fs/crypto/policy.c | 11 ++++++++++-
fs/ext4/crypto.c | 9 ---------
fs/ext4/inode.c | 6 ------
fs/ext4/readpage.c | 10 ++++++++++
fs/ext4/super.c | 22 +---------------------
8 files changed, 47 insertions(+), 42 deletions(-)
--
2.43.7
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/4] fscrypt: Cap data units at the page size
2026-11-03 15:31 [PATCH 0/4] ext4: support encryption with block size larger than page size Baokun Li
@ 2026-11-03 15:31 ` Baokun Li
2026-11-03 15:44 ` sashiko-bot
2026-11-03 15:31 ` [PATCH 2/4] fscrypt: Validate the test_dummy_encryption policy for new inodes Baokun Li
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Baokun Li @ 2026-11-03 15:31 UTC (permalink / raw)
To: linux-fscrypt
Cc: ebiggers, jaegeuk, tytso, linux-ext4, adilger.kernel, jack,
yi.zhang, ojaswin, ritesh.list, linux-kernel
blk-crypto-fallback cannot handle a data unit larger than a page:
it walks the bio one page-sized segment at a time, so a data unit
that spans multiple pages never ends on a segment boundary and
the bio fails with BLK_STS_INVAL after the I/O was already
reported to userspace as successful, losing data.
Fix this in fscrypt_supported_v2_policy() by rejecting any v2 policy
that explicitly specifies a data unit size larger than the page size.
A v1 policy always uses the block size as its data unit size,
so fscrypt_supported_v1_policy() has to reject any v1 policy on
a filesystem with a block size larger than the page size (e.g. ext4).
A v2 policy with no data unit size specified uses the block size too,
but rejection is not necessary there: sub-block data units are
supported, so it is enough to cap the data unit bits at PAGE_SHIFT in
fscrypt_policy_v2_du_bits().
Note that a filesystem whose block size exceeds 4K then cannot be
made compatible across page sizes (e.g. 4K and 64K); this can be
avoided by explicitly specifying a data unit size of 4K or smaller.
Suggested-by: Eric Biggers <ebiggers@kernel.org>
Link: https://lore.kernel.org/r/20261015185325.GG2170687@google.com
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
---
Documentation/filesystems/fscrypt.rst | 19 +++++++++++++++----
fs/crypto/fscrypt_private.h | 4 +++-
fs/crypto/policy.c | 11 ++++++++++-
3 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
index 6e2e511a70bb..78251a9706ba 100644
--- a/Documentation/filesystems/fscrypt.rst
+++ b/Documentation/filesystems/fscrypt.rst
@@ -649,8 +649,9 @@ This structure must be initialized as follows:
Not all filesystems support setting ``log2_data_unit_size``. ext4
and f2fs support it since Linux v6.7. On filesystems that support
it, the supported nonzero values are 9 through the log2 of the
- filesystem block size, inclusively. The default value of 0 selects
- the filesystem block size.
+ filesystem block size, inclusively, but no greater than the log2 of
+ the page size. The default value of 0 selects the filesystem block
+ size, or the page size if the block size is larger.
The main use case for ``log2_data_unit_size`` is for selecting a
data unit size smaller than the filesystem block size for
@@ -659,8 +660,18 @@ This structure must be initialized as follows:
useful for checking which data unit sizes are supported by a
particular system's inline encryption hardware.
- Leave this field zeroed unless you are certain you need it. Using
- an unnecessarily small data unit size reduces performance.
+ A v1 policy has no ``log2_data_unit_size`` and always uses the
+ filesystem block size, so it cannot be used on a filesystem whose
+ block size is larger than the page size.
+
+ A v2 policy on such a filesystem falls back to the page size, so
+ the data unit size depends on the machine's page size and the data
+ becomes unreadable elsewhere. An image portable across page sizes
+ should explicitly specify a data unit size of 4096 or smaller.
+
+ Leave this field zeroed unless you are certain one of the reasons
+ above applies. Using an unnecessarily small data unit size reduces
+ performance.
- For v2 encryption policies, ``__reserved`` must be zeroed.
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index e602c31b3844..0dc158563e71 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -203,7 +203,9 @@ static inline int
fscrypt_policy_v2_du_bits(const struct fscrypt_policy_v2 *policy,
const struct inode *inode)
{
- return policy->log2_data_unit_size ?: inode->i_blkbits;
+ if (policy->log2_data_unit_size)
+ return policy->log2_data_unit_size;
+ return min_t(unsigned int, inode->i_blkbits, PAGE_SHIFT);
}
static inline int
diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c
index 6dd510f93e6d..84c496da248e 100644
--- a/fs/crypto/policy.c
+++ b/fs/crypto/policy.c
@@ -228,6 +228,14 @@ static bool fscrypt_supported_v1_policy(const struct fscrypt_policy_v1 *policy,
return false;
}
+ if (inode->i_sb->s_cop->is_block_based &&
+ inode->i_blkbits > PAGE_SHIFT) {
+ /* v1 has no way to select a sub-block data unit size. */
+ fscrypt_warn(inode,
+ "v1 policies can't be used on fs with block size > page size");
+ return false;
+ }
+
return true;
}
@@ -270,7 +278,8 @@ static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy,
return false;
}
if (policy->log2_data_unit_size > inode->i_blkbits ||
- policy->log2_data_unit_size < SECTOR_SHIFT /* 9 */) {
+ policy->log2_data_unit_size < SECTOR_SHIFT /* 9 */ ||
+ policy->log2_data_unit_size > PAGE_SHIFT) {
fscrypt_warn(inode,
"Unsupported log2_data_unit_size in encryption policy: %d",
policy->log2_data_unit_size);
--
2.43.7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/4] fscrypt: Validate the test_dummy_encryption policy for new inodes
2026-11-03 15:31 [PATCH 0/4] ext4: support encryption with block size larger than page size Baokun Li
2026-11-03 15:31 ` [PATCH 1/4] fscrypt: Cap data units at the " Baokun Li
@ 2026-11-03 15:31 ` Baokun Li
2026-11-03 15:45 ` sashiko-bot
2026-11-03 15:31 ` [PATCH 3/4] ext4: don't put a DUN wraparound in the middle of a read bio Baokun Li
2026-11-03 15:31 ` [PATCH 4/4] ext4: allow large folios and bs > ps encryption Baokun Li
3 siblings, 1 reply; 9+ messages in thread
From: Baokun Li @ 2026-11-03 15:31 UTC (permalink / raw)
To: linux-fscrypt
Cc: ebiggers, jaegeuk, tytso, linux-ext4, adilger.kernel, jack,
yi.zhang, ojaswin, ritesh.list, linux-kernel
Policies set through FS_IOC_SET_ENCRYPTION_POLICY or inherited from
an encrypted directory are validated, but the test_dummy_encryption
policy is not.
fscrypt_prepare_new_inode() applies it directly to the new inode.
As a result, a v1 dummy policy on a filesystem whose block size
exceeds the page size is used unchecked, and data written under
it is lost at writeback.
Fix this by validating dummy policy in fscrypt_prepare_new_inode()
before applying it. Inodes in an encrypted directory inherit an
already validated policy, so the check only concerns the unencrypted
case where the dummy policy is used.
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
---
fs/crypto/keysetup.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c
index a77b889d7578..497ba67ec6fe 100644
--- a/fs/crypto/keysetup.c
+++ b/fs/crypto/keysetup.c
@@ -763,6 +763,14 @@ int fscrypt_prepare_new_inode(struct inode *dir, struct inode *inode,
!S_ISLNK(inode->i_mode))
return 0;
+ /*
+ * A policy inherited from an encrypted directory was validated
+ * when the directory's key was set up. The test dummy policy was
+ * not, so check it here.
+ */
+ if (!IS_ENCRYPTED(dir) && !fscrypt_supported_policy(policy, inode))
+ return -EINVAL;
+
*encrypt_ret = true;
get_random_bytes(nonce, FSCRYPT_FILE_NONCE_SIZE);
--
2.43.7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/4] ext4: don't put a DUN wraparound in the middle of a read bio
2026-11-03 15:31 [PATCH 0/4] ext4: support encryption with block size larger than page size Baokun Li
2026-11-03 15:31 ` [PATCH 1/4] fscrypt: Cap data units at the " Baokun Li
2026-11-03 15:31 ` [PATCH 2/4] fscrypt: Validate the test_dummy_encryption policy for new inodes Baokun Li
@ 2026-11-03 15:31 ` Baokun Li
2026-11-03 15:40 ` sashiko-bot
2026-11-03 15:31 ` [PATCH 4/4] ext4: allow large folios and bs > ps encryption Baokun Li
3 siblings, 1 reply; 9+ messages in thread
From: Baokun Li @ 2026-11-03 15:31 UTC (permalink / raw)
To: linux-fscrypt
Cc: ebiggers, jaegeuk, tytso, linux-ext4, adilger.kernel, jack,
yi.zhang, ojaswin, ritesh.list, linux-kernel
Under IV_INO_LBLK_32, a file's DUNs wrap at 2^32, and the policy
is only allowed when the block size equals the page size.
ext4_mpage_readpages() adds a whole folio to one bio, but checks
only the DUN of the first block. blk-crypto assumes the DUNs
in a bio are contiguous and never wraps them, so blocks past
the wraparound are read with the wrong DUNs.
Writeback and direct I/O get this right, but with large folios
a single folio can still span the wraparound.
Fix this by routing such a folio through the buffer_head path,
which submits one bio per block and so gives each block its own DUN.
fscrypt_limit_io_blocks() tells whether the wraparound falls after
the first block; a wraparound at the first block itself is already
caught by fscrypt_mergeable_bio().
A file's DUNs wrap at most once, so at most one folio per file takes
the slower path, and the per-block bios can be merged again by the
block layer.
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
---
fs/ext4/readpage.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
index c7b6cdb2e124..43af6d9d6ddb 100644
--- a/fs/ext4/readpage.c
+++ b/fs/ext4/readpage.c
@@ -264,6 +264,16 @@ static int ext4_mpage_readpages(struct inode *inode, struct fsverity_info *vi,
folio_set_mappedtodisk(folio);
}
+ /*
+ * blk-crypto assumes a bio's DUNs are contiguous, but under
+ * IV_INO_LBLK_32 alone they wrap at 2^32. A folio spanning
+ * the wrap would be decrypted with wrong IVs, so it goes to
+ * the buffer_head-based path, one bio per block.
+ */
+ if (first_hole >
+ fscrypt_limit_io_blocks(inode, pos >> blkbits, first_hole))
+ goto confused;
+
/*
* This folio will go to BIO. Do we need to send this
* BIO off first?
--
2.43.7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/4] ext4: allow large folios and bs > ps encryption
2026-11-03 15:31 [PATCH 0/4] ext4: support encryption with block size larger than page size Baokun Li
` (2 preceding siblings ...)
2026-11-03 15:31 ` [PATCH 3/4] ext4: don't put a DUN wraparound in the middle of a read bio Baokun Li
@ 2026-11-03 15:31 ` Baokun Li
2026-11-03 15:42 ` sashiko-bot
3 siblings, 1 reply; 9+ messages in thread
From: Baokun Li @ 2026-11-03 15:31 UTC (permalink / raw)
To: linux-fscrypt
Cc: ebiggers, jaegeuk, tytso, linux-ext4, adilger.kernel, jack,
yi.zhang, ojaswin, ritesh.list, linux-kernel
ext4 refuses encryption when the block size exceeds the page size
in three places: at mount time (ext4_check_large_folio()),
in ext4_set_context(), and in __ext4_iget().
Sub-block data units are now enabled by default, so encryption
works on a filesystem whose block size exceeds the page size.
Remove the three checks; stable trees should keep them and
not backport this feature.
ext4_set_max_mapping_order() now runs on every mount, and
the preceding patch routes a folio that crosses a DUN wraparound
to the buffer_head path. Encrypted files therefore get the same
large folio orders as unencrypted files, including when block size
is larger than page size.
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
---
fs/ext4/crypto.c | 9 ---------
fs/ext4/inode.c | 6 ------
fs/ext4/super.c | 22 +---------------------
3 files changed, 1 insertion(+), 36 deletions(-)
diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
index 318b2eaea741..1a0fccb084ef 100644
--- a/fs/ext4/crypto.c
+++ b/fs/ext4/crypto.c
@@ -156,15 +156,6 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
if (ext4_test_inode_flag(inode, EXT4_INODE_DAX))
return -EOPNOTSUPP;
- /*
- * Encryption is not supported when the block size is larger
- * than the page size. This is rejected at mount time by
- * ext4_check_large_folio(), and this check here is for the case
- * when the 'encrypt' feature is enabled on a mounted filesystem.
- */
- if (inode->i_sb->s_blocksize > PAGE_SIZE)
- return -EOPNOTSUPP;
-
res = ext4_convert_inline_data(inode);
if (res)
return res;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 10cd85d4c721..b4d581aa5ee1 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -6571,12 +6571,6 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
ret = -EFSCORRUPTED;
goto bad_inode;
}
- if (IS_ENCRYPTED(inode) && sb->s_blocksize > PAGE_SIZE) {
- ext4_error_inode(inode, function, line, 0,
- "encrypted inode with block size larger than page size");
- ret = -EFSCORRUPTED;
- goto bad_inode;
- }
ext4_set_inode_mapping_order(inode);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 9cae52471dee..ba2d2e184d3a 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5165,24 +5165,6 @@ static void ext4_set_max_mapping_order(struct super_block *sb)
sbi->s_max_folio_order = EXT4_MAX_PAGECACHE_ORDER(sb);
}
-static int ext4_check_large_folio(struct super_block *sb)
-{
- const char *err_str = NULL;
-
- if (ext4_has_feature_encrypt(sb))
- err_str = "encrypt";
-
- if (!err_str) {
- ext4_set_max_mapping_order(sb);
- } else if (sb->s_blocksize > PAGE_SIZE) {
- ext4_msg(sb, KERN_ERR, "bs(%lu) > ps(%lu) unsupported for %s",
- sb->s_blocksize, PAGE_SIZE, err_str);
- return -EINVAL;
- }
-
- return 0;
-}
-
static int ext4_load_super(struct super_block *sb, ext4_fsblk_t *lsb,
int silent)
{
@@ -5461,9 +5443,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
ext4_apply_options(fc, sb);
- err = ext4_check_large_folio(sb);
- if (err < 0)
- goto failed_mount;
+ ext4_set_max_mapping_order(sb);
err = ext4_encoding_init(sb, es);
if (err)
--
2.43.7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 3/4] ext4: don't put a DUN wraparound in the middle of a read bio
2026-11-03 15:31 ` [PATCH 3/4] ext4: don't put a DUN wraparound in the middle of a read bio Baokun Li
@ 2026-11-03 15:40 ` sashiko-bot
0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-11-03 15:40 UTC (permalink / raw)
To: Baokun Li; +Cc: linux-ext4, tytso
> Under IV_INO_LBLK_32, a file's DUNs wrap at 2^32, and the policy
> is only allowed when the block size equals the page size.
>
> ext4_mpage_readpages() adds a whole folio to one bio, but checks
> only the DUN of the first block. blk-crypto assumes the DUNs
> in a bio are contiguous and never wraps them, so blocks past
> the wraparound are read with the wrong DUNs.
>
> Writeback and direct I/O get this right, but with large folios
> a single folio can still span the wraparound.
>
> Fix this by routing such a folio through the buffer_head path,
> which submits one bio per block and so gives each block its own DUN.
>
> fscrypt_limit_io_blocks() tells whether the wraparound falls after
> the first block; a wraparound at the first block itself is already
> caught by fscrypt_mergeable_bio().
>
> A file's DUNs wrap at most once, so at most one folio per file takes
> the slower path, and the per-block bios can be merged again by the
> block layer.
>
> Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261103153132.4154855-1-libaokun@linux.alibaba.com?part=3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 4/4] ext4: allow large folios and bs > ps encryption
2026-11-03 15:31 ` [PATCH 4/4] ext4: allow large folios and bs > ps encryption Baokun Li
@ 2026-11-03 15:42 ` sashiko-bot
0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-11-03 15:42 UTC (permalink / raw)
To: Baokun Li; +Cc: linux-ext4, tytso
> ext4 refuses encryption when the block size exceeds the page size
> in three places: at mount time (ext4_check_large_folio()),
> in ext4_set_context(), and in __ext4_iget().
>
> Sub-block data units are now enabled by default, so encryption
> works on a filesystem whose block size exceeds the page size.
> Remove the three checks; stable trees should keep them and
> not backport this feature.
>
> ext4_set_max_mapping_order() now runs on every mount, and
> the preceding patch routes a folio that crosses a DUN wraparound
> to the buffer_head path. Encrypted files therefore get the same
> large folio orders as unencrypted files, including when block size
> is larger than page size.
>
> Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261103153132.4154855-1-libaokun@linux.alibaba.com?part=4
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/4] fscrypt: Cap data units at the page size
2026-11-03 15:31 ` [PATCH 1/4] fscrypt: Cap data units at the " Baokun Li
@ 2026-11-03 15:44 ` sashiko-bot
0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-11-03 15:44 UTC (permalink / raw)
To: Baokun Li; +Cc: linux-ext4, tytso
> blk-crypto-fallback cannot handle a data unit larger than a page:
> it walks the bio one page-sized segment at a time, so a data unit
> that spans multiple pages never ends on a segment boundary and
> the bio fails with BLK_STS_INVAL after the I/O was already
> reported to userspace as successful, losing data.
>
> Fix this in fscrypt_supported_v2_policy() by rejecting any v2 policy
> that explicitly specifies a data unit size larger than the page size.
>
> A v1 policy always uses the block size as its data unit size,
> so fscrypt_supported_v1_policy() has to reject any v1 policy on
> a filesystem with a block size larger than the page size (e.g. ext4).
>
> A v2 policy with no data unit size specified uses the block size too,
> but rejection is not necessary there: sub-block data units are
> supported, so it is enough to cap the data unit bits at PAGE_SHIFT in
> fscrypt_policy_v2_du_bits().
>
> Note that a filesystem whose block size exceeds 4K then cannot be
> made compatible across page sizes (e.g. 4K and 64K); this can be
> avoided by explicitly specifying a data unit size of 4K or smaller.
>
> Suggested-by: Eric Biggers <ebiggers@kernel.org>
> Link: https://lore.kernel.org/r/20261015185325.GG2170687@google.com
> Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261103153132.4154855-1-libaokun@linux.alibaba.com?part=1
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/4] fscrypt: Validate the test_dummy_encryption policy for new inodes
2026-11-03 15:31 ` [PATCH 2/4] fscrypt: Validate the test_dummy_encryption policy for new inodes Baokun Li
@ 2026-11-03 15:45 ` sashiko-bot
0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-11-03 15:45 UTC (permalink / raw)
To: Baokun Li, linux-fscrypt
Cc: ebiggers, jaegeuk, tytso, linux-ext4, adilger.kernel, jack,
yi.zhang, ojaswin, ritesh.list
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] fscrypt: missed S_CASEFOLD check in fscrypt_prepare_new_inode()
--
commit fa704dc171d6c1edb5f7cea48ff46447da451c52
Author: Baokun Li <libaokun@linux.alibaba.com>
fscrypt: Validate the test_dummy_encryption policy for new inodes
This commit validates the test_dummy_encryption policy in
fscrypt_prepare_new_inode() when creating a new inode in an unencrypted
directory so that unsupported policies are rejected before being applied.
> diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c
> index a77b889d7578c..497ba67ec6fed 100644
> --- a/fs/crypto/keysetup.c
> +++ b/fs/crypto/keysetup.c
> @@ -763,6 +763,14 @@ int fscrypt_prepare_new_inode(struct inode *dir, struct inode *inode,
> !S_ISLNK(inode->i_mode))
> return 0;
>
> + /*
> + * A policy inherited from an encrypted directory was validated
> + * when the directory's key was set up. The test dummy policy was
> + * not, so check it here.
> + */
> + if (!IS_ENCRYPTED(dir) && !fscrypt_supported_policy(policy, inode))
> + return -EINVAL;
[Severity: Medium]
Does fscrypt_supported_policy(policy, inode) miss the casefold check when
creating a new subdirectory inside an unencrypted, casefolded directory with
test_dummy_encryption=v1?
When fscrypt_prepare_new_inode() is called by __ext4_new_inode() or
f2fs_new_inode(), only inode->i_mode and inode->i_blkbits are set on the new
inode. The filesystem has not yet inherited the casefold flag from dir or set
S_CASEFOLD on inode->i_flags, which is why fscrypt_prepare_new_inode() checks
IS_CASEFOLDED(dir) && S_ISDIR(inode->i_mode) just below:
return fscrypt_setup_encryption_info(inode, policy, nonce,
IS_CASEFOLDED(dir) &&
S_ISDIR(inode->i_mode));
However, fscrypt_supported_policy() -> fscrypt_supported_v1_policy() checks
IS_CASEFOLDED(inode):
if (IS_CASEFOLDED(inode)) {
/* With v1, there's no way to derive dirhash keys. */
fscrypt_warn(inode,
"v1 policies can't be used on casefolded directories");
return false;
}
Since IS_CASEFOLDED(inode) is still false at this point, creating a
subdirectory in an unencrypted casefolded directory under
test_dummy_encryption=v1 passes validation and creates a v1-encrypted,
casefolded directory without an initialized dirhash key, triggering
WARN_ON_ONCE(!ci->ci_dirhash_key_initialized) in fscrypt_fname_siphash() on
subsequent lookups or creations.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261103153132.4154855-1-libaokun@linux.alibaba.com?part=2
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-11-03 15:45 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-03 15:31 [PATCH 0/4] ext4: support encryption with block size larger than page size Baokun Li
2026-11-03 15:31 ` [PATCH 1/4] fscrypt: Cap data units at the " Baokun Li
2026-11-03 15:44 ` sashiko-bot
2026-11-03 15:31 ` [PATCH 2/4] fscrypt: Validate the test_dummy_encryption policy for new inodes Baokun Li
2026-11-03 15:45 ` sashiko-bot
2026-11-03 15:31 ` [PATCH 3/4] ext4: don't put a DUN wraparound in the middle of a read bio Baokun Li
2026-11-03 15:40 ` sashiko-bot
2026-11-03 15:31 ` [PATCH 4/4] ext4: allow large folios and bs > ps encryption Baokun Li
2026-11-03 15:42 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox