mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 22:26:55 +00:00
Bluetooth: avoid hci_dev_test_and_set_flag() in mgmt_init_hdev()
[ Upstream commitf74ca25d6d
] 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:3f2893d3c1
("Bluetooth: don't try to cancel uninitialized works at mgmt_index_removed()") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
cc6cd7c0d9
commit
e53c6180db
1 changed files with 3 additions and 1 deletions
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue