From c94243d7c3fb361f3e9a33fe075a50d134338ccd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 27 Oct 2019 08:59:34 +0100 Subject: [PATCH] 4.9-stable patches added patches: alsa-hda-realtek-add-support-for-alc711.patch usb-ldusb-fix-memleak-on-disconnect.patch usb-ldusb-fix-read-info-leaks.patch usb-legousbtower-fix-memleak-on-disconnect.patch usb-serial-ti_usb_3410_5052-fix-port-close-races.patch usb-udc-lpc32xx-fix-bad-bit-shift-operation.patch usb-usblp-fix-use-after-free-on-disconnect.patch --- ...a-hda-realtek-add-support-for-alc711.patch | 46 ++++++++++++ queue-4.9/series | 7 ++ .../usb-ldusb-fix-memleak-on-disconnect.patch | 37 +++++++++ queue-4.9/usb-ldusb-fix-read-info-leaks.patch | 75 +++++++++++++++++++ ...gousbtower-fix-memleak-on-disconnect.patch | 37 +++++++++ ...i_usb_3410_5052-fix-port-close-races.patch | 53 +++++++++++++ ...-lpc32xx-fix-bad-bit-shift-operation.patch | 48 ++++++++++++ ...blp-fix-use-after-free-on-disconnect.patch | 51 +++++++++++++ 8 files changed, 354 insertions(+) create mode 100644 queue-4.9/alsa-hda-realtek-add-support-for-alc711.patch create mode 100644 queue-4.9/usb-ldusb-fix-memleak-on-disconnect.patch create mode 100644 queue-4.9/usb-ldusb-fix-read-info-leaks.patch create mode 100644 queue-4.9/usb-legousbtower-fix-memleak-on-disconnect.patch create mode 100644 queue-4.9/usb-serial-ti_usb_3410_5052-fix-port-close-races.patch create mode 100644 queue-4.9/usb-udc-lpc32xx-fix-bad-bit-shift-operation.patch create mode 100644 queue-4.9/usb-usblp-fix-use-after-free-on-disconnect.patch diff --git a/queue-4.9/alsa-hda-realtek-add-support-for-alc711.patch b/queue-4.9/alsa-hda-realtek-add-support-for-alc711.patch new file mode 100644 index 00000000000..32f452364ff --- /dev/null +++ b/queue-4.9/alsa-hda-realtek-add-support-for-alc711.patch @@ -0,0 +1,46 @@ +From 83629532ce45ef9df1f297b419b9ea112045685d Mon Sep 17 00:00:00 2001 +From: Kailang Yang +Date: Thu, 2 May 2019 16:03:26 +0800 +Subject: ALSA: hda/realtek - Add support for ALC711 + +From: Kailang Yang + +commit 83629532ce45ef9df1f297b419b9ea112045685d upstream. + +Support new codec ALC711. + +Signed-off-by: Kailang Yang +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -353,6 +353,7 @@ static void alc_fill_eapd_coef(struct hd + case 0x10ec0700: + case 0x10ec0701: + case 0x10ec0703: ++ case 0x10ec0711: + alc_update_coef_idx(codec, 0x10, 1<<15, 0); + break; + case 0x10ec0662: +@@ -6424,6 +6425,7 @@ static int patch_alc269(struct hda_codec + case 0x10ec0700: + case 0x10ec0701: + case 0x10ec0703: ++ case 0x10ec0711: + spec->codec_variant = ALC269_TYPE_ALC700; + spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */ + alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */ +@@ -7464,6 +7466,7 @@ static const struct hda_device_id snd_hd + HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269), ++ HDA_CODEC_ENTRY(0x10ec0711, "ALC711", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662), + HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880), + HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882), diff --git a/queue-4.9/series b/queue-4.9/series index 9e4ce4840cc..c1dc9f0939b 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -20,3 +20,10 @@ sctp-change-sctp_prot-.no_autobind-with-true.patch net-avoid-potential-infinite-loop-in-tc_ctl_action.patch ipv4-return-enetunreach-if-we-can-t-create-route-but-saddr-is-valid.patch memfd-fix-locking-when-tagging-pins.patch +usb-legousbtower-fix-memleak-on-disconnect.patch +alsa-hda-realtek-add-support-for-alc711.patch +usb-udc-lpc32xx-fix-bad-bit-shift-operation.patch +usb-serial-ti_usb_3410_5052-fix-port-close-races.patch +usb-ldusb-fix-memleak-on-disconnect.patch +usb-usblp-fix-use-after-free-on-disconnect.patch +usb-ldusb-fix-read-info-leaks.patch diff --git a/queue-4.9/usb-ldusb-fix-memleak-on-disconnect.patch b/queue-4.9/usb-ldusb-fix-memleak-on-disconnect.patch new file mode 100644 index 00000000000..90471431182 --- /dev/null +++ b/queue-4.9/usb-ldusb-fix-memleak-on-disconnect.patch @@ -0,0 +1,37 @@ +From b14a39048c1156cfee76228bf449852da2f14df8 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 10 Oct 2019 14:58:34 +0200 +Subject: USB: ldusb: fix memleak on disconnect + +From: Johan Hovold + +commit b14a39048c1156cfee76228bf449852da2f14df8 upstream. + +If disconnect() races with release() after a process has been +interrupted, release() could end up returning early and the driver would +fail to free its driver data. + +Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") +Cc: stable # 2.6.13 +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20191010125835.27031-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/ldusb.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/drivers/usb/misc/ldusb.c ++++ b/drivers/usb/misc/ldusb.c +@@ -384,10 +384,7 @@ static int ld_usb_release(struct inode * + goto exit; + } + +- if (mutex_lock_interruptible(&dev->mutex)) { +- retval = -ERESTARTSYS; +- goto exit; +- } ++ mutex_lock(&dev->mutex); + + if (dev->open_count != 1) { + retval = -ENODEV; diff --git a/queue-4.9/usb-ldusb-fix-read-info-leaks.patch b/queue-4.9/usb-ldusb-fix-read-info-leaks.patch new file mode 100644 index 00000000000..8ae02e49f1d --- /dev/null +++ b/queue-4.9/usb-ldusb-fix-read-info-leaks.patch @@ -0,0 +1,75 @@ +From 7a6f22d7479b7a0b68eadd308a997dd64dda7dae Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 18 Oct 2019 17:19:54 +0200 +Subject: USB: ldusb: fix read info leaks + +From: Johan Hovold + +commit 7a6f22d7479b7a0b68eadd308a997dd64dda7dae upstream. + +Fix broken read implementation, which could be used to trigger slab info +leaks. + +The driver failed to check if the custom ring buffer was still empty +when waking up after having waited for more data. This would happen on +every interrupt-in completion, even if no data had been added to the +ring buffer (e.g. on disconnect events). + +Due to missing sanity checks and uninitialised (kmalloced) ring-buffer +entries, this meant that huge slab info leaks could easily be triggered. + +Note that the empty-buffer check after wakeup is enough to fix the info +leak on disconnect, but let's clear the buffer on allocation and add a +sanity check to read() to prevent further leaks. + +Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") +Cc: stable # 2.6.13 +Reported-by: syzbot+6fe95b826644f7f12b0b@syzkaller.appspotmail.com +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20191018151955.25135-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/ldusb.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/drivers/usb/misc/ldusb.c ++++ b/drivers/usb/misc/ldusb.c +@@ -468,7 +468,7 @@ static ssize_t ld_usb_read(struct file * + + /* wait for data */ + spin_lock_irq(&dev->rbsl); +- if (dev->ring_head == dev->ring_tail) { ++ while (dev->ring_head == dev->ring_tail) { + dev->interrupt_in_done = 0; + spin_unlock_irq(&dev->rbsl); + if (file->f_flags & O_NONBLOCK) { +@@ -479,11 +479,16 @@ static ssize_t ld_usb_read(struct file * + if (retval < 0) + goto unlock_exit; + } else { +- spin_unlock_irq(&dev->rbsl); ++ spin_lock_irq(&dev->rbsl); + } ++ spin_unlock_irq(&dev->rbsl); + + /* actual_buffer contains actual_length + interrupt_in_buffer */ + actual_buffer = (size_t*)(dev->ring_buffer + dev->ring_tail*(sizeof(size_t)+dev->interrupt_in_endpoint_size)); ++ if (*actual_buffer > dev->interrupt_in_endpoint_size) { ++ retval = -EIO; ++ goto unlock_exit; ++ } + bytes_to_read = min(count, *actual_buffer); + if (bytes_to_read < *actual_buffer) + dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n", +@@ -699,7 +704,9 @@ static int ld_usb_probe(struct usb_inter + dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n"); + + dev->interrupt_in_endpoint_size = usb_endpoint_maxp(dev->interrupt_in_endpoint); +- dev->ring_buffer = kmalloc(ring_buffer_size*(sizeof(size_t)+dev->interrupt_in_endpoint_size), GFP_KERNEL); ++ dev->ring_buffer = kcalloc(ring_buffer_size, ++ sizeof(size_t) + dev->interrupt_in_endpoint_size, ++ GFP_KERNEL); + if (!dev->ring_buffer) + goto error; + dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL); diff --git a/queue-4.9/usb-legousbtower-fix-memleak-on-disconnect.patch b/queue-4.9/usb-legousbtower-fix-memleak-on-disconnect.patch new file mode 100644 index 00000000000..13a7482a05b --- /dev/null +++ b/queue-4.9/usb-legousbtower-fix-memleak-on-disconnect.patch @@ -0,0 +1,37 @@ +From b6c03e5f7b463efcafd1ce141bd5a8fc4e583ae2 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 10 Oct 2019 14:58:35 +0200 +Subject: USB: legousbtower: fix memleak on disconnect + +From: Johan Hovold + +commit b6c03e5f7b463efcafd1ce141bd5a8fc4e583ae2 upstream. + +If disconnect() races with release() after a process has been +interrupted, release() could end up returning early and the driver would +fail to free its driver data. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20191010125835.27031-3-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/legousbtower.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/drivers/usb/misc/legousbtower.c ++++ b/drivers/usb/misc/legousbtower.c +@@ -425,10 +425,7 @@ static int tower_release (struct inode * + goto exit; + } + +- if (mutex_lock_interruptible(&dev->lock)) { +- retval = -ERESTARTSYS; +- goto exit; +- } ++ mutex_lock(&dev->lock); + + if (dev->open_count != 1) { + dev_dbg(&dev->udev->dev, "%s: device not opened exactly once\n", diff --git a/queue-4.9/usb-serial-ti_usb_3410_5052-fix-port-close-races.patch b/queue-4.9/usb-serial-ti_usb_3410_5052-fix-port-close-races.patch new file mode 100644 index 00000000000..389961c0adc --- /dev/null +++ b/queue-4.9/usb-serial-ti_usb_3410_5052-fix-port-close-races.patch @@ -0,0 +1,53 @@ +From 6f1d1dc8d540a9aa6e39b9cb86d3a67bbc1c8d8d Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 11 Oct 2019 11:57:35 +0200 +Subject: USB: serial: ti_usb_3410_5052: fix port-close races + +From: Johan Hovold + +commit 6f1d1dc8d540a9aa6e39b9cb86d3a67bbc1c8d8d upstream. + +Fix races between closing a port and opening or closing another port on +the same device which could lead to a failure to start or stop the +shared interrupt URB. The latter could potentially cause a +use-after-free or worse in the completion handler on driver unbind. + +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 | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -778,7 +778,6 @@ static void ti_close(struct usb_serial_p + struct ti_port *tport; + int port_number; + int status; +- int do_unlock; + unsigned long flags; + + tdev = usb_get_serial_data(port->serial); +@@ -802,16 +801,13 @@ static void ti_close(struct usb_serial_p + "%s - cannot send close port command, %d\n" + , __func__, status); + +- /* if mutex_lock is interrupted, continue anyway */ +- do_unlock = !mutex_lock_interruptible(&tdev->td_open_close_lock); ++ mutex_lock(&tdev->td_open_close_lock); + --tport->tp_tdev->td_open_port_count; +- if (tport->tp_tdev->td_open_port_count <= 0) { ++ if (tport->tp_tdev->td_open_port_count == 0) { + /* last port is closed, shut down interrupt urb */ + usb_kill_urb(port->serial->port[0]->interrupt_in_urb); +- tport->tp_tdev->td_open_port_count = 0; + } +- if (do_unlock) +- mutex_unlock(&tdev->td_open_close_lock); ++ mutex_unlock(&tdev->td_open_close_lock); + } + + diff --git a/queue-4.9/usb-udc-lpc32xx-fix-bad-bit-shift-operation.patch b/queue-4.9/usb-udc-lpc32xx-fix-bad-bit-shift-operation.patch new file mode 100644 index 00000000000..03cd5c265ec --- /dev/null +++ b/queue-4.9/usb-udc-lpc32xx-fix-bad-bit-shift-operation.patch @@ -0,0 +1,48 @@ +From b987b66ac3a2bc2f7b03a0ba48a07dc553100c07 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Mon, 14 Oct 2019 14:18:30 -0500 +Subject: usb: udc: lpc32xx: fix bad bit shift operation + +From: Gustavo A. R. Silva + +commit b987b66ac3a2bc2f7b03a0ba48a07dc553100c07 upstream. + +It seems that the right variable to use in this case is *i*, instead of +*n*, otherwise there is an undefined behavior when right shifiting by more +than 31 bits when multiplying n by 8; notice that *n* can take values +equal or greater than 4 (4, 8, 16, ...). + +Also, notice that under the current conditions (bl = 3), we are skiping +the handling of bytes 3, 7, 31... So, fix this by updating this logic +and limit *bl* up to 4 instead of up to 3. + +This fix is based on function udc_stuff_fifo(). + +Addresses-Coverity-ID: 1454834 ("Bad bit shift operation") +Fixes: 24a28e428351 ("USB: gadget driver for LPC32xx") +Cc: stable@vger.kernel.org +Signed-off-by: Gustavo A. R. Silva +Link: https://lore.kernel.org/r/20191014191830.GA10721@embeddedor +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/lpc32xx_udc.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/gadget/udc/lpc32xx_udc.c ++++ b/drivers/usb/gadget/udc/lpc32xx_udc.c +@@ -1178,11 +1178,11 @@ static void udc_pop_fifo(struct lpc32xx_ + tmp = readl(USBD_RXDATA(udc->udp_baseaddr)); + + bl = bytes - n; +- if (bl > 3) +- bl = 3; ++ if (bl > 4) ++ bl = 4; + + for (i = 0; i < bl; i++) +- data[n + i] = (u8) ((tmp >> (n * 8)) & 0xFF); ++ data[n + i] = (u8) ((tmp >> (i * 8)) & 0xFF); + } + break; + diff --git a/queue-4.9/usb-usblp-fix-use-after-free-on-disconnect.patch b/queue-4.9/usb-usblp-fix-use-after-free-on-disconnect.patch new file mode 100644 index 00000000000..529f3ae4c5f --- /dev/null +++ b/queue-4.9/usb-usblp-fix-use-after-free-on-disconnect.patch @@ -0,0 +1,51 @@ +From 7a759197974894213621aa65f0571b51904733d6 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 15 Oct 2019 19:55:22 +0200 +Subject: USB: usblp: fix use-after-free on disconnect + +From: Johan Hovold + +commit 7a759197974894213621aa65f0571b51904733d6 upstream. + +A recent commit addressing a runtime PM use-count regression, introduced +a use-after-free by not making sure we held a reference to the struct +usb_interface for the lifetime of the driver data. + +Fixes: 9a31535859bf ("USB: usblp: fix runtime PM after driver unbind") +Cc: stable +Reported-by: syzbot+cd24df4d075c319ebfc5@syzkaller.appspotmail.com +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20191015175522.18490-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/usblp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/class/usblp.c ++++ b/drivers/usb/class/usblp.c +@@ -458,6 +458,7 @@ static void usblp_cleanup(struct usblp * + kfree(usblp->readbuf); + kfree(usblp->device_id_string); + kfree(usblp->statusbuf); ++ usb_put_intf(usblp->intf); + kfree(usblp); + } + +@@ -1120,7 +1121,7 @@ static int usblp_probe(struct usb_interf + init_waitqueue_head(&usblp->wwait); + init_usb_anchor(&usblp->urbs); + usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; +- usblp->intf = intf; ++ usblp->intf = usb_get_intf(intf); + + /* Malloc device ID string buffer to the largest expected length, + * since we can re-query it on an ioctl and a dynamic string +@@ -1209,6 +1210,7 @@ abort: + kfree(usblp->readbuf); + kfree(usblp->statusbuf); + kfree(usblp->device_id_string); ++ usb_put_intf(usblp->intf); + kfree(usblp); + abort_ret: + return retval; -- 2.47.2