* [PATCH net v1 1/3] bna: fix use-after-free on DMA mapping failure
2026-07-10 9:05 [PATCH net v1 0/3] net: fix stale TX skb pointers on DMA map failure xuanqiang.luo
@ 2026-07-10 9:05 ` xuanqiang.luo
2026-07-10 9:05 ` [PATCH net v1 2/3] hinic3: " xuanqiang.luo
2026-07-10 9:05 ` [PATCH net v1 3/3] net: hibmcge: fix double-free of tx skb " xuanqiang.luo
2 siblings, 0 replies; 5+ messages in thread
From: xuanqiang.luo @ 2026-07-10 9:05 UTC (permalink / raw)
To: netdev
Cc: Xuanqiang Luo, Rasesh Mody, Sudarsana Kalluru, GR-Linux-NIC-Dev,
Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Ivan Vecera, linux-kernel, stable
From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
If dma_map_single() fails in bnad_start_xmit(), the skb is freed, but
head_unmap->skb was set before the mapping attempt and is not cleared. The
producer index is not advanced, so later transmissions normally overwrite
the entry.
However, if the interface is brought down first, bnad_txq_cleanup() scans
the entire unmap queue, finds the stale pointer, and calls
bnad_tx_buff_unmap() on it. That function dereferences the freed skb in
skb_headlen(). Its zero nvecs count is decremented to -1, causing its
while (nvecs) loop to repeatedly unmap entries around the TX ring and
potentially hang cleanup.
Set head_unmap->skb after the first DMA mapping succeeds. This prevents the
stale entry from reaching bnad_tx_buff_unmap().
Fixes: ba5ca7848be0 ("bna: check for dma mapping errors")
Cc: stable@vger.kernel.org
Assisted-by: Opencode:deepseek-v4-pro[1m]
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
---
drivers/net/ethernet/brocade/bna/bnad.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index 8e19add764db2..8b75004ba7c9d 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -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);
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH net v1 2/3] hinic3: fix use-after-free on DMA mapping failure
2026-07-10 9:05 [PATCH net v1 0/3] net: fix stale TX skb pointers on DMA map failure xuanqiang.luo
2026-07-10 9:05 ` [PATCH net v1 1/3] bna: fix use-after-free on DMA mapping failure xuanqiang.luo
@ 2026-07-10 9:05 ` xuanqiang.luo
2026-07-10 9:05 ` [PATCH net v1 3/3] net: hibmcge: fix double-free of tx skb " xuanqiang.luo
2 siblings, 0 replies; 5+ messages in thread
From: xuanqiang.luo @ 2026-07-10 9:05 UTC (permalink / raw)
To: netdev
Cc: Xuanqiang Luo, Fan Gong, Xin Guo, Gur Stavi, Andrew Lunn,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-kernel, stable
From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
If hinic3_tx_map_skb() fails in hinic3_send_one_skb(), the skb is freed,
but tx_info->skb was set before the mapping attempt and is not cleared. The
SQ producer index is rolled back, so later transmissions normally overwrite
the entry.
If the interface is brought down first, hinic3_free_txqs_res() calls
free_all_tx_skbs(). It scans the entire tx_info array and finds the stale
pointer. hinic3_tx_unmap_skb() then dereferences the freed skb in
skb_shinfo(), before it is freed again.
Set tx_info->skb and its WQEBB count only after DMA mapping succeeds,
preventing the stale pointer from reaching free_all_tx_skbs().
Fixes: 17fcb3dc12bb ("hinic3: module initialization and tx/rx logic")
Cc: stable@vger.kernel.org
Assisted-by: Opencode:deepseek-v4-pro[1m]
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
---
drivers/net/ethernet/huawei/hinic3/hinic3_tx.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
index 9306bf0020caf..5739ecb08d0d3 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
@@ -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),
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH net v1 3/3] net: hibmcge: fix double-free of tx skb on DMA mapping failure
2026-07-10 9:05 [PATCH net v1 0/3] net: fix stale TX skb pointers on DMA map failure xuanqiang.luo
2026-07-10 9:05 ` [PATCH net v1 1/3] bna: fix use-after-free on DMA mapping failure xuanqiang.luo
2026-07-10 9:05 ` [PATCH net v1 2/3] hinic3: " xuanqiang.luo
@ 2026-07-10 9:05 ` xuanqiang.luo
2026-07-10 10:15 ` Jijie Shao
2 siblings, 1 reply; 5+ messages in thread
From: xuanqiang.luo @ 2026-07-10 9:05 UTC (permalink / raw)
To: netdev
Cc: Xuanqiang Luo, Jijie Shao, Jian Shen, Andrew Lunn,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-kernel, stable
From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
If hbg_dma_map() fails, hbg_net_start_xmit() frees the skb, but buffer->skb
is left pointing to it. ring->ntu is not advanced, so the buffer is not
visible to the TX cleanup path.
A subsequent transmit normally overwrites the buffer. However, if the
interface is brought down first, hbg_ring_uninit() calls hbg_buffer_free().
It sees the stale pointer, attempts to unmap the failed mapping, and frees
the skb again.
Clear buffer->skb before freeing the skb in the error path, preventing
hbg_buffer_free() from treating it as an outstanding TX buffer.
Fixes: 40735e7543f9 ("net: hibmcge: Implement .ndo_start_xmit function")
Cc: stable@vger.kernel.org
Assisted-by: Opencode:deepseek-v4-pro[1m]
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
---
drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
index 0ae3149946769..4382af937e2e7 100644
--- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
+++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
@@ -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;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH net v1 3/3] net: hibmcge: fix double-free of tx skb on DMA mapping failure
2026-07-10 9:05 ` [PATCH net v1 3/3] net: hibmcge: fix double-free of tx skb " xuanqiang.luo
@ 2026-07-10 10:15 ` Jijie Shao
0 siblings, 0 replies; 5+ messages in thread
From: Jijie Shao @ 2026-07-10 10:15 UTC (permalink / raw)
To: xuanqiang.luo, netdev
Cc: shaojijie, Xuanqiang Luo, Jian Shen, Andrew Lunn,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-kernel, stable
on 2026/7/10 17:05, xuanqiang.luo@linux.dev wrote:
> From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
>
> If hbg_dma_map() fails, hbg_net_start_xmit() frees the skb, but buffer->skb
> is left pointing to it. ring->ntu is not advanced, so the buffer is not
> visible to the TX cleanup path.
>
> A subsequent transmit normally overwrites the buffer. However, if the
> interface is brought down first, hbg_ring_uninit() calls hbg_buffer_free().
> It sees the stale pointer, attempts to unmap the failed mapping, and frees
> the skb again.
>
> Clear buffer->skb before freeing the skb in the error path, preventing
> hbg_buffer_free() from treating it as an outstanding TX buffer.
>
> Fixes: 40735e7543f9 ("net: hibmcge: Implement .ndo_start_xmit function")
> Cc: stable@vger.kernel.org
> Assisted-by: Opencode:deepseek-v4-pro[1m]
> Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Thanks for fixing this. The patch looks good to me.
Reviewed-by: Jijie Shao <shaojijie@huawei.com>
> ---
> drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
> index 0ae3149946769..4382af937e2e7 100644
> --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
> +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
> @@ -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;
> }
^ permalink raw reply [flat|nested] 5+ messages in thread