Skip to content

Commit

Permalink
[NETFILTER]: ip_conntrack: fix NAT helper unload races
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Patrick McHardy authored and David S. Miller committed Dec 3, 2006
1 parent 468ec44 commit 337fbc4
Show file tree
Hide file tree
Showing 15 changed files with 216 additions and 169 deletions.
9 changes: 6 additions & 3 deletions net/ipv4/netfilter/ip_conntrack_amanda.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 5 additions & 3 deletions net/ipv4/netfilter/ip_conntrack_ftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ static int help(struct sk_buff **pskb,
struct ip_conntrack_expect *exp;
unsigned int i;
int found = 0, ends_in_nl;
typeof(ip_nat_ftp_hook) ip_nat_ftp;

/* Until there's been traffic both ways, don't look in packets. */
if (ctinfo != IP_CT_ESTABLISHED
Expand Down Expand Up @@ -433,9 +434,10 @@ static int help(struct sk_buff **pskb,

/* Now, NAT might want to mangle the packet, and register the
* (possibly changed) expectation itself. */
if (ip_nat_ftp_hook)
ret = ip_nat_ftp_hook(pskb, ctinfo, search[dir][i].ftptype,
matchoff, matchlen, exp, &seq);
ip_nat_ftp = rcu_dereference(ip_nat_ftp_hook);
if (ip_nat_ftp)
ret = ip_nat_ftp(pskb, ctinfo, search[dir][i].ftptype,
matchoff, matchlen, exp, &seq);
else {
/* Can't expect this? Best to drop packet now. */
if (ip_conntrack_expect_related(exp) != 0)
Expand Down
Loading

0 comments on commit 337fbc4

Please sign in to comment.