net: enetc: unmap DMA in enetc_send_cmd()
authorTim Gardner <tim.gardner@canonical.com>
Tue, 19 Oct 2021 18:19:50 +0000 (12:19 -0600)
committerDavid S. Miller <davem@davemloft.net>
Wed, 20 Oct 2021 13:32:15 +0000 (14:32 +0100)
Coverity complains of a possible dereference of a null return value.

    5. returned_null: kzalloc returns NULL. [show details]
    6. var_assigned: Assigning: si_data = NULL return value from kzalloc.
488        si_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL);
489        cbd.length = cpu_to_le16(data_size);
490
491        dma = dma_map_single(&priv->si->pdev->dev, si_data,
492                             data_size, DMA_FROM_DEVICE);

While this kzalloc() is unlikely to fail, I did notice that the function
returned without unmapping si_data.

Fix this by refactoring the error paths and checking for kzalloc()
failure.

Fixes: 888ae5a3952ba ("net: enetc: add tc flower psfp offload driver")
Cc: Claudiu Manoil <claudiu.manoil@nxp.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org (open list)
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Acked-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/freescale/enetc/enetc_qos.c

index 4577226..0536d2c 100644 (file)
@@ -486,14 +486,16 @@ static int enetc_streamid_hw_set(struct enetc_ndev_priv *priv,
 
        data_size = sizeof(struct streamid_data);
        si_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL);
+       if (!si_data)
+               return -ENOMEM;
        cbd.length = cpu_to_le16(data_size);
 
        dma = dma_map_single(&priv->si->pdev->dev, si_data,
                             data_size, DMA_FROM_DEVICE);
        if (dma_mapping_error(&priv->si->pdev->dev, dma)) {
                netdev_err(priv->si->ndev, "DMA mapping failed!\n");
-               kfree(si_data);
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto out;
        }
 
        cbd.addr[0] = cpu_to_le32(lower_32_bits(dma));
@@ -512,12 +514,10 @@ static int enetc_streamid_hw_set(struct enetc_ndev_priv *priv,
 
        err = enetc_send_cmd(priv->si, &cbd);
        if (err)
-               return -EINVAL;
+               goto out;
 
-       if (!enable) {
-               kfree(si_data);
-               return 0;
-       }
+       if (!enable)
+               goto out;
 
        /* Enable the entry overwrite again incase space flushed by hardware */
        memset(&cbd, 0, sizeof(cbd));
@@ -560,6 +560,10 @@ static int enetc_streamid_hw_set(struct enetc_ndev_priv *priv,
        }
 
        err = enetc_send_cmd(priv->si, &cbd);
+out:
+       if (!dma_mapping_error(&priv->si->pdev->dev, dma))
+               dma_unmap_single(&priv->si->pdev->dev, dma, data_size, DMA_FROM_DEVICE);
+
        kfree(si_data);
 
        return err;