Merge branch 'net-fix-stale-tx-skb-pointers-on-dma-map-failure'

Xuanqiang Luo says:

====================
net: fix stale TX skb pointers on DMA map failure

From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>

While I was backporting commit 1a303baa71 ("ice: fix double-free of
tx_buf skb"), an AI-assisted scan identified several suspected TX error
paths. I reviewed the results and found this issue in the three drivers
fixed here.

The drivers differ, but the bug is the same. On a DMA mapping failure, the
TX path frees an skb while its ring entry still points to it. A later
transmission normally overwrites the entry. If the interface is stopped
first, teardown can instead access or free the skb again.

I do not have these adapters, so I have not tested the drivers on hardware.
I checked the error and teardown paths by inspection. Still, these small
fixes seem worth posting for review. They are independent, but are sent as
one series because they address the same issue.
====================

Link: https://patch.msgid.link/20260710090527.58354-1-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-07-21 11:18:57 -07:00
commit e372a49cb8
3 changed files with 5 additions and 3 deletions

View File

@ -3006,7 +3006,6 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
txqent->hdr.wi.reserved = 0;
txqent->hdr.wi.num_vectors = vectors;
head_unmap->skb = skb;
head_unmap->nvecs = 0;
/* Program the vectors */
@ -3018,6 +3017,7 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
BNAD_UPDATE_CTR(bnad, tx_skb_map_failed);
return NETDEV_TX_OK;
}
head_unmap->skb = skb;
BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[0].host_addr);
txqent->vector[0].length = htons(len);
dma_unmap_addr_set(&unmap->vectors[0], dma_addr, dma_addr);

View File

@ -155,6 +155,7 @@ netdev_tx_t hbg_net_start_xmit(struct sk_buff *skb, struct net_device *netdev)
buffer->skb = skb;
buffer->skb_len = skb->len;
if (unlikely(hbg_dma_map(buffer))) {
buffer->skb = NULL;
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}

View File

@ -578,8 +578,6 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
*wqe_combo.task = task;
tx_info = &txq->tx_info[pi];
tx_info->skb = skb;
tx_info->wqebb_cnt = wqebb_cnt;
err = hinic3_tx_map_skb(netdev, skb, txq, tx_info, &wqe_combo);
if (err) {
@ -589,6 +587,9 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
goto err_drop_pkt;
}
tx_info->skb = skb;
tx_info->wqebb_cnt = wqebb_cnt;
netif_subqueue_sent(netdev, txq->sq->q_id, skb->len);
netif_subqueue_maybe_stop(netdev, txq->sq->q_id,
hinic3_wq_free_wqebbs(&txq->sq->wq),