]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/bluetooth/smp.c
Merge branch 'i2c-mux/for-next' of https://github.com/peda-r/i2c-mux into i2c/for...
[linux.git] / net / bluetooth / smp.c
index 3a7b0773536b8e226546ebe417463fcba5c92ba4..73f7211d0431a0f766dfacd488077a081054b67c 100644 (file)
@@ -2422,30 +2422,51 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
        return ret;
 }
 
-void smp_cancel_pairing(struct hci_conn *hcon)
+int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr,
+                                 u8 addr_type)
 {
-       struct l2cap_conn *conn = hcon->l2cap_data;
+       struct hci_conn *hcon;
+       struct l2cap_conn *conn;
        struct l2cap_chan *chan;
        struct smp_chan *smp;
+       int err;
+
+       err = hci_remove_ltk(hdev, bdaddr, addr_type);
+       hci_remove_irk(hdev, bdaddr, addr_type);
+
+       hcon = hci_conn_hash_lookup_le(hdev, bdaddr, addr_type);
+       if (!hcon)
+               goto done;
 
+       conn = hcon->l2cap_data;
        if (!conn)
-               return;
+               goto done;
 
        chan = conn->smp;
        if (!chan)
-               return;
+               goto done;
 
        l2cap_chan_lock(chan);
 
        smp = chan->data;
        if (smp) {
+               /* Set keys to NULL to make sure smp_failure() does not try to
+                * remove and free already invalidated rcu list entries. */
+               smp->ltk = NULL;
+               smp->slave_ltk = NULL;
+               smp->remote_irk = NULL;
+
                if (test_bit(SMP_FLAG_COMPLETE, &smp->flags))
                        smp_failure(conn, 0);
                else
                        smp_failure(conn, SMP_UNSPECIFIED);
+               err = 0;
        }
 
        l2cap_chan_unlock(chan);
+
+done:
+       return err;
 }
 
 static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)