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,
} else {
ret = devm_request_irq(dev, cfg->irq_bt,
btmrvl_wake_irq_bt,
0, "bt_wake", card);
IRQF_NO_AUTOEN, "bt_wake", card);
if (ret) {
dev_err(dev,
"Failed to request irq_bt %d (%d)\n",
......@@ -101,7 +101,6 @@ static int btmrvl_sdio_probe_of(struct device *dev,
/* Configure wakeup (enabled by default) */
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)
hci_dev_lock(hdev);
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);
if (conn) {
......
......@@ -3706,7 +3706,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev, void *data,
goto unlock;
}
if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
if (!ev->status) {
struct hci_cp_remote_name_req cp;
memset(&cp, 0, sizeof(cp));
bacpy(&cp.bdaddr, &conn->dst);
......@@ -5324,19 +5324,16 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data,
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) &&
(!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
/* If we're not the initiators request authorization to
* proceed from user space (mgmt_user_confirm with
* confirm_hint set to 1). The exception is if neither
* side had MITM or if the local IO capability is
* NoInputNoOutput, in which case we do auto-accept
/* If we're not the initiator of request authorization and the
* local IO capability is not NoInputNoOutput, use JUST_WORKS
* method (mgmt_user_confirm with confirm_hint set to 1).
*/
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
(loc_mitm || rem_mitm)) {
conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) {
bt_dev_dbg(hdev, "Confirming auto-accept as acceptor");
confirm_hint = 1;
goto confirm;
......
......@@ -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,
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))
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);
return 0;
}
......
......@@ -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)
{
if (cmd->cmd_complete) {
u8 *status = data;
struct cmd_lookup *match = 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);
return;
......@@ -9394,12 +9399,12 @@ void mgmt_index_added(struct hci_dev *hdev)
void mgmt_index_removed(struct hci_dev *hdev)
{
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))
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)) {
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)
void __mgmt_power_off(struct hci_dev *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);
......@@ -9462,11 +9467,11 @@ void __mgmt_power_off(struct hci_dev *hdev)
* status responses.
*/
if (hci_dev_test_flag(hdev, HCI_UNREGISTER))
status = MGMT_STATUS_INVALID_INDEX;
match.mgmt_status = MGMT_STATUS_INVALID_INDEX;
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) {
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