Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Johan Hedberg says: ==================== pull request: bluetooth 2018-09-27 Here's one more Bluetooth fix for 4.19, fixing the handling of an attempt to unpair a device while pairing is in progress. Let me know if there are any issues pulling. Thanks. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
92d7c74b6f
|
@ -2434,9 +2434,8 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|||
/* LE address type */
|
||||
addr_type = le_addr_type(cp->addr.type);
|
||||
|
||||
hci_remove_irk(hdev, &cp->addr.bdaddr, addr_type);
|
||||
|
||||
err = hci_remove_ltk(hdev, &cp->addr.bdaddr, addr_type);
|
||||
/* Abort any ongoing SMP pairing. Removes ltk and irk if they exist. */
|
||||
err = smp_cancel_and_remove_pairing(hdev, &cp->addr.bdaddr, addr_type);
|
||||
if (err < 0) {
|
||||
err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
|
||||
MGMT_STATUS_NOT_PAIRED, &rp,
|
||||
|
@ -2450,8 +2449,6 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Abort any ongoing SMP pairing */
|
||||
smp_cancel_pairing(conn);
|
||||
|
||||
/* Defer clearing up the connection parameters until closing to
|
||||
* give a chance of keeping them if a repairing happens.
|
||||
|
|
|
@ -2422,30 +2422,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)
|
||||
|
|
|
@ -181,7 +181,8 @@ enum smp_key_pref {
|
|||
};
|
||||
|
||||
/* SMP Commands */
|
||||
void smp_cancel_pairing(struct hci_conn *hcon);
|
||||
int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
u8 addr_type);
|
||||
bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
|
||||
enum smp_key_pref key_pref);
|
||||
int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);
|
||||
|
|
Loading…
Reference in New Issue