* [PATCH] xfrm: Fix xfrm state cache insertion race
@ 2026-06-12 4:58 Herbert Xu
2026-06-15 8:43 ` Simon Horman
0 siblings, 1 reply; 2+ messages in thread
From: Herbert Xu @ 2026-06-12 4:58 UTC (permalink / raw)
To: Steffen Klassert, netdev
Cc: Linus Torvalds, Jakub Kicinski, Paolo Abeni,
zdi-disclosures@trendmicro.com, Willy Tarreau
The xfrm input state cache insertion code checks the validity of
the state before acquiring the global xfrm_state_lock. Thus it's
possible for someone else to kill the state after it passed the
validity check, and then the insertion will add the dead state
to the cache.
Fix this by moving the validity check inside the lock.
This entire function is called on the input path, where BH must
be off (e.g., the caller of this function xfrm_input acquires
its spinlocks without disabling BH).
So there is no need to disable BH here or take the RCU read lock.
Remove both and replace them with an assertion that trips if BH
is accidentally enabled on some future calling path.
Fixes: 81a331a0e72d ("xfrm: Add an inbound percpu state cache.")
Reported-by: Zero Day Initiative <zdi-disclosures@trendmicro.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 1748d374abca..bc669f0d6e0e 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1207,9 +1207,11 @@ struct xfrm_state *xfrm_input_state_lookup(struct net *net, u32 mark,
struct hlist_head *state_cache_input;
struct xfrm_state *x = NULL;
+ /* BH is always disabled on the input path. */
+ lockdep_assert_in_softirq();
+
state_cache_input = raw_cpu_ptr(net->xfrm.state_cache_input);
- rcu_read_lock();
hlist_for_each_entry_rcu(x, state_cache_input, state_cache_input) {
if (x->props.family != family ||
x->id.spi != spi ||
@@ -1227,20 +1229,25 @@ struct xfrm_state *xfrm_input_state_lookup(struct net *net, u32 mark,
xfrm_hash_ptrs_get(net, &state_ptrs);
x = __xfrm_state_lookup(&state_ptrs, mark, daddr, spi, proto, family);
-
- if (x && x->km.state == XFRM_STATE_VALID) {
- spin_lock_bh(&net->xfrm.xfrm_state_lock);
- if (hlist_unhashed(&x->state_cache_input)) {
+ if (x) {
+ spin_lock(&net->xfrm.xfrm_state_lock);
+ if (x->km.state != XFRM_STATE_VALID) {
+ /*
+ * The state is about to be destroyed.
+ *
+ * Don't add it to the cache but still
+ * return it to the caller.
+ */
+ } else if (hlist_unhashed(&x->state_cache_input)) {
hlist_add_head_rcu(&x->state_cache_input, state_cache_input);
} else {
hlist_del_rcu(&x->state_cache_input);
hlist_add_head_rcu(&x->state_cache_input, state_cache_input);
}
- spin_unlock_bh(&net->xfrm.xfrm_state_lock);
+ spin_unlock(&net->xfrm.xfrm_state_lock);
}
out:
- rcu_read_unlock();
return x;
}
EXPORT_SYMBOL(xfrm_input_state_lookup);
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] xfrm: Fix xfrm state cache insertion race
2026-06-12 4:58 [PATCH] xfrm: Fix xfrm state cache insertion race Herbert Xu
@ 2026-06-15 8:43 ` Simon Horman
0 siblings, 0 replies; 2+ messages in thread
From: Simon Horman @ 2026-06-15 8:43 UTC (permalink / raw)
To: Herbert Xu
Cc: Steffen Klassert, netdev, Linus Torvalds, Jakub Kicinski,
Paolo Abeni, zdi-disclosures@trendmicro.com, Willy Tarreau
On Fri, Jun 12, 2026 at 12:58:59PM +0800, Herbert Xu wrote:
> The xfrm input state cache insertion code checks the validity of
> the state before acquiring the global xfrm_state_lock. Thus it's
> possible for someone else to kill the state after it passed the
> validity check, and then the insertion will add the dead state
> to the cache.
>
> Fix this by moving the validity check inside the lock.
>
> This entire function is called on the input path, where BH must
> be off (e.g., the caller of this function xfrm_input acquires
> its spinlocks without disabling BH).
>
> So there is no need to disable BH here or take the RCU read lock.
> Remove both and replace them with an assertion that trips if BH
> is accidentally enabled on some future calling path.
>
> Fixes: 81a331a0e72d ("xfrm: Add an inbound percpu state cache.")
> Reported-by: Zero Day Initiative <zdi-disclosures@trendmicro.com>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-06-15 8:43 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-12 4:58 [PATCH] xfrm: Fix xfrm state cache insertion race Herbert Xu
2026-06-15 8:43 ` Simon Horman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox