summaryrefslogtreecommitdiff
path: root/net/ipv4/netfilter/ip_conntrack_amanda.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-11-29 01:35:25 (GMT)
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 05:31:22 (GMT)
commit337fbc4166967a72c3cc71c597bdde7e6a8633ab (patch)
tree95b2d47e55db3991f66090525b7e28455a6ca39b /net/ipv4/netfilter/ip_conntrack_amanda.c
parent468ec44bd5a863736d955f78b8c38896f26864a1 (diff)
downloadlinux-337fbc4166967a72c3cc71c597bdde7e6a8633ab.tar.xz
[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_conntrack_amanda.c')
-rw-r--r--net/ipv4/netfilter/ip_conntrack_amanda.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
index 7fca246..ad246ba 100644
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -92,6 +92,7 @@ static int help(struct sk_buff **pskb,
char pbuf[sizeof("65535")], *tmp;
u_int16_t port, len;
int ret = NF_ACCEPT;
+ typeof(ip_nat_amanda_hook) ip_nat_amanda;
/* Only look at packets from the Amanda server */
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
@@ -161,9 +162,11 @@ static int help(struct sk_buff **pskb,
exp->mask.dst.protonum = 0xFF;
exp->mask.dst.u.tcp.port = htons(0xFFFF);
- if (ip_nat_amanda_hook)
- ret = ip_nat_amanda_hook(pskb, ctinfo, off - dataoff,
- len, exp);
+ /* RCU read locked by nf_hook_slow */
+ ip_nat_amanda = rcu_dereference(ip_nat_amanda_hook);
+ if (ip_nat_amanda)
+ ret = ip_nat_amanda(pskb, ctinfo, off - dataoff,
+ len, exp);
else if (ip_conntrack_expect_related(exp) != 0)
ret = NF_DROP;
ip_conntrack_expect_put(exp);