Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1762564AbXEQFoS (ORCPT ); Thu, 17 May 2007 01:44:18 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756037AbXEQFoK (ORCPT ); Thu, 17 May 2007 01:44:10 -0400 Received: from mail4.iitk.ac.in ([203.197.196.4]:38339 "EHLO mail4.iitk.ac.in" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755531AbXEQFoJ (ORCPT ); Thu, 17 May 2007 01:44:09 -0400 X-Virus-Scanner: This message was checked by NOD32 Antivirus system for Linux Server. For more information on NOD32 Antivirus System, please, visit our website: http://www.nod32.com/. Date: Thu, 17 May 2007 11:13:36 +0530 (IST) From: Satyam Sharma To: akpm@linux-foundation.org cc: David Miller , Marcel Holtmann , Jiri Kosina , Greg KH , Jeremy Fitzhardinge , maxk@qualcomm.com, Cedric Le Goater , Linux Kernel Mailing List Subject: [PATCH] bluetooth: fix locking in hci_sock_dev_event() Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1948 Lines: 56 [PATCH] bluetooth: fix locking in hci_sock_dev_event() We presently use lock_sock() to acquire a lock on a socket in hci_sock_dev_event(), but this goes BUG because lock_sock() can sleep and we're already holding a read-write spinlock at that point. So, we must use the non-sleeping BH version, bh_lock_sock(). However, hci_sock_dev_event() is called from user context and hence using simply bh_lock_sock() will deadlock against a concurrent softirq that tries to acquire a lock on the same socket. Hence, disabling BH's before acquiring the socket lock and enable them afterwards, is the proper solution to fix socket locking in hci_sock_dev_event(). Cc: David Miller Signed-off-by: Satyam Sharma Signed-off-by: Marcel Holtmann Signed-off-by: Jiri Kosina --- net/bluetooth/hci_sock.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) --- diff -ruNp a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c --- a/net/bluetooth/hci_sock.c 2007-05-16 17:31:06.000000000 +0530 +++ b/net/bluetooth/hci_sock.c 2007-05-16 17:38:35.000000000 +0530 @@ -665,7 +665,8 @@ static int hci_sock_dev_event(struct not /* Detach sockets from device */ read_lock(&hci_sk_list.lock); sk_for_each(sk, node, &hci_sk_list.head) { - lock_sock(sk); + local_bh_disable(); + bh_lock_sock_nested(sk); if (hci_pi(sk)->hdev == hdev) { hci_pi(sk)->hdev = NULL; sk->sk_err = EPIPE; @@ -674,7 +675,8 @@ static int hci_sock_dev_event(struct not hci_dev_put(hdev); } - release_sock(sk); + bh_unlock_sock(sk); + local_bh_enable(); } read_unlock(&hci_sk_list.lock); } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/