]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.109/bluetooth-hci_ldisc-postpone-hci_uart_proto_ready-bit-set-in-hci_uart_set_proto.patch
Linux 4.14.109
[thirdparty/kernel/stable-queue.git] / releases / 4.14.109 / bluetooth-hci_ldisc-postpone-hci_uart_proto_ready-bit-set-in-hci_uart_set_proto.patch
1 From 56897b217a1d0a91c9920cb418d6b3fe922f590a Mon Sep 17 00:00:00 2001
2 From: Kefeng Wang <wangkefeng.wang@huawei.com>
3 Date: Sat, 23 Feb 2019 12:33:27 +0800
4 Subject: Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in hci_uart_set_proto()
5
6 From: Kefeng Wang <wangkefeng.wang@huawei.com>
7
8 commit 56897b217a1d0a91c9920cb418d6b3fe922f590a upstream.
9
10 task A: task B:
11 hci_uart_set_proto flush_to_ldisc
12 - p->open(hu) -> h5_open //alloc h5 - receive_buf
13 - set_bit HCI_UART_PROTO_READY - tty_port_default_receive_buf
14 - hci_uart_register_dev - tty_ldisc_receive_buf
15 - hci_uart_tty_receive
16 - test_bit HCI_UART_PROTO_READY
17 - h5_recv
18 - clear_bit HCI_UART_PROTO_READY while() {
19 - p->open(hu) -> h5_close //free h5
20 - h5_rx_3wire_hdr
21 - h5_reset() //use-after-free
22 }
23
24 It could use ioctl to set hci uart proto, but there is
25 a use-after-free issue when hci_uart_register_dev() fail in
26 hci_uart_set_proto(), see stack above, fix this by setting
27 HCI_UART_PROTO_READY bit only when hci_uart_register_dev()
28 return success.
29
30 Reported-by: syzbot+899a33dc0fa0dbaf06a6@syzkaller.appspotmail.com
31 Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
32 Reviewed-by: Jeremy Cline <jcline@redhat.com>
33 Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
34 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
35
36 ---
37 drivers/bluetooth/hci_ldisc.c | 3 +--
38 1 file changed, 1 insertion(+), 2 deletions(-)
39
40 --- a/drivers/bluetooth/hci_ldisc.c
41 +++ b/drivers/bluetooth/hci_ldisc.c
42 @@ -692,14 +692,13 @@ static int hci_uart_set_proto(struct hci
43 return -EPROTONOSUPPORT;
44
45 hu->proto = p;
46 - set_bit(HCI_UART_PROTO_READY, &hu->flags);
47
48 err = hci_uart_register_dev(hu);
49 if (err) {
50 - clear_bit(HCI_UART_PROTO_READY, &hu->flags);
51 return err;
52 }
53
54 + set_bit(HCI_UART_PROTO_READY, &hu->flags);
55 return 0;
56 }
57