Commit 236434c3 authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle) Committed by Jens Axboe
Browse files

io_uring: Fix XArray usage in io_uring_add_task_file



The xas_store() wasn't paired with an xas_nomem() loop, so if it couldn't
allocate memory using GFP_NOWAIT, it would leak the reference to the file
descriptor.  Also the node pointed to by the xas could be freed between
the call to xas_load() under the rcu_read_lock() and the acquisition of
the xa_lock.

It's easier to just use the normal xa_load/xa_store interface here.

Signed-off-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
[axboe: fix missing assign after alloc, cur_uring -> tctx rename]
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent ce765372
Loading
Loading
Loading
Loading
+9 −12
Original line number Diff line number Diff line
@@ -8586,27 +8586,24 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx,
 */
static int io_uring_add_task_file(struct file *file)
{
	if (unlikely(!current->io_uring)) {
	struct io_uring_task *tctx = current->io_uring;

	if (unlikely(!tctx)) {
		int ret;

		ret = io_uring_alloc_task_context(current);
		if (unlikely(ret))
			return ret;
		tctx = current->io_uring;
	}
	if (current->io_uring->last != file) {
		XA_STATE(xas, &current->io_uring->xa, (unsigned long) file);
		void *old;
	if (tctx->last != file) {
		void *old = xa_load(&tctx->xa, (unsigned long)file);

		rcu_read_lock();
		old = xas_load(&xas);
		if (old != file) {
		if (!old) {
			get_file(file);
			xas_lock(&xas);
			xas_store(&xas, file);
			xas_unlock(&xas);
			xa_store(&tctx->xa, (unsigned long)file, file, GFP_KERNEL);
		}
		rcu_read_unlock();
		current->io_uring->last = file;
		tctx->last = file;
	}

	return 0;