diff mbox series

Bluetooth: avoid hci_dev_test_and_set_flag() in mgmt_init_hdev()

Message ID f6de02d1-dcda-0383-739d-27484b4d5c63@I-love.SAKURA.ne.jp
State New
Headers show
Series Bluetooth: avoid hci_dev_test_and_set_flag() in mgmt_init_hdev() | expand

Commit Message

Tetsuo Handa Sept. 11, 2022, 4:21 p.m. UTC
syzbot is again reporting attempt to cancel uninitialized work
at mgmt_index_removed() [1], for setting of HCI_MGMT flag from
mgmt_init_hdev() from hci_mgmt_cmd() from hci_sock_sendmsg() can
race with testing of HCI_MGMT flag from mgmt_index_removed() from
hci_sock_bind() due to lack of serialization via hci_dev_lock().

Since mgmt_init_hdev() is called with mgmt_chan_list_lock held, we can
safely split hci_dev_test_and_set_flag() into hci_dev_test_flag() and
hci_dev_set_flag(). Thus, in order to close this race, set HCI_MGMT flag
after INIT_DELAYED_WORK() completed.

This is a local fix based on mgmt_chan_list_lock. Lack of serialization
via hci_dev_lock() might be causing different race conditions somewhere
else. But a global fix based on hci_dev_lock() should deserve a future
patch.

Link: https://syzkaller.appspot.com/bug?extid=844c7bf1b1aa4119c5de
Reported-by: syzbot+844c7bf1b1aa4119c5de@syzkaller.appspotmail.com
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Fixes: 3f2893d3c142986a ("Bluetooth: don't try to cancel uninitialized works at mgmt_index_removed()")
---
 net/bluetooth/mgmt.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

bluez.test.bot@gmail.com Sept. 11, 2022, 5:19 p.m. UTC | #1
This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=676039

---Test result---

Test Summary:
CheckPatch                    PASS      1.76 seconds
GitLint                       PASS      0.95 seconds
SubjectPrefix                 PASS      0.82 seconds
BuildKernel                   PASS      34.17 seconds
BuildKernel32                 PASS      30.91 seconds
Incremental Build with patchesPASS      43.79 seconds
TestRunner: Setup             PASS      513.11 seconds
TestRunner: l2cap-tester      PASS      17.32 seconds
TestRunner: iso-tester        PASS      16.55 seconds
TestRunner: bnep-tester       PASS      6.54 seconds
TestRunner: mgmt-tester       PASS      103.20 seconds
TestRunner: rfcomm-tester     PASS      10.20 seconds
TestRunner: sco-tester        PASS      9.78 seconds
TestRunner: smp-tester        PASS      9.87 seconds
TestRunner: userchan-tester   PASS      6.86 seconds



---
Regards,
Linux Bluetooth
patchwork-bot+bluetooth@kernel.org Sept. 14, 2022, 8:10 p.m. UTC | #2
Hello:

This patch was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Mon, 12 Sep 2022 01:21:42 +0900 you wrote:
> syzbot is again reporting attempt to cancel uninitialized work
> at mgmt_index_removed() [1], for setting of HCI_MGMT flag from
> mgmt_init_hdev() from hci_mgmt_cmd() from hci_sock_sendmsg() can
> race with testing of HCI_MGMT flag from mgmt_index_removed() from
> hci_sock_bind() due to lack of serialization via hci_dev_lock().
> 
> Since mgmt_init_hdev() is called with mgmt_chan_list_lock held, we can
> safely split hci_dev_test_and_set_flag() into hci_dev_test_flag() and
> hci_dev_set_flag(). Thus, in order to close this race, set HCI_MGMT flag
> after INIT_DELAYED_WORK() completed.
> 
> [...]

Here is the summary with links:
  - Bluetooth: avoid hci_dev_test_and_set_flag() in mgmt_init_hdev()
    https://git.kernel.org/bluetooth/bluetooth-next/c/f74ca25d6d66

You are awesome, thank you!
diff mbox series

Patch

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 72e6595a71cc..3d1cd0666968 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1050,7 +1050,7 @@  static void discov_off(struct work_struct *work)
 
 static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev)
 {
-	if (hci_dev_test_and_set_flag(hdev, HCI_MGMT))
+	if (hci_dev_test_flag(hdev, HCI_MGMT))
 		return;
 
 	BT_INFO("MGMT ver %d.%d", MGMT_VERSION, MGMT_REVISION);
@@ -1065,6 +1065,8 @@  static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev)
 	 * it
 	 */
 	hci_dev_clear_flag(hdev, HCI_BONDABLE);
+
+	hci_dev_set_flag(hdev, HCI_MGMT);
 }
 
 static int read_controller_info(struct sock *sk, struct hci_dev *hdev,