[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <691ae824.a70a0220.f6df1.000a.GAE@google.com>
Date: Mon, 17 Nov 2025 01:17:24 -0800
From: syzbot <syzbot+ab0ad25088673470d2d9@...kaller.appspotmail.com>
To: linux-kernel@...r.kernel.org, syzkaller-bugs@...glegroups.com
Subject: Forwarded: [PATCH v3] ocfs2: validate xattr entry count in ocfs2_xattr_ibody_list
For archival purposes, forwarding an incoming command email to
linux-kernel@...r.kernel.org, syzkaller-bugs@...glegroups.com.
***
Subject: [PATCH v3] ocfs2: validate xattr entry count in ocfs2_xattr_ibody_list
Author: kartikey406@...il.com
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-kernelci
Add validation of inline xattr size and entry count in
ocfs2_xattr_ibody_list() to prevent out-of-bounds access and
use-after-free bugs when processing corrupted inline xattrs.
The validation performs two checks:
1. Validates i_xattr_inline_size is within reasonable bounds (not larger
than block size and at least large enough for the xattr header)
2. Validates xattr entry count does not exceed the maximum that can fit
in the inline xattr space
Without these checks, a corrupted filesystem with invalid inline xattr
size or entry count can cause the code to access memory beyond the
allocated space, potentially reaching freed memory pages and triggering
KASAN use-after-free detection.
This fix addresses the syzbot-reported bug by validating inline xattr
metadata before use, using the correct inline size calculation rather
than block size.
Reported-by: syzbot+ab0ad25088673470d2d9@...kaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=ab0ad25088673470d2d9
Link: https://lore.kernel.org/all/20251111073831.2027072-1-kartikey406@gmail.com/ [v1]
Link: https://lore.kernel.org/all/20251117063217.5690-1-kartikey406@gmail.com/T/ [v2]
Signed-off-by: Deepanshu Kartikey <kartikey406@...il.com>
---
Changes in v3:
- Moved validation from ocfs2_xattr_list_entries() to
ocfs2_xattr_ibody_list() to use correct inline size calculation
(suggested by Heming Zhao)
- Added validation of i_xattr_inline_size before use
- Changed return value to -EFSCORRUPTED for consistency
---
fs/ocfs2/xattr.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index d70a20d29e3e..98fd4f3f2d2d 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -971,13 +971,39 @@ static int ocfs2_xattr_ibody_list(struct inode *inode,
struct ocfs2_xattr_header *header = NULL;
struct ocfs2_inode_info *oi = OCFS2_I(inode);
int ret = 0;
+ u16 xattr_count;
+ size_t max_entries;
+ u16 inline_size;
if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL))
return ret;
+ inline_size = le16_to_cpu(di->i_xattr_inline_size);
+
+ /* Validate inline size is reasonable */
+ if (inline_size > inode->i_sb->s_blocksize ||
+ inline_size < sizeof(struct ocfs2_xattr_header)) {
+ ocfs2_error(inode->i_sb,
+ "Invalid xattr inline size %u in inode %llu\n",
+ inline_size,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
+ return -EFSCORRUPTED;
+ }
+
header = (struct ocfs2_xattr_header *)
- ((void *)di + inode->i_sb->s_blocksize -
- le16_to_cpu(di->i_xattr_inline_size));
+ ((void *)di + inode->i_sb->s_blocksize - inline_size);
+
+ xattr_count = le16_to_cpu(header->xh_count);
+ max_entries = (inline_size - sizeof(struct ocfs2_xattr_header)) /
+ sizeof(struct ocfs2_xattr_entry);
+
+ if (xattr_count > max_entries) {
+ ocfs2_error(inode->i_sb,
+ "xattr entry count %u exceeds maximum %zu in inode %llu\n",
+ xattr_count, max_entries,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
+ return -EFSCORRUPTED;
+ }
ret = ocfs2_xattr_list_entries(inode, header, buffer, buffer_size);
--
2.43.0
Powered by blists - more mailing lists