diff options
author | David S. Miller <davem@davemloft.net> | 2018-10-02 01:40:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-10-02 01:40:39 -0400 |
commit | 92d7c74b6f72a8a7d04970d5dcfb99673daaf91d (patch) | |
tree | 7d9f6b3d9896ef8537e073ab0fd5c016c716b309 | |
parent | d949cfedbcbab4e91590576cbace2671924ad69c (diff) | |
parent | cb28c306b93b71f2741ce1a5a66289db26715f4d (diff) |
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Johan Hedberg says:
====================
pull request: bluetooth 2018-09-27
Here's one more Bluetooth fix for 4.19, fixing the handling of an
attempt to unpair a device while pairing is in progress.
Let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/bluetooth/mgmt.c | 7 | ||||
-rw-r--r-- | net/bluetooth/smp.c | 29 | ||||
-rw-r--r-- | net/bluetooth/smp.h | 3 |
3 files changed, 29 insertions, 10 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3bdc8f3ca259..ccce954f8146 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -2434,9 +2434,8 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2434 | /* LE address type */ | 2434 | /* LE address type */ |
2435 | addr_type = le_addr_type(cp->addr.type); | 2435 | addr_type = le_addr_type(cp->addr.type); |
2436 | 2436 | ||
2437 | hci_remove_irk(hdev, &cp->addr.bdaddr, addr_type); | 2437 | /* Abort any ongoing SMP pairing. Removes ltk and irk if they exist. */ |
2438 | 2438 | err = smp_cancel_and_remove_pairing(hdev, &cp->addr.bdaddr, addr_type); | |
2439 | err = hci_remove_ltk(hdev, &cp->addr.bdaddr, addr_type); | ||
2440 | if (err < 0) { | 2439 | if (err < 0) { |
2441 | err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, | 2440 | err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, |
2442 | MGMT_STATUS_NOT_PAIRED, &rp, | 2441 | MGMT_STATUS_NOT_PAIRED, &rp, |
@@ -2450,8 +2449,6 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2450 | goto done; | 2449 | goto done; |
2451 | } | 2450 | } |
2452 | 2451 | ||
2453 | /* Abort any ongoing SMP pairing */ | ||
2454 | smp_cancel_pairing(conn); | ||
2455 | 2452 | ||
2456 | /* Defer clearing up the connection parameters until closing to | 2453 | /* Defer clearing up the connection parameters until closing to |
2457 | * give a chance of keeping them if a repairing happens. | 2454 | * give a chance of keeping them if a repairing happens. |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 3a7b0773536b..73f7211d0431 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -2422,30 +2422,51 @@ unlock: | |||
2422 | return ret; | 2422 | return ret; |
2423 | } | 2423 | } |
2424 | 2424 | ||
2425 | void smp_cancel_pairing(struct hci_conn *hcon) | 2425 | int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2426 | u8 addr_type) | ||
2426 | { | 2427 | { |
2427 | struct l2cap_conn *conn = hcon->l2cap_data; | 2428 | struct hci_conn *hcon; |
2429 | struct l2cap_conn *conn; | ||
2428 | struct l2cap_chan *chan; | 2430 | struct l2cap_chan *chan; |
2429 | struct smp_chan *smp; | 2431 | struct smp_chan *smp; |
2432 | int err; | ||
2433 | |||
2434 | err = hci_remove_ltk(hdev, bdaddr, addr_type); | ||
2435 | hci_remove_irk(hdev, bdaddr, addr_type); | ||
2436 | |||
2437 | hcon = hci_conn_hash_lookup_le(hdev, bdaddr, addr_type); | ||
2438 | if (!hcon) | ||
2439 | goto done; | ||
2430 | 2440 | ||
2441 | conn = hcon->l2cap_data; | ||
2431 | if (!conn) | 2442 | if (!conn) |
2432 | return; | 2443 | goto done; |
2433 | 2444 | ||
2434 | chan = conn->smp; | 2445 | chan = conn->smp; |
2435 | if (!chan) | 2446 | if (!chan) |
2436 | return; | 2447 | goto done; |
2437 | 2448 | ||
2438 | l2cap_chan_lock(chan); | 2449 | l2cap_chan_lock(chan); |
2439 | 2450 | ||
2440 | smp = chan->data; | 2451 | smp = chan->data; |
2441 | if (smp) { | 2452 | if (smp) { |
2453 | /* Set keys to NULL to make sure smp_failure() does not try to | ||
2454 | * remove and free already invalidated rcu list entries. */ | ||
2455 | smp->ltk = NULL; | ||
2456 | smp->slave_ltk = NULL; | ||
2457 | smp->remote_irk = NULL; | ||
2458 | |||
2442 | if (test_bit(SMP_FLAG_COMPLETE, &smp->flags)) | 2459 | if (test_bit(SMP_FLAG_COMPLETE, &smp->flags)) |
2443 | smp_failure(conn, 0); | 2460 | smp_failure(conn, 0); |
2444 | else | 2461 | else |
2445 | smp_failure(conn, SMP_UNSPECIFIED); | 2462 | smp_failure(conn, SMP_UNSPECIFIED); |
2463 | err = 0; | ||
2446 | } | 2464 | } |
2447 | 2465 | ||
2448 | l2cap_chan_unlock(chan); | 2466 | l2cap_chan_unlock(chan); |
2467 | |||
2468 | done: | ||
2469 | return err; | ||
2449 | } | 2470 | } |
2450 | 2471 | ||
2451 | static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) | 2472 | static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) |
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 0ff6247eaa6c..121edadd5f8d 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h | |||
@@ -181,7 +181,8 @@ enum smp_key_pref { | |||
181 | }; | 181 | }; |
182 | 182 | ||
183 | /* SMP Commands */ | 183 | /* SMP Commands */ |
184 | void smp_cancel_pairing(struct hci_conn *hcon); | 184 | int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr, |
185 | u8 addr_type); | ||
185 | bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level, | 186 | bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level, |
186 | enum smp_key_pref key_pref); | 187 | enum smp_key_pref key_pref); |
187 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); | 188 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); |