Re: [PATCH 5/5] ocfs2: validate inline xattr header before reflinking inline xattrs
Joseph Qi <[email protected]>
| Newsgroups | dev.linux.lists.ocfs2-devel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 5/8/26 4:59 PM, ZhengYuan Huang wrote: > [BUG] > A corrupt inline xattr header can make ocfs2_reflink_xattr_inline() lock, > copy, and reflink xattr state from an unchecked ibody xattr header. > > [CAUSE] > The inline reflink path still trusted di->i_xattr_inline_size to compute > header_off, xh, and new_xh before handing the source header to the reflink > allocator and copy logic. > > [FIX] > Validate the source inode's inline xattr header with the shared helper > first, then derive the reflink copy offsets from the validated inline > size/header. This keeps the reflink path from traversing corrupt ibody > xattr geometry. > > Signed-off-by: ZhengYuan Huang <[email protected]> Looks fine. Reviewed-by: Joseph Qi <[email protected]> > --- > fs/ocfs2/xattr.c | 19 +++++++++++++------ > 1 file changed, 13 insertions(+), 6 deletions(-) > > diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c > index 4877406a83ce..fcddd3c13acd 100644 > --- a/fs/ocfs2/xattr.c > +++ b/fs/ocfs2/xattr.c > @@ -6511,12 +6511,10 @@ static int ocfs2_reflink_xattr_inline(struct ocfs2_xattr_reflink *args) > handle_t *handle; > struct ocfs2_super *osb = OCFS2_SB(args->old_inode->i_sb); > struct ocfs2_dinode *di = (struct ocfs2_dinode *)args->old_bh->b_data; > - int inline_size = le16_to_cpu(di->i_xattr_inline_size); > - int header_off = osb->sb->s_blocksize - inline_size; > - struct ocfs2_xattr_header *xh = (struct ocfs2_xattr_header *) > - (args->old_bh->b_data + header_off); > - struct ocfs2_xattr_header *new_xh = (struct ocfs2_xattr_header *) > - (args->new_bh->b_data + header_off); > + int inline_size; > + int header_off; > + struct ocfs2_xattr_header *xh; > + struct ocfs2_xattr_header *new_xh; > struct ocfs2_alloc_context *meta_ac = NULL; > struct ocfs2_inode_info *new_oi; > struct ocfs2_dinode *new_di; > @@ -6525,6 +6523,15 @@ static int ocfs2_reflink_xattr_inline(struct ocfs2_xattr_reflink *args) > .vb_access = ocfs2_journal_access_di, > }; > > + ret = ocfs2_xattr_ibody_lookup_header(args->old_inode, di, &xh); > + if (ret) > + goto out; > + > + inline_size = le16_to_cpu(di->i_xattr_inline_size); > + header_off = osb->sb->s_blocksize - inline_size; > + new_xh = (struct ocfs2_xattr_header *) > + (args->new_bh->b_data + header_off); > + > ret = ocfs2_reflink_lock_xattr_allocators(osb, xh, args->ref_root_bh, > &credits, &meta_ac); > if (ret) {