Commit e5e3f369 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'for-net-2024-09-27' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth

Luiz Augusto von Dentz says:

====================
bluetooth pull request for net:

 - btmrvl: Use IRQF_NO_AUTOEN flag in request_irq()
 - MGMT: Fix possible crash on mgmt_index_removed
 - L2CAP: Fix uaf in l2cap_connect
 - Bluetooth: hci_event: Align BR/EDR JUST_WORKS paring with LE

* tag 'for-net-2024-09-27' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth:
  Bluetooth: hci_event: Align BR/EDR JUST_WORKS paring with LE
  Bluetooth: btmrvl: Use IRQF_NO_AUTOEN flag in request_irq()
  Bluetooth: L2CAP: Fix uaf in l2cap_connect
  Bluetooth: MGMT: Fix possible crash on mgmt_index_removed
====================

Link: https://patch.msgid.link/20240927145730.2452175-1-luiz.dentz@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents cb3ad113 b25e11f9
...@@ -92,7 +92,7 @@ static int btmrvl_sdio_probe_of(struct device *dev, ...@@ -92,7 +92,7 @@ static int btmrvl_sdio_probe_of(struct device *dev,
} else { } else {
ret = devm_request_irq(dev, cfg->irq_bt, ret = devm_request_irq(dev, cfg->irq_bt,
btmrvl_wake_irq_bt, btmrvl_wake_irq_bt,
0, "bt_wake", card); IRQF_NO_AUTOEN, "bt_wake", card);
if (ret) { if (ret) {
dev_err(dev, dev_err(dev,
"Failed to request irq_bt %d (%d)\n", "Failed to request irq_bt %d (%d)\n",
...@@ -101,7 +101,6 @@ static int btmrvl_sdio_probe_of(struct device *dev, ...@@ -101,7 +101,6 @@ static int btmrvl_sdio_probe_of(struct device *dev,
/* Configure wakeup (enabled by default) */ /* Configure wakeup (enabled by default) */
device_init_wakeup(dev, true); device_init_wakeup(dev, true);
disable_irq(cfg->irq_bt);
} }
} }
......
...@@ -3782,6 +3782,8 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -3782,6 +3782,8 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_lock(hdev); hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, handle); conn = hci_conn_hash_lookup_handle(hdev, handle);
if (conn && hci_dev_test_flag(hdev, HCI_MGMT))
mgmt_device_connected(hdev, conn, NULL, 0);
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
if (conn) { if (conn) {
......
...@@ -3706,7 +3706,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev, void *data, ...@@ -3706,7 +3706,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev, void *data,
goto unlock; goto unlock;
} }
if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { if (!ev->status) {
struct hci_cp_remote_name_req cp; struct hci_cp_remote_name_req cp;
memset(&cp, 0, sizeof(cp)); memset(&cp, 0, sizeof(cp));
bacpy(&cp.bdaddr, &conn->dst); bacpy(&cp.bdaddr, &conn->dst);
...@@ -5324,19 +5324,16 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data, ...@@ -5324,19 +5324,16 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data,
goto unlock; goto unlock;
} }
/* If no side requires MITM protection; auto-accept */ /* If no side requires MITM protection; use JUST_CFM method */
if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) && if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
(!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) { (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
/* If we're not the initiators request authorization to /* If we're not the initiator of request authorization and the
* proceed from user space (mgmt_user_confirm with * local IO capability is not NoInputNoOutput, use JUST_WORKS
* confirm_hint set to 1). The exception is if neither * method (mgmt_user_confirm with confirm_hint set to 1).
* side had MITM or if the local IO capability is
* NoInputNoOutput, in which case we do auto-accept
*/ */
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) {
(loc_mitm || rem_mitm)) {
bt_dev_dbg(hdev, "Confirming auto-accept as acceptor"); bt_dev_dbg(hdev, "Confirming auto-accept as acceptor");
confirm_hint = 1; confirm_hint = 1;
goto confirm; goto confirm;
......
...@@ -4066,17 +4066,9 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, ...@@ -4066,17 +4066,9 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
static int l2cap_connect_req(struct l2cap_conn *conn, static int l2cap_connect_req(struct l2cap_conn *conn,
struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
{ {
struct hci_dev *hdev = conn->hcon->hdev;
struct hci_conn *hcon = conn->hcon;
if (cmd_len < sizeof(struct l2cap_conn_req)) if (cmd_len < sizeof(struct l2cap_conn_req))
return -EPROTO; return -EPROTO;
hci_dev_lock(hdev);
if (hci_dev_test_flag(hdev, HCI_MGMT))
mgmt_device_connected(hdev, hcon, NULL, 0);
hci_dev_unlock(hdev);
l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP); l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP);
return 0; return 0;
} }
......
...@@ -1453,10 +1453,15 @@ static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data) ...@@ -1453,10 +1453,15 @@ static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data)
static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
{ {
if (cmd->cmd_complete) { struct cmd_lookup *match = data;
u8 *status = data;
cmd->cmd_complete(cmd, *status); /* dequeue cmd_sync entries using cmd as data as that is about to be
* removed/freed.
*/
hci_cmd_sync_dequeue(match->hdev, NULL, cmd, NULL);
if (cmd->cmd_complete) {
cmd->cmd_complete(cmd, match->mgmt_status);
mgmt_pending_remove(cmd); mgmt_pending_remove(cmd);
return; return;
...@@ -9394,12 +9399,12 @@ void mgmt_index_added(struct hci_dev *hdev) ...@@ -9394,12 +9399,12 @@ void mgmt_index_added(struct hci_dev *hdev)
void mgmt_index_removed(struct hci_dev *hdev) void mgmt_index_removed(struct hci_dev *hdev)
{ {
struct mgmt_ev_ext_index ev; struct mgmt_ev_ext_index ev;
u8 status = MGMT_STATUS_INVALID_INDEX; struct cmd_lookup match = { NULL, hdev, MGMT_STATUS_INVALID_INDEX };
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
return; return;
mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status); mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match);
if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0,
...@@ -9450,7 +9455,7 @@ void mgmt_power_on(struct hci_dev *hdev, int err) ...@@ -9450,7 +9455,7 @@ void mgmt_power_on(struct hci_dev *hdev, int err)
void __mgmt_power_off(struct hci_dev *hdev) void __mgmt_power_off(struct hci_dev *hdev)
{ {
struct cmd_lookup match = { NULL, hdev }; struct cmd_lookup match = { NULL, hdev };
u8 status, zero_cod[] = { 0, 0, 0 }; u8 zero_cod[] = { 0, 0, 0 };
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
...@@ -9462,11 +9467,11 @@ void __mgmt_power_off(struct hci_dev *hdev) ...@@ -9462,11 +9467,11 @@ void __mgmt_power_off(struct hci_dev *hdev)
* status responses. * status responses.
*/ */
if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) if (hci_dev_test_flag(hdev, HCI_UNREGISTER))
status = MGMT_STATUS_INVALID_INDEX; match.mgmt_status = MGMT_STATUS_INVALID_INDEX;
else else
status = MGMT_STATUS_NOT_POWERED; match.mgmt_status = MGMT_STATUS_NOT_POWERED;
mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status); mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match);
if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) { if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) {
mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment