public inbox for linux-ext4@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ext4: add bounds check in ext4_xattr_ibody_get() to prevent out-of-bounds access
@ 2026-02-24 23:14 Deepanshu Kartikey
  2026-03-10  1:47 ` Deepanshu Kartikey
  2026-03-26  5:47 ` Theodore Tso
  0 siblings, 2 replies; 6+ messages in thread
From: Deepanshu Kartikey @ 2026-02-24 23:14 UTC (permalink / raw)
  To: tytso, adilger.kernel
  Cc: linux-ext4, linux-kernel, Deepanshu Kartikey,
	syzbot+fb32afec111a7d61b939

When mounting a corrupted ext4 filesystem, the inode's i_extra_isize
can be set to a value that leaves insufficient space in the inode for
the inline xattr header and entries. While ext4_iget() validates that
i_extra_isize fits within the inode size, it does not account for the
additional sizeof(ext4_xattr_ibody_header) needed by IHDR/IFIRST.

This results in IFIRST(header) pointing at or beyond ITAIL(raw_inode),
leaving no room for even the 4-byte terminator entry. When
xattr_find_entry() is subsequently called, IS_LAST_ENTRY() reads 4
bytes from this out-of-bounds pointer, triggering a use-after-free.

For example, with EXT4_INODE_SIZE=256 and i_extra_isize=124:
  - ext4_iget() check: 128 + 124 = 252 <= 256, passes
  - IFIRST = offset 252 + 4 (xattr header) = 256
  - ITAIL  = 256
  - IS_LAST_ENTRY() reads 4 bytes at offset 256, past the inode buffer

Fix this by validating in ext4_xattr_ibody_get() that there is enough
space between IFIRST(header) and ITAIL for at least a 4-byte read
before calling xattr_find_entry(). Return -EFSCORRUPTED if the inline
xattr region is too small.

Reported-by: syzbot+fb32afec111a7d61b939@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=fb32afec111a7d61b939
Tested-by: syzbot+fb32afec111a7d61b939@syzkaller.appspotmail.com
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
 fs/ext4/xattr.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 7bf9ba19a89d..5080ec44228a 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -652,6 +652,13 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
 	header = IHDR(inode, raw_inode);
 	end = ITAIL(inode, raw_inode);
 	entry = IFIRST(header);
+
+	if ((void *)entry + sizeof(__u32) > end) {
+		EXT4_ERROR_INODE(inode, "inline xattr region overflow");
+		error = -EFSCORRUPTED;
+		goto cleanup;
+	}
+
 	error = xattr_find_entry(inode, &entry, end, name_index, name, 0);
 	if (error)
 		goto cleanup;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-03-28 15:02 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-24 23:14 [PATCH] ext4: add bounds check in ext4_xattr_ibody_get() to prevent out-of-bounds access Deepanshu Kartikey
2026-03-10  1:47 ` Deepanshu Kartikey
2026-03-26  5:47 ` Theodore Tso
2026-03-27 14:32   ` Deepanshu Kartikey
2026-03-27 16:31     ` SYZKALLER BUG: messing with a mounted file system via loop ioctls (was: Re: [PATCH] ext4: add bounds check in ext4_xattr_ibody_get() to) " Theodore Tso
2026-03-28 15:02       ` Deepanshu Kartikey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox