diff options
author | Florian Westphal <fw@strlen.de> | 2016-08-25 15:33:29 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-01-31 14:46:13 +0100 |
commit | 64f94c222f630b2a407a36bac38c4f543edde668 (patch) | |
tree | 1fba187cc8003a18a744c95edbc0a07abb6ed9f0 | |
parent | 38a8f8f7f6c61ca1cc6409ee9b0f89b21a8dad79 (diff) | |
download | linux-stable-64f94c222f630b2a407a36bac38c4f543edde668.tar.gz linux-stable-64f94c222f630b2a407a36bac38c4f543edde668.tar.bz2 linux-stable-64f94c222f630b2a407a36bac38c4f543edde668.zip |
netfilter: restart search if moved to other chain
commit 95a8d19f28e6b29377a880c6264391a62e07fccc upstream.
In case nf_conntrack_tuple_taken did not find a conflicting entry
check that all entries in this hash slot were tested and restart
in case an entry was moved to another chain.
Reported-by: Eric Dumazet <edumazet@google.com>
Fixes: ea781f197d6a ("netfilter: nf_conntrack: use SLAB_DESTROY_BY_RCU and get rid of call_rcu()")
Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Acked-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 98cd0e78c94c..13fbd2ab960f 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -695,6 +695,7 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, * least once for the stats anyway. */ rcu_read_lock_bh(); + begin: hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnnode) { ct = nf_ct_tuplehash_to_ctrack(h); if (ct != ignored_conntrack && @@ -706,6 +707,12 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, } NF_CT_STAT_INC(net, searched); } + + if (get_nulls_value(n) != hash) { + NF_CT_STAT_INC(net, search_restart); + goto begin; + } + rcu_read_unlock_bh(); return 0; |