From: Greg Kroah-Hartman Date: Mon, 22 May 2017 10:24:55 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v3.18.55~63 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=78ae8c80dabfce0f6fcfb67a131265a41416a07b;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: alsa-hda-fix-cpu-lockup-when-stopping-the-cmd-dmas.patch char-lp-fix-possible-integer-overflow-in-lp_setup.patch tpm_tis_core-choose-appropriate-timeout-for-reading-burstcount.patch usb-core-replace-p-with-pk.patch usb-ene_usb6250-fix-dma-to-the-stack.patch watchdog-pcwd_usb-fix-null-deref-at-probe.patch --- diff --git a/queue-4.9/alsa-hda-fix-cpu-lockup-when-stopping-the-cmd-dmas.patch b/queue-4.9/alsa-hda-fix-cpu-lockup-when-stopping-the-cmd-dmas.patch new file mode 100644 index 00000000000..8025d1c0f83 --- /dev/null +++ b/queue-4.9/alsa-hda-fix-cpu-lockup-when-stopping-the-cmd-dmas.patch @@ -0,0 +1,70 @@ +From 960013762df0a214b57f2fce655422fb52bdfd2c Mon Sep 17 00:00:00 2001 +From: Jeeja KP +Date: Wed, 10 May 2017 11:51:58 +0530 +Subject: ALSA: hda: Fix cpu lockup when stopping the cmd dmas + +From: Jeeja KP + +commit 960013762df0a214b57f2fce655422fb52bdfd2c upstream. + +Using jiffies in hdac_wait_for_cmd_dmas() to determine when to time out +when interrupts are off (snd_hdac_bus_stop_cmd_io()/spin_lock_irq()) +causes hard lockup so unlock while waiting using jiffies. + +---<-snip->--- +<0>[ 1211.603046] NMI watchdog: Watchdog detected hard LOCKUP on cpu 3 +<4>[ 1211.603047] Modules linked in: snd_hda_intel i915 vgem +<4>[ 1211.603053] irq event stamp: 13366 +<4>[ 1211.603053] hardirqs last enabled at (13365): +... +<4>[ 1211.603059] Call Trace: +<4>[ 1211.603059] ? delay_tsc+0x3d/0xc0 +<4>[ 1211.603059] __delay+0xa/0x10 +<4>[ 1211.603060] __const_udelay+0x31/0x40 +<4>[ 1211.603060] snd_hdac_bus_stop_cmd_io+0x96/0xe0 [snd_hda_core] +<4>[ 1211.603060] ? azx_dev_disconnect+0x20/0x20 [snd_hda_intel] +<4>[ 1211.603061] snd_hdac_bus_stop_chip+0xb1/0x100 [snd_hda_core] +<4>[ 1211.603061] azx_stop_chip+0x9/0x10 [snd_hda_codec] +<4>[ 1211.603061] azx_suspend+0x72/0x220 [snd_hda_intel] +<4>[ 1211.603061] pci_pm_suspend+0x71/0x140 +<4>[ 1211.603062] dpm_run_callback+0x6f/0x330 +<4>[ 1211.603062] ? pci_pm_freeze+0xe0/0xe0 +<4>[ 1211.603062] __device_suspend+0xf9/0x370 +<4>[ 1211.603062] ? dpm_watchdog_set+0x60/0x60 +<4>[ 1211.603063] async_suspend+0x1a/0x90 +<4>[ 1211.603063] async_run_entry_fn+0x34/0x160 +<4>[ 1211.603063] process_one_work+0x1f4/0x6d0 +<4>[ 1211.603063] ? process_one_work+0x16e/0x6d0 +<4>[ 1211.603064] worker_thread+0x49/0x4a0 +<4>[ 1211.603064] kthread+0x107/0x140 +<4>[ 1211.603064] ? process_one_work+0x6d0/0x6d0 +<4>[ 1211.603065] ? kthread_create_on_node+0x40/0x40 +<4>[ 1211.603065] ret_from_fork+0x2e/0x40 + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100419 +Fixes: 38b19ed7f81ec ("ALSA: hda: fix to wait for RIRB & CORB DMA to set") +Reported-by: Marta Lofstedt +Suggested-by: Takashi Iwai +Signed-off-by: Jeeja KP +Acked-by: Vinod Koul +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/hda/hdac_controller.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/sound/hda/hdac_controller.c ++++ b/sound/hda/hdac_controller.c +@@ -106,7 +106,11 @@ void snd_hdac_bus_stop_cmd_io(struct hda + /* disable ringbuffer DMAs */ + snd_hdac_chip_writeb(bus, RIRBCTL, 0); + snd_hdac_chip_writeb(bus, CORBCTL, 0); ++ spin_unlock_irq(&bus->reg_lock); ++ + hdac_wait_for_cmd_dmas(bus); ++ ++ spin_lock_irq(&bus->reg_lock); + /* disable unsolicited responses */ + snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, 0); + spin_unlock_irq(&bus->reg_lock); diff --git a/queue-4.9/char-lp-fix-possible-integer-overflow-in-lp_setup.patch b/queue-4.9/char-lp-fix-possible-integer-overflow-in-lp_setup.patch new file mode 100644 index 00000000000..e640e827f94 --- /dev/null +++ b/queue-4.9/char-lp-fix-possible-integer-overflow-in-lp_setup.patch @@ -0,0 +1,37 @@ +From 3e21f4af170bebf47c187c1ff8bf155583c9f3b1 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Tue, 16 May 2017 19:18:55 +0200 +Subject: char: lp: fix possible integer overflow in lp_setup() + +From: Willy Tarreau + +commit 3e21f4af170bebf47c187c1ff8bf155583c9f3b1 upstream. + +The lp_setup() code doesn't apply any bounds checking when passing +"lp=none", and only in this case, resulting in an overflow of the +parport_nr[] array. All versions in Git history are affected. + +Reported-By: Roee Hay +Cc: Ben Hutchings +Signed-off-by: Willy Tarreau +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/lp.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/char/lp.c ++++ b/drivers/char/lp.c +@@ -859,7 +859,11 @@ static int __init lp_setup (char *str) + } else if (!strcmp(str, "auto")) { + parport_nr[0] = LP_PARPORT_AUTO; + } else if (!strcmp(str, "none")) { +- parport_nr[parport_ptr++] = LP_PARPORT_NONE; ++ if (parport_ptr < LP_NO) ++ parport_nr[parport_ptr++] = LP_PARPORT_NONE; ++ else ++ printk(KERN_INFO "lp: too many ports, %s ignored.\n", ++ str); + } else if (!strcmp(str, "reset")) { + reset = 1; + } diff --git a/queue-4.9/series b/queue-4.9/series index 6750907e221..ad3721b20cc 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -1,2 +1,8 @@ usb-misc-legousbtower-fix-buffers-on-stack.patch usb-misc-legousbtower-fix-memory-leak.patch +usb-ene_usb6250-fix-dma-to-the-stack.patch +watchdog-pcwd_usb-fix-null-deref-at-probe.patch +char-lp-fix-possible-integer-overflow-in-lp_setup.patch +usb-core-replace-p-with-pk.patch +tpm_tis_core-choose-appropriate-timeout-for-reading-burstcount.patch +alsa-hda-fix-cpu-lockup-when-stopping-the-cmd-dmas.patch diff --git a/queue-4.9/tpm_tis_core-choose-appropriate-timeout-for-reading-burstcount.patch b/queue-4.9/tpm_tis_core-choose-appropriate-timeout-for-reading-burstcount.patch new file mode 100644 index 00000000000..8670d5c7248 --- /dev/null +++ b/queue-4.9/tpm_tis_core-choose-appropriate-timeout-for-reading-burstcount.patch @@ -0,0 +1,49 @@ +From 302a6ad7fc77146191126a1f3e2c5d724fd72416 Mon Sep 17 00:00:00 2001 +From: Alexander Steffen +Date: Thu, 16 Feb 2017 15:33:36 +0000 +Subject: tpm_tis_core: Choose appropriate timeout for reading burstcount + +From: Alexander Steffen + +commit 302a6ad7fc77146191126a1f3e2c5d724fd72416 upstream. + +TIS v1.3 for TPM 1.2 and PTP for TPM 2.0 disagree about which timeout +value applies to reading a valid burstcount. It is TIMEOUT_D according to +TIS, but TIMEOUT_A according to PTP, so choose the appropriate value +depending on whether we deal with a TPM 1.2 or a TPM 2.0. + +This is important since according to the PTP TIMEOUT_D is much smaller +than TIMEOUT_A. So the previous implementation could run into timeouts +with a TPM 2.0, even though the TPM was behaving perfectly fine. + +During tpm2_probe TIMEOUT_D will be used even with a TPM 2.0, because +TPM_CHIP_FLAG_TPM2 is not yet set. This is fine, since the timeout values +will only be changed afterwards by tpm_get_timeouts. Until then +TIS_TIMEOUT_D_MAX applies, which is large enough. + +Fixes: aec04cbdf723 ("tpm: TPM 2.0 FIFO Interface") +Signed-off-by: Alexander Steffen +Signed-off-by: Peter Huewe +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm_tis_core.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -160,8 +160,10 @@ static int get_burstcount(struct tpm_chi + u32 value; + + /* wait for burstcount */ +- /* which timeout value, spec has 2 answers (c & d) */ +- stop = jiffies + chip->timeout_d; ++ if (chip->flags & TPM_CHIP_FLAG_TPM2) ++ stop = jiffies + chip->timeout_a; ++ else ++ stop = jiffies + chip->timeout_d; + do { + rc = tpm_tis_read32(priv, TPM_STS(priv->locality), &value); + if (rc < 0) diff --git a/queue-4.9/usb-core-replace-p-with-pk.patch b/queue-4.9/usb-core-replace-p-with-pk.patch new file mode 100644 index 00000000000..358a34f8ff3 --- /dev/null +++ b/queue-4.9/usb-core-replace-p-with-pk.patch @@ -0,0 +1,121 @@ +From 2f964780c03b73de269b08d12aff96a9618d13f3 Mon Sep 17 00:00:00 2001 +From: Vamsi Krishna Samavedam +Date: Tue, 16 May 2017 14:38:08 +0200 +Subject: USB: core: replace %p with %pK + +From: Vamsi Krishna Samavedam + +commit 2f964780c03b73de269b08d12aff96a9618d13f3 upstream. + +Format specifier %p can leak kernel addresses while not valuing the +kptr_restrict system settings. When kptr_restrict is set to (1), kernel +pointers printed using the %pK format specifier will be replaced with +Zeros. Debugging Note : &pK prints only Zeros as address. If you need +actual address information, write 0 to kptr_restrict. + +echo 0 > /proc/sys/kernel/kptr_restrict + +[Found by poking around in a random vendor kernel tree, it would be nice +if someone would actually send these types of patches upstream - gkh] + +Signed-off-by: Vamsi Krishna Samavedam +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/devio.c | 14 +++++++------- + drivers/usb/core/hcd.c | 4 ++-- + drivers/usb/core/urb.c | 2 +- + 3 files changed, 10 insertions(+), 10 deletions(-) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -481,11 +481,11 @@ static void snoop_urb(struct usb_device + + if (userurb) { /* Async */ + if (when == SUBMIT) +- dev_info(&udev->dev, "userurb %p, ep%d %s-%s, " ++ dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, " + "length %u\n", + userurb, ep, t, d, length); + else +- dev_info(&udev->dev, "userurb %p, ep%d %s-%s, " ++ dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, " + "actual_length %u status %d\n", + userurb, ep, t, d, length, + timeout_or_status); +@@ -1905,7 +1905,7 @@ static int proc_reapurb(struct usb_dev_s + if (as) { + int retval; + +- snoop(&ps->dev->dev, "reap %p\n", as->userurb); ++ snoop(&ps->dev->dev, "reap %pK\n", as->userurb); + retval = processcompl(as, (void __user * __user *)arg); + free_async(as); + return retval; +@@ -1922,7 +1922,7 @@ static int proc_reapurbnonblock(struct u + + as = async_getcompleted(ps); + if (as) { +- snoop(&ps->dev->dev, "reap %p\n", as->userurb); ++ snoop(&ps->dev->dev, "reap %pK\n", as->userurb); + retval = processcompl(as, (void __user * __user *)arg); + free_async(as); + } else { +@@ -2053,7 +2053,7 @@ static int proc_reapurb_compat(struct us + if (as) { + int retval; + +- snoop(&ps->dev->dev, "reap %p\n", as->userurb); ++ snoop(&ps->dev->dev, "reap %pK\n", as->userurb); + retval = processcompl_compat(as, (void __user * __user *)arg); + free_async(as); + return retval; +@@ -2070,7 +2070,7 @@ static int proc_reapurbnonblock_compat(s + + as = async_getcompleted(ps); + if (as) { +- snoop(&ps->dev->dev, "reap %p\n", as->userurb); ++ snoop(&ps->dev->dev, "reap %pK\n", as->userurb); + retval = processcompl_compat(as, (void __user * __user *)arg); + free_async(as); + } else { +@@ -2499,7 +2499,7 @@ static long usbdev_do_ioctl(struct file + #endif + + case USBDEVFS_DISCARDURB: +- snoop(&dev->dev, "%s: DISCARDURB %p\n", __func__, p); ++ snoop(&dev->dev, "%s: DISCARDURB %pK\n", __func__, p); + ret = proc_unlinkurb(ps, p); + break; + +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -1722,7 +1722,7 @@ int usb_hcd_unlink_urb (struct urb *urb, + if (retval == 0) + retval = -EINPROGRESS; + else if (retval != -EIDRM && retval != -EBUSY) +- dev_dbg(&udev->dev, "hcd_unlink_urb %p fail %d\n", ++ dev_dbg(&udev->dev, "hcd_unlink_urb %pK fail %d\n", + urb, retval); + usb_put_dev(udev); + } +@@ -1889,7 +1889,7 @@ rescan: + /* kick hcd */ + unlink1(hcd, urb, -ESHUTDOWN); + dev_dbg (hcd->self.controller, +- "shutdown urb %p ep%d%s%s\n", ++ "shutdown urb %pK ep%d%s%s\n", + urb, usb_endpoint_num(&ep->desc), + is_in ? "in" : "out", + ({ char *s; +--- a/drivers/usb/core/urb.c ++++ b/drivers/usb/core/urb.c +@@ -333,7 +333,7 @@ int usb_submit_urb(struct urb *urb, gfp_ + if (!urb || !urb->complete) + return -EINVAL; + if (urb->hcpriv) { +- WARN_ONCE(1, "URB %p submitted while active\n", urb); ++ WARN_ONCE(1, "URB %pK submitted while active\n", urb); + return -EBUSY; + } + diff --git a/queue-4.9/usb-ene_usb6250-fix-dma-to-the-stack.patch b/queue-4.9/usb-ene_usb6250-fix-dma-to-the-stack.patch new file mode 100644 index 00000000000..fc726434f54 --- /dev/null +++ b/queue-4.9/usb-ene_usb6250-fix-dma-to-the-stack.patch @@ -0,0 +1,298 @@ +From 628c2893d44876ddd11602400c70606ade62e129 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 16 May 2017 11:47:29 -0400 +Subject: USB: ene_usb6250: fix DMA to the stack + +From: Alan Stern + +commit 628c2893d44876ddd11602400c70606ade62e129 upstream. + +The ene_usb6250 sub-driver in usb-storage does USB I/O to buffers on +the stack, which doesn't work with vmapped stacks. This patch fixes +the problem by allocating a separate 512-byte buffer at probe time and +using it for all of the offending I/O operations. + +Signed-off-by: Alan Stern +Reported-and-tested-by: Andreas Hartmann +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/ene_ub6250.c | 90 +++++++++++++++++++++++---------------- + 1 file changed, 55 insertions(+), 35 deletions(-) + +--- a/drivers/usb/storage/ene_ub6250.c ++++ b/drivers/usb/storage/ene_ub6250.c +@@ -446,6 +446,10 @@ struct ms_lib_ctrl { + #define SD_BLOCK_LEN 9 + + struct ene_ub6250_info { ++ ++ /* I/O bounce buffer */ ++ u8 *bbuf; ++ + /* for 6250 code */ + struct SD_STATUS SD_Status; + struct MS_STATUS MS_Status; +@@ -493,8 +497,11 @@ static int ene_load_bincode(struct us_da + + static void ene_ub6250_info_destructor(void *extra) + { ++ struct ene_ub6250_info *info = (struct ene_ub6250_info *) extra; ++ + if (!extra) + return; ++ kfree(info->bbuf); + } + + static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg) +@@ -860,8 +867,9 @@ static int ms_read_readpage(struct us_da + u8 PageNum, u32 *PageBuf, struct ms_lib_type_extdat *ExtraDat) + { + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; ++ struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; ++ u8 *bbuf = info->bbuf; + int result; +- u8 ExtBuf[4]; + u32 bn = PhyBlockAddr * 0x20 + PageNum; + + result = ene_load_bincode(us, MS_RW_PATTERN); +@@ -901,7 +909,7 @@ static int ms_read_readpage(struct us_da + bcb->CDB[2] = (unsigned char)(PhyBlockAddr>>16); + bcb->CDB[6] = 0x01; + +- result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0); ++ result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + +@@ -910,9 +918,9 @@ static int ms_read_readpage(struct us_da + ExtraDat->status0 = 0x10; /* Not yet,fireware support */ + + ExtraDat->status1 = 0x00; /* Not yet,fireware support */ +- ExtraDat->ovrflg = ExtBuf[0]; +- ExtraDat->mngflg = ExtBuf[1]; +- ExtraDat->logadr = memstick_logaddr(ExtBuf[2], ExtBuf[3]); ++ ExtraDat->ovrflg = bbuf[0]; ++ ExtraDat->mngflg = bbuf[1]; ++ ExtraDat->logadr = memstick_logaddr(bbuf[2], bbuf[3]); + + return USB_STOR_TRANSPORT_GOOD; + } +@@ -1332,8 +1340,9 @@ static int ms_lib_read_extra(struct us_d + u8 PageNum, struct ms_lib_type_extdat *ExtraDat) + { + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; ++ struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; ++ u8 *bbuf = info->bbuf; + int result; +- u8 ExtBuf[4]; + + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); +@@ -1347,7 +1356,7 @@ static int ms_lib_read_extra(struct us_d + bcb->CDB[2] = (unsigned char)(PhyBlock>>16); + bcb->CDB[6] = 0x01; + +- result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0); ++ result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + +@@ -1355,9 +1364,9 @@ static int ms_lib_read_extra(struct us_d + ExtraDat->intr = 0x80; /* Not yet, waiting for fireware support */ + ExtraDat->status0 = 0x10; /* Not yet, waiting for fireware support */ + ExtraDat->status1 = 0x00; /* Not yet, waiting for fireware support */ +- ExtraDat->ovrflg = ExtBuf[0]; +- ExtraDat->mngflg = ExtBuf[1]; +- ExtraDat->logadr = memstick_logaddr(ExtBuf[2], ExtBuf[3]); ++ ExtraDat->ovrflg = bbuf[0]; ++ ExtraDat->mngflg = bbuf[1]; ++ ExtraDat->logadr = memstick_logaddr(bbuf[2], bbuf[3]); + + return USB_STOR_TRANSPORT_GOOD; + } +@@ -1558,9 +1567,9 @@ static int ms_lib_scan_logicalblocknumbe + u16 PhyBlock, newblk, i; + u16 LogStart, LogEnde; + struct ms_lib_type_extdat extdat; +- u8 buf[0x200]; + u32 count = 0, index = 0; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; ++ u8 *bbuf = info->bbuf; + + for (PhyBlock = 0; PhyBlock < info->MS_Lib.NumberOfPhyBlock;) { + ms_lib_phy_to_log_range(PhyBlock, &LogStart, &LogEnde); +@@ -1574,14 +1583,16 @@ static int ms_lib_scan_logicalblocknumbe + } + + if (count == PhyBlock) { +- ms_lib_read_extrablock(us, PhyBlock, 0, 0x80, &buf); ++ ms_lib_read_extrablock(us, PhyBlock, 0, 0x80, ++ bbuf); + count += 0x80; + } + index = (PhyBlock % 0x80) * 4; + +- extdat.ovrflg = buf[index]; +- extdat.mngflg = buf[index+1]; +- extdat.logadr = memstick_logaddr(buf[index+2], buf[index+3]); ++ extdat.ovrflg = bbuf[index]; ++ extdat.mngflg = bbuf[index+1]; ++ extdat.logadr = memstick_logaddr(bbuf[index+2], ++ bbuf[index+3]); + + if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) { + ms_lib_setacquired_errorblock(us, PhyBlock); +@@ -2064,9 +2075,9 @@ static int ene_ms_init(struct us_data *u + { + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; +- u8 buf[0x200]; + u16 MSP_BlockSize, MSP_UserAreaBlocks; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; ++ u8 *bbuf = info->bbuf; + + printk(KERN_INFO "transport --- ENE_MSInit\n"); + +@@ -2085,13 +2096,13 @@ static int ene_ms_init(struct us_data *u + bcb->CDB[0] = 0xF1; + bcb->CDB[1] = 0x01; + +- result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0); ++ result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR "Execution MS Init Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + /* the same part to test ENE */ +- info->MS_Status = *(struct MS_STATUS *)&buf[0]; ++ info->MS_Status = *(struct MS_STATUS *) bbuf; + + if (info->MS_Status.Insert && info->MS_Status.Ready) { + printk(KERN_INFO "Insert = %x\n", info->MS_Status.Insert); +@@ -2100,15 +2111,15 @@ static int ene_ms_init(struct us_data *u + printk(KERN_INFO "IsMSPHG = %x\n", info->MS_Status.IsMSPHG); + printk(KERN_INFO "WtP= %x\n", info->MS_Status.WtP); + if (info->MS_Status.IsMSPro) { +- MSP_BlockSize = (buf[6] << 8) | buf[7]; +- MSP_UserAreaBlocks = (buf[10] << 8) | buf[11]; ++ MSP_BlockSize = (bbuf[6] << 8) | bbuf[7]; ++ MSP_UserAreaBlocks = (bbuf[10] << 8) | bbuf[11]; + info->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks; + } else { + ms_card_init(us); /* Card is MS (to ms.c)*/ + } + usb_stor_dbg(us, "MS Init Code OK !!\n"); + } else { +- usb_stor_dbg(us, "MS Card Not Ready --- %x\n", buf[0]); ++ usb_stor_dbg(us, "MS Card Not Ready --- %x\n", bbuf[0]); + return USB_STOR_TRANSPORT_ERROR; + } + +@@ -2118,9 +2129,9 @@ static int ene_ms_init(struct us_data *u + static int ene_sd_init(struct us_data *us) + { + int result; +- u8 buf[0x200]; + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; ++ u8 *bbuf = info->bbuf; + + usb_stor_dbg(us, "transport --- ENE_SDInit\n"); + /* SD Init Part-1 */ +@@ -2154,17 +2165,17 @@ static int ene_sd_init(struct us_data *u + bcb->Flags = US_BULK_FLAG_IN; + bcb->CDB[0] = 0xF1; + +- result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0); ++ result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0); + if (result != USB_STOR_XFER_GOOD) { + usb_stor_dbg(us, "Execution SD Init Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + +- info->SD_Status = *(struct SD_STATUS *)&buf[0]; ++ info->SD_Status = *(struct SD_STATUS *) bbuf; + if (info->SD_Status.Insert && info->SD_Status.Ready) { + struct SD_STATUS *s = &info->SD_Status; + +- ene_get_card_status(us, (unsigned char *)&buf); ++ ene_get_card_status(us, bbuf); + usb_stor_dbg(us, "Insert = %x\n", s->Insert); + usb_stor_dbg(us, "Ready = %x\n", s->Ready); + usb_stor_dbg(us, "IsMMC = %x\n", s->IsMMC); +@@ -2172,7 +2183,7 @@ static int ene_sd_init(struct us_data *u + usb_stor_dbg(us, "HiSpeed = %x\n", s->HiSpeed); + usb_stor_dbg(us, "WtP = %x\n", s->WtP); + } else { +- usb_stor_dbg(us, "SD Card Not Ready --- %x\n", buf[0]); ++ usb_stor_dbg(us, "SD Card Not Ready --- %x\n", bbuf[0]); + return USB_STOR_TRANSPORT_ERROR; + } + return USB_STOR_TRANSPORT_GOOD; +@@ -2182,13 +2193,15 @@ static int ene_sd_init(struct us_data *u + static int ene_init(struct us_data *us) + { + int result; +- u8 misc_reg03 = 0; ++ u8 misc_reg03; + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); ++ u8 *bbuf = info->bbuf; + +- result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03); ++ result = ene_get_card_type(us, REG_CARD_STATUS, bbuf); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + ++ misc_reg03 = bbuf[0]; + if (misc_reg03 & 0x01) { + if (!info->SD_Status.Ready) { + result = ene_sd_init(us); +@@ -2305,8 +2318,9 @@ static int ene_ub6250_probe(struct usb_i + const struct usb_device_id *id) + { + int result; +- u8 misc_reg03 = 0; ++ u8 misc_reg03; + struct us_data *us; ++ struct ene_ub6250_info *info; + + result = usb_stor_probe1(&us, intf, id, + (id - ene_ub6250_usb_ids) + ene_ub6250_unusual_dev_list, +@@ -2315,11 +2329,16 @@ static int ene_ub6250_probe(struct usb_i + return result; + + /* FIXME: where should the code alloc extra buf ? */ +- if (!us->extra) { +- us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL); +- if (!us->extra) +- return -ENOMEM; +- us->extra_destructor = ene_ub6250_info_destructor; ++ us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL); ++ if (!us->extra) ++ return -ENOMEM; ++ us->extra_destructor = ene_ub6250_info_destructor; ++ ++ info = (struct ene_ub6250_info *)(us->extra); ++ info->bbuf = kmalloc(512, GFP_KERNEL); ++ if (!info->bbuf) { ++ kfree(us->extra); ++ return -ENOMEM; + } + + us->transport_name = "ene_ub6250"; +@@ -2331,12 +2350,13 @@ static int ene_ub6250_probe(struct usb_i + return result; + + /* probe card type */ +- result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03); ++ result = ene_get_card_type(us, REG_CARD_STATUS, info->bbuf); + if (result != USB_STOR_XFER_GOOD) { + usb_stor_disconnect(intf); + return USB_STOR_TRANSPORT_ERROR; + } + ++ misc_reg03 = info->bbuf[0]; + if (!(misc_reg03 & 0x01)) { + pr_info("ums_eneub6250: This driver only supports SD/MS cards. " + "It does not support SM cards.\n"); diff --git a/queue-4.9/watchdog-pcwd_usb-fix-null-deref-at-probe.patch b/queue-4.9/watchdog-pcwd_usb-fix-null-deref-at-probe.patch new file mode 100644 index 00000000000..c192ad9cb39 --- /dev/null +++ b/queue-4.9/watchdog-pcwd_usb-fix-null-deref-at-probe.patch @@ -0,0 +1,35 @@ +From 46c319b848268dab3f0e7c4a5b6e9146d3bca8a4 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 13 Mar 2017 13:49:45 +0100 +Subject: watchdog: pcwd_usb: fix NULL-deref at probe + +From: Johan Hovold + +commit 46c319b848268dab3f0e7c4a5b6e9146d3bca8a4 upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should a malicious device lack endpoints. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Johan Hovold +Reviewed-by: Guenter Roeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/watchdog/pcwd_usb.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/watchdog/pcwd_usb.c ++++ b/drivers/watchdog/pcwd_usb.c +@@ -630,6 +630,9 @@ static int usb_pcwd_probe(struct usb_int + return -ENODEV; + } + ++ if (iface_desc->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + /* check out the endpoint: it has to be Interrupt & IN */ + endpoint = &iface_desc->endpoint[0].desc; +