Skip to content

Commit

Permalink
Bluetooth: Don't initialize msft/aosp when using user channel
Browse files Browse the repository at this point in the history
A race condition is triggered when usermode control is given to
userspace before the kernel's MSFT query responds, resulting in an
unexpected response to userspace's reset command.

Issue can be observed in btmon:

< HCI Command: Vendor (0x3f|0x001e) plen 2                    #3 [hci0]
        05 01                                            ..
@ USER Open: bt_stack_manage (privileged) version 2.22  {0x0002} [hci0]
< HCI Command: Reset (0x03|0x0003) plen 0                     #4 [hci0]
> HCI Event: Command Complete (0x0e) plen 5                   #5 [hci0]
      Vendor (0x3f|0x001e) ncmd 1
	Status: Command Disallowed (0x0c)
	05                                               .
> HCI Event: Command Complete (0x0e) plen 4                   #6 [hci0]
      Reset (0x03|0x0003) ncmd 2
	Status: Success (0x00)

Reviewed-by: Abhishek Pandit-Subedi <[email protected]>
Reviewed-by: Sonny Sasaka <[email protected]>
Signed-off-by: Jesse Melhuish <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
  • Loading branch information
Jesse Melhuish authored and holtmann committed Nov 16, 2021
1 parent a27c519 commit 385315d
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions net/bluetooth/hci_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -3887,8 +3887,10 @@ int hci_dev_open_sync(struct hci_dev *hdev)
hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
ret = hdev->set_diag(hdev, true);

msft_do_open(hdev);
aosp_do_open(hdev);
if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
msft_do_open(hdev);
aosp_do_open(hdev);
}

clear_bit(HCI_INIT, &hdev->flags);

Expand Down Expand Up @@ -4031,8 +4033,10 @@ int hci_dev_close_sync(struct hci_dev *hdev)

hci_sock_dev_event(hdev, HCI_DEV_DOWN);

aosp_do_close(hdev);
msft_do_close(hdev);
if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
aosp_do_close(hdev);
msft_do_close(hdev);
}

if (hdev->flush)
hdev->flush(hdev);
Expand Down

0 comments on commit 385315d

Please sign in to comment.