summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/smp.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-10-04 06:00:17 +0200
committerDavid S. Miller <davem@davemloft.net>2018-10-04 06:00:17 +0200
commit6f41617bf23a17d9cb7cc6ca8161534f05f80293 (patch)
tree2844d8d197a61b0603e31f09613e3272635dd1cc /net/bluetooth/smp.c
parentMerge branch '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirshe... (diff)
parentMerge gitolite.kernel.org:/pub/scm/linux/kernel/git/davem/net (diff)
downloadlinux-6f41617bf23a17d9cb7cc6ca8161534f05f80293.tar.xz
linux-6f41617bf23a17d9cb7cc6ca8161534f05f80293.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Minor conflict in net/core/rtnetlink.c, David Ahern's bug fix in 'net' overlapped the renaming of a netlink attribute in net-next. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bluetooth/smp.c')
-rw-r--r--net/bluetooth/smp.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 090670fe385f..a1c1b7e8a45c 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -2419,30 +2419,51 @@ unlock:
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)