Patch "xfs: transfer recovered intent item ownership in ->iop_recover" has been added to the 6.1-stable tree

<[email protected]> Sun, 16 Mar 2025 07:17:08 +0100
Newsgroups dev.linux.lists.xfs-stable
Message-ID <2025031608-goofiness-lion-9a76@gregkh>
This is a note to let you know that I've just added the patch titled

    xfs: transfer recovered intent item ownership in ->iop_recover

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     xfs-transfer-recovered-intent-item-ownership-in-iop_recover.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.


From [email protected] Thu Mar 13 21:26:34 2025
From: Leah Rumancik <[email protected]>
Date: Thu, 13 Mar 2025 13:25:36 -0700
Subject: xfs: transfer recovered intent item ownership in ->iop_recover
To: [email protected]
Cc: [email protected], "Darrick J. Wong" <[email protected]>, Christoph Hellwig <[email protected]>, Leah Rumancik <[email protected]>
Message-ID: <[email protected]>

From: "Darrick J. Wong" <[email protected]>

[ Upstream commit deb4cd8ba87f17b12c72b3827820d9c703e9fd95 ]

Now that we pass the xfs_defer_pending object into the intent item
recovery functions, we know exactly when ownership of the sole refcount
passes from the recovery context to the intent done item.  At that
point, we need to null out dfp_intent so that the recovery mechanism
won't release it.  This should fix the UAF problem reported by Long Li.

Note that we still want to recreate the full deferred work state.  That
will be addressed in the next patches.

Fixes: 2e76f188fd90 ("xfs: cancel intents immediately if process_intents fails")
Signed-off-by: Darrick J. Wong <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Signed-off-by: Leah Rumancik <[email protected]>
Acked-by: "Darrick J. Wong" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
 fs/xfs/libxfs/xfs_log_recover.h |    2 ++
 fs/xfs/xfs_attr_item.c          |    1 +
 fs/xfs/xfs_bmap_item.c          |    2 ++
 fs/xfs/xfs_extfree_item.c       |    2 ++
 fs/xfs/xfs_log_recover.c        |   19 ++++++++++++-------
 fs/xfs/xfs_refcount_item.c      |    1 +
 fs/xfs/xfs_rmap_item.c          |    2 ++
 7 files changed, 22 insertions(+), 7 deletions(-)

