[PATCH ipsec v2 4/7] xfrm: prevent AES-GCM nonce reuse after early GSO
From: Jérémy Jean
Date: Sun Nov 08 2026 - 09:30:37 EST
With software ESP offload, xfrm_output() attaches a secpath before
calling xfrm_output_gso() for an encapsulated GSO packet, but
skb_gso_segment() leaves the splitted skbs sharing the same secpath,
including xo->seq.
For the i-th splitted segment, xfrm_output_gso() reaches
xfrm_replay_overflow() through xfrm_output_one(), which allocates
sequence number N+i to that segment, and then incorrectly overwrites
the shared xo->seq with N+i. If encryption is delayed until all t
segments have been processed, xo->seq ends up with value N+t-1 for all
segments. When validate_xmit_xfrm() calls esp*_xmit() for each
segment, the IV is constructed from the same value N+t-1, causing
nonce reuse in AES-GCM. Yet, each ESP header correctly keeps using
value N+i from its private XFRM_SKB_CB.
Call secpath_set() for each offloaded segment before xfrm_output2(),
so sequence allocation writes to private metadata that cannot be
overwritten by later segments.
Fixes: a204aef9fd77 ("xfrm: call xfrm_output_gso when inner_protocol is set in xfrm_output")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Jérémy Jean <Jeremy.Jean@xxxxxxxxxxxxxxxxx>
---
net/xfrm/xfrm_output.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index f1f612cd7b438..99d1b33db52a6 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -672,6 +672,15 @@ static int xfrm_output_gso(struct net *net, struct sock *sk, struct sk_buff *skb
skb_list_walk_safe(segs, segs, nskb) {
int err;
+ /* Each segment reserves its own sequence number and stores
+ * it in the secpath.
+ */
+ if (xfrm_offload(segs) && !secpath_set(segs)) {
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
+ kfree_skb_list(segs);
+ return -ENOMEM;
+ }
+
skb_mark_not_on_list(segs);
err = xfrm_output2(net, sk, segs);
--
2.47.3