]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Add netlink socket hang patch from DaveM
authorChris Wright <chrisw@osdl.org>
Sun, 26 Jun 2005 19:17:10 +0000 (12:17 -0700)
committerChris Wright <chrisw@osdl.org>
Sun, 26 Jun 2005 19:17:10 +0000 (12:17 -0700)
queue/netlink-socket-hang.patch [new file with mode: 0644]
queue/series

diff --git a/queue/netlink-socket-hang.patch b/queue/netlink-socket-hang.patch
new file mode 100644 (file)
index 0000000..157dcbe
--- /dev/null
@@ -0,0 +1,68 @@
+From stable-bounces@linux.kernel.org  Sun Jun 26 00:39:03 2005
+Date: Sun, 26 Jun 2005 00:38:51 -0700 (PDT)
+To: stable@kernel.org
+From: "David S. Miller" <davem@davemloft.net>
+Subject: [PATCH][NETLINK]: Fix two socket hashing bugs.
+
+1) netlink_release() should only decrement the hash entry
+   count if the socket was actually hashed.
+
+   This was causing hash->entries to underflow, which
+   resulting in all kinds of troubles.
+
+   On 64-bit systems, this would cause the following
+   conditional to erroneously trigger:
+
+       err = -ENOMEM;
+       if (BITS_PER_LONG > 32 && unlikely(hash->entries >= UINT_MAX))
+               goto err;
+
+2) netlink_autobind() needs to propagate the error return from
+   netlink_insert().  Otherwise, callers will not see the error
+   as they should and thus try to operate on a socket with a zero pid,
+   which is very bad.
+
+   So bug #1 above, combined with this one, resulted in hangs
+   on netlink_sendmsg() calls to the rtnetlink socket.  We'd try
+   to do the user sendmsg() with the socket's pid set to zero,
+   later we do a socket lookup using that pid (via the value we
+   stashed away in NETLINK_CB(skb).pid), but that won't give us the
+   user socket, it will give us the rtnetlink socket.  So when we
+   try to wake up the receive queue, we dive back into rtnetlink_rcv()
+   which tries to recursively take the rtnetlink semaphore.
+
+Thanks to Jakub Jelink for providing backtraces, and Herbert Xu for
+debugging patches to help track this down.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@osdl.org>
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -315,8 +315,8 @@ err:
+ static void netlink_remove(struct sock *sk)
+ {
+       netlink_table_grab();
+-      nl_table[sk->sk_protocol].hash.entries--;
+-      sk_del_node_init(sk);
++      if (sk_del_node_init(sk))
++              nl_table[sk->sk_protocol].hash.entries--;
+       if (nlk_sk(sk)->groups)
+               __sk_del_bind_node(sk);
+       netlink_table_ungrab();
+@@ -429,7 +429,7 @@ retry:
+       err = netlink_insert(sk, pid);
+       if (err == -EADDRINUSE)
+               goto retry;
+-      return 0;
++      return err;
+ }
+ static inline int netlink_capable(struct socket *sock, unsigned int flag) 
+
+_______________________________________________
+stable mailing list
+stable@linux.kernel.org
+http://linux.kernel.org/mailman/listinfo/stable
+
index 42d95eaaad4aea8aa24d0d29821d258e698c9dd1..c41db7e3ce63dc6448873ce896403dede7e4ba56 100644 (file)
@@ -4,3 +4,4 @@ fix-remap_pte_range-BUG.patch
 e1000-fix-spinlock-bug.patch
 memory-clobber-on-x86.patch
 call-acpi_register_gsi-for-pci-irq.patch
+netlink-socket-hang.patch