* [PATCH] ext4: reject mount if clusters/inodes per group are not 8-aligned
@ 2026-06-08 6:11 Baokun Li
[not found] ` <20260608063318.266E61F00893@smtp.kernel.org>
2026-06-09 10:43 ` Jan Kara
0 siblings, 2 replies; 3+ messages in thread
From: Baokun Li @ 2026-06-08 6:11 UTC (permalink / raw)
To: linux-ext4
Cc: tytso, adilger.kernel, jack, yi.zhang, ojaswin, ritesh.list,
Sashiko
The block and inode bitmap checksums are computed over a whole number of
bytes: ext4_inode_bitmap_csum_*() use EXT4_INODES_PER_GROUP(sb) >> 3 and
ext4_block_bitmap_csum_*() use EXT4_CLUSTERS_PER_GROUP(sb) / 8 as the
length passed to ext4_chksum().
If s_inodes_per_group or s_clusters_per_group is not a multiple of 8, the
trailing fractional bits are excluded from the checksum. Those bits are
then unprotected, and any incremental csum update path that assumes a
byte-aligned bitmap can compute a checksum inconsistent with the full
recalculation, corrupting the on-disk bitmap checksum.
Reject such filesystems at mount time by adding the missing " & 7"
alignment checks alongside the existing range validation.
Suggested-by: Theodore Ts'o <tytso@mit.edu>
Link: https://patch.msgid.link/h3n7jlfhyna64dn5o76qxcspnhxdddcs6crpxftmy7gnl7b3sx@jenszfpcsnit
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260508121539.4174601-1-libaokun%40linux.alibaba.com?part=10
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
---
fs/ext4/super.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 6a77db4d3124..3daf4cdcf07e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4472,8 +4472,9 @@ static int ext4_handle_clustersize(struct super_block *sb)
sbi->s_cluster_bits = 0;
}
sbi->s_clusters_per_group = le32_to_cpu(es->s_clusters_per_group);
- if (sbi->s_clusters_per_group > sb->s_blocksize * 8) {
- ext4_msg(sb, KERN_ERR, "#clusters per group too big: %lu",
+ if (sbi->s_clusters_per_group > sb->s_blocksize * 8 ||
+ sbi->s_clusters_per_group & 7) {
+ ext4_msg(sb, KERN_ERR, "invalid #clusters per group: %lu",
sbi->s_clusters_per_group);
return -EINVAL;
}
@@ -5304,7 +5305,8 @@ static int ext4_block_group_meta_init(struct super_block *sb, int silent)
return -EINVAL;
}
if (sbi->s_inodes_per_group < sbi->s_inodes_per_block ||
- sbi->s_inodes_per_group > sb->s_blocksize * 8) {
+ sbi->s_inodes_per_group > sb->s_blocksize * 8 ||
+ sbi->s_inodes_per_group & 7) {
ext4_msg(sb, KERN_ERR, "invalid inodes per group: %lu\n",
sbi->s_inodes_per_group);
return -EINVAL;
--
2.43.7
^ permalink raw reply related [flat|nested] 3+ messages in thread[parent not found: <20260608063318.266E61F00893@smtp.kernel.org>]
* Re: [PATCH] ext4: reject mount if clusters/inodes per group are not 8-aligned
[not found] ` <20260608063318.266E61F00893@smtp.kernel.org>
@ 2026-06-08 11:21 ` Baokun Li
0 siblings, 0 replies; 3+ messages in thread
From: Baokun Li @ 2026-06-08 11:21 UTC (permalink / raw)
To: sashiko-reviews; +Cc: tytso, Ext4 Developers List
I've sent a V2 that includes two additional patches to address the issues
Sashiko reported:
https://patch.msgid.link/20260608111150.827117-1-libaokun@linux.alibaba.com
Thanks,
Baokun
On 2026/6/8 14:33, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
>
> Pre-existing issues:
> - [Critical] Missing alignment check allows integer truncation in s_itb_per_group, leading to out-of-bounds inode table access and potential local privilege escalation via forged inodes.
> - [High] Integer overflow in bigalloc cluster consistency check on 32-bit systems allows mounting filesystems with arbitrary cross-group overlaps.
> --
>
> commit 063bdba3eb2bd319656b0b2534e820244460e17a
> Author: Baokun Li <libaokun@linux.alibaba.com>
>
> ext4: reject mount if clusters/inodes per group are not 8-aligned
>
> The block and inode bitmap checksums are computed over a whole number of
> bytes. If s_inodes_per_group or s_clusters_per_group is not a multiple of
> 8, the trailing fractional bits are excluded from the checksum. Reject such
> filesystems at mount time by adding the missing bitwise alignment checks.
>
> Link: https://patch.msgid.link/h3n7jlfhyna64dn5o76qxcspnhxdddcs6crpxftmy7gnl7b3sx@jenszfpcsnit
>
>> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
>> index 245f67d10ded3..98f1cefbc6880 100644
>> --- a/fs/ext4/super.c
>> +++ b/fs/ext4/super.c
>> @@ -4475,8 +4475,9 @@ static int ext4_handle_clustersize(struct super_block *sb)
>> sbi->s_cluster_bits = 0;
>> }
>> sbi->s_clusters_per_group = le32_to_cpu(es->s_clusters_per_group);
>> - if (sbi->s_clusters_per_group > sb->s_blocksize * 8) {
>> - ext4_msg(sb, KERN_ERR, "#clusters per group too big: %lu",
>> + if (sbi->s_clusters_per_group > sb->s_blocksize * 8 ||
>> + sbi->s_clusters_per_group & 7) {
>> + ext4_msg(sb, KERN_ERR, "invalid #clusters per group: %lu",
>> sbi->s_clusters_per_group);
>> return -EINVAL;
>> }
> [Severity: High]
> This isn't a bug introduced by this patch, but while we are validating
> s_clusters_per_group, could the bigalloc consistency check slightly below
> this in ext4_handle_clustersize() overflow on 32-bit systems?
>
> The check does:
>
> if (sbi->s_blocks_per_group !=
> (sbi->s_clusters_per_group * (clustersize / sb->s_blocksize))) {
>
> Since unsigned long is 32 bits on 32-bit systems, the multiplication can wrap
> around modulo 2^32. For example, if an image has 16392 clusters and a ratio
> of 262144, the product evaluates to 2^32 + 2097152, matching an
> s_blocks_per_group of 2097152.
>
> Because bigalloc bypasses the usual s_blocks_per_group size limits, the
> wrapped validation would succeed. The block allocator could then allocate
> blocks far outside the truncated group, overwriting metadata of subsequent
> groups. Should this multiplication be cast to a 64-bit type to prevent
> the overflow?
>
> [ ... ]
>
>> @@ -5308,7 +5309,8 @@ static int ext4_block_group_meta_init(struct super_block *sb, int silent)
>> return -EINVAL;
>> }
>> if (sbi->s_inodes_per_group < sbi->s_inodes_per_block ||
>> - sbi->s_inodes_per_group > sb->s_blocksize * 8) {
>> + sbi->s_inodes_per_group > sb->s_blocksize * 8 ||
>> + sbi->s_inodes_per_group & 7) {
>> ext4_msg(sb, KERN_ERR, "invalid inodes per group: %lu\n",
>> sbi->s_inodes_per_group);
>> return -EINVAL;
> [Severity: Critical]
> This is a pre-existing issue, but does adding the & 7 check go far enough
> to prevent integer truncation here?
>
> A few lines below this check in ext4_block_group_meta_init(), the code does:
>
> sbi->s_itb_per_group = sbi->s_inodes_per_group / sbi->s_inodes_per_block;
>
> Since s_inodes_per_group is now guaranteed to be a multiple of 8, but
> s_inodes_per_block can be 16, 32, etc., this division can still truncate.
>
> Could this truncation lead to out-of-bounds accesses? Looking at
> __ext4_get_inode_loc() in fs/ext4/inode.c, the block is calculated without
> checking against the truncated s_itb_per_group:
>
> block += (inode_offset / inodes_per_block);
>
> This could allow reading or writing to the block following the truncated
> inode table, potentially allowing local privilege escalation via forged
> inodes if that block is allocated to a user file. Should we also ensure
> that s_inodes_per_group is a multiple of s_inodes_per_block here?
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] ext4: reject mount if clusters/inodes per group are not 8-aligned
2026-06-08 6:11 [PATCH] ext4: reject mount if clusters/inodes per group are not 8-aligned Baokun Li
[not found] ` <20260608063318.266E61F00893@smtp.kernel.org>
@ 2026-06-09 10:43 ` Jan Kara
1 sibling, 0 replies; 3+ messages in thread
From: Jan Kara @ 2026-06-09 10:43 UTC (permalink / raw)
To: Baokun Li
Cc: linux-ext4, tytso, adilger.kernel, jack, yi.zhang, ojaswin,
ritesh.list, Sashiko
On Mon 08-06-26 14:11:12, Baokun Li wrote:
> The block and inode bitmap checksums are computed over a whole number of
> bytes: ext4_inode_bitmap_csum_*() use EXT4_INODES_PER_GROUP(sb) >> 3 and
> ext4_block_bitmap_csum_*() use EXT4_CLUSTERS_PER_GROUP(sb) / 8 as the
> length passed to ext4_chksum().
>
> If s_inodes_per_group or s_clusters_per_group is not a multiple of 8, the
> trailing fractional bits are excluded from the checksum. Those bits are
> then unprotected, and any incremental csum update path that assumes a
> byte-aligned bitmap can compute a checksum inconsistent with the full
> recalculation, corrupting the on-disk bitmap checksum.
>
> Reject such filesystems at mount time by adding the missing " & 7"
> alignment checks alongside the existing range validation.
>
> Suggested-by: Theodore Ts'o <tytso@mit.edu>
> Link: https://patch.msgid.link/h3n7jlfhyna64dn5o76qxcspnhxdddcs6crpxftmy7gnl7b3sx@jenszfpcsnit
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Closes: https://sashiko.dev/#/patchset/20260508121539.4174601-1-libaokun%40linux.alibaba.com?part=10
> Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
Looks good. Feel free to add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
> ---
> fs/ext4/super.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index 6a77db4d3124..3daf4cdcf07e 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -4472,8 +4472,9 @@ static int ext4_handle_clustersize(struct super_block *sb)
> sbi->s_cluster_bits = 0;
> }
> sbi->s_clusters_per_group = le32_to_cpu(es->s_clusters_per_group);
> - if (sbi->s_clusters_per_group > sb->s_blocksize * 8) {
> - ext4_msg(sb, KERN_ERR, "#clusters per group too big: %lu",
> + if (sbi->s_clusters_per_group > sb->s_blocksize * 8 ||
> + sbi->s_clusters_per_group & 7) {
> + ext4_msg(sb, KERN_ERR, "invalid #clusters per group: %lu",
> sbi->s_clusters_per_group);
> return -EINVAL;
> }
> @@ -5304,7 +5305,8 @@ static int ext4_block_group_meta_init(struct super_block *sb, int silent)
> return -EINVAL;
> }
> if (sbi->s_inodes_per_group < sbi->s_inodes_per_block ||
> - sbi->s_inodes_per_group > sb->s_blocksize * 8) {
> + sbi->s_inodes_per_group > sb->s_blocksize * 8 ||
> + sbi->s_inodes_per_group & 7) {
> ext4_msg(sb, KERN_ERR, "invalid inodes per group: %lu\n",
> sbi->s_inodes_per_group);
> return -EINVAL;
> --
> 2.43.7
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-06-09 10:43 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-08 6:11 [PATCH] ext4: reject mount if clusters/inodes per group are not 8-aligned Baokun Li
[not found] ` <20260608063318.266E61F00893@smtp.kernel.org>
2026-06-08 11:21 ` Baokun Li
2026-06-09 10:43 ` Jan Kara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox