Skip to content

Commit 189d42b

Browse files
committed
Merge: CVE-2024-49983: ext4: drop ppath from ext4_ext_replay_update_ex() to avoid double-free
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/5565 JIRA: https://issues.redhat.com/browse/RHEL-64010 CVE: CVE-2024-49983 ``` ext4: drop ppath from ext4_ext_replay_update_ex() to avoid double-free When calling ext4_force_split_extent_at() in ext4_ext_replay_update_ex(), the 'ppath' is updated but it is the 'path' that is freed, thus potentially triggering a double-free in the following process: ext4_ext_replay_update_ex ppath = path ext4_force_split_extent_at(&ppath) ext4_split_extent_at ext4_ext_insert_extent ext4_ext_create_new_leaf ext4_ext_grow_indepth ext4_find_extent if (depth > path[0].p_maxdepth) kfree(path) ---> path First freed *orig_path = path = NULL ---> null ppath kfree(path) ---> path double-free !!! So drop the unnecessary ppath and use path directly to avoid this problem. And use ext4_find_extent() directly to update path, avoiding unnecessary memory allocation and freeing. Also, propagate the error returned by ext4_find_extent() instead of using strange error codes. Fixes: 8016e29 ("ext4: fast commit recovery path") Cc: stable@kernel.org Signed-off-by: Baokun Li <libaokun1@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Link: https://patch.msgid.link/20240822023545.1994557-8-libaokun@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu> (cherry picked from commit 5c0f4cc) ``` Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com> --- <small>Created 2024-10-22 13:58 UTC by backporter - [KWF FAQ](https://red.ht/kernel_workflow_doc) - [Slack #team-kernel-workflow](https://redhat-internal.slack.com/archives/C04LRUPMJQ5) - [Source](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/webhook/utils/backporter.py) - [Documentation](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/docs/README.backporter.md) - [Report an issue](https://gitlab.com/cki-project/kernel-workflow/-/issues/new?issue%5Btitle%5D=backporter%20webhook%20issue)</small> Approved-by: Brian Foster <bfoster@redhat.com> Approved-by: Chris von Recklinghausen <crecklin@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Rado Vrbovsky <rvrbovsk@redhat.com>
2 parents 02cac43 + 7e54368 commit 189d42b

File tree

1 file changed

+10
-11
lines changed

1 file changed

+10
-11
lines changed

fs/ext4/extents.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5876,7 +5876,7 @@ int ext4_clu_mapped(struct inode *inode, ext4_lblk_t lclu)
58765876
int ext4_ext_replay_update_ex(struct inode *inode, ext4_lblk_t start,
58775877
int len, int unwritten, ext4_fsblk_t pblk)
58785878
{
5879-
struct ext4_ext_path *path = NULL, *ppath;
5879+
struct ext4_ext_path *path;
58805880
struct ext4_extent *ex;
58815881
int ret;
58825882

@@ -5892,30 +5892,29 @@ int ext4_ext_replay_update_ex(struct inode *inode, ext4_lblk_t start,
58925892
if (le32_to_cpu(ex->ee_block) != start ||
58935893
ext4_ext_get_actual_len(ex) != len) {
58945894
/* We need to split this extent to match our extent first */
5895-
ppath = path;
58965895
down_write(&EXT4_I(inode)->i_data_sem);
5897-
ret = ext4_force_split_extent_at(NULL, inode, &ppath, start, 1);
5896+
ret = ext4_force_split_extent_at(NULL, inode, &path, start, 1);
58985897
up_write(&EXT4_I(inode)->i_data_sem);
58995898
if (ret)
59005899
goto out;
5901-
kfree(path);
5902-
path = ext4_find_extent(inode, start, NULL, 0);
5900+
5901+
path = ext4_find_extent(inode, start, &path, 0);
59035902
if (IS_ERR(path))
5904-
return -1;
5905-
ppath = path;
5903+
return PTR_ERR(path);
59065904
ex = path[path->p_depth].p_ext;
59075905
WARN_ON(le32_to_cpu(ex->ee_block) != start);
5906+
59085907
if (ext4_ext_get_actual_len(ex) != len) {
59095908
down_write(&EXT4_I(inode)->i_data_sem);
5910-
ret = ext4_force_split_extent_at(NULL, inode, &ppath,
5909+
ret = ext4_force_split_extent_at(NULL, inode, &path,
59115910
start + len, 1);
59125911
up_write(&EXT4_I(inode)->i_data_sem);
59135912
if (ret)
59145913
goto out;
5915-
kfree(path);
5916-
path = ext4_find_extent(inode, start, NULL, 0);
5914+
5915+
path = ext4_find_extent(inode, start, &path, 0);
59175916
if (IS_ERR(path))
5918-
return -EINVAL;
5917+
return PTR_ERR(path);
59195918
ex = path[path->p_depth].p_ext;
59205919
}
59215920
}

0 commit comments

Comments
 (0)