diff options
author | Darrick J. Wong <djwong@kernel.org> | 2024-04-15 14:54:36 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2024-04-15 14:58:51 -0700 |
commit | f4887fbc41dcb1560ec5da982ac7c6ad04b71de5 (patch) | |
tree | dda77034fb9f6b655c77bd9449626114779d5f75 /fs/xfs/xfs_attr_list.c | |
parent | 33c028ffe36ad7a91930acf0bd3d6ee7340022bf (diff) | |
download | linux-f4887fbc41dcb1560ec5da982ac7c6ad04b71de5.tar.gz linux-f4887fbc41dcb1560ec5da982ac7c6ad04b71de5.tar.bz2 linux-f4887fbc41dcb1560ec5da982ac7c6ad04b71de5.zip |
xfs: validate attr leaf buffer owners
Create a leaf block header checking function to validate the owner field
of xattr leaf blocks.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/xfs_attr_list.c')
-rw-r--r-- | fs/xfs/xfs_attr_list.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 42a575db7267..f6496e33ff91 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -214,6 +214,7 @@ xfs_attr_node_list_lookup( struct xfs_mount *mp = dp->i_mount; struct xfs_trans *tp = context->tp; struct xfs_buf *bp; + xfs_failaddr_t fa; int i; int error = 0; unsigned int expected_level = 0; @@ -273,6 +274,12 @@ xfs_attr_node_list_lookup( } } + fa = xfs_attr3_leaf_header_check(bp, dp->i_ino); + if (fa) { + __xfs_buf_mark_corrupt(bp, fa); + goto out_releasebuf; + } + if (expected_level != 0) goto out_corruptbuf; @@ -281,6 +288,7 @@ xfs_attr_node_list_lookup( out_corruptbuf: xfs_buf_mark_corrupt(bp); +out_releasebuf: xfs_trans_brelse(tp, bp); xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK); return -EFSCORRUPTED; @@ -297,6 +305,7 @@ xfs_attr_node_list( struct xfs_buf *bp; struct xfs_inode *dp = context->dp; struct xfs_mount *mp = dp->i_mount; + xfs_failaddr_t fa; int error = 0; trace_xfs_attr_node_list(context); @@ -332,6 +341,14 @@ xfs_attr_node_list( case XFS_ATTR_LEAF_MAGIC: case XFS_ATTR3_LEAF_MAGIC: leaf = bp->b_addr; + fa = xfs_attr3_leaf_header_check(bp, dp->i_ino); + if (fa) { + __xfs_buf_mark_corrupt(bp, fa); + xfs_trans_brelse(context->tp, bp); + xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK); + bp = NULL; + break; + } xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf); entries = xfs_attr3_leaf_entryp(leaf); @@ -382,8 +399,8 @@ need_lookup: break; cursor->blkno = leafhdr.forw; xfs_trans_brelse(context->tp, bp); - error = xfs_attr3_leaf_read(context->tp, dp, cursor->blkno, - &bp); + error = xfs_attr3_leaf_read(context->tp, dp, dp->i_ino, + cursor->blkno, &bp); if (error) return error; } @@ -503,7 +520,8 @@ xfs_attr_leaf_list( trace_xfs_attr_leaf_list(context); context->cursor.blkno = 0; - error = xfs_attr3_leaf_read(context->tp, context->dp, 0, &bp); + error = xfs_attr3_leaf_read(context->tp, context->dp, + context->dp->i_ino, 0, &bp); if (error) return error; |