The ace_start_xmit function does not check the return value of dma_map_page (via ace_map_tx_skb) and skb_frag_dma_map when building transmit descriptors. If mapping fails, an invalid DMA address is written to the descriptor, which may cause hardware to access illegal memory, leading to system instability or crashes. Add proper dma_mapping_error() checks for all mapping calls. When mapping fails, free the skb, increment the dropped packet counter, and return NETDEV_TX_OK. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Wang Jun <1742789905@qq.com> --- drivers/net/ethernet/alteon/acenic.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c index 455ee8930824..acabede53663 100644 --- a/drivers/net/ethernet/alteon/acenic.c +++ b/drivers/net/ethernet/alteon/acenic.c @@ -2417,6 +2417,11 @@ static netdev_tx_t ace_start_xmit(struct sk_buff *skb, u32 vlan_tag = 0; mapping = ace_map_tx_skb(ap, skb, skb, idx); + if (dma_mapping_error(&ap->pdev->dev, mapping)) { + dev_kfree_skb(skb); + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } flagsize = (skb->len << 16) | (BD_FLG_END); if (skb->ip_summed == CHECKSUM_PARTIAL) flagsize |= BD_FLG_TCP_UDP_SUM; @@ -2438,6 +2443,11 @@ static netdev_tx_t ace_start_xmit(struct sk_buff *skb, int i; mapping = ace_map_tx_skb(ap, skb, NULL, idx); + if (dma_mapping_error(&ap->pdev->dev, mapping)) { + dev_kfree_skb(skb); + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } flagsize = (skb_headlen(skb) << 16); if (skb->ip_summed == CHECKSUM_PARTIAL) flagsize |= BD_FLG_TCP_UDP_SUM; @@ -2460,6 +2470,11 @@ static netdev_tx_t ace_start_xmit(struct sk_buff *skb, mapping = skb_frag_dma_map(&ap->pdev->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); + if (dma_mapping_error(&ap->pdev->dev, mapping)) { + dev_kfree_skb(skb); + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } flagsize = skb_frag_size(frag) << 16; if (skb->ip_summed == CHECKSUM_PARTIAL) -- 2.43.0