Commit 3b7dabf029478bb80507a6c4500ca94132a2bc0b
Committed by
Pablo Neira Ayuso
1 parent
f83bf8da11
netfilter: invoke synchronize_rcu after set the _hook_ to NULL
Otherwise, another CPU may access the invalid pointer. For example: CPU0 CPU1 - rcu_read_lock(); - pfunc = _hook_; _hook_ = NULL; - mod unload - - pfunc(); // invalid, panic - rcu_read_unlock(); So we must call synchronize_rcu() to wait the rcu reader to finish. Also note, in nf_nat_snmp_basic_fini, synchronize_rcu() will be invoked by later nf_conntrack_helper_unregister, but I'm inclined to add a explicit synchronize_rcu after set the nf_nat_snmp_hook to NULL. Depend on such obscure assumptions is not a good idea. Last, in nfnetlink_cttimeout, we use kfree_rcu to free the time object, so in cttimeout_exit, invoking rcu_barrier() is not necessary at all, remove it too. Signed-off-by: Liping Zhang <zlpnobody@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Showing 5 changed files with 7 additions and 1 deletions Side-by-side Diff
net/ipv4/netfilter/nf_nat_snmp_basic.c
net/netfilter/nf_conntrack_ecache.c
... | ... | @@ -290,6 +290,7 @@ |
290 | 290 | BUG_ON(notify != new); |
291 | 291 | RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, NULL); |
292 | 292 | mutex_unlock(&nf_ct_ecache_mutex); |
293 | + /* synchronize_rcu() is called from ctnetlink_exit. */ | |
293 | 294 | } |
294 | 295 | EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier); |
295 | 296 | |
... | ... | @@ -326,6 +327,7 @@ |
326 | 327 | BUG_ON(notify != new); |
327 | 328 | RCU_INIT_POINTER(net->ct.nf_expect_event_cb, NULL); |
328 | 329 | mutex_unlock(&nf_ct_ecache_mutex); |
330 | + /* synchronize_rcu() is called from ctnetlink_exit. */ | |
329 | 331 | } |
330 | 332 | EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier); |
331 | 333 |
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_nat_core.c
net/netfilter/nfnetlink_cttimeout.c
... | ... | @@ -646,8 +646,8 @@ |
646 | 646 | #ifdef CONFIG_NF_CONNTRACK_TIMEOUT |
647 | 647 | RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, NULL); |
648 | 648 | RCU_INIT_POINTER(nf_ct_timeout_put_hook, NULL); |
649 | + synchronize_rcu(); | |
649 | 650 | #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ |
650 | - rcu_barrier(); | |
651 | 651 | } |
652 | 652 | |
653 | 653 | module_init(cttimeout_init); |