From patchwork Sun Dec 31 22:34:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13507904 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 932D1C13B for ; Sun, 31 Dec 2023 22:34:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="W5F02TwX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1A755C433C7; Sun, 31 Dec 2023 22:34:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1704062046; bh=m+RY93tkturq238t9G3jNqjg9FYzvJ/dBJxO1Ew/QLI=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=W5F02TwXgD/fFY695xrNRkDvVKjJVCyDXJsuuCRRC/J1DcTFOYAdtjlSIFr8SBa5d 1Ts1/7dpxTp0rTBBZj5db/0kreILnoG4yhiR3yCJCLDiZUHo7i+1SkPUX9/jMnbvY1 ztfQTGxNtRW1TG+/DIfGzaaOQiIbE80fRIZzU812/yxWTVbetfG0nT63hsJYIbosdP 19RC6syeh6OewWM3W4YnaMvBMkYlYdoS5pABn8xxjDVg/zARknGxwRIf80woHRq4b+ eNTSwQx6OPl5as8Z5OWmYXrmnoV+LlcnTD1uFICHlwsPKA/wa2v9xvoY+aZNNp/k6d oxgc8wyIaTIHw== Date: Sun, 31 Dec 2023 14:34:05 -0800 Subject: [PATCH 7/9] xfs: validate explicit directory data buffer owners From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Message-ID: <170404996961.1796662.16439765852311650250.stgit@frogsfrogsfrogs> In-Reply-To: <170404996860.1796662.9605761412685436403.stgit@frogsfrogsfrogs> References: <170404996860.1796662.9605761412685436403.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Port the existing directory data header checking function to accept an owner number instead of an xfs_inode, then update the callsites to use xfs_da_args.owner when possible. Signed-off-by: Darrick J. Wong --- db/namei.c | 3 ++- libxfs/xfs_dir2.h | 1 + libxfs/xfs_dir2_block.c | 3 ++- libxfs/xfs_dir2_data.c | 15 +++++++++------ libxfs/xfs_dir2_leaf.c | 21 +++++++++++---------- libxfs/xfs_dir2_node.c | 7 +++---- libxfs/xfs_dir2_priv.h | 3 ++- 7 files changed, 30 insertions(+), 23 deletions(-) diff --git a/db/namei.c b/db/namei.c index eb09288b490..d7bf489cd53 100644 --- a/db/namei.c +++ b/db/namei.c @@ -400,7 +400,8 @@ list_leafdir( libxfs_trim_extent(&map, dabno, geo->leafblk - dabno); /* Read the directory block of that first mapping. */ - error = xfs_dir3_data_read(NULL, dp, map.br_startoff, 0, &bp); + error = xfs_dir3_data_read(NULL, dp, args->owner, + map.br_startoff, 0, &bp); if (error) break; diff --git a/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h index 0b01dd6ccf1..537596b9de4 100644 --- a/libxfs/xfs_dir2.h +++ b/libxfs/xfs_dir2.h @@ -99,6 +99,7 @@ extern struct xfs_dir2_data_free *xfs_dir2_data_freefind( extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); xfs_failaddr_t xfs_dir3_leaf_header_check(struct xfs_buf *bp, xfs_ino_t owner); +xfs_failaddr_t xfs_dir3_data_header_check(struct xfs_buf *bp, xfs_ino_t owner); extern const struct xfs_buf_ops xfs_dir3_block_buf_ops; extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops; diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index 1f6a88091e7..86e49fbc2b7 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -979,7 +979,8 @@ xfs_dir2_leaf_to_block( * Read the data block if we don't already have it, give up if it fails. */ if (!dbp) { - error = xfs_dir3_data_read(tp, dp, args->geo->datablk, 0, &dbp); + error = xfs_dir3_data_read(tp, dp, args->owner, + args->geo->datablk, 0, &dbp); if (error) return error; } diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c index 6f3ccfeb69f..9ce0039d6ac 100644 --- a/libxfs/xfs_dir2_data.c +++ b/libxfs/xfs_dir2_data.c @@ -392,17 +392,19 @@ static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = { .verify_write = xfs_dir3_data_write_verify, }; -static xfs_failaddr_t +xfs_failaddr_t xfs_dir3_data_header_check( - struct xfs_inode *dp, - struct xfs_buf *bp) + struct xfs_buf *bp, + xfs_ino_t owner) { - struct xfs_mount *mp = dp->i_mount; + struct xfs_mount *mp = bp->b_mount; if (xfs_has_crc(mp)) { struct xfs_dir3_data_hdr *hdr3 = bp->b_addr; - if (be64_to_cpu(hdr3->hdr.owner) != dp->i_ino) + ASSERT(hdr3->hdr.magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); + + if (be64_to_cpu(hdr3->hdr.owner) != owner) return __this_address; } @@ -413,6 +415,7 @@ int xfs_dir3_data_read( struct xfs_trans *tp, struct xfs_inode *dp, + xfs_ino_t owner, xfs_dablk_t bno, unsigned int flags, struct xfs_buf **bpp) @@ -426,7 +429,7 @@ xfs_dir3_data_read( return err; /* Check things that we can't do in the verifier. */ - fa = xfs_dir3_data_header_check(dp, *bpp); + fa = xfs_dir3_data_header_check(*bpp, owner); if (fa) { __xfs_buf_mark_corrupt(*bpp, fa); xfs_trans_brelse(tp, *bpp); diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c index 14449a23502..dd2bb2bc8b6 100644 --- a/libxfs/xfs_dir2_leaf.c +++ b/libxfs/xfs_dir2_leaf.c @@ -882,9 +882,9 @@ xfs_dir2_leaf_addname( * Already had space in some data block. * Just read that one in. */ - error = xfs_dir3_data_read(tp, dp, - xfs_dir2_db_to_da(args->geo, use_block), - 0, &dbp); + error = xfs_dir3_data_read(tp, dp, args->owner, + xfs_dir2_db_to_da(args->geo, use_block), 0, + &dbp); if (error) { xfs_trans_brelse(tp, lbp); return error; @@ -1325,9 +1325,9 @@ xfs_dir2_leaf_lookup_int( if (newdb != curdb) { if (dbp) xfs_trans_brelse(tp, dbp); - error = xfs_dir3_data_read(tp, dp, - xfs_dir2_db_to_da(args->geo, newdb), - 0, &dbp); + error = xfs_dir3_data_read(tp, dp, args->owner, + xfs_dir2_db_to_da(args->geo, newdb), 0, + &dbp); if (error) { xfs_trans_brelse(tp, lbp); return error; @@ -1367,9 +1367,9 @@ xfs_dir2_leaf_lookup_int( ASSERT(cidb != -1); if (cidb != curdb) { xfs_trans_brelse(tp, dbp); - error = xfs_dir3_data_read(tp, dp, - xfs_dir2_db_to_da(args->geo, cidb), - 0, &dbp); + error = xfs_dir3_data_read(tp, dp, args->owner, + xfs_dir2_db_to_da(args->geo, cidb), 0, + &dbp); if (error) { xfs_trans_brelse(tp, lbp); return error; @@ -1663,7 +1663,8 @@ xfs_dir2_leaf_trim_data( /* * Read the offending data block. We need its buffer. */ - error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(geo, db), 0, &dbp); + error = xfs_dir3_data_read(tp, dp, args->owner, + xfs_dir2_db_to_da(geo, db), 0, &dbp); if (error) return error; diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index c0160d725e5..69040737418 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -860,7 +860,7 @@ xfs_dir2_leafn_lookup_for_entry( ASSERT(state->extravalid); curbp = state->extrablk.bp; } else { - error = xfs_dir3_data_read(tp, dp, + error = xfs_dir3_data_read(tp, dp, args->owner, xfs_dir2_db_to_da(args->geo, newdb), 0, &curbp); @@ -1946,9 +1946,8 @@ xfs_dir2_node_addname_int( &freehdr, &findex); } else { /* Read the data block in. */ - error = xfs_dir3_data_read(tp, dp, - xfs_dir2_db_to_da(args->geo, dbno), - 0, &dbp); + error = xfs_dir3_data_read(tp, dp, args->owner, + xfs_dir2_db_to_da(args->geo, dbno), 0, &dbp); } if (error) return error; diff --git a/libxfs/xfs_dir2_priv.h b/libxfs/xfs_dir2_priv.h index 2f0e3ad47b3..879aa2e9fd7 100644 --- a/libxfs/xfs_dir2_priv.h +++ b/libxfs/xfs_dir2_priv.h @@ -78,7 +78,8 @@ extern void xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); extern xfs_failaddr_t __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp, - xfs_dablk_t bno, unsigned int flags, struct xfs_buf **bpp); + xfs_ino_t owner, xfs_dablk_t bno, unsigned int flags, + struct xfs_buf **bpp); int xfs_dir3_data_readahead(struct xfs_inode *dp, xfs_dablk_t bno, unsigned int flags);