From: Greg Kroah-Hartman Date: Sun, 23 Sep 2018 19:33:34 +0000 (+0200) Subject: 4.18-stable patches X-Git-Tag: v3.18.123~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2cc08a5444b0970773189b24f87c99e7a3757579;p=thirdparty%2Fkernel%2Fstable-queue.git 4.18-stable patches added patches: cifs-fix-wrapping-bugs-in-num_entries.patch cifs-integer-overflow-in-in-smb2_ioctl.patch cifs-prevent-integer-overflow-in-nxt_dir_entry.patch dm-verity-fix-crash-on-bufio-buffer-that-was-allocated-with-vmalloc.patch ib-ipoib-avoid-a-race-condition-between-start_xmit-and-cm_rep_handler.patch ipmi-fix-i2c-client-removal-in-the-ssif-driver.patch ipmi-move-bt-capabilities-detection-to-the-detect-call.patch ipmi-rework-smi-registration-failure.patch mei-bus-fix-hw-module-get-put-balance.patch mei-bus-need-to-unlink-client-before-freeing.patch mei-ignore-not-found-client-in-the-enumeration.patch misc-hmc6352-fix-potential-spectre-v1.patch misc-ibmvsm-fix-wrong-assignment-of-return-code.patch mmc-meson-mx-sdio-fix-of-child-node-lookup.patch mmc-omap_hsmmc-fix-wakeirq-handling-on-removal.patch nfsv4-fix-a-tracepoint-oops-in-initiate_file_draining.patch nfsv4.1-fix-infinite-loop-on-i-o.patch of-fix-phandle-cache-creation-for-dts-with-no-phandles.patch ovl-fix-oopses-in-ovl_fill_super-failure-paths.patch perf-core-force-user_ds-when-recording-user-stack-data.patch perf-tools-fix-maps__find_symbol_by_name.patch pstore-fix-incorrect-persistent-ram-buffer-mapping.patch rdma-cma-protect-cma-dev-list-with-lock.patch revert-cdc-acm-implement-put_char-and-flush_chars.patch s390-crypto-fix-return-code-checking-in-cbc_paes_crypt.patch tools-hv-fix-a-bug-in-the-key-delete-code.patch usb-add-quirk-for-worlde-controller-ks49-or-prodipe-midi-49c-usb-controller.patch usb-add-quirk-to-support-dji-cinessd.patch usb-avoid-use-after-free-by-flushing-endpoints-early-in-usb_set_interface.patch usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch usb-don-t-die-twice-if-pci-xhci-host-is-not-responding-in-resume.patch usb-gadget-udc-renesas_usb3-fix-maxpacket-size-of-ep0.patch usb-host-u132-hcd-fix-a-sleep-in-atomic-context-bug-in-u132_get_frame.patch usb-misc-uss720-fix-two-sleep-in-atomic-context-bugs.patch usb-mtu3-fix-error-of-xhci-port-id-when-enable-u3-dual-role.patch usb-net2280-fix-erroneous-synchronization-change.patch usb-serial-io_ti-fix-array-underflow-in-completion-handler.patch usb-serial-ti_usb_3410_5052-fix-array-underflow-in-completion-handler.patch usb-uas-add-support-for-more-quirk-flags.patch usb-xhci-fix-interrupt-transfer-error-happened-on-mtk-platforms.patch usb-yurex-fix-buffer-over-read-in-yurex_write.patch vmbus-don-t-return-values-for-uninitalized-channels.patch x86-eisa-don-t-probe-eisa-bus-for-xen-pv-guests.patch xen-netfront-fix-waiting-for-xenbus-state-change.patch xhci-fix-use-after-free-for-urb-cancellation-on-a-reallocated-endpoint.patch xtensa-iss-don-t-allocate-memory-in-platform_setup.patch --- diff --git a/queue-4.18/cifs-fix-wrapping-bugs-in-num_entries.patch b/queue-4.18/cifs-fix-wrapping-bugs-in-num_entries.patch new file mode 100644 index 00000000000..cf11e34df65 --- /dev/null +++ b/queue-4.18/cifs-fix-wrapping-bugs-in-num_entries.patch @@ -0,0 +1,75 @@ +From 56446f218af1133c802dad8e9e116f07f381846c Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 6 Sep 2018 12:48:22 +0300 +Subject: CIFS: fix wrapping bugs in num_entries() + +From: Dan Carpenter + +commit 56446f218af1133c802dad8e9e116f07f381846c upstream. + +The problem is that "entryptr + next_offset" and "entryptr + len + size" +can wrap. I ended up changing the type of "entryptr" because it makes +the math easier when we don't have to do so much casting. + +Signed-off-by: Dan Carpenter +Signed-off-by: Steve French +Reviewed-by: Aurelien Aptel +Reviewed-by: Pavel Shilovsky +CC: Stable +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb2pdu.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -3492,33 +3492,38 @@ num_entries(char *bufstart, char *end_of + int len; + unsigned int entrycount = 0; + unsigned int next_offset = 0; +- FILE_DIRECTORY_INFO *entryptr; ++ char *entryptr; ++ FILE_DIRECTORY_INFO *dir_info; + + if (bufstart == NULL) + return 0; + +- entryptr = (FILE_DIRECTORY_INFO *)bufstart; ++ entryptr = bufstart; + + while (1) { +- entryptr = (FILE_DIRECTORY_INFO *) +- ((char *)entryptr + next_offset); +- +- if ((char *)entryptr + size > end_of_buf) { ++ if (entryptr + next_offset < entryptr || ++ entryptr + next_offset > end_of_buf || ++ entryptr + next_offset + size > end_of_buf) { + cifs_dbg(VFS, "malformed search entry would overflow\n"); + break; + } + +- len = le32_to_cpu(entryptr->FileNameLength); +- if ((char *)entryptr + len + size > end_of_buf) { ++ entryptr = entryptr + next_offset; ++ dir_info = (FILE_DIRECTORY_INFO *)entryptr; ++ ++ len = le32_to_cpu(dir_info->FileNameLength); ++ if (entryptr + len < entryptr || ++ entryptr + len > end_of_buf || ++ entryptr + len + size > end_of_buf) { + cifs_dbg(VFS, "directory entry name would overflow frame end of buf %p\n", + end_of_buf); + break; + } + +- *lastentry = (char *)entryptr; ++ *lastentry = entryptr; + entrycount++; + +- next_offset = le32_to_cpu(entryptr->NextEntryOffset); ++ next_offset = le32_to_cpu(dir_info->NextEntryOffset); + if (!next_offset) + break; + } diff --git a/queue-4.18/cifs-integer-overflow-in-in-smb2_ioctl.patch b/queue-4.18/cifs-integer-overflow-in-in-smb2_ioctl.patch new file mode 100644 index 00000000000..f66ee7d14a9 --- /dev/null +++ b/queue-4.18/cifs-integer-overflow-in-in-smb2_ioctl.patch @@ -0,0 +1,43 @@ +From 2d204ee9d671327915260071c19350d84344e096 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 10 Sep 2018 14:12:07 +0300 +Subject: cifs: integer overflow in in SMB2_ioctl() + +From: Dan Carpenter + +commit 2d204ee9d671327915260071c19350d84344e096 upstream. + +The "le32_to_cpu(rsp->OutputOffset) + *plen" addition can overflow and +wrap around to a smaller value which looks like it would lead to an +information leak. + +Fixes: 4a72dafa19ba ("SMB2 FSCTL and IOCTL worker function") +Signed-off-by: Dan Carpenter +Signed-off-by: Steve French +Reviewed-by: Aurelien Aptel +CC: Stable +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb2pdu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -2418,14 +2418,14 @@ SMB2_ioctl(const unsigned int xid, struc + /* We check for obvious errors in the output buffer length and offset */ + if (*plen == 0) + goto ioctl_exit; /* server returned no data */ +- else if (*plen > 0xFF00) { ++ else if (*plen > rsp_iov.iov_len || *plen > 0xFF00) { + cifs_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen); + *plen = 0; + rc = -EIO; + goto ioctl_exit; + } + +- if (rsp_iov.iov_len < le32_to_cpu(rsp->OutputOffset) + *plen) { ++ if (rsp_iov.iov_len - *plen < le32_to_cpu(rsp->OutputOffset)) { + cifs_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen, + le32_to_cpu(rsp->OutputOffset)); + *plen = 0; diff --git a/queue-4.18/cifs-prevent-integer-overflow-in-nxt_dir_entry.patch b/queue-4.18/cifs-prevent-integer-overflow-in-nxt_dir_entry.patch new file mode 100644 index 00000000000..f56e401bcfe --- /dev/null +++ b/queue-4.18/cifs-prevent-integer-overflow-in-nxt_dir_entry.patch @@ -0,0 +1,44 @@ +From 8ad8aa353524d89fa2e09522f3078166ff78ec42 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 6 Sep 2018 12:47:51 +0300 +Subject: cifs: prevent integer overflow in nxt_dir_entry() + +From: Dan Carpenter + +commit 8ad8aa353524d89fa2e09522f3078166ff78ec42 upstream. + +The "old_entry + le32_to_cpu(pDirInfo->NextEntryOffset)" can wrap +around so I have added a check for integer overflow. + +Reported-by: Dr Silvio Cesare of InfoSect +Reviewed-by: Ronnie Sahlberg +Reviewed-by: Aurelien Aptel +Signed-off-by: Dan Carpenter +Signed-off-by: Steve French +CC: Stable +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/readdir.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/fs/cifs/readdir.c ++++ b/fs/cifs/readdir.c +@@ -376,8 +376,15 @@ static char *nxt_dir_entry(char *old_ent + + new_entry = old_entry + sizeof(FIND_FILE_STANDARD_INFO) + + pfData->FileNameLength; +- } else +- new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset); ++ } else { ++ u32 next_offset = le32_to_cpu(pDirInfo->NextEntryOffset); ++ ++ if (old_entry + next_offset < old_entry) { ++ cifs_dbg(VFS, "invalid offset %u\n", next_offset); ++ return NULL; ++ } ++ new_entry = old_entry + next_offset; ++ } + cifs_dbg(FYI, "new entry %p old entry %p\n", new_entry, old_entry); + /* validate that new_entry is not past end of SMB */ + if (new_entry >= end_of_smb) { diff --git a/queue-4.18/dm-verity-fix-crash-on-bufio-buffer-that-was-allocated-with-vmalloc.patch b/queue-4.18/dm-verity-fix-crash-on-bufio-buffer-that-was-allocated-with-vmalloc.patch new file mode 100644 index 00000000000..42bba982331 --- /dev/null +++ b/queue-4.18/dm-verity-fix-crash-on-bufio-buffer-that-was-allocated-with-vmalloc.patch @@ -0,0 +1,65 @@ +From e4b069e0945fa14c71cf8b5b89f8b1b2aa68dbc2 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Wed, 22 Aug 2018 12:45:51 -0400 +Subject: dm verity: fix crash on bufio buffer that was allocated with vmalloc + +From: Mikulas Patocka + +commit e4b069e0945fa14c71cf8b5b89f8b1b2aa68dbc2 upstream. + +Since commit d1ac3ff008fb ("dm verity: switch to using asynchronous hash +crypto API") dm-verity uses asynchronous crypto calls for verification, +so that it can use hardware with asynchronous processing of crypto +operations. + +These asynchronous calls don't support vmalloc memory, but the buffer data +can be allocated with vmalloc if dm-bufio is short of memory and uses a +reserved buffer that was preallocated in dm_bufio_client_create(). + +Fix verity_hash_update() so that it deals with vmalloc'd memory +correctly. + +Reported-by: "Xiao, Jin" +Signed-off-by: Mikulas Patocka +Fixes: d1ac3ff008fb ("dm verity: switch to using asynchronous hash crypto API") +Cc: stable@vger.kernel.org # 4.12+ +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-verity-target.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +--- a/drivers/md/dm-verity-target.c ++++ b/drivers/md/dm-verity-target.c +@@ -99,10 +99,26 @@ static int verity_hash_update(struct dm_ + { + struct scatterlist sg; + +- sg_init_one(&sg, data, len); +- ahash_request_set_crypt(req, &sg, NULL, len); +- +- return crypto_wait_req(crypto_ahash_update(req), wait); ++ if (likely(!is_vmalloc_addr(data))) { ++ sg_init_one(&sg, data, len); ++ ahash_request_set_crypt(req, &sg, NULL, len); ++ return crypto_wait_req(crypto_ahash_update(req), wait); ++ } else { ++ do { ++ int r; ++ size_t this_step = min_t(size_t, len, PAGE_SIZE - offset_in_page(data)); ++ flush_kernel_vmap_range((void *)data, this_step); ++ sg_init_table(&sg, 1); ++ sg_set_page(&sg, vmalloc_to_page(data), this_step, offset_in_page(data)); ++ ahash_request_set_crypt(req, &sg, NULL, this_step); ++ r = crypto_wait_req(crypto_ahash_update(req), wait); ++ if (unlikely(r)) ++ return r; ++ data += this_step; ++ len -= this_step; ++ } while (len); ++ return 0; ++ } + } + + /* diff --git a/queue-4.18/ib-ipoib-avoid-a-race-condition-between-start_xmit-and-cm_rep_handler.patch b/queue-4.18/ib-ipoib-avoid-a-race-condition-between-start_xmit-and-cm_rep_handler.patch new file mode 100644 index 00000000000..428ef5b54f2 --- /dev/null +++ b/queue-4.18/ib-ipoib-avoid-a-race-condition-between-start_xmit-and-cm_rep_handler.patch @@ -0,0 +1,76 @@ +From 816e846c2eb9129a3e0afa5f920c8bbc71efecaa Mon Sep 17 00:00:00 2001 +From: Aaron Knister +Date: Fri, 24 Aug 2018 08:42:46 -0400 +Subject: IB/ipoib: Avoid a race condition between start_xmit and cm_rep_handler + +From: Aaron Knister + +commit 816e846c2eb9129a3e0afa5f920c8bbc71efecaa upstream. + +Inside of start_xmit() the call to check if the connection is up and the +queueing of the packets for later transmission is not atomic which leaves +a window where cm_rep_handler can run, set the connection up, dequeue +pending packets and leave the subsequently queued packets by start_xmit() +sitting on neigh->queue until they're dropped when the connection is torn +down. This only applies to connected mode. These dropped packets can +really upset TCP, for example, and cause multi-minute delays in +transmission for open connections. + +Here's the code in start_xmit where we check to see if the connection is +up: + + if (ipoib_cm_get(neigh)) { + if (ipoib_cm_up(neigh)) { + ipoib_cm_send(dev, skb, ipoib_cm_get(neigh)); + goto unref; + } + } + +The race occurs if cm_rep_handler execution occurs after the above +connection check (specifically if it gets to the point where it acquires +priv->lock to dequeue pending skb's) but before the below code snippet in +start_xmit where packets are queued. + + if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) { + push_pseudo_header(skb, phdr->hwaddr); + spin_lock_irqsave(&priv->lock, flags); + __skb_queue_tail(&neigh->queue, skb); + spin_unlock_irqrestore(&priv->lock, flags); + } else { + ++dev->stats.tx_dropped; + dev_kfree_skb_any(skb); + } + +The patch acquires the netif tx lock in cm_rep_handler for the section +where it sets the connection up and dequeues and retransmits deferred +skb's. + +Fixes: 839fcaba355a ("IPoIB: Connected mode experimental support") +Cc: stable@vger.kernel.org +Signed-off-by: Aaron Knister +Tested-by: Ira Weiny +Reviewed-by: Ira Weiny +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/ipoib/ipoib_cm.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c +@@ -1028,12 +1028,14 @@ static int ipoib_cm_rep_handler(struct i + + skb_queue_head_init(&skqueue); + ++ netif_tx_lock_bh(p->dev); + spin_lock_irq(&priv->lock); + set_bit(IPOIB_FLAG_OPER_UP, &p->flags); + if (p->neigh) + while ((skb = __skb_dequeue(&p->neigh->queue))) + __skb_queue_tail(&skqueue, skb); + spin_unlock_irq(&priv->lock); ++ netif_tx_unlock_bh(p->dev); + + while ((skb = __skb_dequeue(&skqueue))) { + skb->dev = p->dev; diff --git a/queue-4.18/ipmi-fix-i2c-client-removal-in-the-ssif-driver.patch b/queue-4.18/ipmi-fix-i2c-client-removal-in-the-ssif-driver.patch new file mode 100644 index 00000000000..52147830191 --- /dev/null +++ b/queue-4.18/ipmi-fix-i2c-client-removal-in-the-ssif-driver.patch @@ -0,0 +1,123 @@ +From 0745dde62835be7e2afe62fcdb482fcad79cb743 Mon Sep 17 00:00:00 2001 +From: Corey Minyard +Date: Thu, 30 Aug 2018 13:06:21 -0500 +Subject: ipmi: Fix I2C client removal in the SSIF driver + +From: Corey Minyard + +commit 0745dde62835be7e2afe62fcdb482fcad79cb743 upstream. + +The SSIF driver was removing any client that came in through the +platform interface, but it should only remove clients that it +added. On a failure in the probe function, this could result +in the following oops when the driver is removed and the +client gets unregistered twice: + + CPU: 107 PID: 30266 Comm: rmmod Not tainted 4.18.0+ #80 + Hardware name: Cavium Inc. Saber/Saber, BIOS Cavium reference firmware version 7.0 08/04/2018 + pstate: 60400009 (nZCv daif +PAN -UAO) + pc : kernfs_find_ns+0x28/0x120 + lr : kernfs_find_and_get_ns+0x40/0x60 + sp : ffff00002310fb50 + x29: ffff00002310fb50 x28: ffff800a8240f800 + x27: 0000000000000000 x26: 0000000000000000 + x25: 0000000056000000 x24: ffff000009073000 + x23: ffff000008998b38 x22: 0000000000000000 + x21: ffff800ed86de820 x20: 0000000000000000 + x19: ffff00000913a1d8 x18: 0000000000000000 + x17: 0000000000000000 x16: 0000000000000000 + x15: 0000000000000000 x14: 5300737265766972 + x13: 643d4d4554535953 x12: 0000000000000030 + x11: 0000000000000030 x10: 0101010101010101 + x9 : ffff800ea06cc3f9 x8 : 0000000000000000 + x7 : 0000000000000141 x6 : ffff000009073000 + x5 : ffff800adb706b00 x4 : 0000000000000000 + x3 : 00000000ffffffff x2 : 0000000000000000 + x1 : ffff000008998b38 x0 : ffff000008356760 + Process rmmod (pid: 30266, stack limit = 0x00000000e218418d) + Call trace: + kernfs_find_ns+0x28/0x120 + kernfs_find_and_get_ns+0x40/0x60 + sysfs_unmerge_group+0x2c/0x6c + dpm_sysfs_remove+0x34/0x70 + device_del+0x58/0x30c + device_unregister+0x30/0x7c + i2c_unregister_device+0x84/0x90 [i2c_core] + ssif_platform_remove+0x38/0x98 [ipmi_ssif] + platform_drv_remove+0x2c/0x6c + device_release_driver_internal+0x168/0x1f8 + driver_detach+0x50/0xbc + bus_remove_driver+0x74/0xe8 + driver_unregister+0x34/0x5c + platform_driver_unregister+0x20/0x2c + cleanup_ipmi_ssif+0x50/0xd82c [ipmi_ssif] + __arm64_sys_delete_module+0x1b4/0x220 + el0_svc_handler+0x104/0x160 + el0_svc+0x8/0xc + Code: aa1e03e0 aa0203f6 aa0103f7 d503201f (7940e280) + ---[ end trace 09f0e34cce8e2d8c ]--- + Kernel panic - not syncing: Fatal exception + SMP: stopping secondary CPUs + Kernel Offset: disabled + CPU features: 0x23800c38 + +So track the clients that the SSIF driver adds and only remove +those. + +Reported-by: George Cherian +Signed-off-by: Corey Minyard +Tested-by: George Cherian +Cc: # 4.14.x +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/ipmi/ipmi_ssif.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +--- a/drivers/char/ipmi/ipmi_ssif.c ++++ b/drivers/char/ipmi/ipmi_ssif.c +@@ -181,6 +181,8 @@ struct ssif_addr_info { + struct device *dev; + struct i2c_client *client; + ++ struct i2c_client *added_client; ++ + struct mutex clients_mutex; + struct list_head clients; + +@@ -1641,15 +1643,7 @@ static int ssif_probe(struct i2c_client + + out: + if (rv) { +- /* +- * Note that if addr_info->client is assigned, we +- * leave it. The i2c client hangs around even if we +- * return a failure here, and the failure here is not +- * propagated back to the i2c code. This seems to be +- * design intent, strange as it may be. But if we +- * don't leave it, ssif_platform_remove will not remove +- * the client like it should. +- */ ++ addr_info->client = NULL; + dev_err(&client->dev, "Unable to start IPMI SSIF: %d\n", rv); + kfree(ssif_info); + } +@@ -1669,7 +1663,8 @@ static int ssif_adapter_handler(struct d + if (adev->type != &i2c_adapter_type) + return 0; + +- i2c_new_device(to_i2c_adapter(adev), &addr_info->binfo); ++ addr_info->added_client = i2c_new_device(to_i2c_adapter(adev), ++ &addr_info->binfo); + + if (!addr_info->adapter_name) + return 1; /* Only try the first I2C adapter by default. */ +@@ -1842,7 +1837,7 @@ static int ssif_platform_remove(struct p + return 0; + + mutex_lock(&ssif_infos_mutex); +- i2c_unregister_device(addr_info->client); ++ i2c_unregister_device(addr_info->added_client); + + list_del(&addr_info->link); + kfree(addr_info); diff --git a/queue-4.18/ipmi-move-bt-capabilities-detection-to-the-detect-call.patch b/queue-4.18/ipmi-move-bt-capabilities-detection-to-the-detect-call.patch new file mode 100644 index 00000000000..65c978bb982 --- /dev/null +++ b/queue-4.18/ipmi-move-bt-capabilities-detection-to-the-detect-call.patch @@ -0,0 +1,185 @@ +From c86ba91be75702c013bbf7379542920b6920e98f Mon Sep 17 00:00:00 2001 +From: Corey Minyard +Date: Thu, 23 Aug 2018 15:22:35 -0500 +Subject: ipmi: Move BT capabilities detection to the detect call + +From: Corey Minyard + +commit c86ba91be75702c013bbf7379542920b6920e98f upstream. + +The capabilities detection was being done as part of the normal +state machine, but it was possible for it to be running while +the upper layers of the IPMI driver were initializing the +device, resulting in error and failure to initialize. + +Move the capabilities detection to the the detect function, +so it's done before anything else runs on the device. This also +simplifies the state machine and removes some code, as a bonus. + +Signed-off-by: Corey Minyard +Reported-by: Andrew Banman +Tested-by: Andrew Banman +Cc: +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/ipmi/ipmi_bt_sm.c | 92 +++++++++++++++++++++-------------------- + 1 file changed, 48 insertions(+), 44 deletions(-) + +--- a/drivers/char/ipmi/ipmi_bt_sm.c ++++ b/drivers/char/ipmi/ipmi_bt_sm.c +@@ -59,8 +59,6 @@ enum bt_states { + BT_STATE_RESET3, + BT_STATE_RESTART, + BT_STATE_PRINTME, +- BT_STATE_CAPABILITIES_BEGIN, +- BT_STATE_CAPABILITIES_END, + BT_STATE_LONG_BUSY /* BT doesn't get hosed :-) */ + }; + +@@ -86,7 +84,6 @@ struct si_sm_data { + int error_retries; /* end of "common" fields */ + int nonzero_status; /* hung BMCs stay all 0 */ + enum bt_states complete; /* to divert the state machine */ +- int BT_CAP_outreqs; + long BT_CAP_req2rsp; + int BT_CAP_retries; /* Recommended retries */ + }; +@@ -137,8 +134,6 @@ static char *state2txt(unsigned char sta + case BT_STATE_RESET3: return("RESET3"); + case BT_STATE_RESTART: return("RESTART"); + case BT_STATE_LONG_BUSY: return("LONG_BUSY"); +- case BT_STATE_CAPABILITIES_BEGIN: return("CAP_BEGIN"); +- case BT_STATE_CAPABILITIES_END: return("CAP_END"); + } + return("BAD STATE"); + } +@@ -185,7 +180,6 @@ static unsigned int bt_init_data(struct + bt->complete = BT_STATE_IDLE; /* end here */ + bt->BT_CAP_req2rsp = BT_NORMAL_TIMEOUT * USEC_PER_SEC; + bt->BT_CAP_retries = BT_NORMAL_RETRY_LIMIT; +- /* BT_CAP_outreqs == zero is a flag to read BT Capabilities */ + return 3; /* We claim 3 bytes of space; ought to check SPMI table */ + } + +@@ -451,7 +445,7 @@ static enum si_sm_result error_recovery( + + static enum si_sm_result bt_event(struct si_sm_data *bt, long time) + { +- unsigned char status, BT_CAP[8]; ++ unsigned char status; + static enum bt_states last_printed = BT_STATE_PRINTME; + int i; + +@@ -504,12 +498,6 @@ static enum si_sm_result bt_event(struct + if (status & BT_H_BUSY) /* clear a leftover H_BUSY */ + BT_CONTROL(BT_H_BUSY); + +- bt->timeout = bt->BT_CAP_req2rsp; +- +- /* Read BT capabilities if it hasn't been done yet */ +- if (!bt->BT_CAP_outreqs) +- BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN, +- SI_SM_CALL_WITHOUT_DELAY); + BT_SI_SM_RETURN(SI_SM_IDLE); + + case BT_STATE_XACTION_START: +@@ -614,37 +602,6 @@ static enum si_sm_result bt_event(struct + BT_STATE_CHANGE(BT_STATE_XACTION_START, + SI_SM_CALL_WITH_DELAY); + +- /* +- * Get BT Capabilities, using timing of upper level state machine. +- * Set outreqs to prevent infinite loop on timeout. +- */ +- case BT_STATE_CAPABILITIES_BEGIN: +- bt->BT_CAP_outreqs = 1; +- { +- unsigned char GetBT_CAP[] = { 0x18, 0x36 }; +- bt->state = BT_STATE_IDLE; +- bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP)); +- } +- bt->complete = BT_STATE_CAPABILITIES_END; +- BT_STATE_CHANGE(BT_STATE_XACTION_START, +- SI_SM_CALL_WITH_DELAY); +- +- case BT_STATE_CAPABILITIES_END: +- i = bt_get_result(bt, BT_CAP, sizeof(BT_CAP)); +- bt_init_data(bt, bt->io); +- if ((i == 8) && !BT_CAP[2]) { +- bt->BT_CAP_outreqs = BT_CAP[3]; +- bt->BT_CAP_req2rsp = BT_CAP[6] * USEC_PER_SEC; +- bt->BT_CAP_retries = BT_CAP[7]; +- } else +- printk(KERN_WARNING "IPMI BT: using default values\n"); +- if (!bt->BT_CAP_outreqs) +- bt->BT_CAP_outreqs = 1; +- printk(KERN_WARNING "IPMI BT: req2rsp=%ld secs retries=%d\n", +- bt->BT_CAP_req2rsp / USEC_PER_SEC, bt->BT_CAP_retries); +- bt->timeout = bt->BT_CAP_req2rsp; +- return SI_SM_CALL_WITHOUT_DELAY; +- + default: /* should never occur */ + return error_recovery(bt, + status, +@@ -655,6 +612,11 @@ static enum si_sm_result bt_event(struct + + static int bt_detect(struct si_sm_data *bt) + { ++ unsigned char GetBT_CAP[] = { 0x18, 0x36 }; ++ unsigned char BT_CAP[8]; ++ enum si_sm_result smi_result; ++ int rv; ++ + /* + * It's impossible for the BT status and interrupt registers to be + * all 1's, (assuming a properly functioning, self-initialized BMC) +@@ -665,6 +627,48 @@ static int bt_detect(struct si_sm_data * + if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF)) + return 1; + reset_flags(bt); ++ ++ /* ++ * Try getting the BT capabilities here. ++ */ ++ rv = bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP)); ++ if (rv) { ++ dev_warn(bt->io->dev, ++ "Can't start capabilities transaction: %d\n", rv); ++ goto out_no_bt_cap; ++ } ++ ++ smi_result = SI_SM_CALL_WITHOUT_DELAY; ++ for (;;) { ++ if (smi_result == SI_SM_CALL_WITH_DELAY || ++ smi_result == SI_SM_CALL_WITH_TICK_DELAY) { ++ schedule_timeout_uninterruptible(1); ++ smi_result = bt_event(bt, jiffies_to_usecs(1)); ++ } else if (smi_result == SI_SM_CALL_WITHOUT_DELAY) { ++ smi_result = bt_event(bt, 0); ++ } else ++ break; ++ } ++ ++ rv = bt_get_result(bt, BT_CAP, sizeof(BT_CAP)); ++ bt_init_data(bt, bt->io); ++ if (rv < 8) { ++ dev_warn(bt->io->dev, "bt cap response too short: %d\n", rv); ++ goto out_no_bt_cap; ++ } ++ ++ if (BT_CAP[2]) { ++ dev_warn(bt->io->dev, "Error fetching bt cap: %x\n", BT_CAP[2]); ++out_no_bt_cap: ++ dev_warn(bt->io->dev, "using default values\n"); ++ } else { ++ bt->BT_CAP_req2rsp = BT_CAP[6] * USEC_PER_SEC; ++ bt->BT_CAP_retries = BT_CAP[7]; ++ } ++ ++ dev_info(bt->io->dev, "req2rsp=%ld secs retries=%d\n", ++ bt->BT_CAP_req2rsp / USEC_PER_SEC, bt->BT_CAP_retries); ++ + return 0; + } + diff --git a/queue-4.18/ipmi-rework-smi-registration-failure.patch b/queue-4.18/ipmi-rework-smi-registration-failure.patch new file mode 100644 index 00000000000..f8c47b911b2 --- /dev/null +++ b/queue-4.18/ipmi-rework-smi-registration-failure.patch @@ -0,0 +1,198 @@ +From 2512e40e48d21d8bac09f7e91d2c3ceb2d3b50b2 Mon Sep 17 00:00:00 2001 +From: Corey Minyard +Date: Wed, 22 Aug 2018 12:08:13 -0500 +Subject: ipmi: Rework SMI registration failure + +From: Corey Minyard + +commit 2512e40e48d21d8bac09f7e91d2c3ceb2d3b50b2 upstream. + +There were certain situations where ipmi_register_smi() would +return a failure, but the interface would still be registered +and would need to be unregistered. This is obviously a bad +design and resulted in an oops in certain failure cases. + +If the interface is started up in ipmi_register_smi(), then +an error occurs, shut down the interface there so the +cleanup can be done properly. + +Fix the various smi users, too. + +Signed-off-by: Corey Minyard +Reported-by: Justin Ernst +Tested-by: Justin Ernst +Cc: Andrew Banman +Cc: Russ Anderson +Cc: # 4.18.x +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/ipmi/ipmi_msghandler.c | 53 ++++++++++++++++++++---------------- + drivers/char/ipmi/ipmi_si_intf.c | 17 ++--------- + drivers/char/ipmi/ipmi_ssif.c | 13 ++------ + 3 files changed, 37 insertions(+), 46 deletions(-) + +--- a/drivers/char/ipmi/ipmi_msghandler.c ++++ b/drivers/char/ipmi/ipmi_msghandler.c +@@ -3381,39 +3381,45 @@ int ipmi_register_smi(const struct ipmi_ + + rv = handlers->start_processing(send_info, intf); + if (rv) +- goto out; ++ goto out_err; + + rv = __bmc_get_device_id(intf, NULL, &id, NULL, NULL, i); + if (rv) { + dev_err(si_dev, "Unable to get the device id: %d\n", rv); +- goto out; ++ goto out_err_started; + } + + mutex_lock(&intf->bmc_reg_mutex); + rv = __scan_channels(intf, &id); + mutex_unlock(&intf->bmc_reg_mutex); ++ if (rv) ++ goto out_err_bmc_reg; + +- out: +- if (rv) { +- ipmi_bmc_unregister(intf); +- list_del_rcu(&intf->link); +- mutex_unlock(&ipmi_interfaces_mutex); +- synchronize_srcu(&ipmi_interfaces_srcu); +- cleanup_srcu_struct(&intf->users_srcu); +- kref_put(&intf->refcount, intf_free); +- } else { +- /* +- * Keep memory order straight for RCU readers. Make +- * sure everything else is committed to memory before +- * setting intf_num to mark the interface valid. +- */ +- smp_wmb(); +- intf->intf_num = i; +- mutex_unlock(&ipmi_interfaces_mutex); ++ /* ++ * Keep memory order straight for RCU readers. Make ++ * sure everything else is committed to memory before ++ * setting intf_num to mark the interface valid. ++ */ ++ smp_wmb(); ++ intf->intf_num = i; ++ mutex_unlock(&ipmi_interfaces_mutex); + +- /* After this point the interface is legal to use. */ +- call_smi_watchers(i, intf->si_dev); +- } ++ /* After this point the interface is legal to use. */ ++ call_smi_watchers(i, intf->si_dev); ++ ++ return 0; ++ ++ out_err_bmc_reg: ++ ipmi_bmc_unregister(intf); ++ out_err_started: ++ if (intf->handlers->shutdown) ++ intf->handlers->shutdown(intf->send_info); ++ out_err: ++ list_del_rcu(&intf->link); ++ mutex_unlock(&ipmi_interfaces_mutex); ++ synchronize_srcu(&ipmi_interfaces_srcu); ++ cleanup_srcu_struct(&intf->users_srcu); ++ kref_put(&intf->refcount, intf_free); + + return rv; + } +@@ -3504,7 +3510,8 @@ void ipmi_unregister_smi(struct ipmi_smi + } + srcu_read_unlock(&intf->users_srcu, index); + +- intf->handlers->shutdown(intf->send_info); ++ if (intf->handlers->shutdown) ++ intf->handlers->shutdown(intf->send_info); + + cleanup_smi_msgs(intf); + +--- a/drivers/char/ipmi/ipmi_si_intf.c ++++ b/drivers/char/ipmi/ipmi_si_intf.c +@@ -2083,18 +2083,9 @@ static int try_smi_init(struct smi_info + si_to_str[new_smi->io.si_type]); + + WARN_ON(new_smi->io.dev->init_name != NULL); +- kfree(init_name); +- +- return 0; +- +-out_err: +- if (new_smi->intf) { +- ipmi_unregister_smi(new_smi->intf); +- new_smi->intf = NULL; +- } + ++ out_err: + kfree(init_name); +- + return rv; + } + +@@ -2227,6 +2218,8 @@ static void shutdown_smi(void *send_info + + kfree(smi_info->si_sm); + smi_info->si_sm = NULL; ++ ++ smi_info->intf = NULL; + } + + /* +@@ -2240,10 +2233,8 @@ static void cleanup_one_si(struct smi_in + + list_del(&smi_info->link); + +- if (smi_info->intf) { ++ if (smi_info->intf) + ipmi_unregister_smi(smi_info->intf); +- smi_info->intf = NULL; +- } + + if (smi_info->pdev) { + if (smi_info->pdev_registered) +--- a/drivers/char/ipmi/ipmi_ssif.c ++++ b/drivers/char/ipmi/ipmi_ssif.c +@@ -1214,18 +1214,11 @@ static void shutdown_ssif(void *send_inf + complete(&ssif_info->wake_thread); + kthread_stop(ssif_info->thread); + } +- +- /* +- * No message can be outstanding now, we have removed the +- * upper layer and it permitted us to do so. +- */ +- kfree(ssif_info); + } + + static int ssif_remove(struct i2c_client *client) + { + struct ssif_info *ssif_info = i2c_get_clientdata(client); +- struct ipmi_smi *intf; + struct ssif_addr_info *addr_info; + + if (!ssif_info) +@@ -1235,9 +1228,7 @@ static int ssif_remove(struct i2c_client + * After this point, we won't deliver anything asychronously + * to the message handler. We can unregister ourself. + */ +- intf = ssif_info->intf; +- ssif_info->intf = NULL; +- ipmi_unregister_smi(intf); ++ ipmi_unregister_smi(ssif_info->intf); + + list_for_each_entry(addr_info, &ssif_infos, link) { + if (addr_info->client == client) { +@@ -1246,6 +1237,8 @@ static int ssif_remove(struct i2c_client + } + } + ++ kfree(ssif_info); ++ + return 0; + } + diff --git a/queue-4.18/mei-bus-fix-hw-module-get-put-balance.patch b/queue-4.18/mei-bus-fix-hw-module-get-put-balance.patch new file mode 100644 index 00000000000..7716499b717 --- /dev/null +++ b/queue-4.18/mei-bus-fix-hw-module-get-put-balance.patch @@ -0,0 +1,39 @@ +From 69bf5313035926b0b6a6578de4f3168a8f5c19b8 Mon Sep 17 00:00:00 2001 +From: Tomas Winkler +Date: Mon, 27 Aug 2018 22:40:15 +0300 +Subject: mei: bus: fix hw module get/put balance +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Tomas Winkler + +commit 69bf5313035926b0b6a6578de4f3168a8f5c19b8 upstream. + +In case the device is not connected it doesn't 'get' +hw module and hence should not 'put' it on disable. + +Cc: 4.16+ +Fixes:'commit 257355a44b99 ("mei: make module referencing local to the bus.c")' +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200455 +Tested-by: Georg Müller +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/bus.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/misc/mei/bus.c ++++ b/drivers/misc/mei/bus.c +@@ -600,9 +600,8 @@ int mei_cldev_disable(struct mei_cl_devi + if (err < 0) + dev_err(bus->dev, "Could not disconnect from the ME client\n"); + +-out: + mei_cl_bus_module_put(cldev); +- ++out: + /* Flush queues and remove any pending read */ + mei_cl_flush_queues(cl, NULL); + mei_cl_unlink(cl); diff --git a/queue-4.18/mei-bus-need-to-unlink-client-before-freeing.patch b/queue-4.18/mei-bus-need-to-unlink-client-before-freeing.patch new file mode 100644 index 00000000000..abcc90101cd --- /dev/null +++ b/queue-4.18/mei-bus-need-to-unlink-client-before-freeing.patch @@ -0,0 +1,79 @@ +From 34f1166afd67f9f48a08c52f36180048908506a4 Mon Sep 17 00:00:00 2001 +From: Tomas Winkler +Date: Mon, 27 Aug 2018 22:40:16 +0300 +Subject: mei: bus: need to unlink client before freeing +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Tomas Winkler + +commit 34f1166afd67f9f48a08c52f36180048908506a4 upstream. + +In case a client fails to connect in mei_cldev_enable(), the +caller won't call the mei_cldev_disable leaving the client +in a linked stated. Upon driver unload the client structure +will be freed in mei_cl_bus_dev_release(), leaving a stale pointer +on a fail_list. This will eventually end up in crash +during power down flow in mei_cl_set_disonnected(). + +RIP: mei_cl_set_disconnected+0x5/0x260[mei] +Call trace: +mei_cl_all_disconnect+0x22/0x30 +mei_reset+0x194/0x250 +__synchronize_hardirq+0x43/0x50 +_cond_resched+0x15/0x30 +mei_me_intr_clear+0x20/0x100 +mei_stop+0x76/0xb0 +mei_me_shutdown+0x3f/0x80 +pci_device_shutdown+0x34/0x60 +kernel_restart+0x0e/0x30 + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200455 +Fixes: 'c110cdb17148 ("mei: bus: make a client pointer always available")' +Cc: 4.10+ +Tested-by: Georg Müller +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/bus.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/drivers/misc/mei/bus.c ++++ b/drivers/misc/mei/bus.c +@@ -505,17 +505,15 @@ int mei_cldev_enable(struct mei_cl_devic + + cl = cldev->cl; + ++ mutex_lock(&bus->device_lock); + if (cl->state == MEI_FILE_UNINITIALIZED) { +- mutex_lock(&bus->device_lock); + ret = mei_cl_link(cl); +- mutex_unlock(&bus->device_lock); + if (ret) +- return ret; ++ goto out; + /* update pointers */ + cl->cldev = cldev; + } + +- mutex_lock(&bus->device_lock); + if (mei_cl_is_connected(cl)) { + ret = 0; + goto out; +@@ -859,12 +857,13 @@ static void mei_cl_bus_dev_release(struc + + mei_me_cl_put(cldev->me_cl); + mei_dev_bus_put(cldev->bus); ++ mei_cl_unlink(cldev->cl); + kfree(cldev->cl); + kfree(cldev); + } + + static const struct device_type mei_cl_device_type = { +- .release = mei_cl_bus_dev_release, ++ .release = mei_cl_bus_dev_release, + }; + + /** diff --git a/queue-4.18/mei-ignore-not-found-client-in-the-enumeration.patch b/queue-4.18/mei-ignore-not-found-client-in-the-enumeration.patch new file mode 100644 index 00000000000..3b57bff1915 --- /dev/null +++ b/queue-4.18/mei-ignore-not-found-client-in-the-enumeration.patch @@ -0,0 +1,58 @@ +From 8d2d8935d30cc2acc57a3196dc10dfa8d5cbcdab Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Mon, 6 Aug 2018 17:47:33 +0300 +Subject: mei: ignore not found client in the enumeration + +From: Alexander Usyskin + +commit 8d2d8935d30cc2acc57a3196dc10dfa8d5cbcdab upstream. + +Some of the ME clients are available only for BIOS operation and are +removed during hand off to an OS. However the removal is not instant. +A client may be visible on the client list when the mei driver requests +for enumeration, while the subsequent request for properties will be +answered with client not found error value. The default behavior +for an error is to perform client reset while this error is harmless and +the link reset should be prevented. This issue started to be visible due to +suspend/resume timing changes. Currently reported only on the Haswell +based system. + +Fixes: +[33.564957] mei_me 0000:00:16.0: hbm: properties response: wrong status = 1 CLIENT_NOT_FOUND +[33.564978] mei_me 0000:00:16.0: mei_irq_read_handler ret = -71. +[33.565270] mei_me 0000:00:16.0: unexpected reset: dev_state = INIT_CLIENTS fw status = 1E000255 60002306 00000200 00004401 00000000 00000010 + +Cc: +Reported-by: Heiner Kallweit +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/hbm.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/misc/mei/hbm.c ++++ b/drivers/misc/mei/hbm.c +@@ -1140,15 +1140,18 @@ int mei_hbm_dispatch(struct mei_device * + + props_res = (struct hbm_props_response *)mei_msg; + +- if (props_res->status) { ++ if (props_res->status == MEI_HBMS_CLIENT_NOT_FOUND) { ++ dev_dbg(dev->dev, "hbm: properties response: %d CLIENT_NOT_FOUND\n", ++ props_res->me_addr); ++ } else if (props_res->status) { + dev_err(dev->dev, "hbm: properties response: wrong status = %d %s\n", + props_res->status, + mei_hbm_status_str(props_res->status)); + return -EPROTO; ++ } else { ++ mei_hbm_me_cl_add(dev, props_res); + } + +- mei_hbm_me_cl_add(dev, props_res); +- + /* request property for the next client */ + if (mei_hbm_prop_req(dev, props_res->me_addr + 1)) + return -EIO; diff --git a/queue-4.18/misc-hmc6352-fix-potential-spectre-v1.patch b/queue-4.18/misc-hmc6352-fix-potential-spectre-v1.patch new file mode 100644 index 00000000000..b1029f96f5c --- /dev/null +++ b/queue-4.18/misc-hmc6352-fix-potential-spectre-v1.patch @@ -0,0 +1,51 @@ +From de916736aaaadddbd6061472969f667b14204aa9 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Wed, 15 Aug 2018 10:50:41 -0500 +Subject: misc: hmc6352: fix potential Spectre v1 + +From: Gustavo A. R. Silva + +commit de916736aaaadddbd6061472969f667b14204aa9 upstream. + +val is indirectly controlled by user-space, hence leading to a +potential exploitation of the Spectre variant 1 vulnerability. + +This issue was detected with the help of Smatch: + +drivers/misc/hmc6352.c:54 compass_store() warn: potential spectre issue +'map' [r] + +Fix this by sanitizing val before using it to index map + +Notice that given that speculation windows are large, the policy is +to kill the speculation on the first load and not worry if it can be +completed with a dependent load/store [1]. + +[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2 + +Cc: stable@vger.kernel.org +Signed-off-by: Gustavo A. R. Silva +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/hmc6352.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/misc/hmc6352.c ++++ b/drivers/misc/hmc6352.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + static DEFINE_MUTEX(compass_mutex); + +@@ -50,6 +51,7 @@ static int compass_store(struct device * + return ret; + if (val >= strlen(map)) + return -EINVAL; ++ val = array_index_nospec(val, strlen(map)); + mutex_lock(&compass_mutex); + ret = compass_command(c, map[val]); + mutex_unlock(&compass_mutex); diff --git a/queue-4.18/misc-ibmvsm-fix-wrong-assignment-of-return-code.patch b/queue-4.18/misc-ibmvsm-fix-wrong-assignment-of-return-code.patch new file mode 100644 index 00000000000..0246307667f --- /dev/null +++ b/queue-4.18/misc-ibmvsm-fix-wrong-assignment-of-return-code.patch @@ -0,0 +1,32 @@ +From c55e9318871cd06e4aa10f5023cc2dcdfbb08577 Mon Sep 17 00:00:00 2001 +From: "Bryant G. Ly" +Date: Mon, 6 Aug 2018 08:31:00 -0500 +Subject: misc: ibmvsm: Fix wrong assignment of return code + +From: Bryant G. Ly + +commit c55e9318871cd06e4aa10f5023cc2dcdfbb08577 upstream. + +Currently the assignment is flipped and rc is always 0. + +Signed-off-by: Bryant G. Ly +Fixes: 0eca353e7ae7 ("misc: IBM Virtual Management Channel Driver (VMC)") +Reviewed-by: Bradley Warrum +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/ibmvmc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/misc/ibmvmc.c ++++ b/drivers/misc/ibmvmc.c +@@ -2131,7 +2131,7 @@ static int ibmvmc_init_crq_queue(struct + retrc = plpar_hcall_norets(H_REG_CRQ, + vdev->unit_address, + queue->msg_token, PAGE_SIZE); +- retrc = rc; ++ rc = retrc; + + if (rc == H_RESOURCE) + rc = ibmvmc_reset_crq_queue(adapter); diff --git a/queue-4.18/mmc-meson-mx-sdio-fix-of-child-node-lookup.patch b/queue-4.18/mmc-meson-mx-sdio-fix-of-child-node-lookup.patch new file mode 100644 index 00000000000..f4c41d209fb --- /dev/null +++ b/queue-4.18/mmc-meson-mx-sdio-fix-of-child-node-lookup.patch @@ -0,0 +1,62 @@ +From c483a5cc9d09f4ceaa9abb106f863cc89cb643d9 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 27 Aug 2018 10:21:48 +0200 +Subject: mmc: meson-mx-sdio: fix OF child-node lookup + +From: Johan Hovold + +commit c483a5cc9d09f4ceaa9abb106f863cc89cb643d9 upstream. + +Use the new of_get_compatible_child() helper to lookup the slot child +node instead of using of_find_compatible_node(), which searches the +entire tree from a given start node and thus can return an unrelated +(i.e. non-child) node. + +This also addresses a potential use-after-free (e.g. after probe +deferral) as the tree-wide helper drops a reference to its first +argument (i.e. the node of the device being probed). + +While at it, also fix up the related slot-node reference leak. + +Fixes: ed80a13bb4c4 ("mmc: meson-mx-sdio: Add a driver for the Amlogic Meson8 and Meson8b SoCs") +Cc: stable # 4.15 +Cc: Carlo Caione +Cc: Martin Blumenstingl +Cc: Ulf Hansson +Acked-by: Martin Blumenstingl +Signed-off-by: Johan Hovold +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/meson-mx-sdio.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/mmc/host/meson-mx-sdio.c ++++ b/drivers/mmc/host/meson-mx-sdio.c +@@ -517,19 +517,23 @@ static struct mmc_host_ops meson_mx_mmc_ + static struct platform_device *meson_mx_mmc_slot_pdev(struct device *parent) + { + struct device_node *slot_node; ++ struct platform_device *pdev; + + /* + * TODO: the MMC core framework currently does not support + * controllers with multiple slots properly. So we only register + * the first slot for now + */ +- slot_node = of_find_compatible_node(parent->of_node, NULL, "mmc-slot"); ++ slot_node = of_get_compatible_child(parent->of_node, "mmc-slot"); + if (!slot_node) { + dev_warn(parent, "no 'mmc-slot' sub-node found\n"); + return ERR_PTR(-ENOENT); + } + +- return of_platform_device_create(slot_node, NULL, parent); ++ pdev = of_platform_device_create(slot_node, NULL, parent); ++ of_node_put(slot_node); ++ ++ return pdev; + } + + static int meson_mx_mmc_add_host(struct meson_mx_mmc_host *host) diff --git a/queue-4.18/mmc-omap_hsmmc-fix-wakeirq-handling-on-removal.patch b/queue-4.18/mmc-omap_hsmmc-fix-wakeirq-handling-on-removal.patch new file mode 100644 index 00000000000..30e8cc4dfa4 --- /dev/null +++ b/queue-4.18/mmc-omap_hsmmc-fix-wakeirq-handling-on-removal.patch @@ -0,0 +1,45 @@ +From 3c398f3c3bef21961eaaeb93227fa66d440dc83d Mon Sep 17 00:00:00 2001 +From: Andreas Kemnade +Date: Sun, 2 Sep 2018 09:30:58 +0200 +Subject: mmc: omap_hsmmc: fix wakeirq handling on removal + +From: Andreas Kemnade + +commit 3c398f3c3bef21961eaaeb93227fa66d440dc83d upstream. + +after unbinding mmc I get things like this: +[ 185.294067] mmc1: card 0001 removed +[ 185.305206] omap_hsmmc 480b4000.mmc: wake IRQ with no resume: -13 + +The wakeirq stays in /proc-interrupts + +rebinding shows this: +[ 289.795959] genirq: Flags mismatch irq 112. 0000200a (480b4000.mmc:wakeup) vs. 0000200a (480b4000.mmc:wakeup) +[ 289.808959] omap_hsmmc 480b4000.mmc: Unable to request wake IRQ +[ 289.815338] omap_hsmmc 480b4000.mmc: no SDIO IRQ support, falling back to polling + +That bug seems to be introduced by switching from devm_request_irq() +to generic wakeirq handling. + +So let us cleanup at removal. + +Signed-off-by: Andreas Kemnade +Fixes: 5b83b2234be6 ("mmc: omap_hsmmc: Change wake-up interrupt to use generic wakeirq") +Cc: stable@vger.kernel.org # v4.2+ +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/omap_hsmmc.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/mmc/host/omap_hsmmc.c ++++ b/drivers/mmc/host/omap_hsmmc.c +@@ -2177,6 +2177,7 @@ static int omap_hsmmc_remove(struct plat + dma_release_channel(host->tx_chan); + dma_release_channel(host->rx_chan); + ++ dev_pm_clear_wake_irq(host->dev); + pm_runtime_dont_use_autosuspend(host->dev); + pm_runtime_put_sync(host->dev); + pm_runtime_disable(host->dev); diff --git a/queue-4.18/nfsv4-fix-a-tracepoint-oops-in-initiate_file_draining.patch b/queue-4.18/nfsv4-fix-a-tracepoint-oops-in-initiate_file_draining.patch new file mode 100644 index 00000000000..fe1c7240f4d --- /dev/null +++ b/queue-4.18/nfsv4-fix-a-tracepoint-oops-in-initiate_file_draining.patch @@ -0,0 +1,33 @@ +From 2a534a7473bf4e7f1c12805113f80c795fc8e89a Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Thu, 23 Aug 2018 11:02:49 -0400 +Subject: NFSv4: Fix a tracepoint Oops in initiate_file_draining() + +From: Trond Myklebust + +commit 2a534a7473bf4e7f1c12805113f80c795fc8e89a upstream. + +Now that the value of 'ino' can be NULL or an ERR_PTR(), we need to +change the test in the tracepoint. + +Fixes: ce5624f7e6675 ("NFSv4: Return NFS4ERR_DELAY when a layout fails...") +Signed-off-by: Trond Myklebust +Cc: stable@vger.kernel.org # v4.17+ +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4trace.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/nfs4trace.h ++++ b/fs/nfs/nfs4trace.h +@@ -1194,7 +1194,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_stateid_c + TP_fast_assign( + __entry->error = error; + __entry->fhandle = nfs_fhandle_hash(fhandle); +- if (inode != NULL) { ++ if (!IS_ERR_OR_NULL(inode)) { + __entry->fileid = NFS_FILEID(inode); + __entry->dev = inode->i_sb->s_dev; + } else { diff --git a/queue-4.18/nfsv4.1-fix-infinite-loop-on-i-o.patch b/queue-4.18/nfsv4.1-fix-infinite-loop-on-i-o.patch new file mode 100644 index 00000000000..e61dc398508 --- /dev/null +++ b/queue-4.18/nfsv4.1-fix-infinite-loop-on-i-o.patch @@ -0,0 +1,69 @@ +From 994b15b983a72e1148a173b61e5b279219bb45ae Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Wed, 5 Sep 2018 14:07:14 -0400 +Subject: NFSv4.1 fix infinite loop on I/O. + +From: Trond Myklebust + +commit 994b15b983a72e1148a173b61e5b279219bb45ae upstream. + +The previous fix broke recovery of delegated stateids because it assumes +that if we did not mark the delegation as suspect, then the delegation has +effectively been revoked, and so it removes that delegation irrespectively +of whether or not it is valid and still in use. While this is "mostly +harmless" for ordinary I/O, we've seen pNFS fail with LAYOUTGET spinning +in an infinite loop while complaining that we're using an invalid stateid +(in this case the all-zero stateid). + +What we rather want to do here is ensure that the delegation is always +correctly marked as needing testing when that is the case. So we want +to close the loophole offered by nfs4_schedule_stateid_recovery(), +which marks the state as needing to be reclaimed, but not the +delegation that may be backing it. + +Fixes: 0e3d3e5df07dc ("NFSv4.1 fix infinite loop on IO BAD_STATEID error") +Signed-off-by: Trond Myklebust +Cc: stable@vger.kernel.org # v4.11+ +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4proc.c | 10 +++++++--- + fs/nfs/nfs4state.c | 2 ++ + 2 files changed, 9 insertions(+), 3 deletions(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -2642,14 +2642,18 @@ static void nfs41_check_delegation_state + } + + nfs4_stateid_copy(&stateid, &delegation->stateid); +- if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) || +- !test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED, +- &delegation->flags)) { ++ if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) { + rcu_read_unlock(); + nfs_finish_clear_delegation_stateid(state, &stateid); + return; + } + ++ if (!test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED, ++ &delegation->flags)) { ++ rcu_read_unlock(); ++ return; ++ } ++ + cred = get_rpccred(delegation->cred); + rcu_read_unlock(); + status = nfs41_test_and_free_expired_stateid(server, &stateid, cred); +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -1390,6 +1390,8 @@ int nfs4_schedule_stateid_recovery(const + + if (!nfs4_state_mark_reclaim_nograce(clp, state)) + return -EBADF; ++ nfs_inode_find_delegation_state_and_recover(state->inode, ++ &state->stateid); + dprintk("%s: scheduling stateid recovery for server %s\n", __func__, + clp->cl_hostname); + nfs4_schedule_state_manager(clp); diff --git a/queue-4.18/of-fix-phandle-cache-creation-for-dts-with-no-phandles.patch b/queue-4.18/of-fix-phandle-cache-creation-for-dts-with-no-phandles.patch new file mode 100644 index 00000000000..ab7bbad712e --- /dev/null +++ b/queue-4.18/of-fix-phandle-cache-creation-for-dts-with-no-phandles.patch @@ -0,0 +1,42 @@ +From e54192b48da75f025ae4b277925eaf6aca1d13bd Mon Sep 17 00:00:00 2001 +From: Rob Herring +Date: Tue, 11 Sep 2018 09:28:14 -0500 +Subject: of: fix phandle cache creation for DTs with no phandles + +From: Rob Herring + +commit e54192b48da75f025ae4b277925eaf6aca1d13bd upstream. + +With commit 0b3ce78e90fc ("of: cache phandle nodes to reduce cost of +of_find_node_by_phandle()"), a G3 PowerMac fails to boot. The root cause +is the DT for this system has no phandle properties when booted with +BootX. of_populate_phandle_cache() does not handle the case of no +phandles correctly. The problem is roundup_pow_of_two() for 0 is +undefined. The implementation subtracts 1 underflowing and then things +are in the weeds. + +Fixes: 0b3ce78e90fc ("of: cache phandle nodes to reduce cost of of_find_node_by_phandle()") +Cc: stable@vger.kernel.org # 4.17+ +Reported-by: Finn Thain +Tested-by: Stan Johnson +Reviewed-by: Frank Rowand +Cc: Benjamin Herrenschmidt +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/of/base.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -118,6 +118,9 @@ void of_populate_phandle_cache(void) + if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL) + phandles++; + ++ if (!phandles) ++ goto out; ++ + cache_entries = roundup_pow_of_two(phandles); + phandle_cache_mask = cache_entries - 1; + diff --git a/queue-4.18/ovl-fix-oopses-in-ovl_fill_super-failure-paths.patch b/queue-4.18/ovl-fix-oopses-in-ovl_fill_super-failure-paths.patch new file mode 100644 index 00000000000..3d1d65e4c51 --- /dev/null +++ b/queue-4.18/ovl-fix-oopses-in-ovl_fill_super-failure-paths.patch @@ -0,0 +1,82 @@ +From 8c25741aaad8be6fbe51510e917c740e0059cf83 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Mon, 10 Sep 2018 11:43:29 +0200 +Subject: ovl: fix oopses in ovl_fill_super() failure paths + +From: Miklos Szeredi + +commit 8c25741aaad8be6fbe51510e917c740e0059cf83 upstream. + +ovl_free_fs() dereferences ofs->workbasedir and ofs->upper_mnt in cases when +those might not have been initialized yet. + +Fix the initialization order for these fields. + +Reported-by: syzbot+c75f181dc8429d2eb887@syzkaller.appspotmail.com +Signed-off-by: Miklos Szeredi +Cc: # v4.15 +Fixes: 95e6d4177cb7 ("ovl: grab reference to workbasedir early") +Fixes: a9075cdb467d ("ovl: factor out ovl_free_fs() helper") +Signed-off-by: Greg Kroah-Hartman + +--- + fs/overlayfs/super.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -970,16 +970,6 @@ static int ovl_get_upper(struct ovl_fs * + if (err) + goto out; + +- err = -EBUSY; +- if (ovl_inuse_trylock(upperpath->dentry)) { +- ofs->upperdir_locked = true; +- } else if (ofs->config.index) { +- pr_err("overlayfs: upperdir is in-use by another mount, mount with '-o index=off' to override exclusive upperdir protection.\n"); +- goto out; +- } else { +- pr_warn("overlayfs: upperdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n"); +- } +- + upper_mnt = clone_private_mount(upperpath); + err = PTR_ERR(upper_mnt); + if (IS_ERR(upper_mnt)) { +@@ -990,6 +980,17 @@ static int ovl_get_upper(struct ovl_fs * + /* Don't inherit atime flags */ + upper_mnt->mnt_flags &= ~(MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME); + ofs->upper_mnt = upper_mnt; ++ ++ err = -EBUSY; ++ if (ovl_inuse_trylock(ofs->upper_mnt->mnt_root)) { ++ ofs->upperdir_locked = true; ++ } else if (ofs->config.index) { ++ pr_err("overlayfs: upperdir is in-use by another mount, mount with '-o index=off' to override exclusive upperdir protection.\n"); ++ goto out; ++ } else { ++ pr_warn("overlayfs: upperdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n"); ++ } ++ + err = 0; + out: + return err; +@@ -1089,8 +1090,10 @@ static int ovl_get_workdir(struct ovl_fs + goto out; + } + ++ ofs->workbasedir = dget(workpath.dentry); ++ + err = -EBUSY; +- if (ovl_inuse_trylock(workpath.dentry)) { ++ if (ovl_inuse_trylock(ofs->workbasedir)) { + ofs->workdir_locked = true; + } else if (ofs->config.index) { + pr_err("overlayfs: workdir is in-use by another mount, mount with '-o index=off' to override exclusive workdir protection.\n"); +@@ -1099,7 +1102,6 @@ static int ovl_get_workdir(struct ovl_fs + pr_warn("overlayfs: workdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n"); + } + +- ofs->workbasedir = dget(workpath.dentry); + err = ovl_make_workdir(ofs, &workpath); + if (err) + goto out; diff --git a/queue-4.18/perf-core-force-user_ds-when-recording-user-stack-data.patch b/queue-4.18/perf-core-force-user_ds-when-recording-user-stack-data.patch new file mode 100644 index 00000000000..2b0a6241766 --- /dev/null +++ b/queue-4.18/perf-core-force-user_ds-when-recording-user-stack-data.patch @@ -0,0 +1,58 @@ +From 02e184476eff848273826c1d6617bb37e5bcc7ad Mon Sep 17 00:00:00 2001 +From: Yabin Cui +Date: Thu, 23 Aug 2018 15:59:35 -0700 +Subject: perf/core: Force USER_DS when recording user stack data + +From: Yabin Cui + +commit 02e184476eff848273826c1d6617bb37e5bcc7ad upstream. + +Perf can record user stack data in response to a synchronous request, such +as a tracepoint firing. If this happens under set_fs(KERNEL_DS), then we +end up reading user stack data using __copy_from_user_inatomic() under +set_fs(KERNEL_DS). I think this conflicts with the intention of using +set_fs(KERNEL_DS). And it is explicitly forbidden by hardware on ARM64 +when both CONFIG_ARM64_UAO and CONFIG_ARM64_PAN are used. + +So fix this by forcing USER_DS when recording user stack data. + +Signed-off-by: Yabin Cui +Acked-by: Peter Zijlstra (Intel) +Cc: +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Fixes: 88b0193d9418 ("perf/callchain: Force USER_DS when invoking perf_callchain_user()") +Link: http://lkml.kernel.org/r/20180823225935.27035-1-yabinc@google.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/events/core.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -5948,6 +5948,7 @@ perf_output_sample_ustack(struct perf_ou + unsigned long sp; + unsigned int rem; + u64 dyn_size; ++ mm_segment_t fs; + + /* + * We dump: +@@ -5965,7 +5966,10 @@ perf_output_sample_ustack(struct perf_ou + + /* Data. */ + sp = perf_user_stack_pointer(regs); ++ fs = get_fs(); ++ set_fs(USER_DS); + rem = __output_copy_user(handle, (void *) sp, dump_size); ++ set_fs(fs); + dyn_size = dump_size - rem; + + perf_output_skip(handle, rem); diff --git a/queue-4.18/perf-tools-fix-maps__find_symbol_by_name.patch b/queue-4.18/perf-tools-fix-maps__find_symbol_by_name.patch new file mode 100644 index 00000000000..b1fe1ec5e04 --- /dev/null +++ b/queue-4.18/perf-tools-fix-maps__find_symbol_by_name.patch @@ -0,0 +1,67 @@ +From 03db8b583d1c3c84963e08e2abf6c79081da5c31 Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Fri, 7 Sep 2018 11:51:16 +0300 +Subject: perf tools: Fix maps__find_symbol_by_name() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Adrian Hunter + +commit 03db8b583d1c3c84963e08e2abf6c79081da5c31 upstream. + +Commit 1c5aae7710bb ("perf machine: Create maps for x86 PTI entry +trampolines") revealed a problem with maps__find_symbol_by_name() that +resulted in probes not being found e.g. + + $ sudo perf probe xsk_mmap + xsk_mmap is out of .text, skip it. + Probe point 'xsk_mmap' not found. + Error: Failed to add events. + +maps__find_symbol_by_name() can optionally return the map of the found +symbol. It can get the map wrong because, in fact, the symbol is found +on the map's dso, not allowing for the possibility that the dso has more +than one map. Fix by always checking the map contains the symbol. + +Reported-by: Björn Töpel +Signed-off-by: Adrian Hunter +Tested-by: Björn Töpel +Cc: Jiri Olsa +Cc: stable@vger.kernel.org +Fixes: 1c5aae7710bb ("perf machine: Create maps for x86 PTI entry trampolines") +Link: http://lkml.kernel.org/r/20180907085116.25782-1-adrian.hunter@intel.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/util/map.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/tools/perf/util/map.c ++++ b/tools/perf/util/map.c +@@ -590,6 +590,13 @@ struct symbol *map_groups__find_symbol(s + return NULL; + } + ++static bool map__contains_symbol(struct map *map, struct symbol *sym) ++{ ++ u64 ip = map->unmap_ip(map, sym->start); ++ ++ return ip >= map->start && ip < map->end; ++} ++ + struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, + struct map **mapp) + { +@@ -605,6 +612,10 @@ struct symbol *maps__find_symbol_by_name + + if (sym == NULL) + continue; ++ if (!map__contains_symbol(pos, sym)) { ++ sym = NULL; ++ continue; ++ } + if (mapp != NULL) + *mapp = pos; + goto out; diff --git a/queue-4.18/pstore-fix-incorrect-persistent-ram-buffer-mapping.patch b/queue-4.18/pstore-fix-incorrect-persistent-ram-buffer-mapping.patch new file mode 100644 index 00000000000..02de35a6fc5 --- /dev/null +++ b/queue-4.18/pstore-fix-incorrect-persistent-ram-buffer-mapping.patch @@ -0,0 +1,105 @@ +From 831b624df1b420c8f9281ed1307a8db23afb72df Mon Sep 17 00:00:00 2001 +From: Bin Yang +Date: Wed, 12 Sep 2018 03:36:34 +0000 +Subject: pstore: Fix incorrect persistent ram buffer mapping + +From: Bin Yang + +commit 831b624df1b420c8f9281ed1307a8db23afb72df upstream. + +persistent_ram_vmap() returns the page start vaddr. +persistent_ram_iomap() supports non-page-aligned mapping. + +persistent_ram_buffer_map() always adds offset-in-page to the vaddr +returned from these two functions, which causes incorrect mapping of +non-page-aligned persistent ram buffer. + +By default ftrace_size is 4096 and max_ftrace_cnt is nr_cpu_ids. Without +this patch, the zone_sz in ramoops_init_przs() is 4096/nr_cpu_ids which +might not be page aligned. If the offset-in-page > 2048, the vaddr will be +in next page. If the next page is not mapped, it will cause kernel panic: + +[ 0.074231] BUG: unable to handle kernel paging request at ffffa19e0081b000 +... +[ 0.075000] RIP: 0010:persistent_ram_new+0x1f8/0x39f +... +[ 0.075000] Call Trace: +[ 0.075000] ramoops_init_przs.part.10.constprop.15+0x105/0x260 +[ 0.075000] ramoops_probe+0x232/0x3a0 +[ 0.075000] platform_drv_probe+0x3e/0xa0 +[ 0.075000] driver_probe_device+0x2cd/0x400 +[ 0.075000] __driver_attach+0xe4/0x110 +[ 0.075000] ? driver_probe_device+0x400/0x400 +[ 0.075000] bus_for_each_dev+0x70/0xa0 +[ 0.075000] driver_attach+0x1e/0x20 +[ 0.075000] bus_add_driver+0x159/0x230 +[ 0.075000] ? do_early_param+0x95/0x95 +[ 0.075000] driver_register+0x70/0xc0 +[ 0.075000] ? init_pstore_fs+0x4d/0x4d +[ 0.075000] __platform_driver_register+0x36/0x40 +[ 0.075000] ramoops_init+0x12f/0x131 +[ 0.075000] do_one_initcall+0x4d/0x12c +[ 0.075000] ? do_early_param+0x95/0x95 +[ 0.075000] kernel_init_freeable+0x19b/0x222 +[ 0.075000] ? rest_init+0xbb/0xbb +[ 0.075000] kernel_init+0xe/0xfc +[ 0.075000] ret_from_fork+0x3a/0x50 + +Signed-off-by: Bin Yang +[kees: add comments describing the mapping differences, updated commit log] +Fixes: 24c3d2f342ed ("staging: android: persistent_ram: Make it possible to use memory outside of bootmem") +Cc: stable@vger.kernel.org +Signed-off-by: Kees Cook +Signed-off-by: Greg Kroah-Hartman + +--- + fs/pstore/ram_core.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +--- a/fs/pstore/ram_core.c ++++ b/fs/pstore/ram_core.c +@@ -429,7 +429,12 @@ static void *persistent_ram_vmap(phys_ad + vaddr = vmap(pages, page_count, VM_MAP, prot); + kfree(pages); + +- return vaddr; ++ /* ++ * Since vmap() uses page granularity, we must add the offset ++ * into the page here, to get the byte granularity address ++ * into the mapping to represent the actual "start" location. ++ */ ++ return vaddr + offset_in_page(start); + } + + static void *persistent_ram_iomap(phys_addr_t start, size_t size, +@@ -448,6 +453,11 @@ static void *persistent_ram_iomap(phys_a + else + va = ioremap_wc(start, size); + ++ /* ++ * Since request_mem_region() and ioremap() are byte-granularity ++ * there is no need handle anything special like we do when the ++ * vmap() case in persistent_ram_vmap() above. ++ */ + return va; + } + +@@ -468,7 +478,7 @@ static int persistent_ram_buffer_map(phy + return -ENOMEM; + } + +- prz->buffer = prz->vaddr + offset_in_page(start); ++ prz->buffer = prz->vaddr; + prz->buffer_size = size - sizeof(struct persistent_ram_buffer); + + return 0; +@@ -515,7 +525,8 @@ void persistent_ram_free(struct persiste + + if (prz->vaddr) { + if (pfn_valid(prz->paddr >> PAGE_SHIFT)) { +- vunmap(prz->vaddr); ++ /* We must vunmap() at page-granularity. */ ++ vunmap(prz->vaddr - offset_in_page(prz->paddr)); + } else { + iounmap(prz->vaddr); + release_mem_region(prz->paddr, prz->size); diff --git a/queue-4.18/rdma-cma-protect-cma-dev-list-with-lock.patch b/queue-4.18/rdma-cma-protect-cma-dev-list-with-lock.patch new file mode 100644 index 00000000000..fc4533046e7 --- /dev/null +++ b/queue-4.18/rdma-cma-protect-cma-dev-list-with-lock.patch @@ -0,0 +1,75 @@ +From 954a8e3aea87e896e320cf648c1a5bbe47de443e Mon Sep 17 00:00:00 2001 +From: Parav Pandit +Date: Thu, 30 Aug 2018 08:35:19 +0300 +Subject: RDMA/cma: Protect cma dev list with lock + +From: Parav Pandit + +commit 954a8e3aea87e896e320cf648c1a5bbe47de443e upstream. + +When AF_IB addresses are used during rdma_resolve_addr() a lock is not +held. A cma device can get removed while list traversal is in progress +which may lead to crash. ie + + CPU0 CPU1 + ==== ==== +rdma_resolve_addr() + cma_resolve_ib_dev() + list_for_each() cma_remove_one() + cur_dev->device mutex_lock(&lock) + list_del(); + mutex_unlock(&lock); + cma_process_remove(); + + +Therefore, hold a lock while traversing the list which avoids such +situation. + +Cc: # 3.10 +Fixes: f17df3b0dede ("RDMA/cma: Add support for AF_IB to rdma_resolve_addr()") +Signed-off-by: Parav Pandit +Reviewed-by: Daniel Jurgens +Signed-off-by: Leon Romanovsky +Reviewed-by: Dennis Dalessandro +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/cma.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/infiniband/core/cma.c ++++ b/drivers/infiniband/core/cma.c +@@ -722,6 +722,7 @@ static int cma_resolve_ib_dev(struct rdm + dgid = (union ib_gid *) &addr->sib_addr; + pkey = ntohs(addr->sib_pkey); + ++ mutex_lock(&lock); + list_for_each_entry(cur_dev, &dev_list, list) { + for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) { + if (!rdma_cap_af_ib(cur_dev->device, p)) +@@ -748,18 +749,19 @@ static int cma_resolve_ib_dev(struct rdm + cma_dev = cur_dev; + sgid = gid; + id_priv->id.port_num = p; ++ goto found; + } + } + } + } +- +- if (!cma_dev) +- return -ENODEV; ++ mutex_unlock(&lock); ++ return -ENODEV; + + found: + cma_attach_to_dev(id_priv, cma_dev); +- addr = (struct sockaddr_ib *) cma_src_addr(id_priv); +- memcpy(&addr->sib_addr, &sgid, sizeof sgid); ++ mutex_unlock(&lock); ++ addr = (struct sockaddr_ib *)cma_src_addr(id_priv); ++ memcpy(&addr->sib_addr, &sgid, sizeof(sgid)); + cma_translate_ib(addr, &id_priv->id.route.addr.dev_addr); + return 0; + } diff --git a/queue-4.18/revert-cdc-acm-implement-put_char-and-flush_chars.patch b/queue-4.18/revert-cdc-acm-implement-put_char-and-flush_chars.patch new file mode 100644 index 00000000000..30e2d28c437 --- /dev/null +++ b/queue-4.18/revert-cdc-acm-implement-put_char-and-flush_chars.patch @@ -0,0 +1,170 @@ +From df3aa13c7bbb307e172c37f193f9a7aa058d4739 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Wed, 5 Sep 2018 17:56:46 +0200 +Subject: Revert "cdc-acm: implement put_char() and flush_chars()" + +From: Oliver Neukum + +commit df3aa13c7bbb307e172c37f193f9a7aa058d4739 upstream. + +This reverts commit a81cf9799ad7299b03a4dff020d9685f9ac5f3e0. + +The patch causes a regression, which I cannot find the reason for. +So let's revert for now, as a revert hurts only performance. + +Original report: +I was trying to resolve the problem with Oliver but we don't get any conclusion +for 5 months, so I am now sending this to mail list and cdc_acm authors. + +I am using simple request-response protocol to obtain the boiller parameters +in constant intervals. + +A simple one transaction is: +1. opening the /dev/ttyACM0 +2. sending the following 10-bytes request to the device: + unsigned char req[] = {0x02, 0xfe, 0x01, 0x05, 0x08, 0x02, 0x01, 0x69, 0xab, 0x03}; +3. reading response (frame of 74 bytes length). +4. closing the descriptor +I am doing this transaction with 5 seconds intervals. + +Before the bad commit everything was working correctly: I've got a requests and +a responses in a timely manner. + +After the bad commit more time I am using the kernel module, more problems I have. +The graph [2] is showing the problem. + +As you can see after module load all seems fine but after about 30 minutes I've got +a plenty of EAGAINs when doing read()'s and trying to read back the data. + +When I rmmod and insmod the cdc_acm module again, then the situation is starting +over again: running ok shortly after load, and more time it is running, more EAGAINs +I have when calling read(). + +As a bonus I can see the problem on the device itself: +The device is configured as you can see here on this screen [3]. +It has two transmision LEDs: TX and RX. Blink duration is set for 100ms. +This is a recording before the bad commit when all is working fine: [4] +And this is with the bad commit: [5] +As you can see the TX led is blinking wrongly long (indicating transmission?) +and I have problems doing read() calls (EAGAIN). + +Reported-by: Mariusz Bialonczyk +Signed-off-by: Oliver Neukum +Fixes: a81cf9799ad7 ("cdc-acm: implement put_char() and flush_chars()") +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-acm.c | 73 -------------------------------------------- + drivers/usb/class/cdc-acm.h | 1 + 2 files changed, 74 deletions(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -779,20 +779,9 @@ static int acm_tty_write(struct tty_stru + } + + if (acm->susp_count) { +- if (acm->putbuffer) { +- /* now to preserve order */ +- usb_anchor_urb(acm->putbuffer->urb, &acm->delayed); +- acm->putbuffer = NULL; +- } + usb_anchor_urb(wb->urb, &acm->delayed); + spin_unlock_irqrestore(&acm->write_lock, flags); + return count; +- } else { +- if (acm->putbuffer) { +- /* at this point there is no good way to handle errors */ +- acm_start_wb(acm, acm->putbuffer); +- acm->putbuffer = NULL; +- } + } + + stat = acm_start_wb(acm, wb); +@@ -803,66 +792,6 @@ static int acm_tty_write(struct tty_stru + return count; + } + +-static void acm_tty_flush_chars(struct tty_struct *tty) +-{ +- struct acm *acm = tty->driver_data; +- struct acm_wb *cur; +- int err; +- unsigned long flags; +- +- spin_lock_irqsave(&acm->write_lock, flags); +- +- cur = acm->putbuffer; +- if (!cur) /* nothing to do */ +- goto out; +- +- acm->putbuffer = NULL; +- err = usb_autopm_get_interface_async(acm->control); +- if (err < 0) { +- cur->use = 0; +- acm->putbuffer = cur; +- goto out; +- } +- +- if (acm->susp_count) +- usb_anchor_urb(cur->urb, &acm->delayed); +- else +- acm_start_wb(acm, cur); +-out: +- spin_unlock_irqrestore(&acm->write_lock, flags); +- return; +-} +- +-static int acm_tty_put_char(struct tty_struct *tty, unsigned char ch) +-{ +- struct acm *acm = tty->driver_data; +- struct acm_wb *cur; +- int wbn; +- unsigned long flags; +- +-overflow: +- cur = acm->putbuffer; +- if (!cur) { +- spin_lock_irqsave(&acm->write_lock, flags); +- wbn = acm_wb_alloc(acm); +- if (wbn >= 0) { +- cur = &acm->wb[wbn]; +- acm->putbuffer = cur; +- } +- spin_unlock_irqrestore(&acm->write_lock, flags); +- if (!cur) +- return 0; +- } +- +- if (cur->len == acm->writesize) { +- acm_tty_flush_chars(tty); +- goto overflow; +- } +- +- cur->buf[cur->len++] = ch; +- return 1; +-} +- + static int acm_tty_write_room(struct tty_struct *tty) + { + struct acm *acm = tty->driver_data; +@@ -1987,8 +1916,6 @@ static const struct tty_operations acm_o + .cleanup = acm_tty_cleanup, + .hangup = acm_tty_hangup, + .write = acm_tty_write, +- .put_char = acm_tty_put_char, +- .flush_chars = acm_tty_flush_chars, + .write_room = acm_tty_write_room, + .ioctl = acm_tty_ioctl, + .throttle = acm_tty_throttle, +--- a/drivers/usb/class/cdc-acm.h ++++ b/drivers/usb/class/cdc-acm.h +@@ -96,7 +96,6 @@ struct acm { + unsigned long read_urbs_free; + struct urb *read_urbs[ACM_NR]; + struct acm_rb read_buffers[ACM_NR]; +- struct acm_wb *putbuffer; /* for acm_tty_put_char() */ + int rx_buflimit; + spinlock_t read_lock; + u8 *notification_buffer; /* to reassemble fragmented notifications */ diff --git a/queue-4.18/s390-crypto-fix-return-code-checking-in-cbc_paes_crypt.patch b/queue-4.18/s390-crypto-fix-return-code-checking-in-cbc_paes_crypt.patch new file mode 100644 index 00000000000..cfccbb14f46 --- /dev/null +++ b/queue-4.18/s390-crypto-fix-return-code-checking-in-cbc_paes_crypt.patch @@ -0,0 +1,36 @@ +From b81126e01a8c6048249955feea46c8217ebefa91 Mon Sep 17 00:00:00 2001 +From: Ingo Franzki +Date: Mon, 27 Aug 2018 14:28:47 +0200 +Subject: s390/crypto: Fix return code checking in cbc_paes_crypt() + +From: Ingo Franzki + +commit b81126e01a8c6048249955feea46c8217ebefa91 upstream. + +The return code of cpacf_kmc() is less than the number of +bytes to process in case of an error, not greater. +The crypt routines for the other cipher modes already have +this correctly. + +Cc: stable@vger.kernel.org # v4.11+ +Fixes: 279378430768 ("s390/crypt: Add protected key AES module") +Signed-off-by: Ingo Franzki +Acked-by: Harald Freudenberger +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/crypto/paes_s390.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/s390/crypto/paes_s390.c ++++ b/arch/s390/crypto/paes_s390.c +@@ -208,7 +208,7 @@ static int cbc_paes_crypt(struct blkciph + walk->dst.virt.addr, walk->src.virt.addr, n); + if (k) + ret = blkcipher_walk_done(desc, walk, nbytes - k); +- if (n < k) { ++ if (k < n) { + if (__cbc_paes_set_key(ctx) != 0) + return blkcipher_walk_done(desc, walk, -EIO); + memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE); diff --git a/queue-4.18/series b/queue-4.18/series index 2b860067eec..0310db0f5f0 100644 --- a/queue-4.18/series +++ b/queue-4.18/series @@ -96,3 +96,49 @@ x86-pti-check-the-return-value-of-pti_user_pagetable_walk_pmd.patch x86-mm-pti-add-an-overflow-check-to-pti_clone_pmds.patch pci-aer-honor-pcie_ports-native-even-if-hest-sets-firmware_first.patch xen-netfront-fix-warn-message-as-irq-device-name-has.patch +rdma-cma-protect-cma-dev-list-with-lock.patch +pstore-fix-incorrect-persistent-ram-buffer-mapping.patch +xen-netfront-fix-waiting-for-xenbus-state-change.patch +ib-ipoib-avoid-a-race-condition-between-start_xmit-and-cm_rep_handler.patch +s390-crypto-fix-return-code-checking-in-cbc_paes_crypt.patch +mmc-meson-mx-sdio-fix-of-child-node-lookup.patch +mmc-omap_hsmmc-fix-wakeirq-handling-on-removal.patch +ipmi-rework-smi-registration-failure.patch +ipmi-move-bt-capabilities-detection-to-the-detect-call.patch +ipmi-fix-i2c-client-removal-in-the-ssif-driver.patch +ovl-fix-oopses-in-ovl_fill_super-failure-paths.patch +vmbus-don-t-return-values-for-uninitalized-channels.patch +tools-hv-fix-a-bug-in-the-key-delete-code.patch +misc-ibmvsm-fix-wrong-assignment-of-return-code.patch +misc-hmc6352-fix-potential-spectre-v1.patch +xhci-fix-use-after-free-for-urb-cancellation-on-a-reallocated-endpoint.patch +usb-don-t-die-twice-if-pci-xhci-host-is-not-responding-in-resume.patch +usb-xhci-fix-interrupt-transfer-error-happened-on-mtk-platforms.patch +usb-mtu3-fix-error-of-xhci-port-id-when-enable-u3-dual-role.patch +mei-ignore-not-found-client-in-the-enumeration.patch +mei-bus-fix-hw-module-get-put-balance.patch +mei-bus-need-to-unlink-client-before-freeing.patch +dm-verity-fix-crash-on-bufio-buffer-that-was-allocated-with-vmalloc.patch +usb-add-quirk-to-support-dji-cinessd.patch +usb-uas-add-support-for-more-quirk-flags.patch +usb-avoid-use-after-free-by-flushing-endpoints-early-in-usb_set_interface.patch +usb-host-u132-hcd-fix-a-sleep-in-atomic-context-bug-in-u132_get_frame.patch +usb-add-quirk-for-worlde-controller-ks49-or-prodipe-midi-49c-usb-controller.patch +usb-gadget-udc-renesas_usb3-fix-maxpacket-size-of-ep0.patch +usb-net2280-fix-erroneous-synchronization-change.patch +usb-serial-io_ti-fix-array-underflow-in-completion-handler.patch +usb-misc-uss720-fix-two-sleep-in-atomic-context-bugs.patch +usb-serial-ti_usb_3410_5052-fix-array-underflow-in-completion-handler.patch +usb-yurex-fix-buffer-over-read-in-yurex_write.patch +usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch +revert-cdc-acm-implement-put_char-and-flush_chars.patch +cifs-prevent-integer-overflow-in-nxt_dir_entry.patch +cifs-fix-wrapping-bugs-in-num_entries.patch +cifs-integer-overflow-in-in-smb2_ioctl.patch +xtensa-iss-don-t-allocate-memory-in-platform_setup.patch +perf-core-force-user_ds-when-recording-user-stack-data.patch +perf-tools-fix-maps__find_symbol_by_name.patch +of-fix-phandle-cache-creation-for-dts-with-no-phandles.patch +x86-eisa-don-t-probe-eisa-bus-for-xen-pv-guests.patch +nfsv4-fix-a-tracepoint-oops-in-initiate_file_draining.patch +nfsv4.1-fix-infinite-loop-on-i-o.patch diff --git a/queue-4.18/tools-hv-fix-a-bug-in-the-key-delete-code.patch b/queue-4.18/tools-hv-fix-a-bug-in-the-key-delete-code.patch new file mode 100644 index 00000000000..fa196614b54 --- /dev/null +++ b/queue-4.18/tools-hv-fix-a-bug-in-the-key-delete-code.patch @@ -0,0 +1,33 @@ +From 86503bd35dec0ce363e9fdbf5299927422ed3899 Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Fri, 10 Aug 2018 23:06:07 +0000 +Subject: Tools: hv: Fix a bug in the key delete code + +From: K. Y. Srinivasan + +commit 86503bd35dec0ce363e9fdbf5299927422ed3899 upstream. + +Fix a bug in the key delete code - the num_records range +from 0 to num_records-1. + +Signed-off-by: K. Y. Srinivasan +Reported-by: David Binderman +Cc: +Reviewed-by: Michael Kelley +Signed-off-by: Greg Kroah-Hartman + +--- + tools/hv/hv_kvp_daemon.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/tools/hv/hv_kvp_daemon.c ++++ b/tools/hv/hv_kvp_daemon.c +@@ -286,7 +286,7 @@ static int kvp_key_delete(int pool, cons + * Found a match; just move the remaining + * entries up. + */ +- if (i == num_records) { ++ if (i == (num_records - 1)) { + kvp_file_info[pool].num_records--; + kvp_update_file(pool); + return 0; diff --git a/queue-4.18/usb-add-quirk-for-worlde-controller-ks49-or-prodipe-midi-49c-usb-controller.patch b/queue-4.18/usb-add-quirk-for-worlde-controller-ks49-or-prodipe-midi-49c-usb-controller.patch new file mode 100644 index 00000000000..926b28251ee --- /dev/null +++ b/queue-4.18/usb-add-quirk-for-worlde-controller-ks49-or-prodipe-midi-49c-usb-controller.patch @@ -0,0 +1,38 @@ +From 9b83a1c301ad6d24988a128c69b42cbaaf537d82 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Maxence=20Dupr=C3=A8s?= +Date: Wed, 8 Aug 2018 23:56:33 +0000 +Subject: USB: add quirk for WORLDE Controller KS49 or Prodipe MIDI 49C USB controller + +From: Maxence Duprès + +commit 9b83a1c301ad6d24988a128c69b42cbaaf537d82 upstream. + +WORLDE Controller KS49 or Prodipe MIDI 49C USB controller +cause a -EPROTO error, a communication restart and loop again. + +This issue has already been fixed for KS25. +https://lore.kernel.org/patchwork/patch/753077/ + +I just add device 201 for KS49 in quirks.c to get it works. + +Signed-off-by: Laurent Roux +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/quirks.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -178,6 +178,10 @@ static const struct usb_device_id usb_qu + /* CBM - Flash disk */ + { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* WORLDE Controller KS49 or Prodipe MIDI 49C USB controller */ ++ { USB_DEVICE(0x0218, 0x0201), .driver_info = ++ USB_QUIRK_CONFIG_INTF_STRINGS }, ++ + /* WORLDE easy key (easykey.25) MIDI controller */ + { USB_DEVICE(0x0218, 0x0401), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, diff --git a/queue-4.18/usb-add-quirk-to-support-dji-cinessd.patch b/queue-4.18/usb-add-quirk-to-support-dji-cinessd.patch new file mode 100644 index 00000000000..1d62673b11b --- /dev/null +++ b/queue-4.18/usb-add-quirk-to-support-dji-cinessd.patch @@ -0,0 +1,73 @@ +From f45681f9becaa65111ed0a691ccf080a0cd5feb8 Mon Sep 17 00:00:00 2001 +From: Tim Anderson +Date: Thu, 9 Aug 2018 14:55:34 -0700 +Subject: USB: Add quirk to support DJI CineSSD + +From: Tim Anderson + +commit f45681f9becaa65111ed0a691ccf080a0cd5feb8 upstream. + +This device does not correctly handle the LPM operations. + +Also, the device cannot handle ATA pass-through commands +and locks up when attempted while running in super speed. + +This patch adds the equivalent quirk logic as found in uas. + +Signed-off-by: Tim Anderson +Acked-by: Alan Stern +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/quirks.c | 3 +++ + drivers/usb/storage/scsiglue.c | 9 +++++++++ + drivers/usb/storage/unusual_devs.h | 7 +++++++ + 3 files changed, 19 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -406,6 +406,9 @@ static const struct usb_device_id usb_qu + { USB_DEVICE(0x2040, 0x7200), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, + ++ /* DJI CineSSD */ ++ { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + +--- a/drivers/usb/storage/scsiglue.c ++++ b/drivers/usb/storage/scsiglue.c +@@ -376,6 +376,15 @@ static int queuecommand_lck(struct scsi_ + return 0; + } + ++ if ((us->fflags & US_FL_NO_ATA_1X) && ++ (srb->cmnd[0] == ATA_12 || srb->cmnd[0] == ATA_16)) { ++ memcpy(srb->sense_buffer, usb_stor_sense_invalidCDB, ++ sizeof(usb_stor_sense_invalidCDB)); ++ srb->result = SAM_STAT_CHECK_CONDITION; ++ done(srb); ++ return 0; ++ } ++ + /* enqueue the command and wake up the control thread */ + srb->scsi_done = done; + us->srb = srb; +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -2288,6 +2288,13 @@ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_GO_SLOW ), + ++/* Reported-by: Tim Anderson */ ++UNUSUAL_DEV( 0x2ca3, 0x0031, 0x0000, 0x9999, ++ "DJI", ++ "CineSSD", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_NO_ATA_1X), ++ + /* + * Reported by Frederic Marchal + * Mio Moov 330 diff --git a/queue-4.18/usb-avoid-use-after-free-by-flushing-endpoints-early-in-usb_set_interface.patch b/queue-4.18/usb-avoid-use-after-free-by-flushing-endpoints-early-in-usb_set_interface.patch new file mode 100644 index 00000000000..5e0e96d6f0d --- /dev/null +++ b/queue-4.18/usb-avoid-use-after-free-by-flushing-endpoints-early-in-usb_set_interface.patch @@ -0,0 +1,64 @@ +From f9a5b4f58b280c1d26255376713c132f93837621 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 3 Sep 2018 15:44:16 +0300 +Subject: usb: Avoid use-after-free by flushing endpoints early in usb_set_interface() + +From: Mathias Nyman + +commit f9a5b4f58b280c1d26255376713c132f93837621 upstream. + +The steps taken by usb core to set a new interface is very different from +what is done on the xHC host side. + +xHC hardware will do everything in one go. One command is used to set up +new endpoints, free old endpoints, check bandwidth, and run the new +endpoints. + +All this is done by xHC when usb core asks the hcd to check for +available bandwidth. At this point usb core has not yet flushed the old +endpoints, which will cause use-after-free issues in xhci driver as +queued URBs are cancelled on a re-allocated endpoint. + +To resolve this add a call to usb_disable_interface() which will flush +the endpoints before calling usb_hcd_alloc_bandwidth() + +Additional checks in xhci driver will also be implemented to gracefully +handle stale URB cancel on freed and re-allocated endpoints + +Cc: +Reported-by: Sudip Mukherjee +Signed-off-by: Mathias Nyman +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/message.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -1340,6 +1340,11 @@ void usb_enable_interface(struct usb_dev + * is submitted that needs that bandwidth. Some other operating systems + * allocate bandwidth early, when a configuration is chosen. + * ++ * xHCI reserves bandwidth and configures the alternate setting in ++ * usb_hcd_alloc_bandwidth(). If it fails the original interface altsetting ++ * may be disabled. Drivers cannot rely on any particular alternate ++ * setting being in effect after a failure. ++ * + * This call is synchronous, and may not be used in an interrupt context. + * Also, drivers must not change altsettings while urbs are scheduled for + * endpoints in that interface; all such urbs must first be completed +@@ -1375,6 +1380,12 @@ int usb_set_interface(struct usb_device + alternate); + return -EINVAL; + } ++ /* ++ * usb3 hosts configure the interface in usb_hcd_alloc_bandwidth, ++ * including freeing dropped endpoint ring buffers. ++ * Make sure the interface endpoints are flushed before that ++ */ ++ usb_disable_interface(dev, iface, false); + + /* Make sure we have enough bandwidth for this alternate interface. + * Remove the current alt setting and add the new alt setting. diff --git a/queue-4.18/usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch b/queue-4.18/usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch new file mode 100644 index 00000000000..54e4abb479c --- /dev/null +++ b/queue-4.18/usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch @@ -0,0 +1,36 @@ +From 6e22e3af7bb3a7b9dc53cb4687659f6e63fca427 Mon Sep 17 00:00:00 2001 +From: Jia-Ju Bai +Date: Sat, 1 Sep 2018 16:12:10 +0800 +Subject: usb: cdc-wdm: Fix a sleep-in-atomic-context bug in service_outstanding_interrupt() + +From: Jia-Ju Bai + +commit 6e22e3af7bb3a7b9dc53cb4687659f6e63fca427 upstream. + +wdm_in_callback() is a completion handler function for the USB driver. +So it should not sleep. But it calls service_outstanding_interrupt(), +which calls usb_submit_urb() with GFP_KERNEL. + +To fix this bug, GFP_KERNEL is replaced with GFP_ATOMIC. + +This bug is found by my static analysis tool DSAC. + +Signed-off-by: Jia-Ju Bai +Cc: stable +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_KERNEL); ++ rv = usb_submit_urb(desc->response, GFP_ATOMIC); + spin_lock_irq(&desc->iuspin); + if (rv) { + dev_err(&desc->intf->dev, diff --git a/queue-4.18/usb-don-t-die-twice-if-pci-xhci-host-is-not-responding-in-resume.patch b/queue-4.18/usb-don-t-die-twice-if-pci-xhci-host-is-not-responding-in-resume.patch new file mode 100644 index 00000000000..2b56bc5a301 --- /dev/null +++ b/queue-4.18/usb-don-t-die-twice-if-pci-xhci-host-is-not-responding-in-resume.patch @@ -0,0 +1,35 @@ +From f3dc41c5d22b2ca14a0802a65d8cdc33a3882d4e Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Tue, 4 Sep 2018 17:35:16 +0300 +Subject: usb: Don't die twice if PCI xhci host is not responding in resume + +From: Mathias Nyman + +commit f3dc41c5d22b2ca14a0802a65d8cdc33a3882d4e upstream. + +usb_hc_died() should only be called once, and with the primary HCD +as parameter. It will mark both primary and secondary hcd's dead. + +Remove the extra call to usb_cd_died with the shared hcd as parameter. + +Fixes: ff9d78b36f76 ("USB: Set usb_hcd->state and flags for shared roothubs") +Signed-off-by: Mathias Nyman +Cc: stable +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hcd-pci.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/usb/core/hcd-pci.c ++++ b/drivers/usb/core/hcd-pci.c +@@ -515,8 +515,6 @@ static int resume_common(struct device * + event == PM_EVENT_RESTORE); + if (retval) { + dev_err(dev, "PCI post-resume error %d!\n", retval); +- if (hcd->shared_hcd) +- usb_hc_died(hcd->shared_hcd); + usb_hc_died(hcd); + } + } diff --git a/queue-4.18/usb-gadget-udc-renesas_usb3-fix-maxpacket-size-of-ep0.patch b/queue-4.18/usb-gadget-udc-renesas_usb3-fix-maxpacket-size-of-ep0.patch new file mode 100644 index 00000000000..a698253a4ee --- /dev/null +++ b/queue-4.18/usb-gadget-udc-renesas_usb3-fix-maxpacket-size-of-ep0.patch @@ -0,0 +1,53 @@ +From dfe1a51d2a36647f74cbad478801efa7cf394376 Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Fri, 3 Aug 2018 12:12:46 +0900 +Subject: usb: gadget: udc: renesas_usb3: fix maxpacket size of ep0 + +From: Yoshihiro Shimoda + +commit dfe1a51d2a36647f74cbad478801efa7cf394376 upstream. + +This patch fixes an issue that maxpacket size of ep0 is incorrect +for SuperSpeed. Otherwise, CDC NCM class with SuperSpeed doesn't +work correctly on this driver because its control read data size +is more than 64 bytes. + +Reported-by: Junki Kato +Fixes: 746bfe63bba3 ("usb: gadget: renesas_usb3: add support for Renesas USB3.0 peripheral controller") +Cc: # v4.5+ +Signed-off-by: Yoshihiro Shimoda +Tested-by: Junki Kato +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/renesas_usb3.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/renesas_usb3.c ++++ b/drivers/usb/gadget/udc/renesas_usb3.c +@@ -787,12 +787,15 @@ static void usb3_irq_epc_int_1_speed(str + switch (speed) { + case USB_STA_SPEED_SS: + usb3->gadget.speed = USB_SPEED_SUPER; ++ usb3->gadget.ep0->maxpacket = USB3_EP0_SS_MAX_PACKET_SIZE; + break; + case USB_STA_SPEED_HS: + usb3->gadget.speed = USB_SPEED_HIGH; ++ usb3->gadget.ep0->maxpacket = USB3_EP0_HSFS_MAX_PACKET_SIZE; + break; + case USB_STA_SPEED_FS: + usb3->gadget.speed = USB_SPEED_FULL; ++ usb3->gadget.ep0->maxpacket = USB3_EP0_HSFS_MAX_PACKET_SIZE; + break; + default: + usb3->gadget.speed = USB_SPEED_UNKNOWN; +@@ -2451,7 +2454,7 @@ static int renesas_usb3_init_ep(struct r + /* for control pipe */ + usb3->gadget.ep0 = &usb3_ep->ep; + usb_ep_set_maxpacket_limit(&usb3_ep->ep, +- USB3_EP0_HSFS_MAX_PACKET_SIZE); ++ USB3_EP0_SS_MAX_PACKET_SIZE); + usb3_ep->ep.caps.type_control = true; + usb3_ep->ep.caps.dir_in = true; + usb3_ep->ep.caps.dir_out = true; diff --git a/queue-4.18/usb-host-u132-hcd-fix-a-sleep-in-atomic-context-bug-in-u132_get_frame.patch b/queue-4.18/usb-host-u132-hcd-fix-a-sleep-in-atomic-context-bug-in-u132_get_frame.patch new file mode 100644 index 00000000000..ff00b759bdc --- /dev/null +++ b/queue-4.18/usb-host-u132-hcd-fix-a-sleep-in-atomic-context-bug-in-u132_get_frame.patch @@ -0,0 +1,50 @@ +From 6d4f268fa132742fe96dad22307c68d237356d88 Mon Sep 17 00:00:00 2001 +From: Jia-Ju Bai +Date: Sat, 1 Sep 2018 17:23:47 +0800 +Subject: usb: host: u132-hcd: Fix a sleep-in-atomic-context bug in u132_get_frame() + +From: Jia-Ju Bai + +commit 6d4f268fa132742fe96dad22307c68d237356d88 upstream. + +i_usX2Y_subs_startup in usbusx2yaudio.c is a completion handler function +for the USB driver. So it should not sleep, but it is can sleep +according to the function call paths (from bottom to top) in Linux-4.16. + +[FUNC] msleep +drivers/usb/host/u132-hcd.c, 2558: + msleep in u132_get_frame +drivers/usb/core/hcd.c, 2231: + [FUNC_PTR]u132_get_frame in usb_hcd_get_frame_number +drivers/usb/core/usb.c, 822: + usb_hcd_get_frame_number in usb_get_current_frame_number +sound/usb/usx2y/usbusx2yaudio.c, 303: + usb_get_current_frame_number in i_usX2Y_urb_complete +sound/usb/usx2y/usbusx2yaudio.c, 366: + i_usX2Y_urb_complete in i_usX2Y_subs_startup + +Note that [FUNC_PTR] means a function pointer call is used. + +To fix this bug, msleep() is replaced with mdelay(). + +This bug is found by my static analysis tool DSAC. + +Signed-off-by: Jia-Ju Bai +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/u132-hcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/u132-hcd.c ++++ b/drivers/usb/host/u132-hcd.c +@@ -2555,7 +2555,7 @@ static int u132_get_frame(struct usb_hcd + } else { + int frame = 0; + dev_err(&u132->platform_dev->dev, "TODO: u132_get_frame\n"); +- msleep(100); ++ mdelay(100); + return frame; + } + } diff --git a/queue-4.18/usb-misc-uss720-fix-two-sleep-in-atomic-context-bugs.patch b/queue-4.18/usb-misc-uss720-fix-two-sleep-in-atomic-context-bugs.patch new file mode 100644 index 00000000000..1ffa8d5101a --- /dev/null +++ b/queue-4.18/usb-misc-uss720-fix-two-sleep-in-atomic-context-bugs.patch @@ -0,0 +1,71 @@ +From bc8acc214d3f1cafebcbcd101a695bbac716595d Mon Sep 17 00:00:00 2001 +From: Jia-Ju Bai +Date: Sat, 1 Sep 2018 16:25:08 +0800 +Subject: usb: misc: uss720: Fix two sleep-in-atomic-context bugs + +From: Jia-Ju Bai + +commit bc8acc214d3f1cafebcbcd101a695bbac716595d upstream. + +async_complete() in uss720.c is a completion handler function for the +USB driver. So it should not sleep, but it is can sleep according to the +function call paths (from bottom to top) in Linux-4.16. + +[FUNC] set_1284_register(GFP_KERNEL) +drivers/usb/misc/uss720.c, 372: + set_1284_register in parport_uss720_frob_control +drivers/parport/ieee1284.c, 560: + [FUNC_PTR]parport_uss720_frob_control in parport_ieee1284_ack_data_avail +drivers/parport/ieee1284.c, 577: + parport_ieee1284_ack_data_avail in parport_ieee1284_interrupt +./include/linux/parport.h, 474: + parport_ieee1284_interrupt in parport_generic_irq +drivers/usb/misc/uss720.c, 116: + parport_generic_irq in async_complete + +[FUNC] get_1284_register(GFP_KERNEL) +drivers/usb/misc/uss720.c, 382: + get_1284_register in parport_uss720_read_status +drivers/parport/ieee1284.c, 555: + [FUNC_PTR]parport_uss720_read_status in parport_ieee1284_ack_data_avail +drivers/parport/ieee1284.c, 577: + parport_ieee1284_ack_data_avail in parport_ieee1284_interrupt +./include/linux/parport.h, 474: + parport_ieee1284_interrupt in parport_generic_irq +drivers/usb/misc/uss720.c, 116: + parport_generic_irq in async_complete + +Note that [FUNC_PTR] means a function pointer call is used. + +To fix these bugs, GFP_KERNEL is replaced with GFP_ATOMIC. + +These bugs are found by my static analysis tool DSAC. + +Signed-off-by: Jia-Ju Bai +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/uss720.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/misc/uss720.c ++++ b/drivers/usb/misc/uss720.c +@@ -369,7 +369,7 @@ static unsigned char parport_uss720_frob + mask &= 0x0f; + val &= 0x0f; + d = (priv->reg[1] & (~mask)) ^ val; +- if (set_1284_register(pp, 2, d, GFP_KERNEL)) ++ if (set_1284_register(pp, 2, d, GFP_ATOMIC)) + return 0; + priv->reg[1] = d; + return d & 0xf; +@@ -379,7 +379,7 @@ static unsigned char parport_uss720_read + { + unsigned char ret; + +- if (get_1284_register(pp, 1, &ret, GFP_KERNEL)) ++ if (get_1284_register(pp, 1, &ret, GFP_ATOMIC)) + return 0; + return ret & 0xf8; + } diff --git a/queue-4.18/usb-mtu3-fix-error-of-xhci-port-id-when-enable-u3-dual-role.patch b/queue-4.18/usb-mtu3-fix-error-of-xhci-port-id-when-enable-u3-dual-role.patch new file mode 100644 index 00000000000..acc1565cfda --- /dev/null +++ b/queue-4.18/usb-mtu3-fix-error-of-xhci-port-id-when-enable-u3-dual-role.patch @@ -0,0 +1,49 @@ +From 78af87b8bbbbcaa613f1a7d8f14472fe9a7dc622 Mon Sep 17 00:00:00 2001 +From: Chunfeng Yun +Date: Wed, 29 Aug 2018 10:36:49 +0800 +Subject: usb: mtu3: fix error of xhci port id when enable U3 dual role + +From: Chunfeng Yun + +commit 78af87b8bbbbcaa613f1a7d8f14472fe9a7dc622 upstream. + +If dual role mode is enabled, when switch u3port0 to device mode, +it will affect port id calculation of host(xHCI), specially when +host supports multi U2 ports or U3 ports, so need enable its dual +role mode, and fix it here. + +Signed-off-by: Chunfeng Yun +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/mtu3/mtu3_core.c | 6 +++++- + drivers/usb/mtu3/mtu3_hw_regs.h | 1 + + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/usb/mtu3/mtu3_core.c ++++ b/drivers/usb/mtu3/mtu3_core.c +@@ -107,8 +107,12 @@ static int mtu3_device_enable(struct mtu + (SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN | + SSUSB_U2_PORT_HOST_SEL)); + +- if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG) ++ if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG) { + mtu3_setbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL); ++ if (mtu->is_u3_ip) ++ mtu3_setbits(ibase, SSUSB_U3_CTRL(0), ++ SSUSB_U3_PORT_DUAL_MODE); ++ } + + return ssusb_check_clocks(mtu->ssusb, check_clk); + } +--- a/drivers/usb/mtu3/mtu3_hw_regs.h ++++ b/drivers/usb/mtu3/mtu3_hw_regs.h +@@ -459,6 +459,7 @@ + + /* U3D_SSUSB_U3_CTRL_0P */ + #define SSUSB_U3_PORT_SSP_SPEED BIT(9) ++#define SSUSB_U3_PORT_DUAL_MODE BIT(7) + #define SSUSB_U3_PORT_HOST_SEL BIT(2) + #define SSUSB_U3_PORT_PDN BIT(1) + #define SSUSB_U3_PORT_DIS BIT(0) diff --git a/queue-4.18/usb-net2280-fix-erroneous-synchronization-change.patch b/queue-4.18/usb-net2280-fix-erroneous-synchronization-change.patch new file mode 100644 index 00000000000..2b351190f39 --- /dev/null +++ b/queue-4.18/usb-net2280-fix-erroneous-synchronization-change.patch @@ -0,0 +1,115 @@ +From dec3c23c9aa1815f07d98ae0375b4cbc10971e13 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 8 Aug 2018 11:20:39 -0400 +Subject: USB: net2280: Fix erroneous synchronization change + +From: Alan Stern + +commit dec3c23c9aa1815f07d98ae0375b4cbc10971e13 upstream. + +Commit f16443a034c7 ("USB: gadgetfs, dummy-hcd, net2280: fix locking +for callbacks") was based on a serious misunderstanding. It +introduced regressions into both the dummy-hcd and net2280 drivers. + +The problem in dummy-hcd was fixed by commit 7dbd8f4cabd9 ("USB: +dummy-hcd: Fix erroneous synchronization change"), but the problem in +net2280 remains. Namely: the ->disconnect(), ->suspend(), ->resume(), +and ->reset() callbacks must be invoked without the private lock held; +otherwise a deadlock will occur when the callback routine tries to +interact with the UDC driver. + +This patch largely is a reversion of the relevant parts of +f16443a034c7. It also drops the private lock around the calls to +->suspend() and ->resume() (something the earlier patch forgot to do). +This is safe from races with device interrupts because it occurs +within the interrupt handler. + +Finally, the patch changes where the ->disconnect() callback is +invoked when net2280_pullup() turns the pullup off. Rather than +making the callback from within stop_activity() at a time when dropping +the private lock could be unsafe, the callback is moved to a point +after the lock has already been dropped. + +Signed-off-by: Alan Stern +Fixes: f16443a034c7 ("USB: gadgetfs, dummy-hcd, net2280: fix locking for callbacks") +Reported-by: D. Ziesche +Tested-by: D. Ziesche +CC: +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/net2280.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/udc/net2280.c ++++ b/drivers/usb/gadget/udc/net2280.c +@@ -1545,11 +1545,14 @@ static int net2280_pullup(struct usb_gad + writel(tmp | BIT(USB_DETECT_ENABLE), &dev->usb->usbctl); + } else { + writel(tmp & ~BIT(USB_DETECT_ENABLE), &dev->usb->usbctl); +- stop_activity(dev, dev->driver); ++ stop_activity(dev, NULL); + } + + spin_unlock_irqrestore(&dev->lock, flags); + ++ if (!is_on && dev->driver) ++ dev->driver->disconnect(&dev->gadget); ++ + return 0; + } + +@@ -2466,8 +2469,11 @@ static void stop_activity(struct net2280 + nuke(&dev->ep[i]); + + /* report disconnect; the driver is already quiesced */ +- if (driver) ++ if (driver) { ++ spin_unlock(&dev->lock); + driver->disconnect(&dev->gadget); ++ spin_lock(&dev->lock); ++ } + + usb_reinit(dev); + } +@@ -3341,6 +3347,8 @@ next_endpoints: + BIT(PCI_RETRY_ABORT_INTERRUPT)) + + static void handle_stat1_irqs(struct net2280 *dev, u32 stat) ++__releases(dev->lock) ++__acquires(dev->lock) + { + struct net2280_ep *ep; + u32 tmp, num, mask, scratch; +@@ -3381,12 +3389,14 @@ static void handle_stat1_irqs(struct net + if (disconnect || reset) { + stop_activity(dev, dev->driver); + ep0_start(dev); ++ spin_unlock(&dev->lock); + if (reset) + usb_gadget_udc_reset + (&dev->gadget, dev->driver); + else + (dev->driver->disconnect) + (&dev->gadget); ++ spin_lock(&dev->lock); + return; + } + } +@@ -3405,6 +3415,7 @@ static void handle_stat1_irqs(struct net + tmp = BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT); + if (stat & tmp) { + writel(tmp, &dev->regs->irqstat1); ++ spin_unlock(&dev->lock); + if (stat & BIT(SUSPEND_REQUEST_INTERRUPT)) { + if (dev->driver->suspend) + dev->driver->suspend(&dev->gadget); +@@ -3415,6 +3426,7 @@ static void handle_stat1_irqs(struct net + dev->driver->resume(&dev->gadget); + /* at high speed, note erratum 0133 */ + } ++ spin_lock(&dev->lock); + stat &= ~tmp; + } + diff --git a/queue-4.18/usb-serial-io_ti-fix-array-underflow-in-completion-handler.patch b/queue-4.18/usb-serial-io_ti-fix-array-underflow-in-completion-handler.patch new file mode 100644 index 00000000000..acd66baeb6e --- /dev/null +++ b/queue-4.18/usb-serial-io_ti-fix-array-underflow-in-completion-handler.patch @@ -0,0 +1,38 @@ +From 691a03cfe8ca483f9c48153b869d354e4ae3abef Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 21 Aug 2018 11:59:52 +0200 +Subject: USB: serial: io_ti: fix array underflow in completion handler + +From: Johan Hovold + +commit 691a03cfe8ca483f9c48153b869d354e4ae3abef upstream. + +As reported by Dan Carpenter, a malicious USB device could set +port_number to a negative value and we would underflow the port array in +the interrupt completion handler. + +As these devices only have one or two ports, fix this by making sure we +only consider the seventh bit when determining the port number (and +ignore bits 0xb0 which are typically set to 0x30). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable +Reported-by: Dan Carpenter +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/io_ti.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/serial/io_ti.h ++++ b/drivers/usb/serial/io_ti.h +@@ -173,7 +173,7 @@ struct ump_interrupt { + } __attribute__((packed)); + + +-#define TIUMP_GET_PORT_FROM_CODE(c) (((c) >> 4) - 3) ++#define TIUMP_GET_PORT_FROM_CODE(c) (((c) >> 6) & 0x01) + #define TIUMP_GET_FUNC_FROM_CODE(c) ((c) & 0x0f) + #define TIUMP_INTERRUPT_CODE_LSR 0x03 + #define TIUMP_INTERRUPT_CODE_MSR 0x04 diff --git a/queue-4.18/usb-serial-ti_usb_3410_5052-fix-array-underflow-in-completion-handler.patch b/queue-4.18/usb-serial-ti_usb_3410_5052-fix-array-underflow-in-completion-handler.patch new file mode 100644 index 00000000000..8d971ed7fdd --- /dev/null +++ b/queue-4.18/usb-serial-ti_usb_3410_5052-fix-array-underflow-in-completion-handler.patch @@ -0,0 +1,37 @@ +From 5dfdd24eb3d39d815bc952ae98128e967c9bba49 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 21 Aug 2018 11:59:53 +0200 +Subject: USB: serial: ti_usb_3410_5052: fix array underflow in completion handler + +From: Johan Hovold + +commit 5dfdd24eb3d39d815bc952ae98128e967c9bba49 upstream. + +Similarly to a recently reported bug in io_ti, a malicious USB device +could set port_number to a negative value and we would underflow the +port array in the interrupt completion handler. + +As these devices only have one or two ports, fix this by making sure we +only consider the seventh bit when determining the port number (and +ignore bits 0xb0 which are typically set to 0x30). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ti_usb_3410_5052.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -1119,7 +1119,7 @@ static void ti_break(struct tty_struct * + + static int ti_get_port_from_code(unsigned char code) + { +- return (code >> 4) - 3; ++ return (code >> 6) & 0x01; + } + + static int ti_get_func_from_code(unsigned char code) diff --git a/queue-4.18/usb-uas-add-support-for-more-quirk-flags.patch b/queue-4.18/usb-uas-add-support-for-more-quirk-flags.patch new file mode 100644 index 00000000000..f60a8562eb6 --- /dev/null +++ b/queue-4.18/usb-uas-add-support-for-more-quirk-flags.patch @@ -0,0 +1,51 @@ +From 42d1c6d4a06a77b3ab206a919b9050c3080f3a71 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 9 Aug 2018 16:03:37 +0200 +Subject: usb: uas: add support for more quirk flags + +From: Oliver Neukum + +commit 42d1c6d4a06a77b3ab206a919b9050c3080f3a71 upstream. + +The hope that UAS devices would be less broken than old style storage +devices has turned out to be unfounded. Make UAS support more of the +quirk flags of the old driver. + +Signed-off-by: Oliver Neukum +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/uas.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -842,6 +842,27 @@ static int uas_slave_configure(struct sc + sdev->skip_ms_page_8 = 1; + sdev->wce_default_on = 1; + } ++ ++ /* ++ * Some disks return the total number of blocks in response ++ * to READ CAPACITY rather than the highest block number. ++ * If this device makes that mistake, tell the sd driver. ++ */ ++ if (devinfo->flags & US_FL_FIX_CAPACITY) ++ sdev->fix_capacity = 1; ++ ++ /* ++ * Some devices don't like MODE SENSE with page=0x3f, ++ * which is the command used for checking if a device ++ * is write-protected. Now that we tell the sd driver ++ * to do a 192-byte transfer with this command the ++ * majority of devices work fine, but a few still can't ++ * handle it. The sd driver will simply assume those ++ * devices are write-enabled. ++ */ ++ if (devinfo->flags & US_FL_NO_WP_DETECT) ++ sdev->skip_ms_page_3f = 1; ++ + scsi_change_queue_depth(sdev, devinfo->qdepth - 2); + return 0; + } diff --git a/queue-4.18/usb-xhci-fix-interrupt-transfer-error-happened-on-mtk-platforms.patch b/queue-4.18/usb-xhci-fix-interrupt-transfer-error-happened-on-mtk-platforms.patch new file mode 100644 index 00000000000..5b320602c47 --- /dev/null +++ b/queue-4.18/usb-xhci-fix-interrupt-transfer-error-happened-on-mtk-platforms.patch @@ -0,0 +1,42 @@ +From 0a3b53305c8ff427bbc1d9d5bd78524007f19600 Mon Sep 17 00:00:00 2001 +From: Chunfeng Yun +Date: Fri, 7 Sep 2018 15:29:12 +0800 +Subject: usb: xhci: fix interrupt transfer error happened on MTK platforms + +From: Chunfeng Yun + +commit 0a3b53305c8ff427bbc1d9d5bd78524007f19600 upstream. + +The MTK xHCI controller use some reserved bytes in endpoint context for +bandwidth scheduling, so need keep them in xhci_endpoint_copy(); + +The issue is introduced by: +commit f5249461b504 ("xhci: Clear the host side toggle manually when +endpoint is soft reset") +It resets endpoints and will drop bandwidth scheduling parameters used +by interrupt or isochronous endpoints on MTK xHCI controller. +Fixes: f5249461b504 ("xhci: Clear the host side toggle manually when +endpoint is soft reset") + +Cc: stable@vger.kernel.org +Signed-off-by: Chunfeng Yun +Tested-by: Sean Wang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-mem.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1613,6 +1613,10 @@ void xhci_endpoint_copy(struct xhci_hcd + in_ep_ctx->ep_info2 = out_ep_ctx->ep_info2; + in_ep_ctx->deq = out_ep_ctx->deq; + in_ep_ctx->tx_info = out_ep_ctx->tx_info; ++ if (xhci->quirks & XHCI_MTK_HOST) { ++ in_ep_ctx->reserved[0] = out_ep_ctx->reserved[0]; ++ in_ep_ctx->reserved[1] = out_ep_ctx->reserved[1]; ++ } + } + + /* Copy output xhci_slot_ctx to the input xhci_slot_ctx. diff --git a/queue-4.18/usb-yurex-fix-buffer-over-read-in-yurex_write.patch b/queue-4.18/usb-yurex-fix-buffer-over-read-in-yurex_write.patch new file mode 100644 index 00000000000..afa07d0ead1 --- /dev/null +++ b/queue-4.18/usb-yurex-fix-buffer-over-read-in-yurex_write.patch @@ -0,0 +1,55 @@ +From 7e10f14ebface44a48275c8d6dc1caae3668d5a9 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Wed, 15 Aug 2018 21:44:25 +0100 +Subject: USB: yurex: Fix buffer over-read in yurex_write() + +From: Ben Hutchings + +commit 7e10f14ebface44a48275c8d6dc1caae3668d5a9 upstream. + +If the written data starts with a digit, yurex_write() tries to parse +it as an integer using simple_strtoull(). This requires a null- +terminator, and currently there's no guarantee that there is one. + +(The sample program at +https://github.com/NeoCat/YUREX-driver-for-Linux/blob/master/sample/yurex_clock.pl +writes an integer without a null terminator. It seems like it must +have worked by chance!) + +Always add a null byte after the written data. Enlarge the buffer +to allow for this. + +Cc: stable@vger.kernel.org +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/yurex.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/usb/misc/yurex.c ++++ b/drivers/usb/misc/yurex.c +@@ -421,13 +421,13 @@ static ssize_t yurex_write(struct file * + { + struct usb_yurex *dev; + int i, set = 0, retval = 0; +- char buffer[16]; ++ char buffer[16 + 1]; + char *data = buffer; + unsigned long long c, c2 = 0; + signed long timeout = 0; + DEFINE_WAIT(wait); + +- count = min(sizeof(buffer), count); ++ count = min(sizeof(buffer) - 1, count); + dev = file->private_data; + + /* verify that we actually have some data to write */ +@@ -446,6 +446,7 @@ static ssize_t yurex_write(struct file * + retval = -EFAULT; + goto error; + } ++ buffer[count] = 0; + memset(dev->cntl_buffer, CMD_PADDING, YUREX_BUF_SIZE); + + switch (buffer[0]) { diff --git a/queue-4.18/vmbus-don-t-return-values-for-uninitalized-channels.patch b/queue-4.18/vmbus-don-t-return-values-for-uninitalized-channels.patch new file mode 100644 index 00000000000..5883ecd1b53 --- /dev/null +++ b/queue-4.18/vmbus-don-t-return-values-for-uninitalized-channels.patch @@ -0,0 +1,36 @@ +From 6712cc9c22117a8af9f3df272b4a44fd2e4201cd Mon Sep 17 00:00:00 2001 +From: Stephen Hemminger +Date: Mon, 20 Aug 2018 21:16:40 +0000 +Subject: vmbus: don't return values for uninitalized channels + +From: Stephen Hemminger + +commit 6712cc9c22117a8af9f3df272b4a44fd2e4201cd upstream. + +For unsupported device types, the vmbus channel ringbuffer is never +initialized, and therefore reading the sysfs files will return garbage +or cause a kernel OOPS. + +Fixes: c2e5df616e1a ("vmbus: add per-channel sysfs info") + +Signed-off-by: Stephen Hemminger +Signed-off-by: K. Y. Srinivasan +Cc: # 4.15 +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hv/vmbus_drv.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -1178,6 +1178,9 @@ static ssize_t vmbus_chan_attr_show(stru + if (!attribute->show) + return -EIO; + ++ if (chan->state != CHANNEL_OPENED_STATE) ++ return -EINVAL; ++ + return attribute->show(chan, buf); + } + diff --git a/queue-4.18/x86-eisa-don-t-probe-eisa-bus-for-xen-pv-guests.patch b/queue-4.18/x86-eisa-don-t-probe-eisa-bus-for-xen-pv-guests.patch new file mode 100644 index 00000000000..8f727189bb6 --- /dev/null +++ b/queue-4.18/x86-eisa-don-t-probe-eisa-bus-for-xen-pv-guests.patch @@ -0,0 +1,51 @@ +From 6a92b11169a65b3f8cc512c75a252cbd0d096ba0 Mon Sep 17 00:00:00 2001 +From: Boris Ostrovsky +Date: Tue, 11 Sep 2018 15:55:38 -0400 +Subject: x86/EISA: Don't probe EISA bus for Xen PV guests + +From: Boris Ostrovsky + +commit 6a92b11169a65b3f8cc512c75a252cbd0d096ba0 upstream. + +For unprivileged Xen PV guests this is normal memory and ioremap will +not be able to properly map it. + +While at it, since ioremap may return NULL, add a test for pointer's +validity. + +Reported-by: Andy Smith +Signed-off-by: Boris Ostrovsky +Signed-off-by: Thomas Gleixner +Cc: hpa@zytor.com +Cc: xen-devel@lists.xenproject.org +Cc: jgross@suse.com +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20180911195538.23289-1-boris.ostrovsky@oracle.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/eisa.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/arch/x86/kernel/eisa.c ++++ b/arch/x86/kernel/eisa.c +@@ -7,11 +7,17 @@ + #include + #include + ++#include ++ + static __init int eisa_bus_probe(void) + { +- void __iomem *p = ioremap(0x0FFFD9, 4); ++ void __iomem *p; ++ ++ if (xen_pv_domain() && !xen_initial_domain()) ++ return 0; + +- if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24)) ++ p = ioremap(0x0FFFD9, 4); ++ if (p && readl(p) == 'E' + ('I' << 8) + ('S' << 16) + ('A' << 24)) + EISA_bus = 1; + iounmap(p); + return 0; diff --git a/queue-4.18/xen-netfront-fix-waiting-for-xenbus-state-change.patch b/queue-4.18/xen-netfront-fix-waiting-for-xenbus-state-change.patch new file mode 100644 index 00000000000..81e9e45b964 --- /dev/null +++ b/queue-4.18/xen-netfront-fix-waiting-for-xenbus-state-change.patch @@ -0,0 +1,109 @@ +From 8edfe2e992b75aee3da9316e9697c531194c2f53 Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Fri, 7 Sep 2018 14:21:30 +0200 +Subject: xen/netfront: fix waiting for xenbus state change + +From: Juergen Gross + +commit 8edfe2e992b75aee3da9316e9697c531194c2f53 upstream. + +Commit 822fb18a82aba ("xen-netfront: wait xenbus state change when load +module manually") added a new wait queue to wait on for a state change +when the module is loaded manually. Unfortunately there is no wakeup +anywhere to stop that waiting. + +Instead of introducing a new wait queue rename the existing +module_unload_q to module_wq and use it for both purposes (loading and +unloading). + +As any state change of the backend might be intended to stop waiting +do the wake_up_all() in any case when netback_changed() is called. + +Fixes: 822fb18a82aba ("xen-netfront: wait xenbus state change when load module manually") +Cc: #4.18 +Signed-off-by: Juergen Gross +Reviewed-by: Boris Ostrovsky +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/xen-netfront.c | 24 ++++++++++-------------- + 1 file changed, 10 insertions(+), 14 deletions(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -87,8 +87,7 @@ struct netfront_cb { + /* IRQ name is queue name with "-tx" or "-rx" appended */ + #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) + +-static DECLARE_WAIT_QUEUE_HEAD(module_load_q); +-static DECLARE_WAIT_QUEUE_HEAD(module_unload_q); ++static DECLARE_WAIT_QUEUE_HEAD(module_wq); + + struct netfront_stats { + u64 packets; +@@ -1331,11 +1330,11 @@ static struct net_device *xennet_create_ + netif_carrier_off(netdev); + + xenbus_switch_state(dev, XenbusStateInitialising); +- wait_event(module_load_q, +- xenbus_read_driver_state(dev->otherend) != +- XenbusStateClosed && +- xenbus_read_driver_state(dev->otherend) != +- XenbusStateUnknown); ++ wait_event(module_wq, ++ xenbus_read_driver_state(dev->otherend) != ++ XenbusStateClosed && ++ xenbus_read_driver_state(dev->otherend) != ++ XenbusStateUnknown); + return netdev; + + exit: +@@ -2009,15 +2008,14 @@ static void netback_changed(struct xenbu + + dev_dbg(&dev->dev, "%s\n", xenbus_strstate(backend_state)); + ++ wake_up_all(&module_wq); ++ + switch (backend_state) { + case XenbusStateInitialising: + case XenbusStateInitialised: + case XenbusStateReconfiguring: + case XenbusStateReconfigured: +- break; +- + case XenbusStateUnknown: +- wake_up_all(&module_unload_q); + break; + + case XenbusStateInitWait: +@@ -2033,12 +2031,10 @@ static void netback_changed(struct xenbu + break; + + case XenbusStateClosed: +- wake_up_all(&module_unload_q); + if (dev->state == XenbusStateClosed) + break; + /* Missed the backend's CLOSING state -- fallthrough */ + case XenbusStateClosing: +- wake_up_all(&module_unload_q); + xenbus_frontend_closed(dev); + break; + } +@@ -2146,14 +2142,14 @@ static int xennet_remove(struct xenbus_d + + if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) { + xenbus_switch_state(dev, XenbusStateClosing); +- wait_event(module_unload_q, ++ wait_event(module_wq, + xenbus_read_driver_state(dev->otherend) == + XenbusStateClosing || + xenbus_read_driver_state(dev->otherend) == + XenbusStateUnknown); + + xenbus_switch_state(dev, XenbusStateClosed); +- wait_event(module_unload_q, ++ wait_event(module_wq, + xenbus_read_driver_state(dev->otherend) == + XenbusStateClosed || + xenbus_read_driver_state(dev->otherend) == diff --git a/queue-4.18/xhci-fix-use-after-free-for-urb-cancellation-on-a-reallocated-endpoint.patch b/queue-4.18/xhci-fix-use-after-free-for-urb-cancellation-on-a-reallocated-endpoint.patch new file mode 100644 index 00000000000..d6ce3f0d8ce --- /dev/null +++ b/queue-4.18/xhci-fix-use-after-free-for-urb-cancellation-on-a-reallocated-endpoint.patch @@ -0,0 +1,77 @@ +From 4937213ba7fafa13f30496b3965ffe93970d8b53 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Fri, 31 Aug 2018 17:24:43 +0300 +Subject: xhci: Fix use after free for URB cancellation on a reallocated endpoint + +From: Mathias Nyman + +commit 4937213ba7fafa13f30496b3965ffe93970d8b53 upstream. + +Make sure the cancelled URB is on the current endpoint ring. + +If the endpoint ring has been reallocated since the URB was enqueued +then the URB may contain TD and TRB pointers to a already freed ring. +In this the case return the URB without touching any of the freed ring +structure data. + +Don't try to stop the ring. It would be useless. + +This can occur if endpoint is not flushed before it is dropped and +re-added, which is the case in usb_set_interface() as xhci does +things in an odd order. + +Cc: +Tested-by: Sudip Mukherjee +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -37,6 +37,21 @@ static unsigned long long quirks; + module_param(quirks, ullong, S_IRUGO); + MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default"); + ++static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring) ++{ ++ struct xhci_segment *seg = ring->first_seg; ++ ++ if (!td || !td->start_seg) ++ return false; ++ do { ++ if (seg == td->start_seg) ++ return true; ++ seg = seg->next; ++ } while (seg && seg != ring->first_seg); ++ ++ return false; ++} ++ + /* TODO: copied from ehci-hcd.c - can this be refactored? */ + /* + * xhci_handshake - spin reading hc until handshake completes or fails +@@ -1571,6 +1586,21 @@ static int xhci_urb_dequeue(struct usb_h + goto done; + } + ++ /* ++ * check ring is not re-allocated since URB was enqueued. If it is, then ++ * make sure none of the ring related pointers in this URB private data ++ * are touched, such as td_list, otherwise we overwrite freed data ++ */ ++ if (!td_on_ring(&urb_priv->td[0], ep_ring)) { ++ xhci_err(xhci, "Canceled URB td not found on endpoint ring"); ++ for (i = urb_priv->num_tds_done; i < urb_priv->num_tds; i++) { ++ td = &urb_priv->td[i]; ++ if (!list_empty(&td->cancelled_td_list)) ++ list_del_init(&td->cancelled_td_list); ++ } ++ goto err_giveback; ++ } ++ + if (xhci->xhc_state & XHCI_STATE_HALTED) { + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, + "HC halted, freeing TD manually."); diff --git a/queue-4.18/xtensa-iss-don-t-allocate-memory-in-platform_setup.patch b/queue-4.18/xtensa-iss-don-t-allocate-memory-in-platform_setup.patch new file mode 100644 index 00000000000..d6bf5f890b8 --- /dev/null +++ b/queue-4.18/xtensa-iss-don-t-allocate-memory-in-platform_setup.patch @@ -0,0 +1,61 @@ +From ef439d49e0bfb26cd5f03c88b4cb7cc9073ed30c Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Thu, 6 Sep 2018 11:19:20 -0700 +Subject: xtensa: ISS: don't allocate memory in platform_setup + +From: Max Filippov + +commit ef439d49e0bfb26cd5f03c88b4cb7cc9073ed30c upstream. + +Memory allocator is not initialized at that point yet, use static array +instead. + +Cc: stable@vger.kernel.org +Signed-off-by: Max Filippov +Signed-off-by: Greg Kroah-Hartman + +--- + arch/xtensa/platforms/iss/setup.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +--- a/arch/xtensa/platforms/iss/setup.c ++++ b/arch/xtensa/platforms/iss/setup.c +@@ -78,23 +78,28 @@ static struct notifier_block iss_panic_b + + void __init platform_setup(char **p_cmdline) + { ++ static void *argv[COMMAND_LINE_SIZE / sizeof(void *)] __initdata; ++ static char cmdline[COMMAND_LINE_SIZE] __initdata; + int argc = simc_argc(); + int argv_size = simc_argv_size(); + + if (argc > 1) { +- void **argv = alloc_bootmem(argv_size); +- char *cmdline = alloc_bootmem(argv_size); +- int i; ++ if (argv_size > sizeof(argv)) { ++ pr_err("%s: command line too long: argv_size = %d\n", ++ __func__, argv_size); ++ } else { ++ int i; + +- cmdline[0] = 0; +- simc_argv((void *)argv); ++ cmdline[0] = 0; ++ simc_argv((void *)argv); + +- for (i = 1; i < argc; ++i) { +- if (i > 1) +- strcat(cmdline, " "); +- strcat(cmdline, argv[i]); ++ for (i = 1; i < argc; ++i) { ++ if (i > 1) ++ strcat(cmdline, " "); ++ strcat(cmdline, argv[i]); ++ } ++ *p_cmdline = cmdline; + } +- *p_cmdline = cmdline; + } + + atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block);