Commit 8d2fa6af authored by Pavel Begunkov's avatar Pavel Begunkov Committed by Wentao Guan
Browse files

io_uring/kbuf: reallocate buf lists on upgrade

stable inclusion
from stable-v6.6.79
commit 146a185f6c05ee263db715f860620606303c4633
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBXANC

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=146a185f6c05ee263db715f860620606303c4633



--------------------------------

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: default avatarPumpkin Chang <pumpkin@devco.re>
Fixes: 2fcabce2 ("io_uring: disallow mixed provided buffer group registrations")
Signed-off-by: default avatarPavel Begunkov <asml.silence@gmail.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 146a185f6c05ee263db715f860620606303c4633)
Signed-off-by: default avatarWentao Guan <guanwentao@uniontech.com>
parent 1946ceb7
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -301,6 +301,12 @@ void io_destroy_buffers(struct io_ring_ctx *ctx)
	}
}

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,11 +648,12 @@ int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg)
		/* if mapped buffer ring OR classic exists, don't allow */
		if (bl->is_mapped || !list_empty(&bl->buf_list))
			return -EEXIST;
	} else {
		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(&reg, bl);