Commit 43454e83 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'io_uring-6.12-20241004' of git://git.kernel.dk/linux

Pull io_uring fixes from Jens Axboe:

 - Fix an error path memory leak, if one part fails to allocate.
   Obviously not something that'll generally hit without error
   injection.

 - Fix an io_req_flags_t cast to make sparse happier.

 - Improve the recv multishot termination. Not a bug now, but could be
   one in the future. This makes it do the same thing that recvmsg does
   in terms of when to terminate a request or not.

* tag 'io_uring-6.12-20241004' of git://git.kernel.dk/linux:
  io_uring/net: harden multishot termination case for recv
  io_uring: fix casts to io_req_flags_t
  io_uring: fix memory leak when cache init fail
parents e02f08e2 c314094c
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -321,7 +321,7 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
			    sizeof(struct io_kiocb));
	ret |= io_futex_cache_init(ctx);
	if (ret)
		goto err;
		goto free_ref;
	init_completion(&ctx->ref_comp);
	xa_init_flags(&ctx->personalities, XA_FLAGS_ALLOC1);
	mutex_init(&ctx->uring_lock);
@@ -349,6 +349,9 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
	io_napi_init(ctx);

	return ctx;

free_ref:
	percpu_ref_exit(&ctx->refs);
err:
	io_alloc_cache_free(&ctx->rsrc_node_cache, kfree);
	io_alloc_cache_free(&ctx->apoll_cache, kfree);
@@ -2038,7 +2041,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
	req->opcode = opcode = READ_ONCE(sqe->opcode);
	/* same numerical values with corresponding REQ_F_*, safe to copy */
	sqe_flags = READ_ONCE(sqe->flags);
	req->flags = (io_req_flags_t) sqe_flags;
	req->flags = (__force io_req_flags_t) sqe_flags;
	req->cqe.user_data = READ_ONCE(sqe->user_data);
	req->file = NULL;
	req->rsrc_node = NULL;
+3 −1
Original line number Diff line number Diff line
@@ -1133,6 +1133,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)
	int ret, min_ret = 0;
	bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
	size_t len = sr->len;
	bool mshot_finished;

	if (!(req->flags & REQ_F_POLLED) &&
	    (sr->flags & IORING_RECVSEND_POLL_FIRST))
@@ -1187,6 +1188,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)
		req_set_fail(req);
	}

	mshot_finished = ret <= 0;
	if (ret > 0)
		ret += sr->done_io;
	else if (sr->done_io)
@@ -1194,7 +1196,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)
	else
		io_kbuf_recycle(req, issue_flags);

	if (!io_recv_finish(req, &ret, kmsg, ret <= 0, issue_flags))
	if (!io_recv_finish(req, &ret, kmsg, mshot_finished, issue_flags))
		goto retry_multishot;

	return ret;