Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
This commit is contained in:
Коммит
7f4dbaa3ae
|
@ -610,11 +610,6 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
|
||||||
if (hci_update_random_address(req, false, &own_addr_type))
|
if (hci_update_random_address(req, false, &own_addr_type))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Save the address type used for this connnection attempt so we able
|
|
||||||
* to retrieve this information if we need it.
|
|
||||||
*/
|
|
||||||
conn->src_type = own_addr_type;
|
|
||||||
|
|
||||||
cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
|
cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
|
||||||
cp.scan_window = cpu_to_le16(hdev->le_scan_window);
|
cp.scan_window = cpu_to_le16(hdev->le_scan_window);
|
||||||
bacpy(&cp.peer_addr, &conn->dst);
|
bacpy(&cp.peer_addr, &conn->dst);
|
||||||
|
@ -894,7 +889,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
|
||||||
/* If we're already encrypted set the REAUTH_PEND flag,
|
/* If we're already encrypted set the REAUTH_PEND flag,
|
||||||
* otherwise set the ENCRYPT_PEND.
|
* otherwise set the ENCRYPT_PEND.
|
||||||
*/
|
*/
|
||||||
if (conn->key_type != 0xff)
|
if (conn->link_mode & HCI_LM_ENCRYPT)
|
||||||
set_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
|
set_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
|
||||||
else
|
else
|
||||||
set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
|
set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
|
||||||
|
|
|
@ -48,6 +48,10 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
|
||||||
smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
|
smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
|
||||||
wake_up_bit(&hdev->flags, HCI_INQUIRY);
|
wake_up_bit(&hdev->flags, HCI_INQUIRY);
|
||||||
|
|
||||||
|
hci_dev_lock(hdev);
|
||||||
|
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
|
||||||
|
hci_dev_unlock(hdev);
|
||||||
|
|
||||||
hci_conn_check_pending(hdev);
|
hci_conn_check_pending(hdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3537,7 +3541,11 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||||
cp.authentication = conn->auth_type;
|
cp.authentication = conn->auth_type;
|
||||||
|
|
||||||
/* Request MITM protection if our IO caps allow it
|
/* Request MITM protection if our IO caps allow it
|
||||||
* except for the no-bonding case
|
* except for the no-bonding case.
|
||||||
|
* conn->auth_type is not updated here since
|
||||||
|
* that might cause the user confirmation to be
|
||||||
|
* rejected in case the remote doesn't have the
|
||||||
|
* IO capabilities for MITM.
|
||||||
*/
|
*/
|
||||||
if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
|
if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
|
||||||
cp.authentication != HCI_AT_NO_BONDING)
|
cp.authentication != HCI_AT_NO_BONDING)
|
||||||
|
@ -3628,8 +3636,11 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev,
|
||||||
|
|
||||||
/* If we're not the initiators request authorization to
|
/* If we're not the initiators request authorization to
|
||||||
* proceed from user space (mgmt_user_confirm with
|
* proceed from user space (mgmt_user_confirm with
|
||||||
* confirm_hint set to 1). */
|
* confirm_hint set to 1). The exception is if neither
|
||||||
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
|
* side had MITM in which case we do auto-accept.
|
||||||
|
*/
|
||||||
|
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
|
||||||
|
(loc_mitm || rem_mitm)) {
|
||||||
BT_DBG("Confirming auto-accept as acceptor");
|
BT_DBG("Confirming auto-accept as acceptor");
|
||||||
confirm_hint = 1;
|
confirm_hint = 1;
|
||||||
goto confirm;
|
goto confirm;
|
||||||
|
|
|
@ -1663,7 +1663,13 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
|
||||||
kfree_skb(conn->rx_skb);
|
kfree_skb(conn->rx_skb);
|
||||||
|
|
||||||
skb_queue_purge(&conn->pending_rx);
|
skb_queue_purge(&conn->pending_rx);
|
||||||
flush_work(&conn->pending_rx_work);
|
|
||||||
|
/* We can not call flush_work(&conn->pending_rx_work) here since we
|
||||||
|
* might block if we are running on a worker from the same workqueue
|
||||||
|
* pending_rx_work is waiting on.
|
||||||
|
*/
|
||||||
|
if (work_pending(&conn->pending_rx_work))
|
||||||
|
cancel_work_sync(&conn->pending_rx_work);
|
||||||
|
|
||||||
l2cap_unregister_all_users(conn);
|
l2cap_unregister_all_users(conn);
|
||||||
|
|
||||||
|
|
|
@ -787,11 +787,6 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
|
||||||
/*change security for LE channels */
|
/*change security for LE channels */
|
||||||
if (chan->scid == L2CAP_CID_ATT) {
|
if (chan->scid == L2CAP_CID_ATT) {
|
||||||
if (!conn->hcon->out) {
|
|
||||||
err = -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (smp_conn_security(conn->hcon, sec.level))
|
if (smp_conn_security(conn->hcon, sec.level))
|
||||||
break;
|
break;
|
||||||
sk->sk_state = BT_CONFIG;
|
sk->sk_state = BT_CONFIG;
|
||||||
|
|
|
@ -1047,6 +1047,43 @@ static void clean_up_hci_complete(struct hci_dev *hdev, u8 status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hci_stop_discovery(struct hci_request *req)
|
||||||
|
{
|
||||||
|
struct hci_dev *hdev = req->hdev;
|
||||||
|
struct hci_cp_remote_name_req_cancel cp;
|
||||||
|
struct inquiry_entry *e;
|
||||||
|
|
||||||
|
switch (hdev->discovery.state) {
|
||||||
|
case DISCOVERY_FINDING:
|
||||||
|
if (test_bit(HCI_INQUIRY, &hdev->flags)) {
|
||||||
|
hci_req_add(req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
|
||||||
|
} else {
|
||||||
|
cancel_delayed_work(&hdev->le_scan_disable);
|
||||||
|
hci_req_add_le_scan_disable(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DISCOVERY_RESOLVING:
|
||||||
|
e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
|
||||||
|
NAME_PENDING);
|
||||||
|
if (!e)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bacpy(&cp.bdaddr, &e->data.bdaddr);
|
||||||
|
hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
|
||||||
|
&cp);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Passive scanning */
|
||||||
|
if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
|
||||||
|
hci_req_add_le_scan_disable(req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int clean_up_hci_state(struct hci_dev *hdev)
|
static int clean_up_hci_state(struct hci_dev *hdev)
|
||||||
{
|
{
|
||||||
struct hci_request req;
|
struct hci_request req;
|
||||||
|
@ -1063,9 +1100,7 @@ static int clean_up_hci_state(struct hci_dev *hdev)
|
||||||
if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
|
if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
|
||||||
disable_advertising(&req);
|
disable_advertising(&req);
|
||||||
|
|
||||||
if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
|
hci_stop_discovery(&req);
|
||||||
hci_req_add_le_scan_disable(&req);
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry(conn, &hdev->conn_hash.list, list) {
|
list_for_each_entry(conn, &hdev->conn_hash.list, list) {
|
||||||
struct hci_cp_disconnect dc;
|
struct hci_cp_disconnect dc;
|
||||||
|
@ -2996,8 +3031,13 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) {
|
if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) {
|
||||||
/* Continue with pairing via SMP */
|
/* Continue with pairing via SMP. The hdev lock must be
|
||||||
|
* released as SMP may try to recquire it for crypto
|
||||||
|
* purposes.
|
||||||
|
*/
|
||||||
|
hci_dev_unlock(hdev);
|
||||||
err = smp_user_confirm_reply(conn, mgmt_op, passkey);
|
err = smp_user_confirm_reply(conn, mgmt_op, passkey);
|
||||||
|
hci_dev_lock(hdev);
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
err = cmd_complete(sk, hdev->id, mgmt_op,
|
err = cmd_complete(sk, hdev->id, mgmt_op,
|
||||||
|
@ -3574,8 +3614,6 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||||
{
|
{
|
||||||
struct mgmt_cp_stop_discovery *mgmt_cp = data;
|
struct mgmt_cp_stop_discovery *mgmt_cp = data;
|
||||||
struct pending_cmd *cmd;
|
struct pending_cmd *cmd;
|
||||||
struct hci_cp_remote_name_req_cancel cp;
|
|
||||||
struct inquiry_entry *e;
|
|
||||||
struct hci_request req;
|
struct hci_request req;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -3605,52 +3643,22 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||||
|
|
||||||
hci_req_init(&req, hdev);
|
hci_req_init(&req, hdev);
|
||||||
|
|
||||||
switch (hdev->discovery.state) {
|
hci_stop_discovery(&req);
|
||||||
case DISCOVERY_FINDING:
|
|
||||||
if (test_bit(HCI_INQUIRY, &hdev->flags)) {
|
|
||||||
hci_req_add(&req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
|
|
||||||
} else {
|
|
||||||
cancel_delayed_work(&hdev->le_scan_disable);
|
|
||||||
|
|
||||||
hci_req_add_le_scan_disable(&req);
|
err = hci_req_run(&req, stop_discovery_complete);
|
||||||
}
|
if (!err) {
|
||||||
|
hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
|
||||||
break;
|
|
||||||
|
|
||||||
case DISCOVERY_RESOLVING:
|
|
||||||
e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
|
|
||||||
NAME_PENDING);
|
|
||||||
if (!e) {
|
|
||||||
mgmt_pending_remove(cmd);
|
|
||||||
err = cmd_complete(sk, hdev->id,
|
|
||||||
MGMT_OP_STOP_DISCOVERY, 0,
|
|
||||||
&mgmt_cp->type,
|
|
||||||
sizeof(mgmt_cp->type));
|
|
||||||
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
|
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
bacpy(&cp.bdaddr, &e->data.bdaddr);
|
|
||||||
hci_req_add(&req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
|
|
||||||
&cp);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
BT_DBG("unknown discovery state %u", hdev->discovery.state);
|
|
||||||
|
|
||||||
mgmt_pending_remove(cmd);
|
|
||||||
err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
|
|
||||||
MGMT_STATUS_FAILED, &mgmt_cp->type,
|
|
||||||
sizeof(mgmt_cp->type));
|
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = hci_req_run(&req, stop_discovery_complete);
|
mgmt_pending_remove(cmd);
|
||||||
if (err < 0)
|
|
||||||
mgmt_pending_remove(cmd);
|
/* If no HCI commands were sent we're done */
|
||||||
else
|
if (err == -ENODATA) {
|
||||||
hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
|
err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0,
|
||||||
|
&mgmt_cp->type, sizeof(mgmt_cp->type));
|
||||||
|
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
|
||||||
|
}
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
hci_dev_unlock(hdev);
|
hci_dev_unlock(hdev);
|
||||||
|
|
|
@ -544,7 +544,7 @@ static u8 smp_random(struct smp_chan *smp)
|
||||||
hci_le_start_enc(hcon, ediv, rand, stk);
|
hci_le_start_enc(hcon, ediv, rand, stk);
|
||||||
hcon->enc_key_size = smp->enc_key_size;
|
hcon->enc_key_size = smp->enc_key_size;
|
||||||
} else {
|
} else {
|
||||||
u8 stk[16];
|
u8 stk[16], auth;
|
||||||
__le64 rand = 0;
|
__le64 rand = 0;
|
||||||
__le16 ediv = 0;
|
__le16 ediv = 0;
|
||||||
|
|
||||||
|
@ -556,8 +556,13 @@ static u8 smp_random(struct smp_chan *smp)
|
||||||
memset(stk + smp->enc_key_size, 0,
|
memset(stk + smp->enc_key_size, 0,
|
||||||
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
|
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
|
||||||
|
|
||||||
|
if (hcon->pending_sec_level == BT_SECURITY_HIGH)
|
||||||
|
auth = 1;
|
||||||
|
else
|
||||||
|
auth = 0;
|
||||||
|
|
||||||
hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
|
hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
|
||||||
HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
|
HCI_SMP_STK_SLAVE, auth, stk, smp->enc_key_size,
|
||||||
ediv, rand);
|
ediv, rand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче