--- /dev/null
+From b36a1552d7319bbfd5cf7f08726c23c5c66d4f73 Mon Sep 17 00:00:00 2001
+From: Vladis Dronov <vdronov@redhat.com>
+Date: Tue, 30 Jul 2019 11:33:45 +0200
+Subject: Bluetooth: hci_uart: check for missing tty operations
+
+From: Vladis Dronov <vdronov@redhat.com>
+
+commit b36a1552d7319bbfd5cf7f08726c23c5c66d4f73 upstream.
+
+Certain ttys operations (pty_unix98_ops) lack tiocmget() and tiocmset()
+functions which are called by the certain HCI UART protocols (hci_ath,
+hci_bcm, hci_intel, hci_mrvl, hci_qca) via hci_uart_set_flow_control()
+or directly. This leads to an execution at NULL and can be triggered by
+an unprivileged user. Fix this by adding a helper function and a check
+for the missing tty operations in the protocols code.
+
+This fixes CVE-2019-10207. The Fixes: lines list commits where calls to
+tiocm[gs]et() or hci_uart_set_flow_control() were added to the HCI UART
+protocols.
+
+Link: https://syzkaller.appspot.com/bug?id=1b42faa2848963564a5b1b7f8c837ea7b55ffa50
+Reported-by: syzbot+79337b501d6aa974d0f6@syzkaller.appspotmail.com
+Cc: stable@vger.kernel.org # v2.6.36+
+Fixes: b3190df62861 ("Bluetooth: Support for Atheros AR300x serial chip")
+Fixes: 118612fb9165 ("Bluetooth: hci_bcm: Add suspend/resume PM functions")
+Fixes: ff2895592f0f ("Bluetooth: hci_intel: Add Intel baudrate configuration support")
+Fixes: 162f812f23ba ("Bluetooth: hci_uart: Add Marvell support")
+Fixes: fa9ad876b8e0 ("Bluetooth: hci_qca: Add support for Qualcomm Bluetooth chip wcn3990")
+Signed-off-by: Vladis Dronov <vdronov@redhat.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Reviewed-by: Yu-Chen, Cho <acho@suse.com>
+Tested-by: Yu-Chen, Cho <acho@suse.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/bluetooth/hci_ath.c | 3 +++
+ drivers/bluetooth/hci_bcm.c | 3 +++
+ drivers/bluetooth/hci_intel.c | 3 +++
+ drivers/bluetooth/hci_ldisc.c | 13 +++++++++++++
+ drivers/bluetooth/hci_mrvl.c | 3 +++
+ drivers/bluetooth/hci_qca.c | 3 +++
+ drivers/bluetooth/hci_uart.h | 1 +
+ 7 files changed, 29 insertions(+)
+
+--- a/drivers/bluetooth/hci_ath.c
++++ b/drivers/bluetooth/hci_ath.c
+@@ -98,6 +98,9 @@ static int ath_open(struct hci_uart *hu)
+
+ BT_DBG("hu %p", hu);
+
++ if (!hci_uart_has_flow_control(hu))
++ return -EOPNOTSUPP;
++
+ ath = kzalloc(sizeof(*ath), GFP_KERNEL);
+ if (!ath)
+ return -ENOMEM;
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -406,6 +406,9 @@ static int bcm_open(struct hci_uart *hu)
+
+ bt_dev_dbg(hu->hdev, "hu %p", hu);
+
++ if (!hci_uart_has_flow_control(hu))
++ return -EOPNOTSUPP;
++
+ bcm = kzalloc(sizeof(*bcm), GFP_KERNEL);
+ if (!bcm)
+ return -ENOMEM;
+--- a/drivers/bluetooth/hci_intel.c
++++ b/drivers/bluetooth/hci_intel.c
+@@ -391,6 +391,9 @@ static int intel_open(struct hci_uart *h
+
+ BT_DBG("hu %p", hu);
+
++ if (!hci_uart_has_flow_control(hu))
++ return -EOPNOTSUPP;
++
+ intel = kzalloc(sizeof(*intel), GFP_KERNEL);
+ if (!intel)
+ return -ENOMEM;
+--- a/drivers/bluetooth/hci_ldisc.c
++++ b/drivers/bluetooth/hci_ldisc.c
+@@ -284,6 +284,19 @@ static int hci_uart_send_frame(struct hc
+ return 0;
+ }
+
++/* Check the underlying device or tty has flow control support */
++bool hci_uart_has_flow_control(struct hci_uart *hu)
++{
++ /* serdev nodes check if the needed operations are present */
++ if (hu->serdev)
++ return true;
++
++ if (hu->tty->driver->ops->tiocmget && hu->tty->driver->ops->tiocmset)
++ return true;
++
++ return false;
++}
++
+ /* Flow control or un-flow control the device */
+ void hci_uart_set_flow_control(struct hci_uart *hu, bool enable)
+ {
+--- a/drivers/bluetooth/hci_mrvl.c
++++ b/drivers/bluetooth/hci_mrvl.c
+@@ -52,6 +52,9 @@ static int mrvl_open(struct hci_uart *hu
+
+ BT_DBG("hu %p", hu);
+
++ if (!hci_uart_has_flow_control(hu))
++ return -EOPNOTSUPP;
++
+ mrvl = kzalloc(sizeof(*mrvl), GFP_KERNEL);
+ if (!mrvl)
+ return -ENOMEM;
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -458,6 +458,9 @@ static int qca_open(struct hci_uart *hu)
+
+ BT_DBG("hu %p qca_open", hu);
+
++ if (!hci_uart_has_flow_control(hu))
++ return -EOPNOTSUPP;
++
+ qca = kzalloc(sizeof(struct qca_data), GFP_KERNEL);
+ if (!qca)
+ return -ENOMEM;
+--- a/drivers/bluetooth/hci_uart.h
++++ b/drivers/bluetooth/hci_uart.h
+@@ -103,6 +103,7 @@ int hci_uart_tx_wakeup(struct hci_uart *
+ int hci_uart_init_ready(struct hci_uart *hu);
+ void hci_uart_init_work(struct work_struct *work);
+ void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed);
++bool hci_uart_has_flow_control(struct hci_uart *hu);
+ void hci_uart_set_flow_control(struct hci_uart *hu, bool enable);
+ void hci_uart_set_speeds(struct hci_uart *hu, unsigned int init_speed,
+ unsigned int oper_speed);
--- /dev/null
+From 66b20ac0a1a10769d059d6903202f53494e3d902 Mon Sep 17 00:00:00 2001
+From: Marta Rybczynska <mrybczyn@kalray.eu>
+Date: Tue, 23 Jul 2019 07:41:20 +0200
+Subject: nvme: fix multipath crash when ANA is deactivated
+
+From: Marta Rybczynska <mrybczyn@kalray.eu>
+
+commit 66b20ac0a1a10769d059d6903202f53494e3d902 upstream.
+
+Fix a crash with multipath activated. It happends when ANA log
+page is larger than MDTS and because of that ANA is disabled.
+The driver then tries to access unallocated buffer when connecting
+to a nvme target. The signature is as follows:
+
+[ 300.433586] nvme nvme0: ANA log page size (8208) larger than MDTS (8192).
+[ 300.435387] nvme nvme0: disabling ANA support.
+[ 300.437835] nvme nvme0: creating 4 I/O queues.
+[ 300.459132] nvme nvme0: new ctrl: NQN "nqn.0.0.0", addr 10.91.0.1:8009
+[ 300.464609] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
+[ 300.466342] #PF error: [normal kernel read fault]
+[ 300.467385] PGD 0 P4D 0
+[ 300.467987] Oops: 0000 [#1] SMP PTI
+[ 300.468787] CPU: 3 PID: 50 Comm: kworker/u8:1 Not tainted 5.0.20kalray+ #4
+[ 300.470264] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
+[ 300.471532] Workqueue: nvme-wq nvme_scan_work [nvme_core]
+[ 300.472724] RIP: 0010:nvme_parse_ana_log+0x21/0x140 [nvme_core]
+[ 300.474038] Code: 45 01 d2 d8 48 98 c3 66 90 0f 1f 44 00 00 41 57 41 56 41 55 41 54 55 53 48 89 fb 48 83 ec 08 48 8b af 20 0a 00 00 48 89 34 24 <66> 83 7d 08 00 0f 84 c6 00 00 00 44 8b 7d 14 49 89 d5 8b 55 10 48
+[ 300.477374] RSP: 0018:ffffa50e80fd7cb8 EFLAGS: 00010296
+[ 300.478334] RAX: 0000000000000001 RBX: ffff9130f1872258 RCX: 0000000000000000
+[ 300.479784] RDX: ffffffffc06c4c30 RSI: ffff9130edad4280 RDI: ffff9130f1872258
+[ 300.481488] RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000044
+[ 300.483203] R10: 0000000000000220 R11: 0000000000000040 R12: ffff9130f18722c0
+[ 300.484928] R13: ffff9130f18722d0 R14: ffff9130edad4280 R15: ffff9130f18722c0
+[ 300.486626] FS: 0000000000000000(0000) GS:ffff9130f7b80000(0000) knlGS:0000000000000000
+[ 300.488538] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 300.489907] CR2: 0000000000000008 CR3: 00000002365e6000 CR4: 00000000000006e0
+[ 300.491612] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 300.493303] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 300.494991] Call Trace:
+[ 300.495645] nvme_mpath_add_disk+0x5c/0xb0 [nvme_core]
+[ 300.496880] nvme_validate_ns+0x2ef/0x550 [nvme_core]
+[ 300.498105] ? nvme_identify_ctrl.isra.45+0x6a/0xb0 [nvme_core]
+[ 300.499539] nvme_scan_work+0x2b4/0x370 [nvme_core]
+[ 300.500717] ? __switch_to_asm+0x35/0x70
+[ 300.501663] process_one_work+0x171/0x380
+[ 300.502340] worker_thread+0x49/0x3f0
+[ 300.503079] kthread+0xf8/0x130
+[ 300.503795] ? max_active_store+0x80/0x80
+[ 300.504690] ? kthread_bind+0x10/0x10
+[ 300.505502] ret_from_fork+0x35/0x40
+[ 300.506280] Modules linked in: nvme_tcp nvme_rdma rdma_cm iw_cm ib_cm ib_core nvme_fabrics nvme_core xt_physdev ip6table_raw ip6table_mangle ip6table_filter ip6_tables xt_comment iptable_nat nf_nat_ipv4 nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 xt_CHECKSUM iptable_mangle iptable_filter veth ebtable_filter ebtable_nat ebtables iptable_raw vxlan ip6_udp_tunnel udp_tunnel sunrpc joydev pcspkr virtio_balloon br_netfilter bridge stp llc ip_tables xfs libcrc32c ata_generic pata_acpi virtio_net virtio_console net_failover virtio_blk failover ata_piix serio_raw libata virtio_pci virtio_ring virtio
+[ 300.514984] CR2: 0000000000000008
+[ 300.515569] ---[ end trace faa2eefad7e7f218 ]---
+[ 300.516354] RIP: 0010:nvme_parse_ana_log+0x21/0x140 [nvme_core]
+[ 300.517330] Code: 45 01 d2 d8 48 98 c3 66 90 0f 1f 44 00 00 41 57 41 56 41 55 41 54 55 53 48 89 fb 48 83 ec 08 48 8b af 20 0a 00 00 48 89 34 24 <66> 83 7d 08 00 0f 84 c6 00 00 00 44 8b 7d 14 49 89 d5 8b 55 10 48
+[ 300.520353] RSP: 0018:ffffa50e80fd7cb8 EFLAGS: 00010296
+[ 300.521229] RAX: 0000000000000001 RBX: ffff9130f1872258 RCX: 0000000000000000
+[ 300.522399] RDX: ffffffffc06c4c30 RSI: ffff9130edad4280 RDI: ffff9130f1872258
+[ 300.523560] RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000044
+[ 300.524734] R10: 0000000000000220 R11: 0000000000000040 R12: ffff9130f18722c0
+[ 300.525915] R13: ffff9130f18722d0 R14: ffff9130edad4280 R15: ffff9130f18722c0
+[ 300.527084] FS: 0000000000000000(0000) GS:ffff9130f7b80000(0000) knlGS:0000000000000000
+[ 300.528396] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 300.529440] CR2: 0000000000000008 CR3: 00000002365e6000 CR4: 00000000000006e0
+[ 300.530739] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 300.531989] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 300.533264] Kernel panic - not syncing: Fatal exception
+[ 300.534338] Kernel Offset: 0x17c00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
+[ 300.536227] ---[ end Kernel panic - not syncing: Fatal exception ]---
+
+Condition check refactoring from Christoph Hellwig.
+
+Signed-off-by: Marta Rybczynska <marta.rybczynska@kalray.eu>
+Tested-by: Jean-Baptiste Riaux <jbriaux@kalray.eu>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/nvme/host/multipath.c | 8 ++------
+ drivers/nvme/host/nvme.h | 6 +++++-
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -12,11 +12,6 @@ module_param(multipath, bool, 0444);
+ MODULE_PARM_DESC(multipath,
+ "turn on native support for multiple controllers per subsystem");
+
+-inline bool nvme_ctrl_use_ana(struct nvme_ctrl *ctrl)
+-{
+- return multipath && ctrl->subsys && (ctrl->subsys->cmic & (1 << 3));
+-}
+-
+ /*
+ * If multipathing is enabled we need to always use the subsystem instance
+ * number for numbering our devices to avoid conflicts between subsystems that
+@@ -614,7 +609,8 @@ int nvme_mpath_init(struct nvme_ctrl *ct
+ {
+ int error;
+
+- if (!nvme_ctrl_use_ana(ctrl))
++ /* check if multipath is enabled and we have the capability */
++ if (!multipath || !ctrl->subsys || !(ctrl->subsys->cmic & (1 << 3)))
+ return 0;
+
+ ctrl->anacap = id->anacap;
+--- a/drivers/nvme/host/nvme.h
++++ b/drivers/nvme/host/nvme.h
+@@ -472,7 +472,11 @@ extern const struct attribute_group *nvm
+ extern const struct block_device_operations nvme_ns_head_ops;
+
+ #ifdef CONFIG_NVME_MULTIPATH
+-bool nvme_ctrl_use_ana(struct nvme_ctrl *ctrl);
++static inline bool nvme_ctrl_use_ana(struct nvme_ctrl *ctrl)
++{
++ return ctrl->ana_log_buf != NULL;
++}
++
+ void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns,
+ struct nvme_ctrl *ctrl, int *flags);
+ void nvme_failover_req(struct request *req);