* [PATCH net 1/2] octeontx2-pf: fix skb use-after-free on ipsec transmit drop
2026-10-27 19:54 [PATCH net 0/2] octeontx2-pf: fix ipsec transmit error paths Nicolai Buchwitz
@ 2026-10-27 19:54 ` Nicolai Buchwitz
2026-10-28 2:26 ` Ratheesh Kannoth
2026-10-27 19:54 ` [PATCH net 2/2] octeontx2-pf: pass the skb to otx2_dma_unmap_skb_frags() Nicolai Buchwitz
1 sibling, 1 reply; 5+ messages in thread
From: Nicolai Buchwitz @ 2026-10-27 19:54 UTC (permalink / raw)
To: Sunil Goutham, Geetha sowjanya, Ratheesh Kannoth,
Subbaraya Sundeep, Bharat Bhushan, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: netdev, linux-kernel, Nicolai Buchwitz
When an SA is removed while packets for it are still queued, the
transmit path frees the packet but reports the queue as busy. The stack
then requeues the freed skb, and the DMA mappings leak.
Fixes: 6a77a158848a ("cn10k-ipsec: Process outbound ipsec crypto offload")
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
---
drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
index 77543d472345e..3920cd0985831 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
@@ -1037,6 +1037,9 @@ bool cn10k_ipsec_transmit(struct otx2_nic *pf, struct netdev_queue *txq,
cn10k_cpt_inst_flush(pf, &inst, sizeof(struct cpt_inst_s));
return true;
drop:
+ otx2_dma_unmap_skb_frags(pf, &sq->sg[sq->head]);
+ sq->sg[sq->head].skb = (u64)NULL;
+ atomic_long_inc(&pf->hw.dev_stats.tx_discards);
dev_kfree_skb_any(skb);
- return false;
+ return true;
}
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH net 2/2] octeontx2-pf: pass the skb to otx2_dma_unmap_skb_frags()
2026-10-27 19:54 [PATCH net 0/2] octeontx2-pf: fix ipsec transmit error paths Nicolai Buchwitz
2026-10-27 19:54 ` [PATCH net 1/2] octeontx2-pf: fix skb use-after-free on ipsec transmit drop Nicolai Buchwitz
@ 2026-10-27 19:54 ` Nicolai Buchwitz
2026-10-28 2:38 ` Ratheesh Kannoth
1 sibling, 1 reply; 5+ messages in thread
From: Nicolai Buchwitz @ 2026-10-27 19:54 UTC (permalink / raw)
To: Sunil Goutham, Geetha sowjanya, Ratheesh Kannoth,
Subbaraya Sundeep, Bharat Bhushan, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: netdev, linux-kernel, Nicolai Buchwitz
After a DMA mapping error, the unmap reads an skb pointer that is not
set yet. It can be NULL or left over from an earlier packet.
Fixes: 195c3d463181 ("octeontx2-pf: map skb data as device writeable")
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
---
drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c | 2 +-
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 5 ++---
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h | 3 ++-
drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c | 10 +++++-----
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
index 3920cd0985831..4434356087814 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
@@ -1037,7 +1037,7 @@ bool cn10k_ipsec_transmit(struct otx2_nic *pf, struct netdev_queue *txq,
cn10k_cpt_inst_flush(pf, &inst, sizeof(struct cpt_inst_s));
return true;
drop:
- otx2_dma_unmap_skb_frags(pf, &sq->sg[sq->head]);
+ otx2_dma_unmap_skb_frags(pf, &sq->sg[sq->head], skb);
sq->sg[sq->head].skb = (u64)NULL;
atomic_long_inc(&pf->hw.dev_stats.tx_discards);
dev_kfree_skb_any(skb);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
index c441c0161dbf4..c85436457286e 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
@@ -2132,13 +2132,12 @@ dma_addr_t otx2_dma_map_skb_frag(struct otx2_nic *pfvf,
return otx2_dma_map_page(pfvf, page, offset, *len, dir);
}
-void otx2_dma_unmap_skb_frags(struct otx2_nic *pfvf, struct sg_list *sg)
+void otx2_dma_unmap_skb_frags(struct otx2_nic *pfvf, struct sg_list *sg,
+ struct sk_buff *skb)
{
enum dma_data_direction dir = DMA_TO_DEVICE;
- struct sk_buff *skb = NULL;
int seg;
- skb = (struct sk_buff *)sg->skb;
if (unlikely(xfrm_offload(skb)))
dir = DMA_BIDIRECTIONAL;
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
index 3c7275d545bba..8417af94a02a0 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
@@ -1252,7 +1252,8 @@ static inline int mcam_entry_cmp(const void *a, const void *b)
dma_addr_t otx2_dma_map_skb_frag(struct otx2_nic *pfvf,
struct sk_buff *skb, int seg, int *len);
-void otx2_dma_unmap_skb_frags(struct otx2_nic *pfvf, struct sg_list *sg);
+void otx2_dma_unmap_skb_frags(struct otx2_nic *pfvf, struct sg_list *sg,
+ struct sk_buff *skb);
int otx2_read_free_sqe(struct otx2_nic *pfvf, u16 qidx);
void otx2_queue_vf_work(struct mbox *mw, struct workqueue_struct *mbox_wq,
int first, int mdevs, u64 intr);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
index 3d38ca2402e38..90af9b9044aa0 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
@@ -160,7 +160,7 @@ static void otx2_snd_pkt_handler(struct otx2_nic *pfvf,
*tx_bytes += skb->len;
(*tx_pkts)++;
- otx2_dma_unmap_skb_frags(pfvf, sg);
+ otx2_dma_unmap_skb_frags(pfvf, sg, skb);
napi_consume_skb(skb, budget);
sg->skb = (u64)NULL;
}
@@ -872,7 +872,7 @@ static int otx2_dma_map_tso_skb(struct otx2_nic *pfvf,
}
return 0;
unmap:
- otx2_dma_unmap_skb_frags(pfvf, sg);
+ otx2_dma_unmap_skb_frags(pfvf, sg, skb);
return -EINVAL;
}
@@ -1261,7 +1261,7 @@ bool otx2_sq_append_skb(void *dev, struct netdev_queue *txq,
ret = otx2_sqe_add_sg(pfvf, sq, skb, num_segs, &offset);
if (!ret) {
- otx2_dma_unmap_skb_frags(pfvf, &sq->sg[sq->head]);
+ otx2_dma_unmap_skb_frags(pfvf, &sq->sg[sq->head], skb);
return false;
}
@@ -1353,7 +1353,7 @@ void otx2_cleanup_tx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq)
if (skb) {
tx_bytes += skb->len;
tx_pkts++;
- otx2_dma_unmap_skb_frags(pfvf, sg);
+ otx2_dma_unmap_skb_frags(pfvf, sg, skb);
dev_kfree_skb_any(skb);
sg->skb = (u64)NULL;
}
@@ -1408,7 +1408,7 @@ void otx2_free_pending_sqe(struct otx2_nic *pfvf)
if (skb) {
tx_bytes += skb->len;
tx_pkts++;
- otx2_dma_unmap_skb_frags(pfvf, sg);
+ otx2_dma_unmap_skb_frags(pfvf, sg, skb);
dev_kfree_skb_any(skb);
sg->skb = (u64)NULL;
}
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread