From 16f48bfa438525cbef448d05344be3de5434ebb9 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Sun, 26 Jun 2005 12:17:10 -0700 Subject: [PATCH] Add netlink socket hang patch from DaveM --- queue/netlink-socket-hang.patch | 68 +++++++++++++++++++++++++++++++++ queue/series | 1 + 2 files changed, 69 insertions(+) create mode 100644 queue/netlink-socket-hang.patch diff --git a/queue/netlink-socket-hang.patch b/queue/netlink-socket-hang.patch new file mode 100644 index 00000000000..157dcbe3dd2 --- /dev/null +++ b/queue/netlink-socket-hang.patch @@ -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" +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 +Signed-off-by: Chris Wright + +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 + diff --git a/queue/series b/queue/series index 42d95eaaad4..c41db7e3ce6 100644 --- a/queue/series +++ b/queue/series @@ -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 -- 2.47.3