summaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/hci_ldisc.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2022-08-29 16:58:12 +0200
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2022-09-19 19:33:39 +0200
commit3124d320c22f3f4388d9ac5c8f37eaad0cefd6b1 (patch)
treec1da5477515f4f17331bd5a8ea10fa15a61358ec /drivers/bluetooth/hci_ldisc.c
parentBluetooth: use hdev->workqueue when queuing hdev->{cmd,ncmd}_timer works (diff)
downloadlinux-3124d320c22f3f4388d9ac5c8f37eaad0cefd6b1.tar.xz
linux-3124d320c22f3f4388d9ac5c8f37eaad0cefd6b1.zip
Bluetooth: hci_{ldisc,serdev}: check percpu_init_rwsem() failure
syzbot is reporting NULL pointer dereference at hci_uart_tty_close() [1], for rcu_sync_enter() is called without rcu_sync_init() due to hci_uart_tty_open() ignoring percpu_init_rwsem() failure. While we are at it, fix that hci_uart_register_device() ignores percpu_init_rwsem() failure and hci_uart_unregister_device() does not call percpu_free_rwsem(). Link: https://syzkaller.appspot.com/bug?extid=576dfca25381fb6fbc5f [1] Reported-by: syzbot <syzbot+576dfca25381fb6fbc5f@syzkaller.appspotmail.com> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Fixes: 67d2f8781b9f00d1 ("Bluetooth: hci_ldisc: Allow sleeping while proto locks are held.") Fixes: d73e172816652772 ("Bluetooth: hci_serdev: Init hci_uart proto_lock to avoid oops") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'drivers/bluetooth/hci_ldisc.c')
-rw-r--r--drivers/bluetooth/hci_ldisc.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index f537673ede17..865112e96ff9 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -493,6 +493,11 @@ static int hci_uart_tty_open(struct tty_struct *tty)
BT_ERR("Can't allocate control structure");
return -ENFILE;
}
+ if (percpu_init_rwsem(&hu->proto_lock)) {
+ BT_ERR("Can't allocate semaphore structure");
+ kfree(hu);
+ return -ENOMEM;
+ }
tty->disc_data = hu;
hu->tty = tty;
@@ -505,8 +510,6 @@ static int hci_uart_tty_open(struct tty_struct *tty)
INIT_WORK(&hu->init_ready, hci_uart_init_work);
INIT_WORK(&hu->write_work, hci_uart_write_work);
- percpu_init_rwsem(&hu->proto_lock);
-
/* Flush any pending characters in the driver */
tty_driver_flush_buffer(tty);