ibmvfc_remove() tears down the CRQ and frees all host memory but never
calls ibmvfc_nvme_unregister().  The NVMe-FC transport therefore retains
a live reference to the local port whose private pointer points into the
now-freed ibmvfc_host, leading to a use-after-free whenever the transport
subsequently touches the port (queue creation, port scanning, etc.).

ibmvfc_nvme_unregister() is already called from the NPIV logout and host
reset paths during normal operation; driver removal simply missed it.

Add the call after ibmvfc_release_crq_queue() — at which point the CRQ
is torn down so no further completions can arrive — and before
ibmvfc_free_mem(), so host memory is still valid while
nvme_fc_unregister_localport() runs and waits for the
localport_delete callback to complete.

Fixes: 86e495358096 ("scsi: ibmvfc: implement LLDD callbacks for mapping 
nvme-fc queues")
Signed-off-by: Tyrel Datwyler <[email protected]>
---
 drivers/scsi/ibmvscsi/ibmvfc-core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c 
b/drivers/scsi/ibmvscsi/ibmvfc-core.c
index 190410847efb..7af1867b69c5 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc-core.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c
@@ -6995,6 +6995,8 @@ static void ibmvfc_remove(struct vio_dev *vdev)
        ibmvfc_release_sub_crqs(vhost);
        ibmvfc_release_crq_queue(vhost);
 
+       ibmvfc_nvme_unregister(vhost);
+
        ibmvfc_free_mem(vhost);
        spin_lock(&ibmvfc_driver_lock);
        list_del(&vhost->queue);
-- 
2.55.0


Reply via email to