Commit 474803d37e7fb6291d22cb964014afe457ba5212

Authored by Liping Zhang
Committed by Pablo Neira Ayuso
1 parent 64b87639c9

netfilter: cttimeout: unlink timeout obj again when hash resize happen

Imagine such situation, nf_conntrack_htable_size now is 4096, we are doing
ctnl_untimeout, and iterate on 3000# bucket.

Meanwhile, another user try to reduce hash size to 2048, then all nf_conn
are removed to the new hashtable. When this hash resize operation finished,
we still try to itreate ct begin from 3000# bucket, find nothing to do and
just return.

We may miss unlinking some timeout objects. And later we will end up with
invalid references to timeout object that are already gone.

So when we find that hash resize happened, try to unlink timeout objects
from the 0# bucket again.

Signed-off-by: Liping Zhang <liping.zhang@spreadtrum.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

Showing 1 changed file with 14 additions and 6 deletions Side-by-side Diff

net/netfilter/nfnetlink_cttimeout.c
... ... @@ -303,16 +303,24 @@
303 303 {
304 304 struct nf_conntrack_tuple_hash *h;
305 305 const struct hlist_nulls_node *nn;
  306 + unsigned int last_hsize;
  307 + spinlock_t *lock;
306 308 int i;
307 309  
308 310 local_bh_disable();
309   - for (i = 0; i < nf_conntrack_htable_size; i++) {
310   - nf_conntrack_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
311   - if (i < nf_conntrack_htable_size) {
312   - hlist_nulls_for_each_entry(h, nn, &nf_conntrack_hash[i], hnnode)
313   - untimeout(h, timeout);
  311 +restart:
  312 + last_hsize = nf_conntrack_htable_size;
  313 + for (i = 0; i < last_hsize; i++) {
  314 + lock = &nf_conntrack_locks[i % CONNTRACK_LOCKS];
  315 + nf_conntrack_lock(lock);
  316 + if (last_hsize != nf_conntrack_htable_size) {
  317 + spin_unlock(lock);
  318 + goto restart;
314 319 }
315   - spin_unlock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
  320 +
  321 + hlist_nulls_for_each_entry(h, nn, &nf_conntrack_hash[i], hnnode)
  322 + untimeout(h, timeout);
  323 + spin_unlock(lock);
316 324 }
317 325 local_bh_enable();
318 326 }