mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 22:14:03 +02:00
xfrm: use hlist_del_init_rcu for state_cache and state_cache_input
Commit14acf9652e("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:0045e3d806("xfrm: Cache used outbound xfrm states at the policy.") Fixes:81a331a0e7("xfrm: Add an inbound percpu state cache.") Cc: stable@vger.kernel.org Signed-off-by: Siwei Zhang <fourdizhang@tencent.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
d2f5082f9e
commit
2afb8dc1f4
|
|
@ -826,9 +826,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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user