From 829a09df899dcce860dcf5f70e09c1b2d7d425ab Mon Sep 17 00:00:00 2001 From: Nicolai Buchwitz Date: Tue, 27 Oct 2026 19:44:09 +0100 Subject: octeontx2-pf: fix skb use-after-free with ipsec crypto offload otx2_dma_map_skb_frag() calls skb_unclone_full() on its own copy of the skb pointer. For a cloned skb, for example with tcpdump running on the interface, this frees the skb and the new copy is lost on return. The transmit path then uses the freed skb and the copy leaks. Make the skb writable in place in otx2_sq_append_skb() instead, so the pointer stays valid. Also do this for nonlinear skbs, as the hardware writes the encrypted data back into the frags, which may be shared, for example with the TCP retransmit queue. Fixes: 195c3d463181 ("octeontx2-pf: map skb data as device writeable") Signed-off-by: Nicolai Buchwitz Link: https://patch.msgid.link/20261027-nb-otx2-xfrm-unshare-net-v3-1-31dc9d79d11d@tipi-net.de Signed-off-by: Paolo Abeni --- drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 4 +--- drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c | 9 +++++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c index 16f73797739d..c85436457286 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c @@ -2115,10 +2115,8 @@ dma_addr_t otx2_dma_map_skb_frag(struct otx2_nic *pfvf, int offset; /* Crypto hardware need write permission for ipsec crypto offload */ - if (unlikely(xfrm_offload(skb))) { + if (unlikely(xfrm_offload(skb))) dir = DMA_BIDIRECTIONAL; - skb = skb_unclone_full(skb, GFP_ATOMIC); - } /* First segment is always skb->data */ if (!seg) { diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c index 66dc8cc15486..90af9b9044aa 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c @@ -1205,6 +1205,15 @@ bool otx2_sq_append_skb(void *dev, struct netdev_queue *txq, if (free_desc < otx2_get_sqe_count(pfvf, skb)) return false; + /* Crypto hardware need write permission for ipsec crypto offload */ + if (unlikely(xfrm_offload(skb)) && + (skb_cloned(skb) || skb_is_nonlinear(skb)) && + skb_ensure_writable(skb, skb->len)) { + atomic_long_inc(&pfvf->hw.dev_stats.tx_discards); + dev_kfree_skb_any(skb); + return true; + } + num_segs = skb_shinfo(skb)->nr_frags + 1; /* If SKB doesn't fit in a single SQE, linearize it. -- cgit v1.2.3