diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index c8123f04a33c571dc042aff668d06a8272754fd7..f0018562b028170247f036a7b190368e31d08ea2 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3246,15 +3246,7 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr)) continue; - if (smp_ltk_is_sc(k)) { - if (k->type == SMP_LTK_P256_DEBUG && - !test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags)) - continue; - rcu_read_unlock(); - return k; - } - - if (ltk_role(k->type) == role) { + if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) { rcu_read_unlock(); return k; } diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 1d1c33d5d1dce56c75b9e5b32a049335e300a888..a7b973b867c8ef26d3e3e631af47f1ebddf83a15 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -670,6 +670,7 @@ static void smp_chan_destroy(struct l2cap_conn *conn) { struct l2cap_chan *chan = conn->smp; struct smp_chan *smp = chan->data; + struct hci_conn *hcon = conn->hcon; bool complete; BUG_ON(!smp); @@ -677,7 +678,7 @@ static void smp_chan_destroy(struct l2cap_conn *conn) cancel_delayed_work_sync(&smp->security_timer); complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); - mgmt_smp_complete(conn->hcon, complete); + mgmt_smp_complete(hcon, complete); kfree(smp->csrk); kfree(smp->slave_csrk); @@ -686,6 +687,16 @@ static void smp_chan_destroy(struct l2cap_conn *conn) crypto_free_blkcipher(smp->tfm_aes); crypto_free_hash(smp->tfm_cmac); + /* Ensure that we don't leave any debug key around if debug key + * support hasn't been explicitly enabled. + */ + if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG && + !test_bit(HCI_KEEP_DEBUG_KEYS, &hcon->hdev->dev_flags)) { + list_del_rcu(&smp->ltk->list); + kfree_rcu(smp->ltk, rcu); + smp->ltk = NULL; + } + /* If pairing failed clean up any keys we might have */ if (!complete) { if (smp->ltk) { @@ -706,7 +717,7 @@ static void smp_chan_destroy(struct l2cap_conn *conn) chan->data = NULL; kfree(smp); - hci_conn_drop(conn->hcon); + hci_conn_drop(hcon); } static void smp_failure(struct l2cap_conn *conn, u8 reason)