Commit 255da9b8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'io_uring-6.16-20250619' of git://git.kernel.dk/linux

Pull io_uring fixes from Jens Axboe:

 - Two fixes for error injection failures. One fixes a task leak issue
   introduced in this merge window, the other an older issue with
   handling allocation of a mapped buffer.

 - Fix for a syzbot issue that triggers a kmalloc warning on attempting
   an allocation that's too large

 - Fix for an error injection failure causing a double put of a task,
   introduced in this merge window

* tag 'io_uring-6.16-20250619' of git://git.kernel.dk/linux:
  io_uring: fix potential page leak in io_sqe_buffer_register()
  io_uring/sqpoll: don't put task_struct on tctx setup failure
  io_uring: remove duplicate io_uring_alloc_task_context() definition
  io_uring: fix task leak issue in io_wq_create()
  io_uring/rsrc: validate buffer count with offset for cloning
parents 5f2b6c5f e1c75831
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -1259,8 +1259,10 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
	atomic_set(&wq->worker_refs, 1);
	init_completion(&wq->worker_done);
	ret = cpuhp_state_add_instance_nocalls(io_wq_online, &wq->cpuhp_node);
	if (ret)
	if (ret) {
		put_task_struct(wq->task);
		goto err;
	}

	return wq;
err:
+0 −2
Original line number Diff line number Diff line
@@ -98,8 +98,6 @@ struct llist_node *io_handle_tw_list(struct llist_node *node, unsigned int *coun
struct llist_node *tctx_task_work_run(struct io_uring_task *tctx, unsigned int max_entries, unsigned int *count);
void tctx_task_work(struct callback_head *cb);
__cold void io_uring_cancel_generic(bool cancel_all, struct io_sq_data *sqd);
int io_uring_alloc_task_context(struct task_struct *task,
				struct io_ring_ctx *ctx);

int io_ring_add_registered_file(struct io_uring_task *tctx, struct file *file,
				     int start, int end);
+5 −3
Original line number Diff line number Diff line
@@ -809,10 +809,8 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,

	imu->nr_bvecs = nr_pages;
	ret = io_buffer_account_pin(ctx, pages, nr_pages, imu, last_hpage);
	if (ret) {
		unpin_user_pages(pages, nr_pages);
	if (ret)
		goto done;
	}

	size = iov->iov_len;
	/* store original address for later verification */
@@ -842,6 +840,8 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,
	if (ret) {
		if (imu)
			io_free_imu(ctx, imu);
		if (pages)
			unpin_user_pages(pages, nr_pages);
		io_cache_free(&ctx->node_cache, node);
		node = ERR_PTR(ret);
	}
@@ -1177,6 +1177,8 @@ static int io_clone_buffers(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx
		return -EINVAL;
	if (check_add_overflow(arg->nr, arg->dst_off, &nbufs))
		return -EOVERFLOW;
	if (nbufs > IORING_MAX_REG_BUFFERS)
		return -EINVAL;

	ret = io_rsrc_data_alloc(&data, max(nbufs, ctx->buf_table.nr));
	if (ret)
+2 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <uapi/linux/io_uring.h>

#include "io_uring.h"
#include "tctx.h"
#include "napi.h"
#include "sqpoll.h"

@@ -419,7 +420,6 @@ void io_sqpoll_wait_sq(struct io_ring_ctx *ctx)
__cold int io_sq_offload_create(struct io_ring_ctx *ctx,
				struct io_uring_params *p)
{
	struct task_struct *task_to_put = NULL;
	int ret;

	/* Retain compatibility with failing for an invalid attach attempt */
@@ -498,7 +498,7 @@ __cold int io_sq_offload_create(struct io_ring_ctx *ctx,
		rcu_assign_pointer(sqd->thread, tsk);
		mutex_unlock(&sqd->lock);

		task_to_put = get_task_struct(tsk);
		get_task_struct(tsk);
		ret = io_uring_alloc_task_context(tsk, ctx);
		wake_up_new_task(tsk);
		if (ret)
@@ -513,8 +513,6 @@ __cold int io_sq_offload_create(struct io_ring_ctx *ctx,
	complete(&ctx->sq_data->exited);
err:
	io_sq_thread_finish(ctx);
	if (task_to_put)
		put_task_struct(task_to_put);
	return ret;
}