scsi: qla2xxx: Fix gnl.l memory leak on adapter init failure [Linux 4.19.72]

This Linux kernel change "scsi: qla2xxx: Fix gnl.l memory leak on adapter init failure" is included in the Linux 4.19.72 release. This change is authored by Bill Kuzeja <William.Kuzeja [at] stratus.com> on Wed Aug 14 10:24:41 2019 -0400. The commit for this change in Linux stable tree is 6c9a1e1 (patch) which is from upstream commit 26fa656. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 26fa656.

scsi: qla2xxx: Fix gnl.l memory leak on adapter init failure

[ Upstream commit 26fa656e9a0cbccddf7db132ea020d2169dbe46e ]

If HBA initialization fails unexpectedly (exiting via probe_failed:), we
may fail to free vha->gnl.l. So that we don't attempt to double free, set
this pointer to NULL after a free and check for NULL at probe_failed: so we
know whether or not to call dma_free_coherent.

Signed-off-by: Bill Kuzeja <william.kuzeja@stratus.com>
Acked-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>

There are 13 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/scsi/qla2xxx/qla_attr.c |  2 ++
 drivers/scsi/qla2xxx/qla_os.c   | 11 ++++++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index f8f4d3e..15d493f3 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -2191,6 +2191,8 @@ struct device_attribute *qla2x00_host_attrs[] = {
    dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l,
        vha->gnl.ldma);

+   vha->gnl.l = NULL;
+
    vfree(vha->scan.l);

    if (vha->qpair && vha->qpair->vp_idx == vha->vp_idx) {
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 42b8f0d..02fa81f 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3395,6 +3395,12 @@ static void qla2x00_iocb_work_fn(struct work_struct *work)
    return 0;

 probe_failed:
+   if (base_vha->gnl.l) {
+       dma_free_coherent(&ha->pdev->dev, base_vha->gnl.size,
+               base_vha->gnl.l, base_vha->gnl.ldma);
+       base_vha->gnl.l = NULL;
+   }
+
    if (base_vha->timer_active)
        qla2x00_stop_timer(base_vha);
    base_vha->flags.online = 0;
@@ -3624,7 +3630,7 @@ static void qla2x00_iocb_work_fn(struct work_struct *work)
    if (!atomic_read(&pdev->enable_cnt)) {
        dma_free_coherent(&ha->pdev->dev, base_vha->gnl.size,
            base_vha->gnl.l, base_vha->gnl.ldma);
-
+       base_vha->gnl.l = NULL;
        scsi_host_put(base_vha->host);
        kfree(ha);
        pci_set_drvdata(pdev, NULL);
@@ -3663,6 +3669,8 @@ static void qla2x00_iocb_work_fn(struct work_struct *work)
    dma_free_coherent(&ha->pdev->dev,
        base_vha->gnl.size, base_vha->gnl.l, base_vha->gnl.ldma);

+   base_vha->gnl.l = NULL;
+
    vfree(base_vha->scan.l);

    if (IS_QLAFX00(ha))
@@ -4602,6 +4610,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
            "Alloc failed for scan database.\n");
        dma_free_coherent(&ha->pdev->dev, vha->gnl.size,
            vha->gnl.l, vha->gnl.ldma);
+       vha->gnl.l = NULL;
        scsi_remove_host(vha->host);
        return NULL;
    }

Leave a Reply

Your email address will not be published. Required fields are marked *