]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xfrm: check all hash buckets for leftover states during netns deletion
authorSabrina Dubroca <sd@queasysnail.net>
Thu, 16 Oct 2025 10:39:17 +0000 (12:39 +0200)
committerSteffen Klassert <steffen.klassert@secunet.com>
Tue, 21 Oct 2025 08:42:45 +0000 (10:42 +0200)
The current hlist_empty checks only test the first bucket of each
hashtable, ignoring any other bucket. They should be caught by the
WARN_ON for state_all, but better to make all the checks accurate.

Fixes: 73d189dce486 ("netns xfrm: per-netns xfrm_state_bydst hash")
Fixes: d320bbb306f2 ("netns xfrm: per-netns xfrm_state_bysrc hash")
Fixes: b754a4fd8f58 ("netns xfrm: per-netns xfrm_state_byspi hash")
Fixes: fe9f1d8779cb ("xfrm: add state hashtable keyed by seq")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
net/xfrm/xfrm_state.c

index c3518d1498cd04a8c75792a89f7e623041666905..9e14e453b55cc9490dd3439378b482fc49c3af5f 100644 (file)
@@ -3308,6 +3308,7 @@ out_bydst:
 void xfrm_state_fini(struct net *net)
 {
        unsigned int sz;
+       int i;
 
        flush_work(&net->xfrm.state_hash_work);
        xfrm_state_flush(net, 0, false);
@@ -3315,14 +3316,17 @@ void xfrm_state_fini(struct net *net)
 
        WARN_ON(!list_empty(&net->xfrm.state_all));
 
+       for (i = 0; i <= net->xfrm.state_hmask; i++) {
+               WARN_ON(!hlist_empty(net->xfrm.state_byseq + i));
+               WARN_ON(!hlist_empty(net->xfrm.state_byspi + i));
+               WARN_ON(!hlist_empty(net->xfrm.state_bysrc + i));
+               WARN_ON(!hlist_empty(net->xfrm.state_bydst + i));
+       }
+
        sz = (net->xfrm.state_hmask + 1) * sizeof(struct hlist_head);
-       WARN_ON(!hlist_empty(net->xfrm.state_byseq));
        xfrm_hash_free(net->xfrm.state_byseq, sz);
-       WARN_ON(!hlist_empty(net->xfrm.state_byspi));
        xfrm_hash_free(net->xfrm.state_byspi, sz);
-       WARN_ON(!hlist_empty(net->xfrm.state_bysrc));
        xfrm_hash_free(net->xfrm.state_bysrc, sz);
-       WARN_ON(!hlist_empty(net->xfrm.state_bydst));
        xfrm_hash_free(net->xfrm.state_bydst, sz);
        free_percpu(net->xfrm.state_cache_input);
 }