Skip to content

Commit f7f46b3

Browse files
Liping Zhanggregkh
authored andcommitted
netfilter: invoke synchronize_rcu after set the _hook_ to NULL
[ Upstream commit 3b7dabf029478bb80507a6c4500ca94132a2bc0b ] 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> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e290667 commit f7f46b3

5 files changed

Lines changed: 7 additions & 1 deletion

File tree

net/ipv4/netfilter/nf_nat_snmp_basic.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,7 @@ static int __init nf_nat_snmp_basic_init(void)
13041304
static void __exit nf_nat_snmp_basic_fini(void)
13051305
{
13061306
RCU_INIT_POINTER(nf_nat_snmp_hook, NULL);
1307+
synchronize_rcu();
13071308
nf_conntrack_helper_unregister(&snmp_trap_helper);
13081309
}
13091310

net/netfilter/nf_conntrack_ecache.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ void nf_conntrack_unregister_notifier(struct net *net,
200200
BUG_ON(notify != new);
201201
RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, NULL);
202202
mutex_unlock(&nf_ct_ecache_mutex);
203+
/* synchronize_rcu() is called from ctnetlink_exit. */
203204
}
204205
EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
205206

@@ -236,6 +237,7 @@ void nf_ct_expect_unregister_notifier(struct net *net,
236237
BUG_ON(notify != new);
237238
RCU_INIT_POINTER(net->ct.nf_expect_event_cb, NULL);
238239
mutex_unlock(&nf_ct_ecache_mutex);
240+
/* synchronize_rcu() is called from ctnetlink_exit. */
239241
}
240242
EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
241243

net/netfilter/nf_conntrack_netlink.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3415,6 +3415,7 @@ static void __exit ctnetlink_exit(void)
34153415
#ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
34163416
RCU_INIT_POINTER(nfnl_ct_hook, NULL);
34173417
#endif
3418+
synchronize_rcu();
34183419
}
34193420

34203421
module_init(ctnetlink_init);

net/netfilter/nf_nat_core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,8 @@ static void __exit nf_nat_cleanup(void)
892892
#ifdef CONFIG_XFRM
893893
RCU_INIT_POINTER(nf_nat_decode_session_hook, NULL);
894894
#endif
895+
synchronize_rcu();
896+
895897
for (i = 0; i < NFPROTO_NUMPROTO; i++)
896898
kfree(nf_nat_l4protos[i]);
897899
synchronize_net();

net/netfilter/nfnetlink_cttimeout.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,8 @@ static void __exit cttimeout_exit(void)
611611
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
612612
RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, NULL);
613613
RCU_INIT_POINTER(nf_ct_timeout_put_hook, NULL);
614+
synchronize_rcu();
614615
#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
615-
rcu_barrier();
616616
}
617617

618618
module_init(cttimeout_init);

0 commit comments

Comments
 (0)