--- /dev/null
+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
+