Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: Fix SMP debug key handling

We need to keep debug keys around at least until the point that they are
used - otherwise e.g. slave role behavior wouldn't work as there'd be no
key to be looked up. The correct behavior should therefore be to return
any stored keys but when we clean up the SMP context to remove the key
from the hdev list if keeping debug keys around hasn't been requestsed.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

authored by

Johan Hedberg and committed by
Marcel Holtmann
923e2414 06edf8de

+14 -11
+1 -9
net/bluetooth/hci_core.c
··· 3246 3246 if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr)) 3247 3247 continue; 3248 3248 3249 - if (smp_ltk_is_sc(k)) { 3250 - if (k->type == SMP_LTK_P256_DEBUG && 3251 - !test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags)) 3252 - continue; 3253 - rcu_read_unlock(); 3254 - return k; 3255 - } 3256 - 3257 - if (ltk_role(k->type) == role) { 3249 + if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) { 3258 3250 rcu_read_unlock(); 3259 3251 return k; 3260 3252 }
+13 -2
net/bluetooth/smp.c
··· 670 670 { 671 671 struct l2cap_chan *chan = conn->smp; 672 672 struct smp_chan *smp = chan->data; 673 + struct hci_conn *hcon = conn->hcon; 673 674 bool complete; 674 675 675 676 BUG_ON(!smp); ··· 678 677 cancel_delayed_work_sync(&smp->security_timer); 679 678 680 679 complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); 681 - mgmt_smp_complete(conn->hcon, complete); 680 + mgmt_smp_complete(hcon, complete); 682 681 683 682 kfree(smp->csrk); 684 683 kfree(smp->slave_csrk); ··· 686 685 687 686 crypto_free_blkcipher(smp->tfm_aes); 688 687 crypto_free_hash(smp->tfm_cmac); 688 + 689 + /* Ensure that we don't leave any debug key around if debug key 690 + * support hasn't been explicitly enabled. 691 + */ 692 + if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG && 693 + !test_bit(HCI_KEEP_DEBUG_KEYS, &hcon->hdev->dev_flags)) { 694 + list_del_rcu(&smp->ltk->list); 695 + kfree_rcu(smp->ltk, rcu); 696 + smp->ltk = NULL; 697 + } 689 698 690 699 /* If pairing failed clean up any keys we might have */ 691 700 if (!complete) { ··· 717 706 718 707 chan->data = NULL; 719 708 kfree(smp); 720 - hci_conn_drop(conn->hcon); 709 + hci_conn_drop(hcon); 721 710 } 722 711 723 712 static void smp_failure(struct l2cap_conn *conn, u8 reason)