diff options
author | Patrick McHardy <kaber@trash.net> | 2006-11-29 02:35:25 +0100 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-02 21:31:22 -0800 |
commit | 337fbc4166967a72c3cc71c597bdde7e6a8633ab (patch) | |
tree | 95b2d47e55db3991f66090525b7e28455a6ca39b /net/ipv4/netfilter/ip_nat_helper_h323.c | |
parent | 468ec44bd5a863736d955f78b8c38896f26864a1 (diff) |
[NETFILTER]: ip_conntrack: fix NAT helper unload races
The NAT helpr hooks are protected by RCU, but all of the
conntrack helpers test and use the global pointers instead
of copying them first using rcu_dereference()
Also replace synchronize_net() by synchronize_rcu() for clarity
since sychronizing only with packet receive processing is
insufficient to prevent races.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv4/netfilter/ip_nat_helper_h323.c')
-rw-r--r-- | net/ipv4/netfilter/ip_nat_helper_h323.c | 58 |
1 files changed, 29 insertions, 29 deletions
diff --git a/net/ipv4/netfilter/ip_nat_helper_h323.c b/net/ipv4/netfilter/ip_nat_helper_h323.c index 4a7d34466ee..bdc99ef6159 100644 --- a/net/ipv4/netfilter/ip_nat_helper_h323.c +++ b/net/ipv4/netfilter/ip_nat_helper_h323.c @@ -563,25 +563,25 @@ static int nat_callforwarding(struct sk_buff **pskb, struct ip_conntrack *ct, /****************************************************************************/ static int __init init(void) { - BUG_ON(set_h245_addr_hook != NULL); - BUG_ON(set_h225_addr_hook != NULL); - BUG_ON(set_sig_addr_hook != NULL); - BUG_ON(set_ras_addr_hook != NULL); - BUG_ON(nat_rtp_rtcp_hook != NULL); - BUG_ON(nat_t120_hook != NULL); - BUG_ON(nat_h245_hook != NULL); - BUG_ON(nat_callforwarding_hook != NULL); - BUG_ON(nat_q931_hook != NULL); - - set_h245_addr_hook = set_h245_addr; - set_h225_addr_hook = set_h225_addr; - set_sig_addr_hook = set_sig_addr; - set_ras_addr_hook = set_ras_addr; - nat_rtp_rtcp_hook = nat_rtp_rtcp; - nat_t120_hook = nat_t120; - nat_h245_hook = nat_h245; - nat_callforwarding_hook = nat_callforwarding; - nat_q931_hook = nat_q931; + BUG_ON(rcu_dereference(set_h245_addr_hook) != NULL); + BUG_ON(rcu_dereference(set_h225_addr_hook) != NULL); + BUG_ON(rcu_dereference(set_sig_addr_hook) != NULL); + BUG_ON(rcu_dereference(set_ras_addr_hook) != NULL); + BUG_ON(rcu_dereference(nat_rtp_rtcp_hook) != NULL); + BUG_ON(rcu_dereference(nat_t120_hook) != NULL); + BUG_ON(rcu_dereference(nat_h245_hook) != NULL); + BUG_ON(rcu_dereference(nat_callforwarding_hook) != NULL); + BUG_ON(rcu_dereference(nat_q931_hook) != NULL); + + rcu_assign_pointer(set_h245_addr_hook, set_h245_addr); + rcu_assign_pointer(set_h225_addr_hook, set_h225_addr); + rcu_assign_pointer(set_sig_addr_hook, set_sig_addr); + rcu_assign_pointer(set_ras_addr_hook, set_ras_addr); + rcu_assign_pointer(nat_rtp_rtcp_hook, nat_rtp_rtcp); + rcu_assign_pointer(nat_t120_hook, nat_t120); + rcu_assign_pointer(nat_h245_hook, nat_h245); + rcu_assign_pointer(nat_callforwarding_hook, nat_callforwarding); + rcu_assign_pointer(nat_q931_hook, nat_q931); DEBUGP("ip_nat_h323: init success\n"); return 0; @@ -590,16 +590,16 @@ static int __init init(void) /****************************************************************************/ static void __exit fini(void) { - set_h245_addr_hook = NULL; - set_h225_addr_hook = NULL; - set_sig_addr_hook = NULL; - set_ras_addr_hook = NULL; - nat_rtp_rtcp_hook = NULL; - nat_t120_hook = NULL; - nat_h245_hook = NULL; - nat_callforwarding_hook = NULL; - nat_q931_hook = NULL; - synchronize_net(); + rcu_assign_pointer(set_h245_addr_hook, NULL); + rcu_assign_pointer(set_h225_addr_hook, NULL); + rcu_assign_pointer(set_sig_addr_hook, NULL); + rcu_assign_pointer(set_ras_addr_hook, NULL); + rcu_assign_pointer(nat_rtp_rtcp_hook, NULL); + rcu_assign_pointer(nat_t120_hook, NULL); + rcu_assign_pointer(nat_h245_hook, NULL); + rcu_assign_pointer(nat_callforwarding_hook, NULL); + rcu_assign_pointer(nat_q931_hook, NULL); + synchronize_rcu(); } /****************************************************************************/ |