OSDN Git Service

[NETFILTER]: Fix deadlock on NAT helper unload
authorPatrick McHardy <kaber@trash.net>
Thu, 14 Sep 2006 20:57:54 +0000 (22:57 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 8 Oct 2006 22:21:09 +0000 (00:21 +0200)
When a NAT helper is unlocked conntrack/NAT may deadlock because of
the following lock sequence:

.. ip_nat_helper_unregister
-> ip_ct_selective_cleanup
-> get_next_corpse              (ip_conntrack_lock)
-> kill_helper                  (ip_nat_lock)

.. ip_nat_fn                    (ip_nat_lock)
-> ip_nat_setup_info
-> ip_conntrack_alter_reply     (ip_conntrack_lock)

Taking ip_nat_lock in kill_helper() is unnecessary since the helper assigned
to a connection is immutable and new connections can't have the helper that
is beeing unloaded assigned since it is already removed from the global list.

Reported by <doublefacer007@gmail.com>.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/netfilter/ip_nat_helper.c

index 6298d96..645f46d 100644 (file)
@@ -522,13 +522,7 @@ int ip_nat_helper_register(struct ip_nat_helper *me)
 static int
 kill_helper(struct ip_conntrack *i, void *helper)
 {
-       int ret;
-
-       READ_LOCK(&ip_nat_lock);
-       ret = (i->nat.info.helper == helper);
-       READ_UNLOCK(&ip_nat_lock);
-
-       return ret;
+       return (i->nat.info.helper == helper);
 }
 
 void ip_nat_helper_unregister(struct ip_nat_helper *me)