All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] fixes for syzbot reports
@ 2020-12-21 18:34 Pavel Begunkov
  2020-12-21 18:34 ` [PATCH 1/2] io_uring: fix ignoring xa_store errors Pavel Begunkov
  2020-12-21 18:34 ` [PATCH 2/2] io_uring: fix double io_uring free Pavel Begunkov
  0 siblings, 2 replies; 4+ messages in thread
From: Pavel Begunkov @ 2020-12-21 18:34 UTC (permalink / raw)
  To: Jens Axboe, io-uring

2/2 is io_uring double free reported multiple times,
For 1/1 we may leak uring file references and miss
cancellations for the creator task.

Pavel Begunkov (2):
  io_uring: fix ignoring xa_store errors
  io_uring: fix double io_uring free

 fs/io_uring.c | 79 +++++++++++++++++++++++++++++----------------------
 1 file changed, 45 insertions(+), 34 deletions(-)

-- 
2.24.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] io_uring: fix ignoring xa_store errors
  2020-12-21 18:34 [PATCH 0/2] fixes for syzbot reports Pavel Begunkov
@ 2020-12-21 18:34 ` Pavel Begunkov
  2020-12-21 23:27   ` Chaitanya Kulkarni
  2020-12-21 18:34 ` [PATCH 2/2] io_uring: fix double io_uring free Pavel Begunkov
  1 sibling, 1 reply; 4+ messages in thread
From: Pavel Begunkov @ 2020-12-21 18:34 UTC (permalink / raw)
  To: Jens Axboe, io-uring

xa_store() may fail, check the result.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 fs/io_uring.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index fbf747803dbc..846c635d0620 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -8852,10 +8852,9 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx,
 static int io_uring_add_task_file(struct io_ring_ctx *ctx, struct file *file)
 {
 	struct io_uring_task *tctx = current->io_uring;
+	int ret;
 
 	if (unlikely(!tctx)) {
-		int ret;
-
 		ret = io_uring_alloc_task_context(current);
 		if (unlikely(ret))
 			return ret;
@@ -8866,7 +8865,12 @@ static int io_uring_add_task_file(struct io_ring_ctx *ctx, struct file *file)
 
 		if (!old) {
 			get_file(file);
-			xa_store(&tctx->xa, (unsigned long)file, file, GFP_KERNEL);
+			ret = xa_err(xa_store(&tctx->xa, (unsigned long)file,
+						file, GFP_KERNEL));
+			if (ret) {
+				fput(file);
+				return ret;
+			}
 		}
 		tctx->last = file;
 	}
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] io_uring: fix double io_uring free
  2020-12-21 18:34 [PATCH 0/2] fixes for syzbot reports Pavel Begunkov
  2020-12-21 18:34 ` [PATCH 1/2] io_uring: fix ignoring xa_store errors Pavel Begunkov
