Skip to content

Commit 2a4f334

Browse files
deepanshu406akpm00
authored andcommitted
ocfs2: validate inline xattr size and entry count in ocfs2_xattr_ibody_list
Add comprehensive validation of inline xattr metadata in ocfs2_xattr_ibody_list() to prevent out-of-bounds access and use-after-free bugs when processing corrupted inline xattrs. The patch adds two critical validations: 1. Validates i_xattr_inline_size before use: - Ensures it does not exceed block size - Ensures it is at least large enough for xattr header - Prevents pointer arithmetic with corrupted size values that could point outside the inode block 2. Validates xattr entry count (xh_count): - Calculates maximum entries that can fit in the inline space - Rejects counts that exceed this limit - Prevents out-of-bounds array access in subsequent code Without these checks, a corrupted filesystem with invalid inline xattr metadata can cause the code to access memory beyond the allocated space. For example: - A corrupted i_xattr_inline_size of 0 would cause header pointer calculation to point past the end of the block - A corrupted xh_count of 22 with inline_size of 256 would cause array access 7 entries beyond the 15 that actually fit (the syzbot reproducer used xh_count of 20041), leading to use-after-free when accessing freed memory pages The validation uses the correct inline_size (from di->i_xattr_inline_size) rather than block size, ensuring accurate bounds checking for inline xattrs specifically. Link: https://lkml.kernel.org/r/20251120041145.33176-1-kartikey406@gmail.com 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/ [v2] Link: https://lore.kernel.org/all/20251117114224.12948-1-kartikey406@gmail.com/ [v3] Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com> Reported-by: syzbot+ab0ad25088673470d2d9@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=ab0ad25088673470d2d9 Tested-by: syzbot+ab0ad25088673470d2d9@syzkaller.appspotmail.com Suggested-by: Heming Zhao <heming.zhao@suse.com> Reviewed-by: Heming Zhao <heming.zhao@suse.com> Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com> Cc: Mark Fasheh <mark@fasheh.com> Cc: Joel Becker <jlbec@evilplan.org> Cc: Junxiao Bi <junxiao.bi@oracle.com> Cc: Changwei Ge <gechangwei@live.cn> Cc: Jun Piao <piaojun@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent acce46a commit 2a4f334

1 file changed

Lines changed: 28 additions & 2 deletions

File tree

fs/ocfs2/xattr.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -971,13 +971,39 @@ static int ocfs2_xattr_ibody_list(struct inode *inode,
971971
struct ocfs2_xattr_header *header = NULL;
972972
struct ocfs2_inode_info *oi = OCFS2_I(inode);
973973
int ret = 0;
974+
u16 xattr_count;
975+
size_t max_entries;
976+
u16 inline_size;
974977

975978
if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL))
976979
return ret;
977980

981+
inline_size = le16_to_cpu(di->i_xattr_inline_size);
982+
983+
/* Validate inline size is reasonable */
984+
if (inline_size > inode->i_sb->s_blocksize ||
985+
inline_size < sizeof(struct ocfs2_xattr_header)) {
986+
ocfs2_error(inode->i_sb,
987+
"Invalid xattr inline size %u in inode %llu\n",
988+
inline_size,
989+
(unsigned long long)OCFS2_I(inode)->ip_blkno);
990+
return -EFSCORRUPTED;
991+
}
992+
978993
header = (struct ocfs2_xattr_header *)
979-
((void *)di + inode->i_sb->s_blocksize -
980-
le16_to_cpu(di->i_xattr_inline_size));
994+
((void *)di + inode->i_sb->s_blocksize - inline_size);
995+
996+
xattr_count = le16_to_cpu(header->xh_count);
997+
max_entries = (inline_size - sizeof(struct ocfs2_xattr_header)) /
998+
sizeof(struct ocfs2_xattr_entry);
999+
1000+
if (xattr_count > max_entries) {
1001+
ocfs2_error(inode->i_sb,
1002+
"xattr entry count %u exceeds maximum %zu in inode %llu\n",
1003+
xattr_count, max_entries,
1004+
(unsigned long long)OCFS2_I(inode)->ip_blkno);
1005+
return -EFSCORRUPTED;
1006+
}
9811007

9821008
ret = ocfs2_xattr_list_entries(inode, header, buffer, buffer_size);
9831009

0 commit comments

Comments
 (0)