From: Nicholas Carlini The bounds check guarding sp->xvec[sp->len++] uses == where >= is required. When sp->len has already reached XFRM_MAX_DEPTH via prior ESP processing in xfrm_input(), the check (1 + 6 == 6) is false and the write goes out of bounds into the adjacent skbuff_ext_cache slab object. An unprivileged local user can trigger this by entering a user+network namespace, configuring six transport-mode ESP SAs plus one MIP6 routing SA, and injecting an IPv6 packet with six ESP layers followed by multiple Routing Header Type 2 extensions. The check was correct (>) when the function was introduced, but was changed to == during a refactor in 2007. Fixes: 9473e1f631de ("[XFRM] MIPv6: Fix to input RO state correctly.") Reported-by: Milad Nasr Signed-off-by: Nicholas Carlini --- v1 -> v2: fix whitespace (tabs), rebase on ipsec tree (Steffen Klassert) v1: https://lore.kernel.org/netdev/20260328163516.2111971-1-nicholas@carlini.com net/ipv6/xfrm6_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index 9005fc156a2..a958c08589d 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c @@ -246,7 +246,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, goto drop; } - if (1 + sp->len == XFRM_MAX_DEPTH) { + if (1 + sp->len >= XFRM_MAX_DEPTH) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR); goto drop; } -- 2.43.0