Skip to content

Commit 3c82292

Browse files
israelrugregkh
authored andcommitted
nvmet-rdma: fix use-after-free when a port is removed
[ Upstream commit fcf73a8 ] When removing a port, all its controllers are being removed, but there are queues on the port that doesn't belong to any controller (during connection time). This causes a use-after-free bug for any command that dereferences req->port (like in nvmet_alloc_ctrl). Those queues should be destroyed before freeing the port via configfs. Destroy the remaining queues after the RDMA-CM was destroyed guarantees that no new queue will be created. Signed-off-by: Israel Rukshin <[email protected]> Reviewed-by: Max Gurtovoy <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent e3d5ebe commit 3c82292

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

drivers/nvme/target/rdma.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,12 +1818,36 @@ static void nvmet_rdma_delete_ctrl(struct nvmet_ctrl *ctrl)
18181818
mutex_unlock(&nvmet_rdma_queue_mutex);
18191819
}
18201820

1821+
static void nvmet_rdma_destroy_port_queues(struct nvmet_rdma_port *port)
1822+
{
1823+
struct nvmet_rdma_queue *queue, *tmp;
1824+
struct nvmet_port *nport = port->nport;
1825+
1826+
mutex_lock(&nvmet_rdma_queue_mutex);
1827+
list_for_each_entry_safe(queue, tmp, &nvmet_rdma_queue_list,
1828+
queue_list) {
1829+
if (queue->port != nport)
1830+
continue;
1831+
1832+
list_del_init(&queue->queue_list);
1833+
__nvmet_rdma_queue_disconnect(queue);
1834+
}
1835+
mutex_unlock(&nvmet_rdma_queue_mutex);
1836+
}
1837+
18211838
static void nvmet_rdma_disable_port(struct nvmet_rdma_port *port)
18221839
{
18231840
struct rdma_cm_id *cm_id = xchg(&port->cm_id, NULL);
18241841

18251842
if (cm_id)
18261843
rdma_destroy_id(cm_id);
1844+
1845+
/*
1846+
* Destroy the remaining queues, which are not belong to any
1847+
* controller yet. Do it here after the RDMA-CM was destroyed
1848+
* guarantees that no new queue will be created.
1849+
*/
1850+
nvmet_rdma_destroy_port_queues(port);
18271851
}
18281852

18291853
static int nvmet_rdma_enable_port(struct nvmet_rdma_port *port)

0 commit comments

Comments
 (0)