Commit f2bc8231 authored by Sabrina Dubroca's avatar Sabrina Dubroca Committed by Steffen Klassert
Browse files

xfrm: check all hash buckets for leftover states during netns deletion



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: 73d189dc ("netns xfrm: per-netns xfrm_state_bydst hash")
Fixes: d320bbb3 ("netns xfrm: per-netns xfrm_state_bysrc hash")
Fixes: b754a4fd ("netns xfrm: per-netns xfrm_state_byspi hash")
Fixes: fe9f1d87 ("xfrm: add state hashtable keyed by seq")
Signed-off-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent 1dcf617b
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -3308,6 +3308,7 @@ int __net_init xfrm_state_init(struct net *net)
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);
}