linux/net/bluetooth
Johan Hedberg 02e246aee8 Bluetooth: Fix lockdep warning with l2cap_chan_connect
The L2CAP connection's channel list lock (conn->chan_lock) must never be
taken while already holding a channel lock (chan->lock) in order to
avoid lock-inversion and lockdep warnings. So far the l2cap_chan_connect
function has acquired the chan->lock early in the function and then
later called l2cap_chan_add(conn, chan) which will try to take the
conn->chan_lock. This violates the correct order of taking the locks and
may lead to the following type of lockdep warnings:

-> #1 (&conn->chan_lock){+.+...}:
       [<c109324d>] lock_acquire+0x9d/0x140
       [<c188459c>] mutex_lock_nested+0x6c/0x420
       [<d0aab48e>] l2cap_chan_add+0x1e/0x40 [bluetooth]
       [<d0aac618>] l2cap_chan_connect+0x348/0x8f0 [bluetooth]
       [<d0cc9a91>] lowpan_control_write+0x221/0x2d0 [bluetooth_6lowpan]
-> #0 (&chan->lock){+.+.+.}:
       [<c10928d8>] __lock_acquire+0x1a18/0x1d20
       [<c109324d>] lock_acquire+0x9d/0x140
       [<c188459c>] mutex_lock_nested+0x6c/0x420
       [<d0ab05fd>] l2cap_connect_cfm+0x1dd/0x3f0 [bluetooth]
       [<d0a909c4>] hci_le_meta_evt+0x11a4/0x1260 [bluetooth]
       [<d0a910eb>] hci_event_packet+0x3ab/0x3120 [bluetooth]
       [<d0a7cb08>] hci_rx_work+0x208/0x4a0 [bluetooth]

       CPU0                    CPU1
       ----                    ----
  lock(&conn->chan_lock);
                               lock(&chan->lock);
                               lock(&conn->chan_lock);
  lock(&chan->lock);

Before calling l2cap_chan_add() the channel is not part of the
conn->chan_l list, and can therefore only be accessed by the L2CAP user
(such as l2cap_sock.c). We can therefore assume that it is the
responsibility of the user to handle mutual exclusion until this point
(which we can see is already true in l2cap_sock.c by it in many places
touching chan members without holding chan->lock).

Since the hci_conn and by exctension l2cap_conn creation in the
l2cap_chan_connect() function depend on chan details we cannot simply
add a mutex_lock(&conn->chan_lock) in the beginning of the function
(since the conn object doesn't yet exist there). What we can do however
is move the chan->lock taking later into the function where we already
have the conn object and can that way take conn->chan_lock first.

This patch implements the above strategy and does some other necessary
changes such as using __l2cap_chan_add() which assumes conn->chan_lock
is held, as well as adding a second needed label so the unlocking
happens as it should.

Reported-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Tested-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Acked-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
2014-10-02 10:37:07 +02:00
..
bnep net: set name_assign_type in alloc_netdev() 2014-07-15 16:12:48 -07:00
cmtp Bluetooth: cmtp: Remove unnecessary null test 2014-07-14 23:00:13 +02:00
hidp Bluetooth: Improve *_get() functions to return the object type 2014-09-08 19:07:52 +02:00
rfcomm Bluetooth: Avoid use of session socket after the session gets freed 2014-07-22 16:07:31 +02:00
6lowpan.c Bluetooth: 6lowpan: Enable multicast support 2014-09-29 17:06:38 +02:00
a2mp.c Bluetooth: Provide L2CAP ops callback for memcpy_fromiovec 2014-07-03 17:42:43 +02:00
a2mp.h Bluetooth: Move a2mp.h header file into net/bluetooth/ 2013-10-11 00:10:05 +02:00
af_bluetooth.c Bluetooth: Add BUILD_BUG_ON check for SKB control buffer size 2014-09-15 07:15:41 +03:00
amp.c Bluetooth: LLVMLinux: Remove VLAIS from bluetooth/amp.c 2014-09-08 19:07:56 +02:00
amp.h Bluetooth: Move amp.h header file into net/bluetooth/ 2013-10-11 00:10:03 +02:00
hci_conn.c Bluetooth: Rename sco_param_wideband table to esco_param_msbc 2014-09-25 10:35:08 +02:00
hci_core.c Bluetooth: Remove exported hci_recv_fragment function 2014-09-17 10:23:03 +03:00
hci_event.c Bluetooth: Expire RPA if encryption fails 2014-09-11 07:32:14 +02:00
hci_sock.c Bluetooth: Move struct hci_pinfo into net/bluetooth/hci_sock.c 2014-07-11 13:55:14 +03:00
hci_sysfs.c Bluetooth: Convert to use ATTRIBUTE_GROUPS macro 2014-02-13 09:51:34 +02:00
Kconfig 6lowpan: introduce new net/6lowpan directory 2014-07-12 01:53:30 +02:00
l2cap_core.c Bluetooth: Fix lockdep warning with l2cap_chan_connect 2014-10-02 10:37:07 +02:00
l2cap_sock.c Bluetooth: Fix hci_conn reference counting for fixed channels 2014-09-08 19:07:52 +02:00
lib.c Bluetooth: Convert bt_<level> logging functions to return void 2014-09-24 09:40:08 +02:00
Makefile Bluetooth: 6LoWPAN: Create a kernel module 2014-07-03 17:42:44 +02:00
mgmt.c Bluetooth: Fix mgmt pairing failure when authentication fails 2014-09-09 03:12:15 +02:00
sco.c Bluetooth: never linger on process exit 2014-07-17 12:13:06 +02:00
smp.c Bluetooth: Fix setting correct security level when initiating SMP 2014-09-18 17:39:37 +02:00
smp.h Bluetooth: Add smp_ltk_sec_level() helper function 2014-09-11 02:45:24 +02:00