--- /dev/null
+From 7eb75ce7527129d7f1fee6951566af409a37a1c4 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Fri, 29 Nov 2024 07:20:28 -0700
+Subject: io_uring/tctx: work around xa_store() allocation error issue
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit 7eb75ce7527129d7f1fee6951566af409a37a1c4 upstream.
+
+syzbot triggered the following WARN_ON:
+
+WARNING: CPU: 0 PID: 16 at io_uring/tctx.c:51 __io_uring_free+0xfa/0x140 io_uring/tctx.c:51
+
+which is the
+
+WARN_ON_ONCE(!xa_empty(&tctx->xa));
+
+sanity check in __io_uring_free() when a io_uring_task is going through
+its final put. The syzbot test case includes injecting memory allocation
+failures, and it very much looks like xa_store() can fail one of its
+memory allocations and end up with ->head being non-NULL even though no
+entries exist in the xarray.
+
+Until this issue gets sorted out, work around it by attempting to
+iterate entries in our xarray, and WARN_ON_ONCE() if one is found.
+
+Reported-by: syzbot+cc36d44ec9f368e443d3@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/io-uring/673c1643.050a0220.87769.0066.GAE@google.com/
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+[ Modify the function in io_uring.c because it's located here in v5.15. ]
+Signed-off-by: Robert Garcia <rob_garcia@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/io_uring.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -8524,8 +8524,19 @@ static int io_uring_alloc_task_context(s
+ void __io_uring_free(struct task_struct *tsk)
+ {
+ struct io_uring_task *tctx = tsk->io_uring;
++ struct io_tctx_node *node;
++ unsigned long index;
+
+- WARN_ON_ONCE(!xa_empty(&tctx->xa));
++ /*
++ * Fault injection forcing allocation errors in the xa_store() path
++ * can lead to xa_empty() returning false, even though no actual
++ * node is stored in the xarray. Until that gets sorted out, attempt
++ * an iteration here and warn if any entries are found.
++ */
++ xa_for_each(&tctx->xa, index, node) {
++ WARN_ON_ONCE(1);
++ break;
++ }
+ WARN_ON_ONCE(tctx->io_wq);
+ WARN_ON_ONCE(tctx->cached_refs);
+