net: ethernet: nixge: fix NULL dereference
authorYuri Karpov <YKarpov@ispras.ru>
Thu, 24 Nov 2022 08:43:03 +0000 (11:43 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 8 Dec 2022 10:28:41 +0000 (11:28 +0100)
[ Upstream commit 9256db4e45e8b497b0e993cc3ed4ad08eb2389b6 ]

In function nixge_hw_dma_bd_release() dereference of NULL pointer
priv->rx_bd_v is possible for the case of its allocation failure in
nixge_hw_dma_bd_init().

Move for() loop with priv->rx_bd_v dereference under the check for
its validity.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 492caffa8a1a ("net: ethernet: nixge: Add support for National Instruments XGE netdev")
Signed-off-by: Yuri Karpov <YKarpov@ispras.ru>
Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/ni/nixge.c

index 057b741..5d0cecf 100644 (file)
@@ -249,25 +249,26 @@ static void nixge_hw_dma_bd_release(struct net_device *ndev)
        struct sk_buff *skb;
        int i;
 
-       for (i = 0; i < RX_BD_NUM; i++) {
-               phys_addr = nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
-                                                    phys);
-
-               dma_unmap_single(ndev->dev.parent, phys_addr,
-                                NIXGE_MAX_JUMBO_FRAME_SIZE,
-                                DMA_FROM_DEVICE);
-
-               skb = (struct sk_buff *)(uintptr_t)
-                       nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
-                                                sw_id_offset);
-               dev_kfree_skb(skb);
-       }
+       if (priv->rx_bd_v) {
+               for (i = 0; i < RX_BD_NUM; i++) {
+                       phys_addr = nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
+                                                            phys);
+
+                       dma_unmap_single(ndev->dev.parent, phys_addr,
+                                        NIXGE_MAX_JUMBO_FRAME_SIZE,
+                                        DMA_FROM_DEVICE);
+
+                       skb = (struct sk_buff *)(uintptr_t)
+                               nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
+                                                        sw_id_offset);
+                       dev_kfree_skb(skb);
+               }
 
-       if (priv->rx_bd_v)
                dma_free_coherent(ndev->dev.parent,
                                  sizeof(*priv->rx_bd_v) * RX_BD_NUM,
                                  priv->rx_bd_v,
                                  priv->rx_bd_p);
+       }
 
        if (priv->tx_skb)
                devm_kfree(ndev->dev.parent, priv->tx_skb);