diff options
author | Baokun Li <[email protected]> | 2024-08-22 10:35:24 +0800 |
---|---|---|
committer | Theodore Ts'o <[email protected]> | 2024-09-03 22:12:16 -0400 |
commit | 4e2524ba2ca5f54bdbb9e5153bea00421ef653f5 (patch) | |
tree | dad5d7b05a5c6451aa2145fac02f318ef9f8e770 | |
parent | c26ab35702f8cd0cdc78f96aa5856bfb77be798f (diff) |
ext4: avoid use-after-free in ext4_ext_show_leaf()
In ext4_find_extent(), path may be freed by error or be reallocated, so
using a previously saved *ppath may have been freed and thus may trigger
use-after-free, as follows:
ext4_split_extent
path = *ppath;
ext4_split_extent_at(ppath)
path = ext4_find_extent(ppath)
ext4_split_extent_at(ppath)
// ext4_find_extent fails to free path
// but zeroout succeeds
ext4_ext_show_leaf(inode, path)
eh = path[depth].p_hdr
// path use-after-free !!!
Similar to ext4_split_extent_at(), we use *ppath directly as an input to
ext4_ext_show_leaf(). Fix a spelling error by the way.
Same problem in ext4_ext_handle_unwritten_extents(). Since 'path' is only
used in ext4_ext_show_leaf(), remove 'path' and use *ppath directly.
This issue is triggered only when EXT_DEBUG is defined and therefore does
not affect functionality.
Signed-off-by: Baokun Li <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Reviewed-by: Ojaswin Mujoo <[email protected]>
Tested-by: Ojaswin Mujoo <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Theodore Ts'o <[email protected]>
-rw-r--r-- | fs/ext4/extents.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index fe6bca63f9d6..caef91356557 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3327,7 +3327,7 @@ out: } /* - * ext4_split_extents() splits an extent and mark extent which is covered + * ext4_split_extent() splits an extent and mark extent which is covered * by @map as split_flags indicates * * It may result in splitting the extent into multiple extents (up to three) @@ -3403,7 +3403,7 @@ static int ext4_split_extent(handle_t *handle, goto out; } - ext4_ext_show_leaf(inode, path); + ext4_ext_show_leaf(inode, *ppath); out: return err ? err : allocated; } @@ -3868,14 +3868,13 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode, struct ext4_ext_path **ppath, int flags, unsigned int allocated, ext4_fsblk_t newblock) { - struct ext4_ext_path __maybe_unused *path = *ppath; int ret = 0; int err = 0; ext_debug(inode, "logical block %llu, max_blocks %u, flags 0x%x, allocated %u\n", (unsigned long long)map->m_lblk, map->m_len, flags, allocated); - ext4_ext_show_leaf(inode, path); + ext4_ext_show_leaf(inode, *ppath); /* * When writing into unwritten space, we should not fail to @@ -3972,7 +3971,7 @@ out1: if (allocated > map->m_len) allocated = map->m_len; map->m_len = allocated; - ext4_ext_show_leaf(inode, path); + ext4_ext_show_leaf(inode, *ppath); out2: return err ? err : allocated; } |