Skip to content

Commit 037c97b

Browse files
committed
Merge tag 'for-net-2022-08-25' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - Fix handling of duplicate connection handle - Fix handling of HCI vendor opcode - Fix suspend performance regression - Fix build errors - Fix not handling shutdown condition on ISO sockets - Fix double free issue * tag 'for-net-2022-08-25' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: hci_sync: hold hdev->lock when cleanup hci_conn Bluetooth: move from strlcpy with unused retval to strscpy Bluetooth: hci_event: Fix checking conn for le_conn_complete_evt Bluetooth: ISO: Fix not handling shutdown condition Bluetooth: hci_sync: fix double mgmt_pending_free() in remove_adv_monitor() Bluetooth: MGMT: Fix Get Device Flags Bluetooth: L2CAP: Fix build errors in some archs Bluetooth: hci_sync: Fix suspend performance regression Bluetooth: hci_event: Fix vendor (unknown) opcode status handling ==================== Link: https://lore.kernel.org/r/20220825234559.1837409-1-luiz.dentz@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 2e085ec + 2da8eb8 commit 037c97b

File tree

6 files changed

+105
-61
lines changed

6 files changed

+105
-61
lines changed

net/bluetooth/hci_event.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4179,6 +4179,17 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data,
41794179
}
41804180
}
41814181

4182+
if (i == ARRAY_SIZE(hci_cc_table)) {
4183+
/* Unknown opcode, assume byte 0 contains the status, so
4184+
* that e.g. __hci_cmd_sync() properly returns errors
4185+
* for vendor specific commands send by HCI drivers.
4186+
* If a vendor doesn't actually follow this convention we may
4187+
* need to introduce a vendor CC table in order to properly set
4188+
* the status.
4189+
*/
4190+
*status = skb->data[0];
4191+
}
4192+
41824193
handle_cmd_cnt_and_timer(hdev, ev->ncmd);
41834194

41844195
hci_req_cmd_complete(hdev, *opcode, *status, req_complete,
@@ -5790,7 +5801,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
57905801
*/
57915802
hci_dev_clear_flag(hdev, HCI_LE_ADV);
57925803

5793-
conn = hci_lookup_le_connect(hdev);
5804+
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr);
57945805
if (!conn) {
57955806
/* In case of error status and there is no connection pending
57965807
* just unlock as there is nothing to cleanup.

net/bluetooth/hci_sync.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4773,9 +4773,11 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
47734773
/* Cleanup hci_conn object if it cannot be cancelled as it
47744774
* likelly means the controller and host stack are out of sync.
47754775
*/
4776-
if (err)
4776+
if (err) {
4777+
hci_dev_lock(hdev);
47774778
hci_conn_failed(conn, err);
4778-
4779+
hci_dev_unlock(hdev);
4780+
}
47794781
return err;
47804782
case BT_CONNECT2:
47814783
return hci_reject_conn_sync(hdev, conn, reason);
@@ -5288,17 +5290,21 @@ int hci_suspend_sync(struct hci_dev *hdev)
52885290
/* Prevent disconnects from causing scanning to be re-enabled */
52895291
hci_pause_scan_sync(hdev);
52905292

5291-
/* Soft disconnect everything (power off) */
5292-
err = hci_disconnect_all_sync(hdev, HCI_ERROR_REMOTE_POWER_OFF);
5293-
if (err) {
5294-
/* Set state to BT_RUNNING so resume doesn't notify */
5295-
hdev->suspend_state = BT_RUNNING;
5296-
hci_resume_sync(hdev);
5297-
return err;
5298-
}
5293+
if (hci_conn_count(hdev)) {
5294+
/* Soft disconnect everything (power off) */
5295+
err = hci_disconnect_all_sync(hdev, HCI_ERROR_REMOTE_POWER_OFF);
5296+
if (err) {
5297+
/* Set state to BT_RUNNING so resume doesn't notify */
5298+
hdev->suspend_state = BT_RUNNING;
5299+
hci_resume_sync(hdev);
5300+
return err;
5301+
}
52995302

5300-
/* Update event mask so only the allowed event can wakeup the host */
5301-
hci_set_event_mask_sync(hdev);
5303+
/* Update event mask so only the allowed event can wakeup the
5304+
* host.
5305+
*/
5306+
hci_set_event_mask_sync(hdev);
5307+
}
53025308

53035309
/* Only configure accept list if disconnect succeeded and wake
53045310
* isn't being prevented.

net/bluetooth/hidp/core.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,14 @@ static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo
8383
ci->product = session->input->id.product;
8484
ci->version = session->input->id.version;
8585
if (session->input->name)
86-
strlcpy(ci->name, session->input->name, 128);
86+
strscpy(ci->name, session->input->name, 128);
8787
else
88-
strlcpy(ci->name, "HID Boot Device", 128);
88+
strscpy(ci->name, "HID Boot Device", 128);
8989
} else if (session->hid) {
9090
ci->vendor = session->hid->vendor;
9191
ci->product = session->hid->product;
9292
ci->version = session->hid->version;
93-
strlcpy(ci->name, session->hid->name, 128);
93+
strscpy(ci->name, session->hid->name, 128);
9494
}
9595
}
9696

net/bluetooth/iso.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,25 +1309,40 @@ static int iso_sock_shutdown(struct socket *sock, int how)
13091309
struct sock *sk = sock->sk;
13101310
int err = 0;
13111311

1312-
BT_DBG("sock %p, sk %p", sock, sk);
1312+
BT_DBG("sock %p, sk %p, how %d", sock, sk, how);
13131313

13141314
if (!sk)
13151315
return 0;
13161316

13171317
sock_hold(sk);
13181318
lock_sock(sk);
13191319

1320-
if (!sk->sk_shutdown) {
1321-
sk->sk_shutdown = SHUTDOWN_MASK;
1322-
iso_sock_clear_timer(sk);
1323-
__iso_sock_close(sk);
1324-
1325-
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
1326-
!(current->flags & PF_EXITING))
1327-
err = bt_sock_wait_state(sk, BT_CLOSED,
1328-
sk->sk_lingertime);
1320+
switch (how) {
1321+
case SHUT_RD:
1322+
if (sk->sk_shutdown & RCV_SHUTDOWN)
1323+
goto unlock;
1324+
sk->sk_shutdown |= RCV_SHUTDOWN;
1325+
break;
1326+
case SHUT_WR:
1327+
if (sk->sk_shutdown & SEND_SHUTDOWN)
1328+
goto unlock;
1329+
sk->sk_shutdown |= SEND_SHUTDOWN;
1330+
break;
1331+
case SHUT_RDWR:
1332+
if (sk->sk_shutdown & SHUTDOWN_MASK)
1333+
goto unlock;
1334+
sk->sk_shutdown |= SHUTDOWN_MASK;
1335+
break;
13291336
}
13301337

1338+
iso_sock_clear_timer(sk);
1339+
__iso_sock_close(sk);
1340+
1341+
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
1342+
!(current->flags & PF_EXITING))
1343+
err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
1344+
1345+
unlock:
13311346
release_sock(sk);
13321347
sock_put(sk);
13331348

net/bluetooth/l2cap_core.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,11 +1992,11 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
19921992
src_match = !bacmp(&c->src, src);
19931993
dst_match = !bacmp(&c->dst, dst);
19941994
if (src_match && dst_match) {
1995-
c = l2cap_chan_hold_unless_zero(c);
1996-
if (c) {
1997-
read_unlock(&chan_list_lock);
1998-
return c;
1999-
}
1995+
if (!l2cap_chan_hold_unless_zero(c))
1996+
continue;
1997+
1998+
read_unlock(&chan_list_lock);
1999+
return c;
20002000
}
20012001

20022002
/* Closest match */

net/bluetooth/mgmt.c

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4547,6 +4547,22 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
45474547
MGMT_STATUS_NOT_SUPPORTED);
45484548
}
45494549

4550+
static u32 get_params_flags(struct hci_dev *hdev,
4551+
struct hci_conn_params *params)
4552+
{
4553+
u32 flags = hdev->conn_flags;
4554+
4555+
/* Devices using RPAs can only be programmed in the acceptlist if
4556+
* LL Privacy has been enable otherwise they cannot mark
4557+
* HCI_CONN_FLAG_REMOTE_WAKEUP.
4558+
*/
4559+
if ((flags & HCI_CONN_FLAG_REMOTE_WAKEUP) && !use_ll_privacy(hdev) &&
4560+
hci_find_irk_by_addr(hdev, &params->addr, params->addr_type))
4561+
flags &= ~HCI_CONN_FLAG_REMOTE_WAKEUP;
4562+
4563+
return flags;
4564+
}
4565+
45504566
static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
45514567
u16 data_len)
45524568
{
@@ -4578,10 +4594,10 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
45784594
} else {
45794595
params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
45804596
le_addr_type(cp->addr.type));
4581-
45824597
if (!params)
45834598
goto done;
45844599

4600+
supported_flags = get_params_flags(hdev, params);
45854601
current_flags = params->flags;
45864602
}
45874603

@@ -4649,38 +4665,35 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
46494665
bt_dev_warn(hdev, "No such BR/EDR device %pMR (0x%x)",
46504666
&cp->addr.bdaddr, cp->addr.type);
46514667
}
4652-
} else {
4653-
params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
4654-
le_addr_type(cp->addr.type));
4655-
if (params) {
4656-
/* Devices using RPAs can only be programmed in the
4657-
* acceptlist LL Privacy has been enable otherwise they
4658-
* cannot mark HCI_CONN_FLAG_REMOTE_WAKEUP.
4659-
*/
4660-
if ((current_flags & HCI_CONN_FLAG_REMOTE_WAKEUP) &&
4661-
!use_ll_privacy(hdev) &&
4662-
hci_find_irk_by_addr(hdev, &params->addr,
4663-
params->addr_type)) {
4664-
bt_dev_warn(hdev,
4665-
"Cannot set wakeable for RPA");
4666-
goto unlock;
4667-
}
46684668

4669-
params->flags = current_flags;
4670-
status = MGMT_STATUS_SUCCESS;
4669+
goto unlock;
4670+
}
46714671

4672-
/* Update passive scan if HCI_CONN_FLAG_DEVICE_PRIVACY
4673-
* has been set.
4674-
*/
4675-
if (params->flags & HCI_CONN_FLAG_DEVICE_PRIVACY)
4676-
hci_update_passive_scan(hdev);
4677-
} else {
4678-
bt_dev_warn(hdev, "No such LE device %pMR (0x%x)",
4679-
&cp->addr.bdaddr,
4680-
le_addr_type(cp->addr.type));
4681-
}
4672+
params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
4673+
le_addr_type(cp->addr.type));
4674+
if (!params) {
4675+
bt_dev_warn(hdev, "No such LE device %pMR (0x%x)",
4676+
&cp->addr.bdaddr, le_addr_type(cp->addr.type));
4677+
goto unlock;
46824678
}
46834679

4680+
supported_flags = get_params_flags(hdev, params);
4681+
4682+
if ((supported_flags | current_flags) != supported_flags) {
4683+
bt_dev_warn(hdev, "Bad flag given (0x%x) vs supported (0x%0x)",
4684+
current_flags, supported_flags);
4685+
goto unlock;
4686+
}
4687+
4688+
params->flags = current_flags;
4689+
status = MGMT_STATUS_SUCCESS;
4690+
4691+
/* Update passive scan if HCI_CONN_FLAG_DEVICE_PRIVACY
4692+
* has been set.
4693+
*/
4694+
if (params->flags & HCI_CONN_FLAG_DEVICE_PRIVACY)
4695+
hci_update_passive_scan(hdev);
4696+
46844697
unlock:
46854698
hci_dev_unlock(hdev);
46864699

@@ -5054,7 +5067,6 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
50545067
else
50555068
status = MGMT_STATUS_FAILED;
50565069

5057-
mgmt_pending_remove(cmd);
50585070
goto unlock;
50595071
}
50605072

0 commit comments

Comments
 (0)