--- a/fs/xfs/libxfs/xfs_log_recover.h
+++ b/fs/xfs/libxfs/xfs_log_recover.h
@@ -155,5 +155,7 @@ xlog_recover_resv(const struct xfs_trans
 
 void xlog_recover_intent_item(struct xlog *log, struct xfs_log_item *lip,
 		xfs_lsn_t lsn, unsigned int dfp_type);
+void xlog_recover_transfer_intent(struct xfs_trans *tp,
+		struct xfs_defer_pending *dfp);
 
 #endif	/* __XFS_LOG_RECOVER_H__ */
--- a/fs/xfs/xfs_attr_item.c
+++ b/fs/xfs/xfs_attr_item.c
@@ -632,6 +632,7 @@ xfs_attri_item_recover(
 
 	args->trans = tp;
 	done_item = xfs_trans_get_attrd(tp, attrip);
+	xlog_recover_transfer_intent(tp, dfp);
 
 	xfs_ilock(ip, XFS_ILOCK_EXCL);
 	xfs_trans_ijoin(tp, ip, 0);
--- a/fs/xfs/xfs_bmap_item.c
+++ b/fs/xfs/xfs_bmap_item.c
@@ -491,6 +491,8 @@ xfs_bui_item_recover(
 		goto err_rele;
 
 	budp = xfs_trans_get_bud(tp, buip);
+	xlog_recover_transfer_intent(tp, dfp);
+
 	xfs_ilock(ip, XFS_ILOCK_EXCL);
 	xfs_trans_ijoin(tp, ip, 0);
 
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -626,7 +626,9 @@ xfs_efi_item_recover(
 	error = xfs_trans_alloc(mp, &resv, 0, 0, 0, &tp);
 	if (error)
 		return error;
+
 	efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
+	xlog_recover_transfer_intent(tp, dfp);
 
 	for (i = 0; i < efip->efi_format.efi_nextents; i++) {
 		struct xfs_extent_free_item	fake = {
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2593,13 +2593,6 @@ xlog_recover_process_intents(
 			break;
 		}
 
-		/*
-		 * XXX: @lip could have been freed, so detach the log item from
-		 * the pending item before freeing the pending item.  This does
-		 * not fix the existing UAF bug that occurs if ->iop_recover
-		 * fails after creating the intent done item.
-		 */
-		dfp->dfp_intent = NULL;
 		xfs_defer_cancel_recovery(log->l_mp, dfp);
 	}
 	if (error)
@@ -2634,6 +2627,18 @@ xlog_recover_cancel_intents(
 }
 
 /*
+ * Transfer ownership of the recovered log intent item to the recovery
+ * transaction.
+ */
+void
+xlog_recover_transfer_intent(
+	struct xfs_trans		*tp,
+	struct xfs_defer_pending	*dfp)
+{
+	dfp->dfp_intent = NULL;
+}
+
+/*
  * This routine performs a transaction to null out a bad inode pointer
  * in an agi unlinked inode hash bucket.
  */
--- a/fs/xfs/xfs_refcount_item.c
+++ b/fs/xfs/xfs_refcount_item.c
@@ -499,6 +499,7 @@ xfs_cui_item_recover(
 		return error;
 
 	cudp = xfs_trans_get_cud(tp, cuip);
+	xlog_recover_transfer_intent(tp, dfp);
 
 	for (i = 0; i < cuip->cui_format.cui_nextents; i++) {
 		struct xfs_refcount_intent	fake = { };
--- a/fs/xfs/xfs_rmap_item.c
+++ b/fs/xfs/xfs_rmap_item.c
@@ -526,7 +526,9 @@ xfs_rui_item_recover(
 			XFS_TRANS_RESERVE, &tp);
 	if (error)
 		return error;
+
 	rudp = xfs_trans_get_rud(tp, ruip);
+	xlog_recover_transfer_intent(tp, dfp);
 
 	for (i = 0; i < ruip->rui_format.rui_nextents; i++) {
 		rmap = &ruip->rui_format.rui_extents[i];


Patches currently in stable-queue which might be from [email protected] are

queue-6.1/xfs-fix-confusing-xfs_extent_item-variable-names.patch
queue-6.1/xfs-fix-32-bit-truncation-in-xfs_compute_rextslog.patch
queue-6.1/xfs-transfer-recovered-intent-item-ownership-in-iop_recover.patch
queue-6.1/xfs-initialise-di_crc-in-xfs_log_dinode.patch
queue-6.1/xfs-consider-minlen-sized-extents-in-xfs_rtallocate_extent_block.patch
queue-6.1/xfs-don-t-leak-recovered-attri-intent-items.patch
queue-6.1/xfs-remove-unused-fields-from-struct-xbtree_ifakeroot.patch
queue-6.1/xfs-fix-bounds-check-in-xfs_defer_agfl_block.patch
queue-6.1/xfs-ensure-logflagsp-is-initialized-in-xfs_bmap_del_extent_real.patch
queue-6.1/xfs-convert-rt-bitmap-extent-lengths-to-xfs_rtbxlen_t.patch
queue-6.1/xfs-pass-refcount-intent-directly-through-the-log-intent-code.patch
queue-6.1/xfs-fix-perag-leak-when-growfs-fails.patch
queue-6.1/xfs-pass-the-xfs_defer_pending-object-to-iop_recover.patch
queue-6.1/xfs-update-dir3-leaf-block-metadata-after-swap.patch
queue-6.1/xfs-use-deferred-frees-for-btree-block-freeing.patch
queue-6.1/xfs-make-rextslog-computation-consistent-with-mkfs.patch
queue-6.1/xfs-pass-xfs_extent_free_item-directly-through-the-log-intent-code.patch
queue-6.1/xfs-move-the-xfs_rtbitmap.c-declarations-to-xfs_rtbitmap.h.patch
queue-6.1/xfs-recompute-growfsrtfree-transaction-reservation-while-growing-rt-volume.patch
queue-6.1/xfs-reserve-less-log-space-when-recovering-log-intent-items.patch
queue-6.1/xfs-pass-the-xfs_bmbt_irec-directly-through-the-log-intent-code.patch
queue-6.1/xfs-force-all-buffers-to-be-written-during-btree-bulk-load.patch
queue-6.1/xfs-reset-xfs_attr_incomplete-filter-on-node-removal.patch
queue-6.1/xfs-add-lock-protection-when-remove-perag-from-radix-tree.patch
queue-6.1/xfs-use-xfs_defer_pending-objects-to-recover-intent-items.patch
queue-6.1/xfs-pass-per-ag-references-to-xfs_free_extent.patch
queue-6.1/xfs-validate-block-number-being-freed-before-adding-to-xefi.patch
queue-6.1/xfs-don-t-allow-overly-small-or-large-realtime-volumes.patch
queue-6.1/xfs-remove-conditional-building-of-rt-geometry-validator-functions.patch