aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-11-05 11:38:06 -0500
committerDavid S. Miller <davem@davemloft.net>2015-11-05 11:38:06 -0500
commit096273304cb13b1b6a611026759df7c738a0e4e2 (patch)
treed7a17fa41eaa5de192e09ba7350fb02b33a03cab
parentd4e4bc16102cb1338be9c75f797156718f8a806d (diff)
parent40624183c202278e7e0edd01d1273efc87ddd1f2 (diff)
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Johan Hedberg says: ==================== pull request: bluetooth 2015-11-05 The following set of Bluetooth patches would be good to get into 4.4-rc1 if possible: - Fix for missing LE CoC parameter validity checks - Fix for potential deadlock in btusb - Fix for issuing unsupported commands during HCI init Please let me know if there are any issues pulling. Thanks. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/bluetooth/btusb.c6
-rw-r--r--include/net/bluetooth/l2cap.h2
-rw-r--r--net/bluetooth/hci_core.c17
-rw-r--r--net/bluetooth/l2cap_core.c20
4 files changed, 34 insertions, 11 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index e33dacf5bd98..92f0ee388f9e 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1372,6 +1372,8 @@ static void btusb_work(struct work_struct *work)
1372 } 1372 }
1373 1373
1374 if (data->isoc_altsetting != new_alts) { 1374 if (data->isoc_altsetting != new_alts) {
1375 unsigned long flags;
1376
1375 clear_bit(BTUSB_ISOC_RUNNING, &data->flags); 1377 clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
1376 usb_kill_anchored_urbs(&data->isoc_anchor); 1378 usb_kill_anchored_urbs(&data->isoc_anchor);
1377 1379
@@ -1384,10 +1386,10 @@ static void btusb_work(struct work_struct *work)
1384 * Clear outstanding fragment when selecting a new 1386 * Clear outstanding fragment when selecting a new
1385 * alternate setting. 1387 * alternate setting.
1386 */ 1388 */
1387 spin_lock(&data->rxlock); 1389 spin_lock_irqsave(&data->rxlock, flags);
1388 kfree_skb(data->sco_skb); 1390 kfree_skb(data->sco_skb);
1389 data->sco_skb = NULL; 1391 data->sco_skb = NULL;
1390 spin_unlock(&data->rxlock); 1392 spin_unlock_irqrestore(&data->rxlock, flags);
1391 1393
1392 if (__set_isoc_interface(hdev, new_alts) < 0) 1394 if (__set_isoc_interface(hdev, new_alts) < 0)
1393 return; 1395 return;
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index c98afc08cc26..52899291f401 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -275,6 +275,8 @@ struct l2cap_conn_rsp {
275#define L2CAP_CR_AUTHORIZATION 0x0006 275#define L2CAP_CR_AUTHORIZATION 0x0006
276#define L2CAP_CR_BAD_KEY_SIZE 0x0007 276#define L2CAP_CR_BAD_KEY_SIZE 0x0007
277#define L2CAP_CR_ENCRYPTION 0x0008 277#define L2CAP_CR_ENCRYPTION 0x0008
278#define L2CAP_CR_INVALID_SCID 0x0009
279#define L2CAP_CR_SCID_IN_USE 0x0010
278 280
279/* connect/create channel status */ 281/* connect/create channel status */
280#define L2CAP_CS_NO_INFO 0x0000 282#define L2CAP_CS_NO_INFO 0x0000
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 83a6aacfab31..62edbf1b114e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -508,12 +508,6 @@ static void le_setup(struct hci_request *req)
508 /* Read LE Supported States */ 508 /* Read LE Supported States */
509 hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 509 hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
510 510
511 /* Read LE White List Size */
512 hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
513
514 /* Clear LE White List */
515 hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
516
517 /* LE-only controllers have LE implicitly enabled */ 511 /* LE-only controllers have LE implicitly enabled */
518 if (!lmp_bredr_capable(hdev)) 512 if (!lmp_bredr_capable(hdev))
519 hci_dev_set_flag(hdev, HCI_LE_ENABLED); 513 hci_dev_set_flag(hdev, HCI_LE_ENABLED);
@@ -832,6 +826,17 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
832 hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 826 hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
833 } 827 }
834 828
829 if (hdev->commands[26] & 0x40) {
830 /* Read LE White List Size */
831 hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE,
832 0, NULL);
833 }
834
835 if (hdev->commands[26] & 0x80) {
836 /* Clear LE White List */
837 hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
838 }
839
835 if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { 840 if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
836 /* Read LE Maximum Data Length */ 841 /* Read LE Maximum Data Length */
837 hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL); 842 hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 7c65ee200c29..66e8b6ee19a5 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -239,7 +239,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
239 else 239 else
240 dyn_end = L2CAP_CID_DYN_END; 240 dyn_end = L2CAP_CID_DYN_END;
241 241
242 for (cid = L2CAP_CID_DYN_START; cid < dyn_end; cid++) { 242 for (cid = L2CAP_CID_DYN_START; cid <= dyn_end; cid++) {
243 if (!__l2cap_get_chan_by_scid(conn, cid)) 243 if (!__l2cap_get_chan_by_scid(conn, cid))
244 return cid; 244 return cid;
245 } 245 }
@@ -5250,7 +5250,9 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5250 credits = __le16_to_cpu(rsp->credits); 5250 credits = __le16_to_cpu(rsp->credits);
5251 result = __le16_to_cpu(rsp->result); 5251 result = __le16_to_cpu(rsp->result);
5252 5252
5253 if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23)) 5253 if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23 ||
5254 dcid < L2CAP_CID_DYN_START ||
5255 dcid > L2CAP_CID_LE_DYN_END))
5254 return -EPROTO; 5256 return -EPROTO;
5255 5257
5256 BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x", 5258 BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
@@ -5270,6 +5272,11 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5270 5272
5271 switch (result) { 5273 switch (result) {
5272 case L2CAP_CR_SUCCESS: 5274 case L2CAP_CR_SUCCESS:
5275 if (__l2cap_get_chan_by_dcid(conn, dcid)) {
5276 err = -EBADSLT;
5277 break;
5278 }
5279
5273 chan->ident = 0; 5280 chan->ident = 0;
5274 chan->dcid = dcid; 5281 chan->dcid = dcid;
5275 chan->omtu = mtu; 5282 chan->omtu = mtu;
@@ -5437,9 +5444,16 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
5437 goto response_unlock; 5444 goto response_unlock;
5438 } 5445 }
5439 5446
5447 /* Check for valid dynamic CID range */
5448 if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) {
5449 result = L2CAP_CR_INVALID_SCID;
5450 chan = NULL;
5451 goto response_unlock;
5452 }
5453
5440 /* Check if we already have channel with that dcid */ 5454 /* Check if we already have channel with that dcid */
5441 if (__l2cap_get_chan_by_dcid(conn, scid)) { 5455 if (__l2cap_get_chan_by_dcid(conn, scid)) {
5442 result = L2CAP_CR_NO_MEM; 5456 result = L2CAP_CR_SCID_IN_USE;
5443 chan = NULL; 5457 chan = NULL;
5444 goto response_unlock; 5458 goto response_unlock;
5445 } 5459 }