nvmet: fix NULL dereference of PCI endpoint targets

nvmet_pci_epf_create_ctrl() calls nvmet_alloc_ctrl() without a queue,
the admin queue comes later from the host. nvmet_alloc_ctrl() passes
args->sq to nvmet_queue_tls_keyid(), which with
CONFIG_NVME_TARGET_TCP_TLS dereferences it, so every PCI endpoint
controller creation crashes on such a kernel. The debugfs tls_key file
passes ctrl->sqs[0] to the same function, which is NULL until the admin
queue exists and again once a fabrics host has closed it while keeping
an I/O queue.

A queue that isn't there has no TLS key.

Fixes: fa2e0f8bbc ("nvmet-tcp: support secure channel concatenation")
Cc: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Keith Busch <kbusch@kernel.org>
This commit is contained in:
Josef Bacik 2026-10-28 10:42:15 -06:00 committed by Keith Busch
parent 7dd1d31e2e
commit 4a5ace11b5

View File

@ -957,7 +957,8 @@ static inline void nvmet_req_bio_put(struct nvmet_req *req, struct bio *bio)
#ifdef CONFIG_NVME_TARGET_TCP_TLS
static inline key_serial_t nvmet_queue_tls_keyid(struct nvmet_sq *sq)
{
return sq->tls_key ? key_serial(sq->tls_key) : 0;
/* A PCI endpoint controller is created without a queue */
return sq && sq->tls_key ? key_serial(sq->tls_key) : 0;
}
static inline void nvmet_sq_put_tls_key(struct nvmet_sq *sq)
{