Re: [PATCH 6.6.y] ext4: validate p_idx bounds in ext4_ext_correct_indexes
From: Andreas Dilger
Date: Fri May 08 2026 - 04:11:50 EST
On May 8, 2026, at 00:58, Jianqiang kang <jianqkang@xxxxxxx> wrote:
>
> From: Tejas Bharambe <tejas.bharambe@xxxxxxxxxxx>
>
> [ Upstream commit 2acb5c12ebd860f30e4faf67e6cc8c44ddfe5fe8 ]
>
> ext4_ext_correct_indexes() walks up the extent tree correcting
> index entries when the first extent in a leaf is modified. Before
> accessing path[k].p_idx->ei_block, there is no validation that
> p_idx falls within the valid range of index entries for that
> level.
>
> If the on-disk extent header contains a corrupted or crafted
> eh_entries value, p_idx can point past the end of the allocated
> buffer, causing a slab-out-of-bounds read.
>
> Fix this by validating path[k].p_idx against EXT_LAST_INDEX() at
> both access sites: before the while loop and inside it. Return
> -EFSCORRUPTED if the index pointer is out of range, consistent
> with how other bounds violations are handled in the ext4 extent
> tree code.
Thank you for your patch.
Do you have an image with this corruption in place? Does e2fsck fix
the issue? If not, then ext4 will abort the filesystem when this issue
is hit, and if e2fsck can't fix it then it will just be hit again.
Cheers, Andreas
> Reported-by: syzbot+04c4e65cab786a2e5b7e@xxxxxxxxxxxxxxxxxxxxxxxxx
> Closes: https://syzkaller.appspot.com/bug?extid=04c4e65cab786a2e5b7e
> Signed-off-by: Tejas Bharambe <tejas.bharambe@xxxxxxxxxxx>
> Link: https://patch.msgid.link/JH0PR06MB66326016F9B6AD24097D232B897CA@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Signed-off-by: Theodore Ts'o <tytso@xxxxxxx>
> Cc: stable@xxxxxxxxxx
> [ Minor conflict resolved. ]
> Signed-off-by: Jianqiang kang <jianqkang@xxxxxxx>
> ---
> fs/ext4/extents.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
> index 7626cf2b07f1..a94798e23c1a 100644
> --- a/fs/ext4/extents.c
> +++ b/fs/ext4/extents.c
> @@ -1743,6 +1743,13 @@ static int ext4_ext_correct_indexes(handle_t *handle,
> err = ext4_ext_get_access(handle, inode, path + k);
> if (err)
> return err;
> + if (unlikely(path[k].p_idx > EXT_LAST_INDEX(path[k].p_hdr))) {
> + EXT4_ERROR_INODE(inode,
> + "path[%d].p_idx %p > EXT_LAST_INDEX %p",
> + k, path[k].p_idx,
> + EXT_LAST_INDEX(path[k].p_hdr));
> + return -EFSCORRUPTED;
> + }
> path[k].p_idx->ei_block = border;
> err = ext4_ext_dirty(handle, inode, path + k);
> if (err)
> @@ -1755,6 +1762,14 @@ static int ext4_ext_correct_indexes(handle_t *handle,
> err = ext4_ext_get_access(handle, inode, path + k);
> if (err)
> break;
> + if (unlikely(path[k].p_idx > EXT_LAST_INDEX(path[k].p_hdr))) {
> + EXT4_ERROR_INODE(inode,
> + "path[%d].p_idx %p > EXT_LAST_INDEX %p",
> + k, path[k].p_idx,
> + EXT_LAST_INDEX(path[k].p_hdr));
> + err = -EFSCORRUPTED;
> + break;
> + }
> path[k].p_idx->ei_block = border;
> err = ext4_ext_dirty(handle, inode, path + k);
> if (err)
> --
> 2.34.1
>
Cheers, Andreas