Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f55a038 authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Greg Kroah-Hartman
Browse files

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: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Acked-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChandan Babu R <chandan.babu@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 15b0651f
Loading
Loading
Loading
Loading
+31 −2
Original line number Diff line number Diff line
@@ -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,11 +138,23 @@ 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)
	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;
}