Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: enetc: unmap DMA in enetc_send_cmd()

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>

authored by

Tim Gardner and committed by
David S. Miller
cd4bc63d 5b92be64

+11 -7
+11 -7
drivers/net/ethernet/freescale/enetc/enetc_qos.c
··· 486 486 487 487 data_size = sizeof(struct streamid_data); 488 488 si_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); 489 + if (!si_data) 490 + return -ENOMEM; 489 491 cbd.length = cpu_to_le16(data_size); 490 492 491 493 dma = dma_map_single(&priv->si->pdev->dev, si_data, 492 494 data_size, DMA_FROM_DEVICE); 493 495 if (dma_mapping_error(&priv->si->pdev->dev, dma)) { 494 496 netdev_err(priv->si->ndev, "DMA mapping failed!\n"); 495 - kfree(si_data); 496 - return -ENOMEM; 497 + err = -ENOMEM; 498 + goto out; 497 499 } 498 500 499 501 cbd.addr[0] = cpu_to_le32(lower_32_bits(dma)); ··· 514 512 515 513 err = enetc_send_cmd(priv->si, &cbd); 516 514 if (err) 517 - return -EINVAL; 515 + goto out; 518 516 519 - if (!enable) { 520 - kfree(si_data); 521 - return 0; 522 - } 517 + if (!enable) 518 + goto out; 523 519 524 520 /* Enable the entry overwrite again incase space flushed by hardware */ 525 521 memset(&cbd, 0, sizeof(cbd)); ··· 560 560 } 561 561 562 562 err = enetc_send_cmd(priv->si, &cbd); 563 + out: 564 + if (!dma_mapping_error(&priv->si->pdev->dev, dma)) 565 + dma_unmap_single(&priv->si->pdev->dev, dma, data_size, DMA_FROM_DEVICE); 566 + 563 567 kfree(si_data); 564 568 565 569 return err;