From 22e94d5b5ad80a5c068a729463ffa9f9cdbb49a5 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: May 17 2023 19:16:10 +0000 Subject: ext4: fix invalid free tracking in ext4_xattr_move_to_block() (bsc#1012628). --- diff --git a/patches.kernel.org/6.3.3-238-ext4-fix-invalid-free-tracking-in-ext4_xattr_mo.patch b/patches.kernel.org/6.3.3-238-ext4-fix-invalid-free-tracking-in-ext4_xattr_mo.patch new file mode 100644 index 0000000..7a40a41 --- /dev/null +++ b/patches.kernel.org/6.3.3-238-ext4-fix-invalid-free-tracking-in-ext4_xattr_mo.patch @@ -0,0 +1,68 @@ +From: Theodore Ts'o +Date: Sun, 30 Apr 2023 03:04:13 -0400 +Subject: [PATCH] ext4: fix invalid free tracking in ext4_xattr_move_to_block() +References: bsc#1012628 +Patch-mainline: 6.3.3 +Git-commit: b87c7cdf2bed4928b899e1ce91ef0d147017ba45 + +commit b87c7cdf2bed4928b899e1ce91ef0d147017ba45 upstream. + +In ext4_xattr_move_to_block(), the value of the extended attribute +which we need to move to an external block may be allocated by +kvmalloc() if the value is stored in an external inode. So at the end +of the function the code tried to check if this was the case by +testing entry->e_value_inum. + +However, at this point, the pointer to the xattr entry is no longer +valid, because it was removed from the original location where it had +been stored. So we could end up calling kvfree() on a pointer which +was not allocated by kvmalloc(); or we could also potentially leak +memory by not freeing the buffer when it should be freed. Fix this by +storing whether it should be freed in a separate variable. + +Cc: stable@kernel.org +Link: https://lore.kernel.org/r/20230430160426.581366-1-tytso@mit.edu +Link: https://syzkaller.appspot.com/bug?id=5c2aee8256e30b55ccf57312c16d88417adbd5e1 +Link: https://syzkaller.appspot.com/bug?id=41a6b5d4917c0412eb3b3c3c604965bed7d7420b +Reported-by: syzbot+64b645917ce07d89bde5@syzkaller.appspotmail.com +Reported-by: syzbot+0d042627c4f2ad332195@syzkaller.appspotmail.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Jiri Slaby +--- + fs/ext4/xattr.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index 767454d7..e33a323f 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -2615,6 +2615,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode, + .in_inode = !!entry->e_value_inum, + }; + struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode); ++ int needs_kvfree = 0; + int error; + + is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS); +@@ -2637,7 +2638,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode, + error = -ENOMEM; + goto out; + } +- ++ needs_kvfree = 1; + error = ext4_xattr_inode_get(inode, entry, buffer, value_size); + if (error) + goto out; +@@ -2676,7 +2677,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode, + + out: + kfree(b_entry_name); +- if (entry->e_value_inum && buffer) ++ if (needs_kvfree && buffer) + kvfree(buffer); + if (is) + brelse(is->iloc.bh); +-- +2.35.3 + diff --git a/series.conf b/series.conf index afe965c..774b89d 100644 --- a/series.conf +++ b/series.conf @@ -971,6 +971,7 @@ patches.kernel.org/6.3.3-235-ext4-bail-out-of-ext4_xattr_ibody_get-fails-for.patch patches.kernel.org/6.3.3-236-ext4-fix-lockdep-warning-when-enabling-MMP.patch patches.kernel.org/6.3.3-237-ext4-remove-a-BUG_ON-in-ext4_mb_release_group_p.patch + patches.kernel.org/6.3.3-238-ext4-fix-invalid-free-tracking-in-ext4_xattr_mo.patch ######################################################## # Build fixes that apply to the vanilla kernel too.