From: Greg Kroah-Hartman Date: Sun, 30 Sep 2018 15:38:40 +0000 (-0700) Subject: 3.18-stable patches X-Git-Tag: v4.18.12~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=98a2fda27e9a1055f96c97dfb50fecc0c618cf4b;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: revert-usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch scsi-target-iscsi-use-bin2hex-instead-of-a-re-implementation.patch staging-android-ion-fix-ion_ioc_-map-share-use-after-free.patch usb-remove-lpm-management-from-usb_driver_claim_interface.patch usb-usbdevfs-restore-warning-for-nonsensical-flags.patch usb-usbdevfs-sanitize-flags-more.patch --- diff --git a/queue-3.18/revert-usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch b/queue-3.18/revert-usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch new file mode 100644 index 00000000000..89a5d85a9e7 --- /dev/null +++ b/queue-3.18/revert-usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch @@ -0,0 +1,35 @@ +From e871db8d78df1c411032cbb3acfdf8930509360e Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Tue, 11 Sep 2018 10:00:44 +0200 +Subject: Revert "usb: cdc-wdm: Fix a sleep-in-atomic-context bug in service_outstanding_interrupt()" + +From: Sebastian Andrzej Siewior + +commit e871db8d78df1c411032cbb3acfdf8930509360e upstream. + +This reverts commit 6e22e3af7bb3a7b9dc53cb4687659f6e63fca427. + +The bug the patch describes to, has been already fixed in commit +2df6948428542 ("USB: cdc-wdm: don't enable interrupts in USB-giveback") +so need to this, revert it. + +Fixes: 6e22e3af7bb3 ("usb: cdc-wdm: Fix a sleep-in-atomic-context bug in service_outstanding_interrupt()") +Cc: stable +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-wdm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -452,7 +452,7 @@ static int clear_wdm_read_flag(struct wd + + set_bit(WDM_RESPONDING, &desc->flags); + spin_unlock_irq(&desc->iuspin); +- rv = usb_submit_urb(desc->response, GFP_ATOMIC); ++ rv = usb_submit_urb(desc->response, GFP_KERNEL); + spin_lock_irq(&desc->iuspin); + if (rv) { + dev_err(&desc->intf->dev, diff --git a/queue-3.18/scsi-target-iscsi-use-bin2hex-instead-of-a-re-implementation.patch b/queue-3.18/scsi-target-iscsi-use-bin2hex-instead-of-a-re-implementation.patch new file mode 100644 index 00000000000..5400878b9a6 --- /dev/null +++ b/queue-3.18/scsi-target-iscsi-use-bin2hex-instead-of-a-re-implementation.patch @@ -0,0 +1,64 @@ +From 8c39e2699f8acb2e29782a834e56306da24937fe Mon Sep 17 00:00:00 2001 +From: Vincent Pelletier +Date: Sun, 9 Sep 2018 04:09:27 +0000 +Subject: scsi: target: iscsi: Use bin2hex instead of a re-implementation + +From: Vincent Pelletier + +commit 8c39e2699f8acb2e29782a834e56306da24937fe upstream. + +Signed-off-by: Vincent Pelletier +Reviewed-by: Mike Christie +Signed-off-by: Martin K. Petersen +[plr.vincent@gmail.com: hunk context change for 4.4 and 4.9, no code change] +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target_auth.c | 15 +++------------ + 1 file changed, 3 insertions(+), 12 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target_auth.c ++++ b/drivers/target/iscsi/iscsi_target_auth.c +@@ -26,15 +26,6 @@ + #include "iscsi_target_nego.h" + #include "iscsi_target_auth.h" + +-static void chap_binaryhex_to_asciihex(char *dst, char *src, int src_len) +-{ +- int i; +- +- for (i = 0; i < src_len; i++) { +- sprintf(&dst[i*2], "%02x", (int) src[i] & 0xff); +- } +-} +- + static void chap_gen_challenge( + struct iscsi_conn *conn, + int caller, +@@ -47,7 +38,7 @@ static void chap_gen_challenge( + memset(challenge_asciihex, 0, CHAP_CHALLENGE_LENGTH * 2 + 1); + + get_random_bytes(chap->challenge, CHAP_CHALLENGE_LENGTH); +- chap_binaryhex_to_asciihex(challenge_asciihex, chap->challenge, ++ bin2hex(challenge_asciihex, chap->challenge, + CHAP_CHALLENGE_LENGTH); + /* + * Set CHAP_C, and copy the generated challenge into c_str. +@@ -287,7 +278,7 @@ static int chap_server_compute_md5( + } + crypto_free_hash(tfm); + +- chap_binaryhex_to_asciihex(response, server_digest, MD5_SIGNATURE_SIZE); ++ bin2hex(response, server_digest, MD5_SIGNATURE_SIZE); + pr_debug("[server] MD5 Server Digest: %s\n", response); + + if (memcmp(server_digest, client_digest, MD5_SIGNATURE_SIZE) != 0) { +@@ -431,7 +422,7 @@ static int chap_server_compute_md5( + /* + * Convert response from binary hex to ascii hext. + */ +- chap_binaryhex_to_asciihex(response, digest, MD5_SIGNATURE_SIZE); ++ bin2hex(response, digest, MD5_SIGNATURE_SIZE); + *nr_out_len += sprintf(nr_out_ptr + *nr_out_len, "CHAP_R=0x%s", + response); + *nr_out_len += 1; diff --git a/queue-3.18/series b/queue-3.18/series index cc6745909b8..2718ab415c7 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -55,3 +55,9 @@ usb-fix-error-handling-in-usb_driver_claim_interface.patch usb-handle-null-config-in-usb_find_alt_setting.patch slub-make-cpu_partial-unsigned-int.patch media-uvcvideo-support-realtek-s-uvc-1.5-device.patch +usb-usbdevfs-sanitize-flags-more.patch +usb-usbdevfs-restore-warning-for-nonsensical-flags.patch +revert-usb-cdc-wdm-fix-a-sleep-in-atomic-context-bug-in-service_outstanding_interrupt.patch +usb-remove-lpm-management-from-usb_driver_claim_interface.patch +scsi-target-iscsi-use-bin2hex-instead-of-a-re-implementation.patch +staging-android-ion-fix-ion_ioc_-map-share-use-after-free.patch diff --git a/queue-3.18/staging-android-ion-fix-ion_ioc_-map-share-use-after-free.patch b/queue-3.18/staging-android-ion-fix-ion_ioc_-map-share-use-after-free.patch new file mode 100644 index 00000000000..052791bbd73 --- /dev/null +++ b/queue-3.18/staging-android-ion-fix-ion_ioc_-map-share-use-after-free.patch @@ -0,0 +1,161 @@ +From 2c155709e4ef2d86d0176aac82e44c048a7e0255 Mon Sep 17 00:00:00 2001 +From: Greg Hackmann +Date: Tue, 4 Sep 2018 09:33:36 -0700 +Subject: staging: android: ion: fix ION_IOC_{MAP,SHARE} use-after-free + +From: Greg Hackmann + +commit 2c155709e4ef2d86d0176aac82e44c048a7e0255 upstream. + +The ION_IOC_{MAP,SHARE} ioctls drop and reacquire client->lock several +times while operating on one of the client's ion_handles. This creates +windows where userspace can call ION_IOC_FREE on the same client with +the same handle, and effectively make the kernel drop its own reference. +For example: + +- thread A: ION_IOC_ALLOC creates an ion_handle with refcount 1 +- thread A: starts ION_IOC_MAP and increments the refcount to 2 +- thread B: ION_IOC_FREE decrements the refcount to 1 +- thread B: ION_IOC_FREE decrements the refcount to 0 and frees the + handle +- thread A: continues ION_IOC_MAP with a dangling ion_handle * to + freed memory + +Fix this by holding client->lock for the duration of +ION_IOC_{MAP,SHARE}, preventing the concurrent ION_IOC_FREE. Also +remove ion_handle_get_by_id(), since there's literally no way to use it +safely. + +This patch is applied on top of 4.4.y, and applies to older kernels +too. 4.9.y was fixed separately. Kernels 4.12 and later are +unaffected, since all the underlying ion_handle infrastructure has been +ripped out. + +Cc: stable@vger.kernel.org # v4.4- +Signed-off-by: Greg Hackmann +Acked-by: Laura Abbott +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/android/ion/ion.c | 60 +++++++++++++++++++++++--------------- + 1 file changed, 37 insertions(+), 23 deletions(-) + +--- a/drivers/staging/android/ion/ion.c ++++ b/drivers/staging/android/ion/ion.c +@@ -451,18 +451,6 @@ static struct ion_handle *ion_handle_get + return ERR_PTR(-EINVAL); + } + +-struct ion_handle *ion_handle_get_by_id(struct ion_client *client, +- int id) +-{ +- struct ion_handle *handle; +- +- mutex_lock(&client->lock); +- handle = ion_handle_get_by_id_nolock(client, id); +- mutex_unlock(&client->lock); +- +- return handle; +-} +- + static bool ion_handle_validate(struct ion_client *client, + struct ion_handle *handle) + { +@@ -1138,23 +1126,27 @@ static struct dma_buf_ops dma_buf_ops = + .kunmap = ion_dma_buf_kunmap, + }; + +-struct dma_buf *ion_share_dma_buf(struct ion_client *client, +- struct ion_handle *handle) ++static struct dma_buf *__ion_share_dma_buf(struct ion_client *client, ++ struct ion_handle *handle, ++ bool lock_client) + { + struct ion_buffer *buffer; + struct dma_buf *dmabuf; + bool valid_handle; + +- mutex_lock(&client->lock); ++ if (lock_client) ++ mutex_lock(&client->lock); + valid_handle = ion_handle_validate(client, handle); + if (!valid_handle) { + WARN(1, "%s: invalid handle passed to share.\n", __func__); +- mutex_unlock(&client->lock); ++ if (lock_client) ++ mutex_unlock(&client->lock); + return ERR_PTR(-EINVAL); + } + buffer = handle->buffer; + ion_buffer_get(buffer); +- mutex_unlock(&client->lock); ++ if (lock_client) ++ mutex_unlock(&client->lock); + + dmabuf = dma_buf_export(buffer, &dma_buf_ops, buffer->size, O_RDWR, + NULL); +@@ -1165,14 +1157,21 @@ struct dma_buf *ion_share_dma_buf(struct + + return dmabuf; + } ++ ++struct dma_buf *ion_share_dma_buf(struct ion_client *client, ++ struct ion_handle *handle) ++{ ++ return __ion_share_dma_buf(client, handle, true); ++} + EXPORT_SYMBOL(ion_share_dma_buf); + +-int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle) ++static int __ion_share_dma_buf_fd(struct ion_client *client, ++ struct ion_handle *handle, bool lock_client) + { + struct dma_buf *dmabuf; + int fd; + +- dmabuf = ion_share_dma_buf(client, handle); ++ dmabuf = __ion_share_dma_buf(client, handle, lock_client); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + +@@ -1182,8 +1181,19 @@ int ion_share_dma_buf_fd(struct ion_clie + + return fd; + } ++ ++int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle) ++{ ++ return __ion_share_dma_buf_fd(client, handle, true); ++} + EXPORT_SYMBOL(ion_share_dma_buf_fd); + ++static int ion_share_dma_buf_fd_nolock(struct ion_client *client, ++ struct ion_handle *handle) ++{ ++ return __ion_share_dma_buf_fd(client, handle, false); ++} ++ + struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd) + { + struct dma_buf *dmabuf; +@@ -1330,11 +1340,15 @@ static long ion_ioctl(struct file *filp, + { + struct ion_handle *handle; + +- handle = ion_handle_get_by_id(client, data.handle.handle); +- if (IS_ERR(handle)) ++ mutex_lock(&client->lock); ++ handle = ion_handle_get_by_id_nolock(client, data.handle.handle); ++ if (IS_ERR(handle)) { ++ mutex_unlock(&client->lock); + return PTR_ERR(handle); +- data.fd.fd = ion_share_dma_buf_fd(client, handle); +- ion_handle_put(handle); ++ } ++ data.fd.fd = ion_share_dma_buf_fd_nolock(client, handle); ++ ion_handle_put_nolock(handle); ++ mutex_unlock(&client->lock); + if (data.fd.fd < 0) + ret = data.fd.fd; + break; diff --git a/queue-3.18/usb-remove-lpm-management-from-usb_driver_claim_interface.patch b/queue-3.18/usb-remove-lpm-management-from-usb_driver_claim_interface.patch new file mode 100644 index 00000000000..efbb58dc6eb --- /dev/null +++ b/queue-3.18/usb-remove-lpm-management-from-usb_driver_claim_interface.patch @@ -0,0 +1,76 @@ +From c183813fcee44a249339b7c46e1ad271ca1870aa Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Mon, 10 Sep 2018 13:58:51 -0400 +Subject: USB: remove LPM management from usb_driver_claim_interface() + +From: Alan Stern + +commit c183813fcee44a249339b7c46e1ad271ca1870aa upstream. + +usb_driver_claim_interface() disables and re-enables Link Power +Management, but it shouldn't do either one, for the reasons listed +below. This patch removes the two LPM-related function calls from the +routine. + +The reason for disabling LPM in the analogous function +usb_probe_interface() is so that drivers won't have to deal with +unwanted LPM transitions in their probe routine. But +usb_driver_claim_interface() doesn't call the driver's probe routine +(or any other callbacks), so that reason doesn't apply here. + +Furthermore, no driver other than usbfs will ever call +usb_driver_claim_interface() unless it is already bound to another +interface in the same device, which means disabling LPM here would be +redundant. usbfs doesn't interact with LPM at all. + +Lastly, the error return from usb_unlocked_disable_lpm() isn't handled +properly; the code doesn't clean up its earlier actions before +returning. + +Signed-off-by: Alan Stern +Fixes: 8306095fd2c1 ("USB: Disable USB 3.0 LPM in critical sections.") +CC: +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/driver.c | 15 --------------- + 1 file changed, 15 deletions(-) + +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -506,7 +506,6 @@ int usb_driver_claim_interface(struct us + struct device *dev; + struct usb_device *udev; + int retval = 0; +- int lpm_disable_error = -ENODEV; + + if (!iface) + return -ENODEV; +@@ -523,16 +522,6 @@ int usb_driver_claim_interface(struct us + + iface->condition = USB_INTERFACE_BOUND; + +- /* See the comment about disabling LPM in usb_probe_interface(). */ +- if (driver->disable_hub_initiated_lpm) { +- lpm_disable_error = usb_unlocked_disable_lpm(udev); +- if (lpm_disable_error) { +- dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.", +- __func__, driver->name); +- return -ENOMEM; +- } +- } +- + /* Claimed interfaces are initially inactive (suspended) and + * runtime-PM-enabled, but only if the driver has autosuspend + * support. Otherwise they are marked active, to prevent the +@@ -551,10 +540,6 @@ int usb_driver_claim_interface(struct us + if (device_is_registered(dev)) + retval = device_bind_driver(dev); + +- /* Attempt to re-enable USB3 LPM, if the disable was successful. */ +- if (!lpm_disable_error) +- usb_unlocked_enable_lpm(udev); +- + if (retval) { + dev->driver = NULL; + usb_set_intfdata(iface, NULL); diff --git a/queue-3.18/usb-usbdevfs-restore-warning-for-nonsensical-flags.patch b/queue-3.18/usb-usbdevfs-restore-warning-for-nonsensical-flags.patch new file mode 100644 index 00000000000..afad3eaf079 --- /dev/null +++ b/queue-3.18/usb-usbdevfs-restore-warning-for-nonsensical-flags.patch @@ -0,0 +1,35 @@ +From 81e0403b26d94360abd1f6a57311337973bc82cd Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Wed, 5 Sep 2018 12:07:03 +0200 +Subject: USB: usbdevfs: restore warning for nonsensical flags + +From: Oliver Neukum + +commit 81e0403b26d94360abd1f6a57311337973bc82cd upstream. + +If we filter flags before they reach the core we need to generate our +own warnings. + +Signed-off-by: Oliver Neukum +Fixes: 0cb54a3e47cb ("USB: debugging code shouldn't alter control flow") +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/devio.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -1531,6 +1531,11 @@ static int proc_do_submiturb(struct usb_ + u |= URB_NO_INTERRUPT; + as->urb->transfer_flags = u; + ++ if (!allow_short && uurb->flags & USBDEVFS_URB_SHORT_NOT_OK) ++ dev_warn(&ps->dev->dev, "Requested nonsensical USBDEVFS_URB_SHORT_NOT_OK.\n"); ++ if (!allow_zero && uurb->flags & USBDEVFS_URB_ZERO_PACKET) ++ dev_warn(&ps->dev->dev, "Requested nonsensical USBDEVFS_URB_ZERO_PACKET.\n"); ++ + as->urb->transfer_buffer_length = uurb->buffer_length; + as->urb->setup_packet = (unsigned char *)dr; + dr = NULL; diff --git a/queue-3.18/usb-usbdevfs-sanitize-flags-more.patch b/queue-3.18/usb-usbdevfs-sanitize-flags-more.patch new file mode 100644 index 00000000000..dfb8df7ab3f --- /dev/null +++ b/queue-3.18/usb-usbdevfs-sanitize-flags-more.patch @@ -0,0 +1,88 @@ +From 7a68d9fb851012829c29e770621905529bd9490b Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Wed, 5 Sep 2018 12:07:02 +0200 +Subject: USB: usbdevfs: sanitize flags more + +From: Oliver Neukum + +commit 7a68d9fb851012829c29e770621905529bd9490b upstream. + +Requesting a ZERO_PACKET or not is sensible only for output. +In the input direction the device decides. +Likewise accepting short packets makes sense only for input. + +This allows operation with panic_on_warn without opening up +a local DOS. + +Signed-off-by: Oliver Neukum +Reported-by: syzbot+843efa30c8821bd69f53@syzkaller.appspotmail.com +Fixes: 0cb54a3e47cb ("USB: debugging code shouldn't alter control flow") +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/devio.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -1286,10 +1286,13 @@ static int proc_do_submiturb(struct usb_ + struct async *as = NULL; + struct usb_ctrlrequest *dr = NULL; + unsigned int u, totlen, isofrmlen; +- int i, ret, is_in, num_sgs = 0, ifnum = -1; ++ int i, ret, num_sgs = 0, ifnum = -1; + int number_of_packets = 0; + unsigned int stream_id = 0; + void *buf; ++ bool is_in; ++ bool allow_short = false; ++ bool allow_zero = false; + unsigned long mask = USBDEVFS_URB_SHORT_NOT_OK | + USBDEVFS_URB_BULK_CONTINUATION | + USBDEVFS_URB_NO_FSBR | +@@ -1323,6 +1326,8 @@ static int proc_do_submiturb(struct usb_ + u = 0; + switch(uurb->type) { + case USBDEVFS_URB_TYPE_CONTROL: ++ if (is_in) ++ allow_short = true; + if (!usb_endpoint_xfer_control(&ep->desc)) + return -EINVAL; + /* min 8 byte setup packet */ +@@ -1363,6 +1368,10 @@ static int proc_do_submiturb(struct usb_ + break; + + case USBDEVFS_URB_TYPE_BULK: ++ if (!is_in) ++ allow_zero = true; ++ else ++ allow_short = true; + switch (usb_endpoint_type(&ep->desc)) { + case USB_ENDPOINT_XFER_CONTROL: + case USB_ENDPOINT_XFER_ISOC: +@@ -1383,6 +1392,10 @@ static int proc_do_submiturb(struct usb_ + if (!usb_endpoint_xfer_int(&ep->desc)) + return -EINVAL; + interrupt_urb: ++ if (!is_in) ++ allow_zero = true; ++ else ++ allow_short = true; + break; + + case USBDEVFS_URB_TYPE_ISO: +@@ -1508,11 +1521,11 @@ static int proc_do_submiturb(struct usb_ + u = (is_in ? URB_DIR_IN : URB_DIR_OUT); + if (uurb->flags & USBDEVFS_URB_ISO_ASAP) + u |= URB_ISO_ASAP; +- if (uurb->flags & USBDEVFS_URB_SHORT_NOT_OK && is_in) ++ if (allow_short && uurb->flags & USBDEVFS_URB_SHORT_NOT_OK) + u |= URB_SHORT_NOT_OK; + if (uurb->flags & USBDEVFS_URB_NO_FSBR) + u |= URB_NO_FSBR; +- if (uurb->flags & USBDEVFS_URB_ZERO_PACKET) ++ if (allow_zero && uurb->flags & USBDEVFS_URB_ZERO_PACKET) + u |= URB_ZERO_PACKET; + if (uurb->flags & USBDEVFS_URB_NO_INTERRUPT) + u |= URB_NO_INTERRUPT;