lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20241211083424.2580563-1-make_ruc2021@163.com>
Date: Wed, 11 Dec 2024 16:34:24 +0800
From: Ma Ke <make_ruc2021@....com>
To: andrew+netdev@...n.ch,
	davem@...emloft.net,
	edumazet@...gle.com,
	kuba@...nel.org,
	pabeni@...hat.com,
	make_ruc2021@....com,
	shannon.nelson@....com,
	sd@...asysnail.net,
	u.kleine-koenig@...libre.com,
	mdf@...nel.org
Cc: netdev@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	stable@...r.kernel.org
Subject: [PATCH] net: ethernet: fix NULL dereference in nixge_recv()

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

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

Cc: stable@...r.kernel.org
Fixes: 492caffa8a1a ("net: ethernet: nixge: Add support for National Instruments XGE netdev")
Signed-off-by: Ma Ke <make_ruc2021@....com>
---
 drivers/net/ethernet/ni/nixge.c | 86 ++++++++++++++++-----------------
 1 file changed, 43 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c
index 230d5ff99dd7..2935ffd62e2a 100644
--- a/drivers/net/ethernet/ni/nixge.c
+++ b/drivers/net/ethernet/ni/nixge.c
@@ -603,64 +603,64 @@ static int nixge_recv(struct net_device *ndev, int budget)
 	u32 size = 0;
 
 	cur_p = &priv->rx_bd_v[priv->rx_bd_ci];
+	if (priv->rx_bd_v) {
+		while ((cur_p->status & XAXIDMA_BD_STS_COMPLETE_MASK &&
+			budget > packets)) {
+			tail_p = priv->rx_bd_p + sizeof(*priv->rx_bd_v) *
+				 priv->rx_bd_ci;
 
-	while ((cur_p->status & XAXIDMA_BD_STS_COMPLETE_MASK &&
-		budget > packets)) {
-		tail_p = priv->rx_bd_p + sizeof(*priv->rx_bd_v) *
-			 priv->rx_bd_ci;
+			skb = (struct sk_buff *)(uintptr_t)
+				nixge_hw_dma_bd_get_addr(cur_p, sw_id_offset);
 
-		skb = (struct sk_buff *)(uintptr_t)
-			nixge_hw_dma_bd_get_addr(cur_p, sw_id_offset);
+			length = cur_p->status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK;
+			if (length > NIXGE_MAX_JUMBO_FRAME_SIZE)
+				length = NIXGE_MAX_JUMBO_FRAME_SIZE;
 
-		length = cur_p->status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK;
-		if (length > NIXGE_MAX_JUMBO_FRAME_SIZE)
-			length = NIXGE_MAX_JUMBO_FRAME_SIZE;
+			dma_unmap_single(ndev->dev.parent,
+					 nixge_hw_dma_bd_get_addr(cur_p, phys),
+					 NIXGE_MAX_JUMBO_FRAME_SIZE,
+					 DMA_FROM_DEVICE);
 
-		dma_unmap_single(ndev->dev.parent,
-				 nixge_hw_dma_bd_get_addr(cur_p, phys),
-				 NIXGE_MAX_JUMBO_FRAME_SIZE,
-				 DMA_FROM_DEVICE);
+			skb_put(skb, length);
 
-		skb_put(skb, length);
+			skb->protocol = eth_type_trans(skb, ndev);
+			skb_checksum_none_assert(skb);
 
-		skb->protocol = eth_type_trans(skb, ndev);
-		skb_checksum_none_assert(skb);
+			/* For now mark them as CHECKSUM_NONE since
+			 * we don't have offload capabilities
+			 */
+			skb->ip_summed = CHECKSUM_NONE;
 
-		/* For now mark them as CHECKSUM_NONE since
-		 * we don't have offload capabilities
-		 */
-		skb->ip_summed = CHECKSUM_NONE;
+			napi_gro_receive(&priv->napi, skb);
 
-		napi_gro_receive(&priv->napi, skb);
+			size += length;
+			packets++;
 
-		size += length;
-		packets++;
+			new_skb = netdev_alloc_skb_ip_align(ndev,
+							    NIXGE_MAX_JUMBO_FRAME_SIZE);
+			if (!new_skb)
+				return packets;
 
-		new_skb = netdev_alloc_skb_ip_align(ndev,
-						    NIXGE_MAX_JUMBO_FRAME_SIZE);
-		if (!new_skb)
-			return packets;
-
-		cur_phys = dma_map_single(ndev->dev.parent, new_skb->data,
-					  NIXGE_MAX_JUMBO_FRAME_SIZE,
-					  DMA_FROM_DEVICE);
-		if (dma_mapping_error(ndev->dev.parent, cur_phys)) {
-			/* FIXME: bail out and clean up */
-			netdev_err(ndev, "Failed to map ...\n");
+			cur_phys = dma_map_single(ndev->dev.parent, new_skb->data,
+						  NIXGE_MAX_JUMBO_FRAME_SIZE,
+						  DMA_FROM_DEVICE);
+			if (dma_mapping_error(ndev->dev.parent, cur_phys)) {
+				/* FIXME: bail out and clean up */
+				netdev_err(ndev, "Failed to map ...\n");
+			}
+			nixge_hw_dma_bd_set_phys(cur_p, cur_phys);
+			cur_p->cntrl = NIXGE_MAX_JUMBO_FRAME_SIZE;
+			cur_p->status = 0;
+			nixge_hw_dma_bd_set_offset(cur_p, (uintptr_t)new_skb);
+
+			++priv->rx_bd_ci;
+			priv->rx_bd_ci %= RX_BD_NUM;
+			cur_p = &priv->rx_bd_v[priv->rx_bd_ci];
 		}
-		nixge_hw_dma_bd_set_phys(cur_p, cur_phys);
-		cur_p->cntrl = NIXGE_MAX_JUMBO_FRAME_SIZE;
-		cur_p->status = 0;
-		nixge_hw_dma_bd_set_offset(cur_p, (uintptr_t)new_skb);
-
-		++priv->rx_bd_ci;
-		priv->rx_bd_ci %= RX_BD_NUM;
-		cur_p = &priv->rx_bd_v[priv->rx_bd_ci];
 	}
 
 	ndev->stats.rx_packets += packets;
 	ndev->stats.rx_bytes += size;
-
 	if (tail_p)
 		nixge_dma_write_desc_reg(priv, XAXIDMA_RX_TDESC_OFFSET, tail_p);
 
-- 
2.25.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