--- /dev/null
+From 84cb3df02aea4b00405521e67c4c67c2d525c364 Mon Sep 17 00:00:00 2001
+From: Loic Poulain <loic.poulain@intel.com>
+Date: Mon, 4 Apr 2016 10:48:13 +0200
+Subject: Bluetooth: hci_ldisc: Fix null pointer derefence in case of early data
+
+From: Loic Poulain <loic.poulain@intel.com>
+
+commit 84cb3df02aea4b00405521e67c4c67c2d525c364 upstream.
+
+HCI_UART_PROTO_SET flag is set before hci_uart_set_proto call. If we
+receive data from tty layer during this procedure, proto pointer may
+not be assigned yet, leading to null pointer dereference in rx method
+hci_uart_tty_receive.
+
+This patch fixes this issue by introducing HCI_UART_PROTO_READY flag in
+order to avoid any proto operation before proto opening and assignment.
+
+Signed-off-by: Loic Poulain <loic.poulain@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Cc: Ralph Siemsen <ralph.siemsen@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/bluetooth/hci_ldisc.c | 11 +++++++----
+ drivers/bluetooth/hci_uart.h | 1 +
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/bluetooth/hci_ldisc.c
++++ b/drivers/bluetooth/hci_ldisc.c
+@@ -227,7 +227,7 @@ static int hci_uart_flush(struct hci_dev
+ tty_ldisc_flush(tty);
+ tty_driver_flush_buffer(tty);
+
+- if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
++ if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
+ hu->proto->flush(hu);
+
+ return 0;
+@@ -506,7 +506,7 @@ static void hci_uart_tty_close(struct tt
+
+ cancel_work_sync(&hu->write_work);
+
+- if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
++ if (test_and_clear_bit(HCI_UART_PROTO_READY, &hu->flags)) {
+ if (hdev) {
+ if (test_bit(HCI_UART_REGISTERED, &hu->flags))
+ hci_unregister_dev(hdev);
+@@ -514,6 +514,7 @@ static void hci_uart_tty_close(struct tt
+ }
+ hu->proto->close(hu);
+ }
++ clear_bit(HCI_UART_PROTO_SET, &hu->flags);
+
+ kfree(hu);
+ }
+@@ -540,7 +541,7 @@ static void hci_uart_tty_wakeup(struct t
+ if (tty != hu->tty)
+ return;
+
+- if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
++ if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
+ hci_uart_tx_wakeup(hu);
+ }
+
+@@ -564,7 +565,7 @@ static void hci_uart_tty_receive(struct
+ if (!hu || tty != hu->tty)
+ return;
+
+- if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
++ if (!test_bit(HCI_UART_PROTO_READY, &hu->flags))
+ return;
+
+ /* It does not need a lock here as it is already protected by a mutex in
+@@ -652,9 +653,11 @@ static int hci_uart_set_proto(struct hci
+ return err;
+
+ hu->proto = p;
++ set_bit(HCI_UART_PROTO_READY, &hu->flags);
+
+ err = hci_uart_register_dev(hu);
+ if (err) {
++ clear_bit(HCI_UART_PROTO_READY, &hu->flags);
+ p->close(hu);
+ return err;
+ }
+--- a/drivers/bluetooth/hci_uart.h
++++ b/drivers/bluetooth/hci_uart.h
+@@ -94,6 +94,7 @@ struct hci_uart {
+ /* HCI_UART proto flag bits */
+ #define HCI_UART_PROTO_SET 0
+ #define HCI_UART_REGISTERED 1
++#define HCI_UART_PROTO_READY 2
+
+ /* TX states */
+ #define HCI_UART_SENDING 1
--- /dev/null
+From 3858f013de0ae5a19b8276944e12fd01b0cac979 Mon Sep 17 00:00:00 2001
+From: Kefeng Wang <wangkefeng.wang@huawei.com>
+Date: Sat, 23 Feb 2019 12:33:27 +0800
+Subject: Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in hci_uart_set_proto()
+
+From: Kefeng Wang <wangkefeng.wang@huawei.com>
+
+commit 56897b217a1d0a91c9920cb418d6b3fe922f590a upstream.
+
+task A: task B:
+hci_uart_set_proto flush_to_ldisc
+ - p->open(hu) -> h5_open //alloc h5 - receive_buf
+ - set_bit HCI_UART_PROTO_READY - tty_port_default_receive_buf
+ - hci_uart_register_dev - tty_ldisc_receive_buf
+ - hci_uart_tty_receive
+ - test_bit HCI_UART_PROTO_READY
+ - h5_recv
+ - clear_bit HCI_UART_PROTO_READY while() {
+ - p->open(hu) -> h5_close //free h5
+ - h5_rx_3wire_hdr
+ - h5_reset() //use-after-free
+ }
+
+It could use ioctl to set hci uart proto, but there is
+a use-after-free issue when hci_uart_register_dev() fail in
+hci_uart_set_proto(), see stack above, fix this by setting
+HCI_UART_PROTO_READY bit only when hci_uart_register_dev()
+return success.
+
+Reported-by: syzbot+899a33dc0fa0dbaf06a6@syzkaller.appspotmail.com
+Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
+Reviewed-by: Jeremy Cline <jcline@redhat.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Cc: Ralph Siemsen <ralph.siemsen@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/bluetooth/hci_ldisc.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/bluetooth/hci_ldisc.c
++++ b/drivers/bluetooth/hci_ldisc.c
+@@ -653,15 +653,14 @@ static int hci_uart_set_proto(struct hci
+ return err;
+
+ hu->proto = p;
+- set_bit(HCI_UART_PROTO_READY, &hu->flags);
+
+ err = hci_uart_register_dev(hu);
+ if (err) {
+- clear_bit(HCI_UART_PROTO_READY, &hu->flags);
+ p->close(hu);
+ return err;
+ }
+
++ set_bit(HCI_UART_PROTO_READY, &hu->flags);
+ return 0;
+ }
+