Commit 6f3b6e91 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'io_uring-6.18-20251016' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux

Pull io_uring fixes from Jens Axboe:

 - Revert of a change that went into an older kernel, and which has been
   reported to cause a regression for some write workloads on LVM while
   a snapshop is being created

 - Fix a regression from this merge window, where some compilers (and/or
   certain .config options) would cause an earlier evaluations of a
   dereference which would then cause a NULL pointer dereference.

   I was only able to reproduce this with OPTIMIZE_FOR_SIZE=y, but David
   Howells hit it with just KASAN enabled. Depending on how things
   inlined, this makes sense

 - Fix for a missing lock around a mem region unregistration

 - Fix for ring resizing with the same placement after resize

* tag 'io_uring-6.18-20251016' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux:
  io_uring/rw: check for NULL io_br_sel when putting a buffer
  io_uring: fix unexpected placement on same size resizing
  io_uring: protect mem region deregistration
  Revert "io_uring/rw: drop -EOPNOTSUPP check in __io_complete_rw_common()"
parents 0c8df15f 18d6b174
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
@@ -421,13 +421,6 @@ static int io_register_resize_rings(struct io_ring_ctx *ctx, void __user *arg)
	if (unlikely(ret))
		return ret;

	/* nothing to do, but copy params back */
	if (p.sq_entries == ctx->sq_entries && p.cq_entries == ctx->cq_entries) {
		if (copy_to_user(arg, &p, sizeof(p)))
			return -EFAULT;
		return 0;
	}

	size = rings_size(p.flags, p.sq_entries, p.cq_entries,
				&sq_array_offset);
	if (size == SIZE_MAX)
@@ -613,6 +606,7 @@ static int io_register_mem_region(struct io_ring_ctx *ctx, void __user *uarg)
	if (ret)
		return ret;
	if (copy_to_user(rd_uptr, &rd, sizeof(rd))) {
		guard(mutex)(&ctx->mmap_lock);
		io_free_region(ctx, &ctx->param_region);
		return -EFAULT;
	}
+6 −2
Original line number Diff line number Diff line
@@ -542,7 +542,7 @@ static void __io_complete_rw_common(struct io_kiocb *req, long res)
{
	if (res == req->cqe.res)
		return;
	if (res == -EAGAIN && io_rw_should_reissue(req)) {
	if ((res == -EOPNOTSUPP || res == -EAGAIN) && io_rw_should_reissue(req)) {
		req->flags |= REQ_F_REISSUE | REQ_F_BL_NO_RECYCLE;
	} else {
		req_set_fail(req);
@@ -655,13 +655,17 @@ static int kiocb_done(struct io_kiocb *req, ssize_t ret,
	if (ret >= 0 && req->flags & REQ_F_CUR_POS)
		req->file->f_pos = rw->kiocb.ki_pos;
	if (ret >= 0 && !(req->ctx->flags & IORING_SETUP_IOPOLL)) {
		u32 cflags = 0;

		__io_complete_rw_common(req, ret);
		/*
		 * Safe to call io_end from here as we're inline
		 * from the submission path.
		 */
		io_req_io_end(req);
		io_req_set_res(req, final_ret, io_put_kbuf(req, ret, sel->buf_list));
		if (sel)
			cflags = io_put_kbuf(req, ret, sel->buf_list);
		io_req_set_res(req, final_ret, cflags);
		io_req_rw_cleanup(req, issue_flags);
		return IOU_COMPLETE;
	} else {