From: Greg Kroah-Hartman Date: Sun, 30 Sep 2018 15:38:54 +0000 (-0700) Subject: 4.18-stable patches X-Git-Tag: v4.18.12~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0cd0f0f6d8537da21e0b65eaa79220f421079fe9;p=thirdparty%2Fkernel%2Fstable-queue.git 4.18-stable patches added patches: acpi-hotplug-pci-don-t-scan-for-non-hotplug-bridges-if-slot-is-not-bridge.patch ext2-dax-set-ext2_dax_aops-for-dax-files.patch filesystem-dax-fix-use-of-zero-page.patch ib-hfi1-fix-context-recovery-when-pbc-has-an-unsupportedvl.patch ib-hfi1-fix-destroy_qp-hang-after-a-link-down.patch ib-hfi1-fix-sl-array-bounds-check.patch ib-hfi1-invalid-user-input-can-result-in-crash.patch ib-srp-avoid-that-sg_reset-d-srp_device-triggers-an-infinite-loop.patch input-elantech-enable-middle-button-of-touchpad-on-thinkpad-p72.patch rdma-uverbs-atomically-flush-and-mark-closed-the-comp-event-queue.patch revert-usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch uaccess-fix-is_source-param-for-check_copy_size-in-copy_to_iter_mcsafe.patch usb-remove-lpm-management-from-usb_driver_claim_interface.patch usb-usbdevfs-restore-warning-for-nonsensical-flags.patch usb-usbdevfs-sanitize-flags-more.patch --- diff --git a/queue-4.18/acpi-hotplug-pci-don-t-scan-for-non-hotplug-bridges-if-slot-is-not-bridge.patch b/queue-4.18/acpi-hotplug-pci-don-t-scan-for-non-hotplug-bridges-if-slot-is-not-bridge.patch new file mode 100644 index 00000000000..0bed76492de --- /dev/null +++ b/queue-4.18/acpi-hotplug-pci-don-t-scan-for-non-hotplug-bridges-if-slot-is-not-bridge.patch @@ -0,0 +1,96 @@ +From f188b99f0b2d33794b4af8a225f95d1e968c0a3f Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Wed, 26 Sep 2018 15:39:28 -0500 +Subject: ACPI / hotplug / PCI: Don't scan for non-hotplug bridges if slot is not bridge + +From: Mika Westerberg + +commit f188b99f0b2d33794b4af8a225f95d1e968c0a3f upstream. + +HP 6730b laptop has an ethernet NIC connected to one of the PCIe root +ports. The root ports themselves are native PCIe hotplug capable. Now, +during boot after PCI devices are scanned the BIOS triggers ACPI bus check +directly to the NIC: + + ACPI: \_SB_.PCI0.RP06.NIC_: Bus check in hotplug_event() + +It is not clear why it is sending bus check but regardless the ACPI hotplug +notify handler calls enable_slot() directly (instead of going through +acpiphp_check_bridge() as there is no bridge), which ends up handling +special case for non-hotplug bridges with native PCIe hotplug. This +results a crash of some kind but the reporter only sees black screen so it +is hard to figure out the exact spot and what actually happens. Based on +a few fix proposals it was tracked to crash somewhere inside +pci_assign_unassigned_bridge_resources(). + +In any case we should not really be in that special branch at all because +the ACPI notify happened to a slot that is not a PCI bridge (it is just a +regular PCI device). + +Fix this so that we only go to that special branch if we are calling +enable_slot() for a bridge (e.g., the ACPI notification was for the +bridge). + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=201127 +Fixes: 84c8b58ed3ad ("ACPI / hotplug / PCI: Don't scan bridges managed by native hotplug") +Reported-by: Peter Anemone +Signed-off-by: Mika Westerberg +Signed-off-by: Bjorn Helgaas +Reviewed-by: Rafael J. Wysocki +CC: stable@vger.kernel.org # v4.18+ +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/hotplug/acpiphp_glue.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/pci/hotplug/acpiphp_glue.c ++++ b/drivers/pci/hotplug/acpiphp_glue.c +@@ -457,17 +457,18 @@ static void acpiphp_native_scan_bridge(s + /** + * enable_slot - enable, configure a slot + * @slot: slot to be enabled ++ * @bridge: true if enable is for the whole bridge (not a single slot) + * + * This function should be called per *physical slot*, + * not per each slot object in ACPI namespace. + */ +-static void enable_slot(struct acpiphp_slot *slot) ++static void enable_slot(struct acpiphp_slot *slot, bool bridge) + { + struct pci_dev *dev; + struct pci_bus *bus = slot->bus; + struct acpiphp_func *func; + +- if (bus->self && hotplug_is_native(bus->self)) { ++ if (bridge && bus->self && hotplug_is_native(bus->self)) { + /* + * If native hotplug is used, it will take care of hotplug + * slot management and resource allocation for hotplug +@@ -701,7 +702,7 @@ static void acpiphp_check_bridge(struct + trim_stale_devices(dev); + + /* configure all functions */ +- enable_slot(slot); ++ enable_slot(slot, true); + } else { + disable_slot(slot); + } +@@ -785,7 +786,7 @@ static void hotplug_event(u32 type, stru + if (bridge) + acpiphp_check_bridge(bridge); + else if (!(slot->flags & SLOT_IS_GOING_AWAY)) +- enable_slot(slot); ++ enable_slot(slot, false); + + break; + +@@ -973,7 +974,7 @@ int acpiphp_enable_slot(struct acpiphp_s + + /* configure all functions */ + if (!(slot->flags & SLOT_ENABLED)) +- enable_slot(slot); ++ enable_slot(slot, false); + + pci_unlock_rescan_remove(); + return 0; diff --git a/queue-4.18/ext2-dax-set-ext2_dax_aops-for-dax-files.patch b/queue-4.18/ext2-dax-set-ext2_dax_aops-for-dax-files.patch new file mode 100644 index 00000000000..807f2d2ab45 --- /dev/null +++ b/queue-4.18/ext2-dax-set-ext2_dax_aops-for-dax-files.patch @@ -0,0 +1,51 @@ +From 9e796c9db93b4840d1b00e550eea26db7cb741e2 Mon Sep 17 00:00:00 2001 +From: Toshi Kani +Date: Fri, 14 Sep 2018 08:51:14 -0600 +Subject: ext2, dax: set ext2_dax_aops for dax files + +From: Toshi Kani + +commit 9e796c9db93b4840d1b00e550eea26db7cb741e2 upstream. + +Sync syscall to DAX file needs to flush processor cache, but it +currently does not flush to existing DAX files. This is because +'ext2_da_aops' is set to address_space_operations of existing DAX +files, instead of 'ext2_dax_aops', since S_DAX flag is set after +ext2_set_aops() in the open path. + +Similar to ext4, change ext2_iget() to initialize i_flags before +ext2_set_aops(). + +Fixes: fb094c90748f ("ext2, dax: introduce ext2_dax_aops") +Signed-off-by: Toshi Kani +Suggested-by: Jan Kara +Cc: Jan Kara +Cc: Dan Williams +Cc: "Theodore Ts'o" +Cc: Andreas Dilger +Cc: +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext2/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext2/inode.c ++++ b/fs/ext2/inode.c +@@ -1448,6 +1448,7 @@ struct inode *ext2_iget (struct super_bl + } + inode->i_blocks = le32_to_cpu(raw_inode->i_blocks); + ei->i_flags = le32_to_cpu(raw_inode->i_flags); ++ ext2_set_inode_flags(inode); + ei->i_faddr = le32_to_cpu(raw_inode->i_faddr); + ei->i_frag_no = raw_inode->i_frag; + ei->i_frag_size = raw_inode->i_fsize; +@@ -1517,7 +1518,6 @@ struct inode *ext2_iget (struct super_bl + new_decode_dev(le32_to_cpu(raw_inode->i_block[1]))); + } + brelse (bh); +- ext2_set_inode_flags(inode); + unlock_new_inode(inode); + return inode; + diff --git a/queue-4.18/filesystem-dax-fix-use-of-zero-page.patch b/queue-4.18/filesystem-dax-fix-use-of-zero-page.patch new file mode 100644 index 00000000000..9de2d5186df --- /dev/null +++ b/queue-4.18/filesystem-dax-fix-use-of-zero-page.patch @@ -0,0 +1,50 @@ +From b90ca5cc32f59bb214847c6855959702f00c6801 Mon Sep 17 00:00:00 2001 +From: Matthew Wilcox +Date: Tue, 11 Sep 2018 21:27:44 -0700 +Subject: filesystem-dax: Fix use of zero page + +From: Matthew Wilcox + +commit b90ca5cc32f59bb214847c6855959702f00c6801 upstream. + +Use my_zero_pfn instead of ZERO_PAGE(), and pass the vaddr to it instead +of zero so it works on MIPS and s390 who reference the vaddr to select a +zero page. + +Cc: +Fixes: 91d25ba8a6b0 ("dax: use common 4k zero page for dax mmap reads") +Signed-off-by: Matthew Wilcox +Reviewed-by: Ross Zwisler +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman + +--- + fs/dax.c | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +--- a/fs/dax.c ++++ b/fs/dax.c +@@ -1007,21 +1007,12 @@ static vm_fault_t dax_load_hole(struct a + { + struct inode *inode = mapping->host; + unsigned long vaddr = vmf->address; +- vm_fault_t ret = VM_FAULT_NOPAGE; +- struct page *zero_page; +- pfn_t pfn; ++ pfn_t pfn = pfn_to_pfn_t(my_zero_pfn(vaddr)); ++ vm_fault_t ret; + +- zero_page = ZERO_PAGE(0); +- if (unlikely(!zero_page)) { +- ret = VM_FAULT_OOM; +- goto out; +- } +- +- pfn = page_to_pfn_t(zero_page); + dax_insert_mapping_entry(mapping, vmf, entry, pfn, RADIX_DAX_ZERO_PAGE, + false); + ret = vmf_insert_mixed(vmf->vma, vaddr, pfn); +-out: + trace_dax_load_hole(inode, vmf, ret); + return ret; + } diff --git a/queue-4.18/ib-hfi1-fix-context-recovery-when-pbc-has-an-unsupportedvl.patch b/queue-4.18/ib-hfi1-fix-context-recovery-when-pbc-has-an-unsupportedvl.patch new file mode 100644 index 00000000000..5d3816a9881 --- /dev/null +++ b/queue-4.18/ib-hfi1-fix-context-recovery-when-pbc-has-an-unsupportedvl.patch @@ -0,0 +1,65 @@ +From d623500b3c4efd8d4e945ac9003c6b87b469a9ab Mon Sep 17 00:00:00 2001 +From: "Michael J. Ruhl" +Date: Thu, 20 Sep 2018 12:59:05 -0700 +Subject: IB/hfi1: Fix context recovery when PBC has an UnsupportedVL + +From: Michael J. Ruhl + +commit d623500b3c4efd8d4e945ac9003c6b87b469a9ab upstream. + +If a packet stream uses an UnsupportedVL (virtual lane), the send +engine will not send the packet, and it will not indicate that an +error has occurred. This will cause the packet stream to block. + +HFI has 8 virtual lanes available for packet streams. Each lane can +be enabled or disabled using the UnsupportedVL mask. If a lane is +disabled, adding a packet to the send context must be disallowed. + +The current mask for determining unsupported VLs defaults to 0 (allow +all). This is incorrect. Only the VLs that are defined should be +allowed. + +Determine which VLs are disabled (mtu == 0), and set the appropriate +unsupported bit in the mask. The correct mask will allow the send +engine to error on the invalid VL, and error recovery will work +correctly. + +Cc: # 4.9.x+ +Fixes: 7724105686e7 ("IB/hfi1: add driver files") +Reviewed-by: Mike Marciniszyn +Reviewed-by: Lukasz Odzioba +Signed-off-by: Michael J. Ruhl +Signed-off-by: Dennis Dalessandro +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/hfi1/pio.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/hfi1/pio.c ++++ b/drivers/infiniband/hw/hfi1/pio.c +@@ -86,6 +86,7 @@ void pio_send_control(struct hfi1_devdat + unsigned long flags; + int write = 1; /* write sendctrl back */ + int flush = 0; /* re-read sendctrl to make sure it is flushed */ ++ int i; + + spin_lock_irqsave(&dd->sendctrl_lock, flags); + +@@ -95,9 +96,13 @@ void pio_send_control(struct hfi1_devdat + reg |= SEND_CTRL_SEND_ENABLE_SMASK; + /* Fall through */ + case PSC_DATA_VL_ENABLE: ++ mask = 0; ++ for (i = 0; i < ARRAY_SIZE(dd->vld); i++) ++ if (!dd->vld[i].mtu) ++ mask |= BIT_ULL(i); + /* Disallow sending on VLs not enabled */ +- mask = (((~0ull) << num_vls) & SEND_CTRL_UNSUPPORTED_VL_MASK) << +- SEND_CTRL_UNSUPPORTED_VL_SHIFT; ++ mask = (mask & SEND_CTRL_UNSUPPORTED_VL_MASK) << ++ SEND_CTRL_UNSUPPORTED_VL_SHIFT; + reg = (reg & ~SEND_CTRL_UNSUPPORTED_VL_SMASK) | mask; + break; + case PSC_GLOBAL_DISABLE: diff --git a/queue-4.18/ib-hfi1-fix-destroy_qp-hang-after-a-link-down.patch b/queue-4.18/ib-hfi1-fix-destroy_qp-hang-after-a-link-down.patch new file mode 100644 index 00000000000..a2d025affd8 --- /dev/null +++ b/queue-4.18/ib-hfi1-fix-destroy_qp-hang-after-a-link-down.patch @@ -0,0 +1,212 @@ +From b4a4957d3d1c328b733fce783b7264996f866ad2 Mon Sep 17 00:00:00 2001 +From: "Michael J. Ruhl" +Date: Thu, 20 Sep 2018 12:59:14 -0700 +Subject: IB/hfi1: Fix destroy_qp hang after a link down + +From: Michael J. Ruhl + +commit b4a4957d3d1c328b733fce783b7264996f866ad2 upstream. + +rvt_destroy_qp() cannot complete until all in process packets have +been released from the underlying hardware. If a link down event +occurs, an application can hang with a kernel stack similar to: + +cat /proc//stack + quiesce_qp+0x178/0x250 [hfi1] + rvt_reset_qp+0x23d/0x400 [rdmavt] + rvt_destroy_qp+0x69/0x210 [rdmavt] + ib_destroy_qp+0xba/0x1c0 [ib_core] + nvme_rdma_destroy_queue_ib+0x46/0x80 [nvme_rdma] + nvme_rdma_free_queue+0x3c/0xd0 [nvme_rdma] + nvme_rdma_destroy_io_queues+0x88/0xd0 [nvme_rdma] + nvme_rdma_error_recovery_work+0x52/0xf0 [nvme_rdma] + process_one_work+0x17a/0x440 + worker_thread+0x126/0x3c0 + kthread+0xcf/0xe0 + ret_from_fork+0x58/0x90 + 0xffffffffffffffff + +quiesce_qp() waits until all outstanding packets have been freed. +This wait should be momentary. During a link down event, the cleanup +handling does not ensure that all packets caught by the link down are +flushed properly. + +This is caused by the fact that the freeze path and the link down +event is handled the same. This is not correct. The freeze path +waits until the HFI is unfrozen and then restarts PIO. A link down +is not a freeze event. The link down path cannot restart the PIO +until link is restored. If the PIO path is restarted before the link +comes up, the application (QP) using the PIO path will hang (until +link is restored). + +Fix by separating the linkdown path from the freeze path and use the +link down path for link down events. + +Close a race condition sc_disable() by acquiring both the progress +and release locks. + +Close a race condition in sc_stop() by moving the setting of the flag +bits under the alloc lock. + +Cc: # 4.9.x+ +Fixes: 7724105686e7 ("IB/hfi1: add driver files") +Reviewed-by: Mike Marciniszyn +Signed-off-by: Michael J. Ruhl +Signed-off-by: Dennis Dalessandro +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/hfi1/chip.c | 6 ++++- + drivers/infiniband/hw/hfi1/pio.c | 42 ++++++++++++++++++++++++++++++-------- + drivers/infiniband/hw/hfi1/pio.h | 2 + + 3 files changed, 41 insertions(+), 9 deletions(-) + +--- a/drivers/infiniband/hw/hfi1/chip.c ++++ b/drivers/infiniband/hw/hfi1/chip.c +@@ -6733,6 +6733,7 @@ void start_freeze_handling(struct hfi1_p + struct hfi1_devdata *dd = ppd->dd; + struct send_context *sc; + int i; ++ int sc_flags; + + if (flags & FREEZE_SELF) + write_csr(dd, CCE_CTRL, CCE_CTRL_SPC_FREEZE_SMASK); +@@ -6743,11 +6744,13 @@ void start_freeze_handling(struct hfi1_p + /* notify all SDMA engines that they are going into a freeze */ + sdma_freeze_notify(dd, !!(flags & FREEZE_LINK_DOWN)); + ++ sc_flags = SCF_FROZEN | SCF_HALTED | (flags & FREEZE_LINK_DOWN ? ++ SCF_LINK_DOWN : 0); + /* do halt pre-handling on all enabled send contexts */ + for (i = 0; i < dd->num_send_contexts; i++) { + sc = dd->send_contexts[i].sc; + if (sc && (sc->flags & SCF_ENABLED)) +- sc_stop(sc, SCF_FROZEN | SCF_HALTED); ++ sc_stop(sc, sc_flags); + } + + /* Send context are frozen. Notify user space */ +@@ -10665,6 +10668,7 @@ int set_link_state(struct hfi1_pportdata + add_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK); + + handle_linkup_change(dd, 1); ++ pio_kernel_linkup(dd); + + /* + * After link up, a new link width will have been set. +--- a/drivers/infiniband/hw/hfi1/pio.c ++++ b/drivers/infiniband/hw/hfi1/pio.c +@@ -926,20 +926,18 @@ void sc_free(struct send_context *sc) + void sc_disable(struct send_context *sc) + { + u64 reg; +- unsigned long flags; + struct pio_buf *pbuf; + + if (!sc) + return; + + /* do all steps, even if already disabled */ +- spin_lock_irqsave(&sc->alloc_lock, flags); ++ spin_lock_irq(&sc->alloc_lock); + reg = read_kctxt_csr(sc->dd, sc->hw_context, SC(CTRL)); + reg &= ~SC(CTRL_CTXT_ENABLE_SMASK); + sc->flags &= ~SCF_ENABLED; + sc_wait_for_packet_egress(sc, 1); + write_kctxt_csr(sc->dd, sc->hw_context, SC(CTRL), reg); +- spin_unlock_irqrestore(&sc->alloc_lock, flags); + + /* + * Flush any waiters. Once the context is disabled, +@@ -949,7 +947,7 @@ void sc_disable(struct send_context *sc) + * proceed with the flush. + */ + udelay(1); +- spin_lock_irqsave(&sc->release_lock, flags); ++ spin_lock(&sc->release_lock); + if (sc->sr) { /* this context has a shadow ring */ + while (sc->sr_tail != sc->sr_head) { + pbuf = &sc->sr[sc->sr_tail].pbuf; +@@ -960,7 +958,8 @@ void sc_disable(struct send_context *sc) + sc->sr_tail = 0; + } + } +- spin_unlock_irqrestore(&sc->release_lock, flags); ++ spin_unlock(&sc->release_lock); ++ spin_unlock_irq(&sc->alloc_lock); + } + + /* return SendEgressCtxtStatus.PacketOccupancy */ +@@ -1183,11 +1182,39 @@ void pio_kernel_unfreeze(struct hfi1_dev + sc = dd->send_contexts[i].sc; + if (!sc || !(sc->flags & SCF_FROZEN) || sc->type == SC_USER) + continue; ++ if (sc->flags & SCF_LINK_DOWN) ++ continue; + + sc_enable(sc); /* will clear the sc frozen flag */ + } + } + ++/** ++ * pio_kernel_linkup() - Re-enable send contexts after linkup event ++ * @dd: valid devive data ++ * ++ * When the link goes down, the freeze path is taken. However, a link down ++ * event is different from a freeze because if the send context is re-enabled ++ * whowever is sending data will start sending data again, which will hang ++ * any QP that is sending data. ++ * ++ * The freeze path now looks at the type of event that occurs and takes this ++ * path for link down event. ++ */ ++void pio_kernel_linkup(struct hfi1_devdata *dd) ++{ ++ struct send_context *sc; ++ int i; ++ ++ for (i = 0; i < dd->num_send_contexts; i++) { ++ sc = dd->send_contexts[i].sc; ++ if (!sc || !(sc->flags & SCF_LINK_DOWN) || sc->type == SC_USER) ++ continue; ++ ++ sc_enable(sc); /* will clear the sc link down flag */ ++ } ++} ++ + /* + * Wait for the SendPioInitCtxt.PioInitInProgress bit to clear. + * Returns: +@@ -1387,11 +1414,10 @@ void sc_stop(struct send_context *sc, in + { + unsigned long flags; + +- /* mark the context */ +- sc->flags |= flag; +- + /* stop buffer allocations */ + spin_lock_irqsave(&sc->alloc_lock, flags); ++ /* mark the context */ ++ sc->flags |= flag; + sc->flags &= ~SCF_ENABLED; + spin_unlock_irqrestore(&sc->alloc_lock, flags); + wake_up(&sc->halt_wait); +--- a/drivers/infiniband/hw/hfi1/pio.h ++++ b/drivers/infiniband/hw/hfi1/pio.h +@@ -139,6 +139,7 @@ struct send_context { + #define SCF_IN_FREE 0x02 + #define SCF_HALTED 0x04 + #define SCF_FROZEN 0x08 ++#define SCF_LINK_DOWN 0x10 + + struct send_context_info { + struct send_context *sc; /* allocated working context */ +@@ -306,6 +307,7 @@ void set_pio_integrity(struct send_conte + void pio_reset_all(struct hfi1_devdata *dd); + void pio_freeze(struct hfi1_devdata *dd); + void pio_kernel_unfreeze(struct hfi1_devdata *dd); ++void pio_kernel_linkup(struct hfi1_devdata *dd); + + /* global PIO send control operations */ + #define PSC_GLOBAL_ENABLE 0 diff --git a/queue-4.18/ib-hfi1-fix-sl-array-bounds-check.patch b/queue-4.18/ib-hfi1-fix-sl-array-bounds-check.patch new file mode 100644 index 00000000000..5565a8118d0 --- /dev/null +++ b/queue-4.18/ib-hfi1-fix-sl-array-bounds-check.patch @@ -0,0 +1,50 @@ +From 0dbfaa9f2813787679e296eb5476e40938ab48c8 Mon Sep 17 00:00:00 2001 +From: Ira Weiny +Date: Thu, 20 Sep 2018 12:58:46 -0700 +Subject: IB/hfi1: Fix SL array bounds check + +From: Ira Weiny + +commit 0dbfaa9f2813787679e296eb5476e40938ab48c8 upstream. + +The SL specified by a user needs to be a valid SL. + +Add a range check to the user specified SL value which protects from +running off the end of the SL to SC table. + +CC: stable@vger.kernel.org +Fixes: 7724105686e7 ("IB/hfi1: add driver files") +Signed-off-by: Ira Weiny +Signed-off-by: Dennis Dalessandro +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/hfi1/verbs.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/hfi1/verbs.c ++++ b/drivers/infiniband/hw/hfi1/verbs.c +@@ -1590,6 +1590,7 @@ static int hfi1_check_ah(struct ib_devic + struct hfi1_pportdata *ppd; + struct hfi1_devdata *dd; + u8 sc5; ++ u8 sl; + + if (hfi1_check_mcast(rdma_ah_get_dlid(ah_attr)) && + !(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH)) +@@ -1598,8 +1599,13 @@ static int hfi1_check_ah(struct ib_devic + /* test the mapping for validity */ + ibp = to_iport(ibdev, rdma_ah_get_port_num(ah_attr)); + ppd = ppd_from_ibp(ibp); +- sc5 = ibp->sl_to_sc[rdma_ah_get_sl(ah_attr)]; + dd = dd_from_ppd(ppd); ++ ++ sl = rdma_ah_get_sl(ah_attr); ++ if (sl >= ARRAY_SIZE(ibp->sl_to_sc)) ++ return -EINVAL; ++ ++ sc5 = ibp->sl_to_sc[sl]; + if (sc_to_vlt(dd, sc5) > num_vls && sc_to_vlt(dd, sc5) != 0xf) + return -EINVAL; + return 0; diff --git a/queue-4.18/ib-hfi1-invalid-user-input-can-result-in-crash.patch b/queue-4.18/ib-hfi1-invalid-user-input-can-result-in-crash.patch new file mode 100644 index 00000000000..82c64c0c60a --- /dev/null +++ b/queue-4.18/ib-hfi1-invalid-user-input-can-result-in-crash.patch @@ -0,0 +1,88 @@ +From 94694d18cf27a6faad91487a38ce516c2b16e7d9 Mon Sep 17 00:00:00 2001 +From: "Michael J. Ruhl" +Date: Thu, 20 Sep 2018 12:58:56 -0700 +Subject: IB/hfi1: Invalid user input can result in crash + +From: Michael J. Ruhl + +commit 94694d18cf27a6faad91487a38ce516c2b16e7d9 upstream. + +If the number of packets in a user sdma request does not match +the actual iovectors being sent, sdma_cleanup can be called on +an uninitialized request structure, resulting in a crash similar +to this: + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 +IP: [] __sdma_txclean+0x57/0x1e0 [hfi1] +PGD 8000001044f61067 PUD 1052706067 PMD 0 +Oops: 0000 [#1] SMP +CPU: 30 PID: 69912 Comm: upsm Kdump: loaded Tainted: G OE +------------ 3.10.0-862.el7.x86_64 #1 +Hardware name: Intel Corporation S2600KPR/S2600KPR, BIOS +SE5C610.86B.01.01.0019.101220160604 10/12/2016 +task: ffff8b331c890000 ti: ffff8b2ed1f98000 task.ti: ffff8b2ed1f98000 +RIP: 0010:[] [] __sdma_txclean+0x57/0x1e0 +[hfi1] +RSP: 0018:ffff8b2ed1f9bab0 EFLAGS: 00010286 +RAX: 0000000000008b2b RBX: ffff8b2adf6e0000 RCX: 0000000000000000 +RDX: 00000000000000a0 RSI: ffff8b2e9eedc540 RDI: ffff8b2adf6e0000 +RBP: ffff8b2ed1f9bad8 R08: 0000000000000000 R09: ffffffffc0b04a06 +R10: ffff8b331c890190 R11: ffffe6ed00bf1840 R12: ffff8b3315480000 +R13: ffff8b33154800f0 R14: 00000000fffffff2 R15: ffff8b2e9eedc540 +FS: 00007f035ac47740(0000) GS:ffff8b331e100000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000008 CR3: 0000000c03fe6000 CR4: 00000000001607e0 +Call Trace: + [] user_sdma_send_pkts+0xdcd/0x1990 [hfi1] + [] ? gup_pud_range+0x140/0x290 + [] ? hfi1_mmu_rb_insert+0x155/0x1b0 [hfi1] + [] hfi1_user_sdma_process_request+0xc5b/0x11b0 [hfi1] + [] hfi1_aio_write+0xba/0x110 [hfi1] + [] do_sync_readv_writev+0x7b/0xd0 + [] do_readv_writev+0xce/0x260 + [] ? tty_ldisc_deref+0x19/0x20 + [] ? n_tty_ioctl+0xe0/0xe0 + [] vfs_writev+0x35/0x60 + [] SyS_writev+0x7f/0x110 + [] system_call_fastpath+0x1c/0x21 +Code: 06 49 c7 47 18 00 00 00 00 0f 87 89 01 00 00 5b 41 5c 41 5d 41 5e 41 5f +5d c3 66 2e 0f 1f 84 00 00 00 00 00 48 8b 4e 10 48 89 fb <48> 8b 51 08 49 89 d4 +83 e2 0c 41 81 e4 00 e0 00 00 48 c1 ea 02 +RIP [] __sdma_txclean+0x57/0x1e0 [hfi1] + RSP +CR2: 0000000000000008 + +There are two exit points from user_sdma_send_pkts(). One (free_tx) +merely frees the slab entry and one (free_txreq) cleans the sdma_txreq +prior to freeing the slab entry. The free_txreq variation can only be +called after one of the sdma_init*() variations has been called. + +In the panic case, the slab entry had been allocated but not inited. + +Fix the issue by exiting through free_tx thus avoiding sdma_clean(). + +Cc: # 4.9.x+ +Fixes: 7724105686e7 ("IB/hfi1: add driver files") +Reviewed-by: Mike Marciniszyn +Reviewed-by: Lukasz Odzioba +Signed-off-by: Michael J. Ruhl +Signed-off-by: Dennis Dalessandro +Signed-off-by: Greg Kroah-Hartman + +Signed-off-by: Jason Gunthorpe + +--- + drivers/infiniband/hw/hfi1/user_sdma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/hfi1/user_sdma.c ++++ b/drivers/infiniband/hw/hfi1/user_sdma.c +@@ -828,7 +828,7 @@ static int user_sdma_send_pkts(struct us + if (READ_ONCE(iovec->offset) == iovec->iov.iov_len) { + if (++req->iov_idx == req->data_iovs) { + ret = -EFAULT; +- goto free_txreq; ++ goto free_tx; + } + iovec = &req->iovs[req->iov_idx]; + WARN_ON(iovec->offset); diff --git a/queue-4.18/ib-srp-avoid-that-sg_reset-d-srp_device-triggers-an-infinite-loop.patch b/queue-4.18/ib-srp-avoid-that-sg_reset-d-srp_device-triggers-an-infinite-loop.patch new file mode 100644 index 00000000000..50335dfab77 --- /dev/null +++ b/queue-4.18/ib-srp-avoid-that-sg_reset-d-srp_device-triggers-an-infinite-loop.patch @@ -0,0 +1,45 @@ +From ee92efe41cf358f4b99e73509f2bfd4733609f26 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Mon, 17 Sep 2018 18:10:05 -0700 +Subject: IB/srp: Avoid that sg_reset -d ${srp_device} triggers an infinite loop + +From: Bart Van Assche + +commit ee92efe41cf358f4b99e73509f2bfd4733609f26 upstream. + +Use different loop variables for the inner and outer loop. This avoids +that an infinite loop occurs if there are more RDMA channels than +target->req_ring_size. + +Fixes: d92c0da71a35 ("IB/srp: Add multichannel support") +Cc: +Signed-off-by: Bart Van Assche +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/srp/ib_srp.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -2954,7 +2954,7 @@ static int srp_reset_device(struct scsi_ + { + struct srp_target_port *target = host_to_target(scmnd->device->host); + struct srp_rdma_ch *ch; +- int i; ++ int i, j; + u8 status; + + shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n"); +@@ -2968,8 +2968,8 @@ static int srp_reset_device(struct scsi_ + + for (i = 0; i < target->ch_count; i++) { + ch = &target->ch[i]; +- for (i = 0; i < target->req_ring_size; ++i) { +- struct srp_request *req = &ch->req_ring[i]; ++ for (j = 0; j < target->req_ring_size; ++j) { ++ struct srp_request *req = &ch->req_ring[j]; + + srp_finish_req(ch, req, scmnd->device, DID_RESET << 16); + } diff --git a/queue-4.18/input-elantech-enable-middle-button-of-touchpad-on-thinkpad-p72.patch b/queue-4.18/input-elantech-enable-middle-button-of-touchpad-on-thinkpad-p72.patch new file mode 100644 index 00000000000..13b6183b743 --- /dev/null +++ b/queue-4.18/input-elantech-enable-middle-button-of-touchpad-on-thinkpad-p72.patch @@ -0,0 +1,31 @@ +From 91a97507323e1ad4bfc10f4a5922e67cdaf8b3cd Mon Sep 17 00:00:00 2001 +From: Aaron Ma +Date: Tue, 18 Sep 2018 09:32:22 -0700 +Subject: Input: elantech - enable middle button of touchpad on ThinkPad P72 + +From: Aaron Ma + +commit 91a97507323e1ad4bfc10f4a5922e67cdaf8b3cd upstream. + +Adding 2 new touchpad IDs to support middle button support. + +Cc: stable@vger.kernel.org +Signed-off-by: Aaron Ma +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/elantech.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1178,6 +1178,8 @@ static const struct dmi_system_id elante + static const char * const middle_button_pnp_ids[] = { + "LEN2131", /* ThinkPad P52 w/ NFC */ + "LEN2132", /* ThinkPad P52 */ ++ "LEN2133", /* ThinkPad P72 w/ NFC */ ++ "LEN2134", /* ThinkPad P72 */ + NULL + }; + diff --git a/queue-4.18/rdma-uverbs-atomically-flush-and-mark-closed-the-comp-event-queue.patch b/queue-4.18/rdma-uverbs-atomically-flush-and-mark-closed-the-comp-event-queue.patch new file mode 100644 index 00000000000..477cd79fc26 --- /dev/null +++ b/queue-4.18/rdma-uverbs-atomically-flush-and-mark-closed-the-comp-event-queue.patch @@ -0,0 +1,45 @@ +From 67e3816842fe6414d629c7515b955952ec40c7d7 Mon Sep 17 00:00:00 2001 +From: Steve Wise +Date: Fri, 31 Aug 2018 07:16:03 -0700 +Subject: RDMA/uverbs: Atomically flush and mark closed the comp event queue + +From: Steve Wise + +commit 67e3816842fe6414d629c7515b955952ec40c7d7 upstream. + +Currently a uverbs completion event queue is flushed of events in +ib_uverbs_comp_event_close() with the queue spinlock held and then +released. Yet setting ev_queue->is_closed is not set until later in +uverbs_hot_unplug_completion_event_file(). + +In between the time ib_uverbs_comp_event_close() releases the lock and +uverbs_hot_unplug_completion_event_file() acquires the lock, a completion +event can arrive and be inserted into the event queue by +ib_uverbs_comp_handler(). + +This can cause a "double add" list_add warning or crash depending on the +kernel configuration, or a memory leak because the event is never dequeued +since the queue is already closed down. + +So add setting ev_queue->is_closed = 1 to ib_uverbs_comp_event_close(). + +Cc: stable@vger.kernel.org +Fixes: 1e7710f3f656 ("IB/core: Change completion channel to use the reworked objects schema") +Signed-off-by: Steve Wise +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/uverbs_main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/infiniband/core/uverbs_main.c ++++ b/drivers/infiniband/core/uverbs_main.c +@@ -429,6 +429,7 @@ static int ib_uverbs_comp_event_close(st + list_del(&entry->obj_list); + kfree(entry); + } ++ file->ev_queue.is_closed = 1; + spin_unlock_irq(&file->ev_queue.lock); + + uverbs_close_fd(filp); diff --git a/queue-4.18/revert-usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch b/queue-4.18/revert-usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch new file mode 100644 index 00000000000..46362c478f6 --- /dev/null +++ b/queue-4.18/revert-usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch @@ -0,0 +1,35 @@ +From e871db8d78df1c411032cbb3acfdf8930509360e Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Tue, 11 Sep 2018 10:00:44 +0200 +Subject: Revert "usb: cdc-wdm: Fix a sleep-in-atomic-context bug in service_outstanding_interrupt()" + +From: Sebastian Andrzej Siewior + +commit e871db8d78df1c411032cbb3acfdf8930509360e upstream. + +This reverts commit 6e22e3af7bb3a7b9dc53cb4687659f6e63fca427. + +The bug the patch describes to, has been already fixed in commit +2df6948428542 ("USB: cdc-wdm: don't enable interrupts in USB-giveback") +so need to this, revert it. + +Fixes: 6e22e3af7bb3 ("usb: cdc-wdm: Fix a sleep-in-atomic-context bug in service_outstanding_interrupt()") +Cc: stable +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-wdm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -458,7 +458,7 @@ static int service_outstanding_interrupt + + set_bit(WDM_RESPONDING, &desc->flags); + spin_unlock_irq(&desc->iuspin); +- rv = usb_submit_urb(desc->response, GFP_ATOMIC); ++ rv = usb_submit_urb(desc->response, GFP_KERNEL); + spin_lock_irq(&desc->iuspin); + if (rv) { + dev_err(&desc->intf->dev, diff --git a/queue-4.18/series b/queue-4.18/series index 0705ed729d8..4aa0c78c722 100644 --- a/queue-4.18/series +++ b/queue-4.18/series @@ -151,3 +151,18 @@ usb-handle-null-config-in-usb_find_alt_setting.patch usb-roles-take-care-of-driver-module-reference-counting.patch usb-core-safely-deal-with-the-dynamic-quirk-lists.patch usb-musb-dsps-do-not-disable-cppi41-irq-in-driver-teardown.patch +usb-usbdevfs-sanitize-flags-more.patch +usb-usbdevfs-restore-warning-for-nonsensical-flags.patch +revert-usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch +usb-remove-lpm-management-from-usb_driver_claim_interface.patch +uaccess-fix-is_source-param-for-check_copy_size-in-copy_to_iter_mcsafe.patch +ext2-dax-set-ext2_dax_aops-for-dax-files.patch +filesystem-dax-fix-use-of-zero-page.patch +input-elantech-enable-middle-button-of-touchpad-on-thinkpad-p72.patch +ib-srp-avoid-that-sg_reset-d-srp_device-triggers-an-infinite-loop.patch +ib-hfi1-fix-sl-array-bounds-check.patch +ib-hfi1-invalid-user-input-can-result-in-crash.patch +ib-hfi1-fix-context-recovery-when-pbc-has-an-unsupportedvl.patch +ib-hfi1-fix-destroy_qp-hang-after-a-link-down.patch +acpi-hotplug-pci-don-t-scan-for-non-hotplug-bridges-if-slot-is-not-bridge.patch +rdma-uverbs-atomically-flush-and-mark-closed-the-comp-event-queue.patch diff --git a/queue-4.18/uaccess-fix-is_source-param-for-check_copy_size-in-copy_to_iter_mcsafe.patch b/queue-4.18/uaccess-fix-is_source-param-for-check_copy_size-in-copy_to_iter_mcsafe.patch new file mode 100644 index 00000000000..71494642752 --- /dev/null +++ b/queue-4.18/uaccess-fix-is_source-param-for-check_copy_size-in-copy_to_iter_mcsafe.patch @@ -0,0 +1,38 @@ +From dfb06cba8c73c0704710b2e3fbe2c35ac66a01b4 Mon Sep 17 00:00:00 2001 +From: Dave Jiang +Date: Wed, 5 Sep 2018 13:31:40 -0700 +Subject: uaccess: Fix is_source param for check_copy_size() in copy_to_iter_mcsafe() + +From: Dave Jiang + +commit dfb06cba8c73c0704710b2e3fbe2c35ac66a01b4 upstream. + +copy_to_iter_mcsafe() is passing in the is_source parameter as "false" +to check_copy_size(). This is different than what copy_to_iter() does. +Also, the addr parameter passed to check_copy_size() is the source so +therefore we should be passing in "true" instead. + +Fixes: 8780356ef630 ("x86/asm/memcpy_mcsafe: Define copy_to_iter_mcsafe()") +Cc: +Reported-by: Fan Du +Signed-off-by: Dave Jiang +Reviewed-by: Vishal Verma +Reported-by: Wenwei Tao +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/uio.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/uio.h ++++ b/include/linux/uio.h +@@ -172,7 +172,7 @@ size_t copy_from_iter_flushcache(void *a + static __always_inline __must_check + size_t copy_to_iter_mcsafe(void *addr, size_t bytes, struct iov_iter *i) + { +- if (unlikely(!check_copy_size(addr, bytes, false))) ++ if (unlikely(!check_copy_size(addr, bytes, true))) + return 0; + else + return _copy_to_iter_mcsafe(addr, bytes, i); diff --git a/queue-4.18/usb-remove-lpm-management-from-usb_driver_claim_interface.patch b/queue-4.18/usb-remove-lpm-management-from-usb_driver_claim_interface.patch new file mode 100644 index 00000000000..7f72f8c4503 --- /dev/null +++ b/queue-4.18/usb-remove-lpm-management-from-usb_driver_claim_interface.patch @@ -0,0 +1,76 @@ +From c183813fcee44a249339b7c46e1ad271ca1870aa Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Mon, 10 Sep 2018 13:58:51 -0400 +Subject: USB: remove LPM management from usb_driver_claim_interface() + +From: Alan Stern + +commit c183813fcee44a249339b7c46e1ad271ca1870aa upstream. + +usb_driver_claim_interface() disables and re-enables Link Power +Management, but it shouldn't do either one, for the reasons listed +below. This patch removes the two LPM-related function calls from the +routine. + +The reason for disabling LPM in the analogous function +usb_probe_interface() is so that drivers won't have to deal with +unwanted LPM transitions in their probe routine. But +usb_driver_claim_interface() doesn't call the driver's probe routine +(or any other callbacks), so that reason doesn't apply here. + +Furthermore, no driver other than usbfs will ever call +usb_driver_claim_interface() unless it is already bound to another +interface in the same device, which means disabling LPM here would be +redundant. usbfs doesn't interact with LPM at all. + +Lastly, the error return from usb_unlocked_disable_lpm() isn't handled +properly; the code doesn't clean up its earlier actions before +returning. + +Signed-off-by: Alan Stern +Fixes: 8306095fd2c1 ("USB: Disable USB 3.0 LPM in critical sections.") +CC: +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/driver.c | 15 --------------- + 1 file changed, 15 deletions(-) + +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -512,7 +512,6 @@ int usb_driver_claim_interface(struct us + struct device *dev; + struct usb_device *udev; + int retval = 0; +- int lpm_disable_error = -ENODEV; + + if (!iface) + return -ENODEV; +@@ -533,16 +532,6 @@ int usb_driver_claim_interface(struct us + + iface->condition = USB_INTERFACE_BOUND; + +- /* See the comment about disabling LPM in usb_probe_interface(). */ +- if (driver->disable_hub_initiated_lpm) { +- lpm_disable_error = usb_unlocked_disable_lpm(udev); +- if (lpm_disable_error) { +- dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n", +- __func__, driver->name); +- return -ENOMEM; +- } +- } +- + /* Claimed interfaces are initially inactive (suspended) and + * runtime-PM-enabled, but only if the driver has autosuspend + * support. Otherwise they are marked active, to prevent the +@@ -561,10 +550,6 @@ int usb_driver_claim_interface(struct us + if (device_is_registered(dev)) + retval = device_bind_driver(dev); + +- /* Attempt to re-enable USB3 LPM, if the disable was successful. */ +- if (!lpm_disable_error) +- usb_unlocked_enable_lpm(udev); +- + if (retval) { + dev->driver = NULL; + usb_set_intfdata(iface, NULL); diff --git a/queue-4.18/usb-usbdevfs-restore-warning-for-nonsensical-flags.patch b/queue-4.18/usb-usbdevfs-restore-warning-for-nonsensical-flags.patch new file mode 100644 index 00000000000..38f3c2cfe1e --- /dev/null +++ b/queue-4.18/usb-usbdevfs-restore-warning-for-nonsensical-flags.patch @@ -0,0 +1,35 @@ +From 81e0403b26d94360abd1f6a57311337973bc82cd Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Wed, 5 Sep 2018 12:07:03 +0200 +Subject: USB: usbdevfs: restore warning for nonsensical flags + +From: Oliver Neukum + +commit 81e0403b26d94360abd1f6a57311337973bc82cd upstream. + +If we filter flags before they reach the core we need to generate our +own warnings. + +Signed-off-by: Oliver Neukum +Fixes: 0cb54a3e47cb ("USB: debugging code shouldn't alter control flow") +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/devio.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -1696,6 +1696,11 @@ static int proc_do_submiturb(struct usb_ + u |= URB_NO_INTERRUPT; + as->urb->transfer_flags = u; + ++ if (!allow_short && uurb->flags & USBDEVFS_URB_SHORT_NOT_OK) ++ dev_warn(&ps->dev->dev, "Requested nonsensical USBDEVFS_URB_SHORT_NOT_OK.\n"); ++ if (!allow_zero && uurb->flags & USBDEVFS_URB_ZERO_PACKET) ++ dev_warn(&ps->dev->dev, "Requested nonsensical USBDEVFS_URB_ZERO_PACKET.\n"); ++ + as->urb->transfer_buffer_length = uurb->buffer_length; + as->urb->setup_packet = (unsigned char *)dr; + dr = NULL; diff --git a/queue-4.18/usb-usbdevfs-sanitize-flags-more.patch b/queue-4.18/usb-usbdevfs-sanitize-flags-more.patch new file mode 100644 index 00000000000..bcdca44e661 --- /dev/null +++ b/queue-4.18/usb-usbdevfs-sanitize-flags-more.patch @@ -0,0 +1,86 @@ +From 7a68d9fb851012829c29e770621905529bd9490b Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Wed, 5 Sep 2018 12:07:02 +0200 +Subject: USB: usbdevfs: sanitize flags more + +From: Oliver Neukum + +commit 7a68d9fb851012829c29e770621905529bd9490b upstream. + +Requesting a ZERO_PACKET or not is sensible only for output. +In the input direction the device decides. +Likewise accepting short packets makes sense only for input. + +This allows operation with panic_on_warn without opening up +a local DOS. + +Signed-off-by: Oliver Neukum +Reported-by: syzbot+843efa30c8821bd69f53@syzkaller.appspotmail.com +Fixes: 0cb54a3e47cb ("USB: debugging code shouldn't alter control flow") +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/devio.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -1433,10 +1433,13 @@ static int proc_do_submiturb(struct usb_ + struct async *as = NULL; + struct usb_ctrlrequest *dr = NULL; + unsigned int u, totlen, isofrmlen; +- int i, ret, is_in, num_sgs = 0, ifnum = -1; ++ int i, ret, num_sgs = 0, ifnum = -1; + int number_of_packets = 0; + unsigned int stream_id = 0; + void *buf; ++ bool is_in; ++ bool allow_short = false; ++ bool allow_zero = false; + unsigned long mask = USBDEVFS_URB_SHORT_NOT_OK | + USBDEVFS_URB_BULK_CONTINUATION | + USBDEVFS_URB_NO_FSBR | +@@ -1470,6 +1473,8 @@ static int proc_do_submiturb(struct usb_ + u = 0; + switch (uurb->type) { + case USBDEVFS_URB_TYPE_CONTROL: ++ if (is_in) ++ allow_short = true; + if (!usb_endpoint_xfer_control(&ep->desc)) + return -EINVAL; + /* min 8 byte setup packet */ +@@ -1510,6 +1515,10 @@ static int proc_do_submiturb(struct usb_ + break; + + case USBDEVFS_URB_TYPE_BULK: ++ if (!is_in) ++ allow_zero = true; ++ else ++ allow_short = true; + switch (usb_endpoint_type(&ep->desc)) { + case USB_ENDPOINT_XFER_CONTROL: + case USB_ENDPOINT_XFER_ISOC: +@@ -1530,6 +1539,10 @@ static int proc_do_submiturb(struct usb_ + if (!usb_endpoint_xfer_int(&ep->desc)) + return -EINVAL; + interrupt_urb: ++ if (!is_in) ++ allow_zero = true; ++ else ++ allow_short = true; + break; + + case USBDEVFS_URB_TYPE_ISO: +@@ -1675,9 +1688,9 @@ static int proc_do_submiturb(struct usb_ + u = (is_in ? URB_DIR_IN : URB_DIR_OUT); + if (uurb->flags & USBDEVFS_URB_ISO_ASAP) + u |= URB_ISO_ASAP; +- if (uurb->flags & USBDEVFS_URB_SHORT_NOT_OK && is_in) ++ if (allow_short && uurb->flags & USBDEVFS_URB_SHORT_NOT_OK) + u |= URB_SHORT_NOT_OK; +- if (uurb->flags & USBDEVFS_URB_ZERO_PACKET) ++ if (allow_zero && uurb->flags & USBDEVFS_URB_ZERO_PACKET) + u |= URB_ZERO_PACKET; + if (uurb->flags & USBDEVFS_URB_NO_INTERRUPT) + u |= URB_NO_INTERRUPT;