summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosef Bacik <josef@toxicpanda.com>2021-01-25 12:21:02 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-02-03 23:28:36 +0100
commit41f6f4a3143506ea1499cda2f14a16a2f82118a8 (patch)
treef6993528ac2ff858407e90cd8aee33c3ac03e1b6
parent51f58c4882ec7be6a439f8c0185ab9cc53111a7f (diff)
nbd: freeze the queue while we're adding connections
commit b98e762e3d71e893b221f871825dc64694cfb258 upstream. When setting up a device, we can krealloc the config->socks array to add new sockets to the configuration. However if we happen to get a IO request in at this point even though we aren't setup we could hit a UAF, as we deref config->socks without any locking, assuming that the configuration was setup already and that ->socks is safe to access it as we have a reference on the configuration. But there's nothing really preventing IO from occurring at this point of the device setup, we don't want to incur the overhead of a lock to access ->socks when it will never change while the device is running. To fix this UAF scenario simply freeze the queue if we are adding sockets. This will protect us from this particular case without adding any additional overhead for the normal running case. Cc: stable@vger.kernel.org Signed-off-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/block/nbd.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index aaae9220f3a0..bd5c04fabdab 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -1029,6 +1029,12 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
if (!sock)
return err;
+ /*
+ * We need to make sure we don't get any errant requests while we're
+ * reallocating the ->socks array.
+ */
+ blk_mq_freeze_queue(nbd->disk->queue);
+
if (!netlink && !nbd->task_setup &&
!test_bit(NBD_RT_BOUND, &config->runtime_flags))
nbd->task_setup = current;
@@ -1067,10 +1073,12 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
nsock->cookie = 0;
socks[config->num_connections++] = nsock;
atomic_inc(&config->live_connections);
+ blk_mq_unfreeze_queue(nbd->disk->queue);
return 0;
put_socket:
+ blk_mq_unfreeze_queue(nbd->disk->queue);
sockfd_put(sock);
return err;
}