[PATCH] ext4: save converted extent before merging
From: Jérémy Jean
Date: Wed Sep 30 2026 - 10:28:35 EST
In ext4_split_convert_extents(), merging can release the leaf holding
the extent pointed to by ex. The later extent status cache update can
then dereference freed memory, causing a use-after-free. KASAN reports:
BUG: KASAN: use-after-free in ext4_split_convert_extents.constprop.0+0xb98/0xc80
Read of size 2 at addr ff11000002547034 by task fixture/65
Save the converted extent before merging and use the copy for the cache
update. This also avoids using the old extent slot after a merge with
the left neighbour.
Fixes: 716b9c23b862 ("ext4: refactor split and convert extents")
Cc: stable@xxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Jérémy Jean <Jeremy.Jean@xxxxxxxxxxxxxxxxx>
---
fs/ext4/extents.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 76038b6..f5a3880 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3830,6 +3830,7 @@ static struct ext4_ext_path *ext4_split_convert_extents(handle_t *handle,
ext4_lblk_t eof_block;
ext4_lblk_t ee_block;
struct ext4_extent *ex;
+ struct ext4_extent converted_ex;
unsigned int ee_len;
int split_flag = 0, depth, err = 0;
bool did_zeroout = false;
@@ -3887,6 +3888,9 @@ convert:
else if (flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN)
ext4_ext_mark_unwritten(ex);
+ /* Merging can move ex or release the leaf containing it. */
+ converted_ex = *ex;
+
if (!(flags & EXT4_GET_BLOCKS_SPLIT_NOMERGE))
/*
* note: ext4_ext_correct_indexes() isn't needed here because
@@ -3897,6 +3901,7 @@ convert:
err = ext4_ext_dirty(handle, inode, path + depth);
if (err)
goto err;
+ ex = &converted_ex;
}
/* Lets update the extent status tree after conversion */
--
2.47.3