FAILED: patch "[PATCH] io_uring: fix leaking reg files on exit" failed to apply to 5.10-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 084804002e512427bfe52b448cb7cac0d4209b64 Mon Sep 17 00:00:00 2001
From: Pavel Begunkov <[email protected]>
Date: Tue, 13 Apr 2021 02:58:38 +0100
Subject: [PATCH] io_uring: fix leaking reg files on exit
If io_sqe_files_unregister() faults on io_rsrc_ref_quiesce(), it will fail to do unregister leaving files referenced. And that may well happen because of a strayed signal or just because it does allocations inside.
In io_ring_ctx_free() do an unsafe version of unregister, as it's guaranteed to not have requests by that point and so quiesce is useless.
fs/io_uring.c +15 -14
@@ -7089,6 +7089,10 @@ static void __io_sqe_files_unregister(struct io_ring_ctx *ctx) fput(file); }#endif +io_free_file_tables (&ctx->file_table, ctx->nr_user_files); +kfree (ctx->file_data); + ctx->file_data =NULL ; + ctx->nr_user_files =0 ; }static inline void io_rsrc_ref_lock (struct io_ring_ctx *ctx)
@@ -7195,21 +7199,14 @@ static struct io_rsrc_data *io_rsrc_data_alloc(struct io_ring_ctx *ctx,static int io_sqe_files_unregister (struct io_ring_ctx *ctx) { -struct io_rsrc_data *data = ctx->file_data;int ret; -if (!data) +if (!ctx->file_data)return -ENXIO ; - ret =io_rsrc_ref_quiesce (data, ctx); -if (ret) -return ret; - -__io_sqe_files_unregister (ctx); -io_free_file_tables (&ctx->file_table, ctx->nr_user_files); -kfree (data); - ctx->file_data =NULL ; - ctx->nr_user_files =0 ; -return 0 ; + ret =io_rsrc_ref_quiesce (ctx->file_data, ctx); +if (!ret) +__io_sqe_files_unregister (ctx); +return ret; }static void io_sq_thread_unpark (struct io_sq_data *sqd)
@@ -7659,7 +7656,7 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, ret =io_sqe_files_scm (ctx);if (ret) { -io_sqe_files_unregister (ctx); +__io_sqe_files_unregister (ctx);return ret; }
@@ -8460,7 +8457,11 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx) }mutex_lock (&ctx->uring_lock); -io_sqe_files_unregister (ctx); +if (ctx->file_data) { +if (!atomic_dec_and_test (&ctx->file_data->refs)) +wait_for_completion (&ctx->file_data->done); +__io_sqe_files_unregister (ctx); + }if (ctx->rings)__io_cqring_overflow_flush (ctx, true);mutex_unlock (&ctx->uring_lock);