CVE-2024-49882

Severity CVSS v4.0:
Pending analysis
Type:
CWE-415 Double Free
Publication date:
21/10/2024
Last modified:
03/11/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> ext4: fix double brelse() the buffer of the extents path<br /> <br /> In ext4_ext_try_to_merge_up(), set path[1].p_bh to NULL after it has been<br /> released, otherwise it may be released twice. An example of what triggers<br /> this is as follows:<br /> <br /> split2 map split1<br /> |--------|-------|--------|<br /> <br /> ext4_ext_map_blocks<br /> ext4_ext_handle_unwritten_extents<br /> ext4_split_convert_extents<br /> // path-&gt;p_depth == 0<br /> ext4_split_extent<br /> // 1. do split1<br /> ext4_split_extent_at<br /> |ext4_ext_insert_extent<br /> | ext4_ext_create_new_leaf<br /> | ext4_ext_grow_indepth<br /> | le16_add_cpu(&amp;neh-&gt;eh_depth, 1)<br /> | ext4_find_extent<br /> | // return -ENOMEM<br /> |// get error and try zeroout<br /> |path = ext4_find_extent<br /> | path-&gt;p_depth = 1<br /> |ext4_ext_try_to_merge<br /> | ext4_ext_try_to_merge_up<br /> | path-&gt;p_depth = 0<br /> | brelse(path[1].p_bh) ---&gt; not set to NULL here<br /> |// zeroout success<br /> // 2. update path<br /> ext4_find_extent<br /> // 3. do split2<br /> ext4_split_extent_at<br /> ext4_ext_insert_extent<br /> ext4_ext_create_new_leaf<br /> ext4_ext_grow_indepth<br /> le16_add_cpu(&amp;neh-&gt;eh_depth, 1)<br /> ext4_find_extent<br /> path[0].p_bh = NULL;<br /> path-&gt;p_depth = 1<br /> read_extent_tree_block ---&gt; return err<br /> // path[1].p_bh is still the old value<br /> ext4_free_ext_path<br /> ext4_ext_drop_refs<br /> // path-&gt;p_depth == 1<br /> brelse(path[1].p_bh) ---&gt; brelse a buffer twice<br /> <br /> Finally got the following WARRNING when removing the buffer from lru:<br /> <br /> ============================================<br /> VFS: brelse: Trying to free free buffer<br /> WARNING: CPU: 2 PID: 72 at fs/buffer.c:1241 __brelse+0x58/0x90<br /> CPU: 2 PID: 72 Comm: kworker/u19:1 Not tainted 6.9.0-dirty #716<br /> RIP: 0010:__brelse+0x58/0x90<br /> Call Trace:<br /> <br /> __find_get_block+0x6e7/0x810<br /> bdev_getblk+0x2b/0x480<br /> __ext4_get_inode_loc+0x48a/0x1240<br /> ext4_get_inode_loc+0xb2/0x150<br /> ext4_reserve_inode_write+0xb7/0x230<br /> __ext4_mark_inode_dirty+0x144/0x6a0<br /> ext4_ext_insert_extent+0x9c8/0x3230<br /> ext4_ext_map_blocks+0xf45/0x2dc0<br /> ext4_map_blocks+0x724/0x1700<br /> ext4_do_writepages+0x12d6/0x2a70<br /> [...]<br /> ============================================

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 3.7 (including) 5.10.227 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.11 (including) 5.15.168 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.16 (including) 6.1.113 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.2 (including) 6.6.55 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.7 (including) 6.10.14 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.11 (including) 6.11.3 (excluding)