aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-10-02 01:40:39 -0400
committerDavid S. Miller <davem@davemloft.net>2018-10-02 01:40:39 -0400
commit92d7c74b6f72a8a7d04970d5dcfb99673daaf91d (patch)
tree7d9f6b3d9896ef8537e073ab0fd5c016c716b309
parentd949cfedbcbab4e91590576cbace2671924ad69c (diff)
parentcb28c306b93b71f2741ce1a5a66289db26715f4d (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.c7
-rw-r--r--net/bluetooth/smp.c29
-rw-r--r--net/bluetooth/smp.h3
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
2425void smp_cancel_pairing(struct hci_conn *hcon) 2425int 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
2468done:
2469 return err;
2449} 2470}
2450 2471
2451static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) 2472static 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 */
184void smp_cancel_pairing(struct hci_conn *hcon); 184int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr,
185 u8 addr_type);
185bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level, 186bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
186 enum smp_key_pref key_pref); 187 enum smp_key_pref key_pref);
187int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); 188int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);