--- /dev/null
+From 56897b217a1d0a91c9920cb418d6b3fe922f590a 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>
+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;
+ }
+
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- arch/x86/kvm/x86.c | 4 ++--
+ arch/x86/kvm/x86.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
-diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
-index 0b6517f5821be..384127a00328d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
-@@ -587,7 +587,7 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu)
+@@ -587,7 +587,7 @@ static bool pdptrs_changed(struct kvm_vc
gfn_t gfn;
int r;
return false;
if (!test_bit(VCPU_EXREG_PDPTR,
-@@ -7491,7 +7491,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
+@@ -7491,7 +7491,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct
kvm_update_cpuid(vcpu);
idx = srcu_read_lock(&vcpu->kvm->srcu);
load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu));
mmu_reset_needed = 1;
}
---
-2.20.1
-