[lvc-project] [PATCH] Bluetooth: do not send mgmt commands to device which is going to close
Dmitry Antipov
dmantipov at yandex.ru
Mon Oct 7 10:45:38 MSK 2024
Syzbot has observed the following race between 'hci_dev_close()' and
'hci_cmd_sync_work()':
T0: T1:
...
-> sock_ioctl()
-> sock_do_ioctl()
-> hci_dev_close()
-> hci_dev_close_sync()
-> __mgmt_power_off() ...
-> mgmt_pending_foreach() -> process_scheduled_works()
-> settings_rsp() -> hci_cmd_sync_work()
-> kfree() -> set_powered_sync()
That is, 'hci_cmd_sync_work()' makes an attempt to process a command
from (partially) freed 'cmd_sync_work_list', which causes UAF detected
by KASAN. Fix this by marking the closing device with HCI_CLOSING bit
very early and rejecting new mgmt commands for such a device.
Reported-by: syzbot+03d6270b6425df1605bf at syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=03d6270b6425df1605bf
Signed-off-by: Dmitry Antipov <dmantipov at yandex.ru>
---
include/net/bluetooth/hci.h | 1 +
net/bluetooth/hci_core.c | 4 ++++
net/bluetooth/hci_sock.c | 5 +++++
3 files changed, 10 insertions(+)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index bab1e3d7452a..492723a22e68 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -345,6 +345,7 @@ enum {
HCI_UP,
HCI_INIT,
HCI_RUNNING,
+ HCI_CLOSING,
HCI_PSCAN,
HCI_ISCAN,
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 629c302f7407..95f55cfb6da6 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -501,12 +501,16 @@ int hci_dev_close(__u16 dev)
goto done;
}
+ set_bit(HCI_CLOSING, &hdev->flags);
+
cancel_work_sync(&hdev->power_on);
if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
cancel_delayed_work(&hdev->power_off);
err = hci_dev_do_close(hdev);
+ if (unlikely(err))
+ clear_bit(HCI_CLOSING, &hdev->flags);
done:
hci_dev_put(hdev);
return err;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 2272e1849ebd..ff43718822d4 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -1671,6 +1671,11 @@ static int hci_mgmt_cmd(struct hci_mgmt_chan *chan, struct sock *sk,
goto done;
}
+ if (unlikely(test_bit(HCI_CLOSING, &hdev->flags))) {
+ err = -ENODEV;
+ goto done;
+ }
+
if (hci_dev_test_flag(hdev, HCI_SETUP) ||
hci_dev_test_flag(hdev, HCI_CONFIG) ||
hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
--
2.46.2
More information about the lvc-project
mailing list