Bluetooth: Fix missing address type check for removing LTKs
authorJohan Hedberg <johan.hedberg@intel.com>
Tue, 18 Feb 2014 15:14:31 +0000 (17:14 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 18 Feb 2014 16:58:20 +0000 (08:58 -0800)
When removing Long Term Keys we should also be checking that the given
address type (public vs random) matches. This patch updates the
hci_remove_ltk function to take an extra parameter and uses it for
address type matching.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_core.c
net/bluetooth/mgmt.c

index 86ea4ba..ab94abd 100644 (file)
@@ -792,7 +792,7 @@ int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
                __le16 ediv, u8 rand[8]);
 struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
                                     u8 addr_type, bool master);
-int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr);
+int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type);
 int hci_smp_ltks_clear(struct hci_dev *hdev);
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
index 59a76b2..957c8f4 100644 (file)
@@ -2810,12 +2810,12 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
        return 0;
 }
 
-int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
+int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
 {
        struct smp_ltk *k, *tmp;
 
        list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
-               if (bacmp(bdaddr, &k->bdaddr))
+               if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
                        continue;
 
                BT_DBG("%s removing %pMR", hdev->name, bdaddr);
index 782e2bb..473f868 100644 (file)
@@ -2318,10 +2318,18 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
                goto unlock;
        }
 
-       if (cp->addr.type == BDADDR_BREDR)
+       if (cp->addr.type == BDADDR_BREDR) {
                err = hci_remove_link_key(hdev, &cp->addr.bdaddr);
-       else
-               err = hci_remove_ltk(hdev, &cp->addr.bdaddr);
+       } else {
+               u8 addr_type;
+
+               if (cp->addr.type == BDADDR_LE_PUBLIC)
+                       addr_type = ADDR_LE_DEV_PUBLIC;
+               else
+                       addr_type = ADDR_LE_DEV_RANDOM;
+
+               err = hci_remove_ltk(hdev, &cp->addr.bdaddr, addr_type);
+       }
 
        if (err < 0) {
                err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,