mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 15:03:53 +02:00
io_uring/msg_ring: kill alloc_cache for io_kiocb allocations
Commit df8922afc37aa2111ca79a216653a629146763ad upstream. A recent commit:fc582cd26e
("io_uring/msg_ring: ensure io_kiocb freeing is deferred for RCU") fixed an issue with not deferring freeing of io_kiocb structs that msg_ring allocates to after the current RCU grace period. But this only covers requests that don't end up in the allocation cache. If a request goes into the alloc cache, it can get reused before it is sane to do so. A recent syzbot report would seem to indicate that there's something there, however it may very well just be because of the KASAN poisoning that the alloc_cache handles manually. Rather than attempt to make the alloc_cache sane for that use case, just drop the usage of the alloc_cache for msg_ring request payload data. Fixes:50cf5f3842
("io_uring/msg_ring: add an alloc cache for io_kiocb entries") Link: https://lore.kernel.org/io-uring/68cc2687.050a0220.139b6.0005.GAE@google.com/ Reported-by: syzbot+baa2e0f4e02df602583e@syzkaller.appspotmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
e6b2b4a0ff
commit
93e9d0293d
|
@ -400,9 +400,6 @@ struct io_ring_ctx {
|
|||
struct callback_head poll_wq_task_work;
|
||||
struct list_head defer_list;
|
||||
|
||||
struct io_alloc_cache msg_cache;
|
||||
spinlock_t msg_lock;
|
||||
|
||||
#ifdef CONFIG_NET_RX_BUSY_POLL
|
||||
struct list_head napi_list; /* track busy poll napi_id */
|
||||
spinlock_t napi_lock; /* napi_list lock */
|
||||
|
|
|
@ -316,9 +316,6 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
|
|||
sizeof(struct io_async_rw));
|
||||
ret |= io_alloc_cache_init(&ctx->uring_cache, IO_ALLOC_CACHE_MAX,
|
||||
sizeof(struct uring_cache));
|
||||
spin_lock_init(&ctx->msg_lock);
|
||||
ret |= io_alloc_cache_init(&ctx->msg_cache, IO_ALLOC_CACHE_MAX,
|
||||
sizeof(struct io_kiocb));
|
||||
ret |= io_futex_cache_init(ctx);
|
||||
if (ret)
|
||||
goto free_ref;
|
||||
|
@ -358,7 +355,6 @@ err:
|
|||
io_alloc_cache_free(&ctx->netmsg_cache, io_netmsg_cache_free);
|
||||
io_alloc_cache_free(&ctx->rw_cache, io_rw_cache_free);
|
||||
io_alloc_cache_free(&ctx->uring_cache, kfree);
|
||||
io_alloc_cache_free(&ctx->msg_cache, io_msg_cache_free);
|
||||
io_futex_cache_free(ctx);
|
||||
kfree(ctx->cancel_table.hbs);
|
||||
kfree(ctx->cancel_table_locked.hbs);
|
||||
|
@ -2743,7 +2739,6 @@ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx)
|
|||
io_alloc_cache_free(&ctx->netmsg_cache, io_netmsg_cache_free);
|
||||
io_alloc_cache_free(&ctx->rw_cache, io_rw_cache_free);
|
||||
io_alloc_cache_free(&ctx->uring_cache, kfree);
|
||||
io_alloc_cache_free(&ctx->msg_cache, io_msg_cache_free);
|
||||
io_futex_cache_free(ctx);
|
||||
io_destroy_buffers(ctx);
|
||||
mutex_unlock(&ctx->uring_lock);
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "io_uring.h"
|
||||
#include "rsrc.h"
|
||||
#include "filetable.h"
|
||||
#include "alloc_cache.h"
|
||||
#include "msg_ring.h"
|
||||
|
||||
/* All valid masks for MSG_RING */
|
||||
|
@ -76,13 +75,7 @@ static void io_msg_tw_complete(struct io_kiocb *req, struct io_tw_state *ts)
|
|||
struct io_ring_ctx *ctx = req->ctx;
|
||||
|
||||
io_add_aux_cqe(ctx, req->cqe.user_data, req->cqe.res, req->cqe.flags);
|
||||
if (spin_trylock(&ctx->msg_lock)) {
|
||||
if (io_alloc_cache_put(&ctx->msg_cache, req))
|
||||
req = NULL;
|
||||
spin_unlock(&ctx->msg_lock);
|
||||
}
|
||||
if (req)
|
||||
kfree_rcu(req, rcu_head);
|
||||
kfree_rcu(req, rcu_head);
|
||||
percpu_ref_put(&ctx->refs);
|
||||
}
|
||||
|
||||
|
@ -104,19 +97,6 @@ static int io_msg_remote_post(struct io_ring_ctx *ctx, struct io_kiocb *req,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct io_kiocb *io_msg_get_kiocb(struct io_ring_ctx *ctx)
|
||||
{
|
||||
struct io_kiocb *req = NULL;
|
||||
|
||||
if (spin_trylock(&ctx->msg_lock)) {
|
||||
req = io_alloc_cache_get(&ctx->msg_cache);
|
||||
spin_unlock(&ctx->msg_lock);
|
||||
if (req)
|
||||
return req;
|
||||
}
|
||||
return kmem_cache_alloc(req_cachep, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO);
|
||||
}
|
||||
|
||||
static int io_msg_data_remote(struct io_kiocb *req)
|
||||
{
|
||||
struct io_ring_ctx *target_ctx = req->file->private_data;
|
||||
|
@ -124,7 +104,7 @@ static int io_msg_data_remote(struct io_kiocb *req)
|
|||
struct io_kiocb *target;
|
||||
u32 flags = 0;
|
||||
|
||||
target = io_msg_get_kiocb(req->ctx);
|
||||
target = kmem_cache_alloc(req_cachep, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO);
|
||||
if (unlikely(!target))
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user