linux/net/bluetooth
Arjan van de Ven 4c8411f8c1 bluetooth: fix locking bug in the rfcomm socket cleanup handling
in net/bluetooth/rfcomm/sock.c, rfcomm_sk_state_change() does the
following operation:

        if (parent && sock_flag(sk, SOCK_ZAPPED)) {
                /* We have to drop DLC lock here, otherwise
                 * rfcomm_sock_destruct() will dead lock. */
                rfcomm_dlc_unlock(d);
                rfcomm_sock_kill(sk);
                rfcomm_dlc_lock(d);
        }
}

which is fine, since rfcomm_sock_kill() will call sk_free() which will call
rfcomm_sock_destruct() which takes the rfcomm_dlc_lock()... so far so good.

HOWEVER, this assumes that the rfcomm_sk_state_change() function always gets
called with the rfcomm_dlc_lock() taken. This is the case for all but one
case, and in that case where we don't have the lock, we do a double unlock
followed by an attempt to take the lock, which due to underflow isn't
going anywhere fast.

This patch fixes this by moving the stragling case inside the lock, like
the other usages of the same call are doing in this code.

This was found with the help of the www.kerneloops.org project, where this
deadlock was observed 51 times at this point in time:
http://www.kerneloops.org/search.php?search=rfcomm_sock_destruct

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-05-29 01:32:47 -07:00
..
bnep bluetooth: use get/put_unaligned_* helpers 2008-05-02 16:25:46 -07:00
cmtp
hidp bluetooth: uninlining 2008-02-05 03:07:58 -08:00
rfcomm bluetooth: fix locking bug in the rfcomm socket cleanup handling 2008-05-29 01:32:47 -07:00
af_bluetooth.c bluetooth : use lockdep sub-classes for diffrent bluetooth protocol 2008-04-01 23:58:35 -07:00
hci_conn.c bluetooth: put hci dev after del conn 2008-02-18 20:44:01 -08:00
hci_core.c bluetooth: hci_core: defer hci_unregister_sysfs() 2008-03-05 18:45:59 -08:00
hci_event.c bluetooth: use get/put_unaligned_* helpers 2008-05-02 16:25:46 -07:00
hci_sock.c bluetooth: use get/put_unaligned_* helpers 2008-05-02 16:25:46 -07:00
hci_sysfs.c bluetooth: do not move child device other than rfcomm 2008-02-18 20:45:41 -08:00
Kconfig
l2cap.c bluetooth: use get/put_unaligned_* helpers 2008-05-02 16:25:46 -07:00
lib.c
Makefile
sco.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6 2008-04-02 22:35:23 -07:00