Re: [PATCH net v2 1/1] xfrm: use hlist_del_init_rcu for state_cache and state_cache_input

"Siwei Zhang" <[email protected]>
Newsgroups org.kernel.vger.netdev,org.kernel.vger.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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.