Re: [PATCH net v2 1/1] xfrm: use hlist_del_init_rcu for state_cache and state_cache_input
"Siwei Zhang" <[email protected]>
| Newsgroups | gmane.linux.network,gmane.linux.kernel.stable |
|---|---|
| Message-ID | <[email protected]> |
On Mon, Aug 17, 2026, at 4:30 AM, Steffen Klassert wrote: > On Thu, Jul 30, 2026 at 07:40:08PM +0800, Siwei Zhang wrote: >> From: Siwei Zhang <[email protected]> >> >> Commit 14acf9652e56 ("xfrm: defensively unhash xfrm_state lists in >> __xfrm_state_delete") converted bydst/bysrc/byseq/byspi from >> hlist_del_rcu() to hlist_del_init_rcu() so that a second >> __xfrm_state_delete() on the same object becomes a no-op rather than a >> write through LIST_POISON pprev. It missed state_cache and >> state_cache_input, which kept hlist_del_rcu(): >> >> - hlist_del_rcu() leaves pprev = LIST_POISON2 (non-NULL), so >> hlist_unhashed() returns false. >> - hlist_del_init_rcu() leaves pprev = NULL, so hlist_unhashed() >> returns true. >> >> A second __xfrm_state_delete() therefore enters __hlist_del() on the >> already-deleted state_cache/state_cache_input nodes and does >> WRITE_ONCE(*pprev, next) through LIST_POISON2 — a write use-after-free >> once the slab is reused. The corruption can in turn cause a subsequent >> hlist_for_each_entry_rcu traversal to follow a dangling next pointer, >> producing the read use-after-free reported in xfrm_input_state_lookup(). >> >> Switch state_cache and state_cache_input to hlist_del_init_rcu() to >> match the other four lists, closing the write use-after-free and, with >> it, the read use-after-free it spawns. >> >> Assisted-by: CodeBuddy:GLM-5.2 >> Fixes: 0045e3d80613 ("xfrm: Cache used outbound xfrm states at the policy.") >> Fixes: 81a331a0e72d ("xfrm: Add an inbound percpu state cache.") >> Cc: [email protected] >> Signed-off-by: Siwei Zhang <[email protected]> >> --- >> net/xfrm/xfrm_state.c | 4 ++-- >> 1 file changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c >> index 36a4f6793ede..f494c1ac57a4 100644 >> --- a/net/xfrm/xfrm_state.c >> +++ b/net/xfrm/xfrm_state.c >> @@ -823,9 +823,9 @@ int __xfrm_state_delete(struct xfrm_state *x) >> if (!hlist_unhashed(&x->byseq)) >> hlist_del_init_rcu(&x->byseq); >> if (!hlist_unhashed(&x->state_cache)) >> - hlist_del_rcu(&x->state_cache); >> + hlist_del_init_rcu(&x->state_cache); >> if (!hlist_unhashed(&x->state_cache_input)) >> - hlist_del_rcu(&x->state_cache_input); >> + hlist_del_init_rcu(&x->state_cache_input); >> >> if (!hlist_unhashed(&x->byspi)) >> hlist_del_init_rcu(&x->byspi); > > What is the difference between v1 and v2 of your patch? > Both look identical to me. I forgot the net subject prefix in the email subject. Best, Siwei