[lvc-project] [PATCH 1/3] ext2: reject out-of-range block_group in ext2_free_blocks()
Denis Zubov
d.zubov at tssltd.ru
Tue May 12 15:22:13 MSK 2026
On a corrupt ext2 image, ext2_free_blocks() can compute block_group
beyond sbi->s_groups_count from an on-disk block pointer recovered
during inode eviction. ext2_get_group_desc() then issues a WARN; with
panic_on_warn set this panics the kernel:
WARNING: CPU: 0 PID: 207 at fs/ext2/balloc.c:49 ext2_get_group_desc+0x1f1/0x280
block_group >= groups_count - block_group = 1, groups_count = 1
...
read_block_bitmap+0x26/0x870
ext2_free_blocks+0x30b/0xaf0
__ext2_truncate_blocks+0xa0a/0xc90
ext2_evict_inode+0x3c3/0x500
...
ext2_mkdir+0x1b8/0x240
Validate block_group before calling read_block_bitmap() and log via
ext2_error().
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: 8b91582500ae ("ext2: retry block allocation if new blocks are allocated from system zone")
Signed-off-by: Denis Zubov <d.zubov at tssltd.ru>
---
fs/ext2/balloc.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index b8cfab8f98b9..bc181aa47265 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -509,6 +509,14 @@ void ext2_free_blocks(struct inode * inode, ext2_fsblk_t block,
EXT2_BLOCKS_PER_GROUP(sb);
bit = (block - le32_to_cpu(es->s_first_data_block)) %
EXT2_BLOCKS_PER_GROUP(sb);
+
+ if (block_group >= sbi->s_groups_count) {
+ ext2_error(sb, "ext2_free_blocks",
+ "Freeing blocks in non-existent group %lu (groups_count = %lu): block = %llu, count = %lu",
+ block_group, sbi->s_groups_count,
+ (unsigned long long)block, count);
+ goto error_return;
+ }
/*
* Check to see if we are freeing blocks across a group
* boundary.
--
2.53.0
More information about the lvc-project
mailing list