--- /dev/null
+From 8802766324e1f5d414a81ac43365c20142e85603 Mon Sep 17 00:00:00 2001
+From: Pavel Begunkov <asml.silence@gmail.com>
+Date: Wed, 12 Feb 2025 13:46:46 +0000
+Subject: io_uring/kbuf: reallocate buf lists on upgrade
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+commit 8802766324e1f5d414a81ac43365c20142e85603 upstream.
+
+IORING_REGISTER_PBUF_RING can reuse an old struct io_buffer_list if it
+was created for legacy selected buffer and has been emptied. It violates
+the requirement that most of the field should stay stable after publish.
+Always reallocate it instead.
+
+Cc: stable@vger.kernel.org
+Reported-by: Pumpkin Chang <pumpkin@devco.re>
+Fixes: 2fcabce2d7d34 ("io_uring: disallow mixed provided buffer group registrations")
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/kbuf.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/io_uring/kbuf.c
++++ b/io_uring/kbuf.c
+@@ -301,6 +301,12 @@ void io_destroy_buffers(struct io_ring_c
+ }
+ }
+
++static void io_destroy_bl(struct io_ring_ctx *ctx, struct io_buffer_list *bl)
++{
++ xa_erase(&ctx->io_bl_xa, bl->bgid);
++ io_put_bl(ctx, bl);
++}
++
+ int io_remove_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+ {
+ struct io_provide_buf *p = io_kiocb_to_cmd(req, struct io_provide_buf);
+@@ -642,12 +648,13 @@ int io_register_pbuf_ring(struct io_ring
+ /* if mapped buffer ring OR classic exists, don't allow */
+ if (bl->is_mapped || !list_empty(&bl->buf_list))
+ return -EEXIST;
+- } else {
+- free_bl = bl = kzalloc(sizeof(*bl), GFP_KERNEL);
+- if (!bl)
+- return -ENOMEM;
++ io_destroy_bl(ctx, bl);
+ }
+
++ free_bl = bl = kzalloc(sizeof(*bl), GFP_KERNEL);
++ if (!bl)
++ return -ENOMEM;
++
+ if (!(reg.flags & IOU_PBUF_RING_MMAP))
+ ret = io_pin_pbuf_ring(®, bl);
+ else