diff options
author | David S. Miller <davem@davemloft.net> | 2015-11-05 11:38:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-11-05 11:38:06 -0500 |
commit | 096273304cb13b1b6a611026759df7c738a0e4e2 (patch) | |
tree | d7a17fa41eaa5de192e09ba7350fb02b33a03cab | |
parent | d4e4bc16102cb1338be9c75f797156718f8a806d (diff) | |
parent | 40624183c202278e7e0edd01d1273efc87ddd1f2 (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.c | 6 | ||||
-rw-r--r-- | include/net/bluetooth/l2cap.h | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 17 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 20 |
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 | } |