netfilter: restart search if moved to other chain
authorFlorian Westphal <fw@strlen.de>
Thu, 25 Aug 2016 13:33:29 +0000 (15:33 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 30 Aug 2016 09:43:08 +0000 (11:43 +0200)
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>
net/netfilter/nf_conntrack_core.c

index 7d90a5d..887926a 100644 (file)
@@ -809,6 +809,7 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
        zone = nf_ct_zone(ignored_conntrack);
 
        rcu_read_lock();
+ begin:
        nf_conntrack_get_ht(&ct_hash, &hsize);
        hash = __hash_conntrack(net, tuple, hsize);
 
@@ -822,6 +823,12 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
                }
                NF_CT_STAT_INC_ATOMIC(net, searched);
        }
+
+       if (get_nulls_value(n) != hash) {
+               NF_CT_STAT_INC_ATOMIC(net, search_restart);
+               goto begin;
+       }
+
        rcu_read_unlock();
 
        return 0;