summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_log_recover.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2023-11-22 21:47:10 +0300
committerDarrick J. Wong <djwong@kernel.org>2023-12-07 05:45:14 +0300
commitdeb4cd8ba87f17b12c72b3827820d9c703e9fd95 (patch)
tree98a85e6dca65337a4ce0ce7b9e30d71094cdda1a /fs/xfs/xfs_log_recover.c
parenta050acdfa8003a44eae4558fddafc7afb1aef458 (diff)
downloadlinux-deb4cd8ba87f17b12c72b3827820d9c703e9fd95.tar.xz
xfs: transfer recovered intent item ownership in ->iop_recover
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 <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r--fs/xfs/xfs_log_recover.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index ff768217f2c7..cc14cd1c2282 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2590,13 +2590,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)
@@ -2631,6 +2624,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.
*/