From: Deepanshu Kartikey <kartikey406@gmail.com>
To: tytso@mit.edu, adilger.kernel@dilger.ca
Cc: linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org,
Deepanshu Kartikey <kartikey406@gmail.com>,
syzbot+fb32afec111a7d61b939@syzkaller.appspotmail.com
Subject: [PATCH] ext4: add bounds check in ext4_xattr_ibody_get() to prevent out-of-bounds access
Date: Wed, 25 Feb 2026 04:44:29 +0530 [thread overview]
Message-ID: <20260224231429.31361-1-kartikey406@gmail.com> (raw)
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
next reply other threads:[~2026-02-24 23:14 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-24 23:14 Deepanshu Kartikey [this message]
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
2026-03-29 9:47 ` Dmitry Vyukov
2026-03-29 13:48 ` Theodore Tso
2026-03-29 14:39 ` Deepanshu Kartikey
2026-03-29 17:06 ` Theodore Tso
2026-03-30 4:44 ` Deepanshu Kartikey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260224231429.31361-1-kartikey406@gmail.com \
--to=kartikey406@gmail.com \
--cc=adilger.kernel@dilger.ca \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=syzbot+fb32afec111a7d61b939@syzkaller.appspotmail.com \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®