]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ocfs2: validate inline xattr header before inline refcount attach
authorZhengYuan Huang <gality369@gmail.com>
Fri, 8 May 2026 08:59:13 +0000 (16:59 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 29 May 2026 04:24:48 +0000 (21:24 -0700)
[BUG]
A corrupt inline xattr header can make ocfs2_xattr_inline_attach_refcount()
feed an unchecked header into the refcount-attachment walk for inline
xattr values.

[CAUSE]
The inline refcount-attach path still derived the header directly from
di->i_xattr_inline_size and then passed it to code that iterates xh_count
and xattr entries.

[FIX]
Use the shared ibody header helper before attaching refcounts to inline
xattr values so corrupt header geometry is rejected with -EFSCORRUPTED
instead of being traversed.

Link: https://lore.kernel.org/20260508085914.61647-5-gality369@gmail.com
Signed-off-by: ZhengYuan Huang <gality369@gmail.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Jia-Ju Bai <baijiaju1990@gmail.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Zixuan Fu <r33s3n6@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/ocfs2/xattr.c

index bbb25a01b0971176c37a67dcc97d2934f3c08b71..4877406a83ceebeab4bdc4268b57b60c5bd5dd56 100644 (file)
@@ -6016,14 +6016,17 @@ static int ocfs2_xattr_inline_attach_refcount(struct inode *inode,
                                struct ocfs2_cached_dealloc_ctxt *dealloc)
 {
        struct ocfs2_dinode *di = (struct ocfs2_dinode *)fe_bh->b_data;
-       struct ocfs2_xattr_header *header = (struct ocfs2_xattr_header *)
-                               (fe_bh->b_data + inode->i_sb->s_blocksize -
-                               le16_to_cpu(di->i_xattr_inline_size));
+       struct ocfs2_xattr_header *header;
+       int ret;
        struct ocfs2_xattr_value_buf vb = {
                .vb_bh = fe_bh,
                .vb_access = ocfs2_journal_access_di,
        };
 
+       ret = ocfs2_xattr_ibody_lookup_header(inode, di, &header);
+       if (ret)
+               return ret;
+
        return ocfs2_xattr_attach_refcount_normal(inode, &vb, header,
                                                  ref_ci, ref_root_bh, dealloc);
 }