@ 2020-12-21 18:34 ` Pavel Begunkov
  1 sibling, 0 replies; 4+ messages in thread
From: Pavel Begunkov @ 2020-12-21 18:34 UTC (permalink / raw)
  To: Jens Axboe, io-uring; +Cc: syzbot+c9937dfb2303a5f18640

Once we created a file for current context during setup, we should not
call io_ring_ctx_wait_and_kill() directly as it'll be done by fput(file)

Reported-by: syzbot+c9937dfb2303a5f18640@syzkaller.appspotmail.com
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 fs/io_uring.c | 69 ++++++++++++++++++++++++++++-----------------------
 1 file changed, 38 insertions(+), 31 deletions(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 846c635d0620..19ec1898b934 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -9379,55 +9379,52 @@ static int io_allocate_scq_urings(struct io_ring_ctx *ctx,
 	return 0;
 }
 
+static int io_uring_install_fd(struct io_ring_ctx *ctx, struct file *file)
+{
+	int ret, fd;
+
+	fd = get_unused_fd_flags(O_RDWR | O_CLOEXEC);
+	if (fd < 0)
+		return fd;
+
+	ret = io_uring_add_task_file(ctx, file);
+	if (ret) {
+		put_unused_fd(fd);
+		return ret;
+	}
+	fd_install(fd, file);
+	return fd;
+}
+
 /*
  * Allocate an anonymous fd, this is what constitutes the application
  * visible backing of an io_uring instance. The application mmaps this
  * fd to gain access to the SQ/CQ ring details. If UNIX sockets are enabled,
  * we have to tie this fd to a socket for file garbage collection purposes.
  */
-static int io_uring_get_fd(struct io_ring_ctx *ctx)
+static struct file *io_uring_get_file(struct io_ring_ctx *ctx)
 {
 	struct file *file;
 	int ret;
-	int fd;
 
 #if defined(CONFIG_UNIX)
 	ret = sock_create_kern(&init_net, PF_UNIX, SOCK_RAW, IPPROTO_IP,
 				&ctx->ring_sock);
 	if (ret)
-		return ret;
+		return ERR_PTR(ret);
 #endif
 
-	ret = get_unused_fd_flags(O_RDWR | O_CLOEXEC);
-	if (ret < 0)
-		goto err;
-	fd = ret;
-
 	file = anon_inode_getfile("[io_uring]", &io_uring_fops, ctx,
 					O_RDWR | O_CLOEXEC);
-	if (IS_ERR(file)) {
-		put_unused_fd(fd);
-		ret = PTR_ERR(file);
-		goto err;
-	}
-
 #if defined(CONFIG_UNIX)
-	ctx->ring_sock->file = file;
-#endif
-	ret = io_uring_add_task_file(ctx, file);
-	if (ret) {
-		fput(file);
-		put_unused_fd(fd);
-		goto err;
+	if (IS_ERR(file)) {
+		sock_release(ctx->ring_sock);
+		ctx->ring_sock = NULL;
+	} else {
+		ctx->ring_sock->file = file;
 	}
-	fd_install(fd, file);
-	return fd;
-err:
-#if defined(CONFIG_UNIX)
-	sock_release(ctx->ring_sock);
-	ctx->ring_sock = NULL;
 #endif
-	return ret;
+	return file;
 }
 
 static int io_uring_create(unsigned entries, struct io_uring_params *p,
@@ -9435,6 +9432,7 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p,
 {
 	struct user_struct *user = NULL;
 	struct io_ring_ctx *ctx;
+	struct file *file;
 	bool limit_mem;
 	int ret;
 
@@ -9582,13 +9580,22 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p,
 		goto err;
 	}
 
+	file = io_uring_get_file(ctx);
+	if (IS_ERR(file)) {
+		ret = PTR_ERR(file);
+		goto err;
+	}
+
 	/*
 	 * Install ring fd as the very last thing, so we don't risk someone
 	 * having closed it before we finish setup
 	 */
-	ret = io_uring_get_fd(ctx);
-	if (ret < 0)
-		goto err;
+	ret = io_uring_install_fd(ctx, file);
+	if (ret < 0) {
+		/* fput will clean it up */
+		fput(file);
+		return ret;
+	}
 
 	trace_io_uring_create(ret, ctx, p->sq_entries, p->cq_entries, p->flags);
 	return ret;
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] io_uring: fix ignoring xa_store errors
  2020-12-21 18:34 ` [PATCH 1/2] io_uring: fix ignoring xa_store errors Pavel Begunkov
@ 2020-12-21 23:27   ` Chaitanya Kulkarni
  0 siblings, 0 replies; 4+ messages in thread
From: Chaitanya Kulkarni @ 2020-12-21 23:27 UTC (permalink / raw)
  To: Pavel Begunkov, Jens Axboe, io-uring

On 12/21/20 10:40, Pavel Begunkov wrote:
> @@ -8866,7 +8865,12 @@ static int io_uring_add_task_file(struct io_ring_ctx *ctx, struct file *file)
>  
>  		if (!old) {
>  			get_file(file);
> -			xa_store(&tctx->xa, (unsigned long)file, file, GFP_KERNEL);
> +			ret = xa_err(xa_store(&tctx->xa, (unsigned long)file,
> +						file, GFP_KERNEL));
> +			if (ret) {
> +				fput(file);
> +				return ret;
> +			}
>  		}
>  		tctx->last = file;
>  	}
Looks good.

Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-12-21 23:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-21 18:34 [PATCH 0/2] fixes for syzbot reports Pavel Begunkov
2020-12-21 18:34 ` [PATCH 1/2] io_uring: fix ignoring xa_store errors Pavel Begunkov
2020-12-21 23:27   ` Chaitanya Kulkarni
2020-12-21 18:34 ` [PATCH 2/2] io_uring: fix double io_uring free Pavel Begunkov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.