The function nbd_add_socket use krealloc to expand the config->socks array when adding new sockets. If I/O operations concurrently, this can lead to UAF when accessing config->socks. Commit b98e762e3d71 ("nbd: freeze the queue while we're adding connections") addressed this by freezing the request_queue during the addtion. However, freezing and unfreezing for multiprocess environments introduces noticeable latency, espically there can be multi call for nbd_add_socket when one nbd setup. Actually, after previous commit, nbd_add_socket cannot be called after nbd_start_device, causing the device's capabilities to remain 0 and write cache disabled. This will make sure no I/O can happened simultaneously(nbd accept I/O from bio): - read/write bios with sectors are rejected by bio_check_eod in submit_bio_noacct - flush-only bio for write cache disabled device will directly return 0 in submit_bio_noacct (ps: we cannot enable write_cache for nbd device since without BLK_FEAT_WRITE_CACHE) Removing the freeze in nbd_add_socket to speed up nbd device startup. Signed-off-by: Yang Erkun --- drivers/block/nbd.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 7ec85f94f742..1a31e621b6f7 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1272,7 +1272,6 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, struct socket *sock; struct nbd_sock **socks; struct nbd_sock *nsock; - unsigned int memflags; int err; /* Arg will be cast to int, check it to avoid overflow */ @@ -1290,12 +1289,6 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, return err; nbd_reclassify_socket(sock); - /* - * We need to make sure we don't get any errant requests while we're - * reallocating the ->socks array. - */ - memflags = blk_mq_freeze_queue(nbd->disk->queue); - if (!netlink && !nbd->task_setup && !test_bit(NBD_RT_BOUND, &config->runtime_flags)) nbd->task_setup = current; @@ -1335,12 +1328,10 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, INIT_WORK(&nsock->work, nbd_pending_cmd_work); socks[config->num_connections++] = nsock; atomic_inc(&config->live_connections); - blk_mq_unfreeze_queue(nbd->disk->queue, memflags); return 0; put_socket: - blk_mq_unfreeze_queue(nbd->disk->queue, memflags); sockfd_put(sock); return err; } -- 2.52.0