xfs: check owner of dir3 blocks
commit 1b2c1a63b678d63e9c98314d44413f5af79c9c80 upstream. Check the owner field of dir3 block headers. If it's corrupt, release the buffer and return EFSCORRUPTED. All callers handle this properly. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Acked-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
15b0651f38
commit
2f55a03891
@ -114,6 +114,23 @@ const struct xfs_buf_ops xfs_dir3_block_buf_ops = {
|
||||
.verify_struct = xfs_dir3_block_verify,
|
||||
};
|
||||
|
||||
static xfs_failaddr_t
|
||||
xfs_dir3_block_header_check(
|
||||
struct xfs_inode *dp,
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_mount *mp = dp->i_mount;
|
||||
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
|
||||
|
||||
if (be64_to_cpu(hdr3->owner) != dp->i_ino)
|
||||
return __this_address;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
xfs_dir3_block_read(
|
||||
struct xfs_trans *tp,
|
||||
@ -121,12 +138,24 @@ xfs_dir3_block_read(
|
||||
struct xfs_buf **bpp)
|
||||
{
|
||||
struct xfs_mount *mp = dp->i_mount;
|
||||
xfs_failaddr_t fa;
|
||||
int err;
|
||||
|
||||
err = xfs_da_read_buf(tp, dp, mp->m_dir_geo->datablk, -1, bpp,
|
||||
XFS_DATA_FORK, &xfs_dir3_block_buf_ops);
|
||||
if (!err && tp && *bpp)
|
||||
xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_BLOCK_BUF);
|
||||
if (err || !*bpp)
|
||||
return err;
|
||||
|
||||
/* Check things that we can't do in the verifier. */
|
||||
fa = xfs_dir3_block_header_check(dp, *bpp);
|
||||
if (fa) {
|
||||
__xfs_buf_mark_corrupt(*bpp, fa);
|
||||
xfs_trans_brelse(tp, *bpp);
|
||||
*bpp = NULL;
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_BLOCK_BUF);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user