diff options
author | Jaganath Kanakkassery <jaganath.k@samsung.com> | 2014-12-11 08:28:15 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-12-11 09:09:04 -0500 |
commit | 5c1a4c8f28059e592da4fff40c0dc54202fb5cc6 (patch) | |
tree | c09f33a79997bd440c3b3c8640d1a640caa3a17b | |
parent | 3ad675827f4a3623b7fc51ffe8fdb0347b3cbc53 (diff) |
Bluetooth: Fix missing hci_dev_lock/unlock in hci_event
mgmt_pending_remove() should be called with hci_dev_lock protection and
all hci_event.c functions which calls mgmt_complete() (which eventually
calls mgmt_pending_remove()) should hold the lock.
So this patch fixes the same
Signed-off-by: Jaganath Kanakkassery <jaganath.k@samsung.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r-- | net/bluetooth/hci_event.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 322abbbbcef9..39a5c8a01726 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -257,6 +257,8 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
257 | if (!sent) | 257 | if (!sent) |
258 | return; | 258 | return; |
259 | 259 | ||
260 | hci_dev_lock(hdev); | ||
261 | |||
260 | if (!status) { | 262 | if (!status) { |
261 | __u8 param = *((__u8 *) sent); | 263 | __u8 param = *((__u8 *) sent); |
262 | 264 | ||
@@ -268,6 +270,8 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
268 | 270 | ||
269 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | 271 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) |
270 | mgmt_auth_enable_complete(hdev, status); | 272 | mgmt_auth_enable_complete(hdev, status); |
273 | |||
274 | hci_dev_unlock(hdev); | ||
271 | } | 275 | } |
272 | 276 | ||
273 | static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) | 277 | static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -443,6 +447,8 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) | |||
443 | if (!sent) | 447 | if (!sent) |
444 | return; | 448 | return; |
445 | 449 | ||
450 | hci_dev_lock(hdev); | ||
451 | |||
446 | if (!status) { | 452 | if (!status) { |
447 | if (sent->mode) | 453 | if (sent->mode) |
448 | hdev->features[1][0] |= LMP_HOST_SSP; | 454 | hdev->features[1][0] |= LMP_HOST_SSP; |
@@ -458,6 +464,8 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) | |||
458 | else | 464 | else |
459 | clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); | 465 | clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); |
460 | } | 466 | } |
467 | |||
468 | hci_dev_unlock(hdev); | ||
461 | } | 469 | } |
462 | 470 | ||
463 | static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) | 471 | static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -471,6 +479,8 @@ static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) | |||
471 | if (!sent) | 479 | if (!sent) |
472 | return; | 480 | return; |
473 | 481 | ||
482 | hci_dev_lock(hdev); | ||
483 | |||
474 | if (!status) { | 484 | if (!status) { |
475 | if (sent->support) | 485 | if (sent->support) |
476 | hdev->features[1][0] |= LMP_HOST_SC; | 486 | hdev->features[1][0] |= LMP_HOST_SC; |
@@ -486,6 +496,8 @@ static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) | |||
486 | else | 496 | else |
487 | clear_bit(HCI_SC_ENABLED, &hdev->dev_flags); | 497 | clear_bit(HCI_SC_ENABLED, &hdev->dev_flags); |
488 | } | 498 | } |
499 | |||
500 | hci_dev_unlock(hdev); | ||
489 | } | 501 | } |
490 | 502 | ||
491 | static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | 503 | static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -1135,6 +1147,8 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | |||
1135 | if (!cp) | 1147 | if (!cp) |
1136 | return; | 1148 | return; |
1137 | 1149 | ||
1150 | hci_dev_lock(hdev); | ||
1151 | |||
1138 | switch (cp->enable) { | 1152 | switch (cp->enable) { |
1139 | case LE_SCAN_ENABLE: | 1153 | case LE_SCAN_ENABLE: |
1140 | set_bit(HCI_LE_SCAN, &hdev->dev_flags); | 1154 | set_bit(HCI_LE_SCAN, &hdev->dev_flags); |
@@ -1184,6 +1198,8 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | |||
1184 | BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable); | 1198 | BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable); |
1185 | break; | 1199 | break; |
1186 | } | 1200 | } |
1201 | |||
1202 | hci_dev_unlock(hdev); | ||
1187 | } | 1203 | } |
1188 | 1204 | ||
1189 | static void hci_cc_le_read_white_list_size(struct hci_dev *hdev, | 1205 | static void hci_cc_le_read_white_list_size(struct hci_dev *hdev, |
@@ -1278,6 +1294,8 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, | |||
1278 | if (!sent) | 1294 | if (!sent) |
1279 | return; | 1295 | return; |
1280 | 1296 | ||
1297 | hci_dev_lock(hdev); | ||
1298 | |||
1281 | if (sent->le) { | 1299 | if (sent->le) { |
1282 | hdev->features[1][0] |= LMP_HOST_LE; | 1300 | hdev->features[1][0] |= LMP_HOST_LE; |
1283 | set_bit(HCI_LE_ENABLED, &hdev->dev_flags); | 1301 | set_bit(HCI_LE_ENABLED, &hdev->dev_flags); |
@@ -1291,6 +1309,8 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, | |||
1291 | hdev->features[1][0] |= LMP_HOST_LE_BREDR; | 1309 | hdev->features[1][0] |= LMP_HOST_LE_BREDR; |
1292 | else | 1310 | else |
1293 | hdev->features[1][0] &= ~LMP_HOST_LE_BREDR; | 1311 | hdev->features[1][0] &= ~LMP_HOST_LE_BREDR; |
1312 | |||
1313 | hci_dev_unlock(hdev); | ||
1294 | } | 1314 | } |
1295 | 1315 | ||
1296 | static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb) | 1316 | static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb) |