]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 May 2017 10:23:35 +0000 (12:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 May 2017 10:23:35 +0000 (12:23 +0200)
added patches:
char-lp-fix-possible-integer-overflow-in-lp_setup.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

queue-3.18/char-lp-fix-possible-integer-overflow-in-lp_setup.patch [new file with mode: 0644]
queue-3.18/series
queue-3.18/usb-core-replace-p-with-pk.patch [new file with mode: 0644]
queue-3.18/usb-ene_usb6250-fix-dma-to-the-stack.patch [new file with mode: 0644]
queue-3.18/watchdog-pcwd_usb-fix-null-deref-at-probe.patch [new file with mode: 0644]

diff --git a/queue-3.18/char-lp-fix-possible-integer-overflow-in-lp_setup.patch b/queue-3.18/char-lp-fix-possible-integer-overflow-in-lp_setup.patch
new file mode 100644 (file)
index 0000000..e640e82
--- /dev/null
@@ -0,0 +1,37 @@
+From 3e21f4af170bebf47c187c1ff8bf155583c9f3b1 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Tue, 16 May 2017 19:18:55 +0200
+Subject: char: lp: fix possible integer overflow in lp_setup()
+
+From: Willy Tarreau <w@1wt.eu>
+
+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 <roee.hay@hcl.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+       }
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2e1ebe42158656fcee9112355ef28c5b403090d6 100644 (file)
@@ -0,0 +1,4 @@
+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
diff --git a/queue-3.18/usb-core-replace-p-with-pk.patch b/queue-3.18/usb-core-replace-p-with-pk.patch
new file mode 100644 (file)
index 0000000..049cf6a
--- /dev/null
@@ -0,0 +1,76 @@
+From 2f964780c03b73de269b08d12aff96a9618d13f3 Mon Sep 17 00:00:00 2001
+From: Vamsi Krishna Samavedam <vskrishn@codeaurora.org>
+Date: Tue, 16 May 2017 14:38:08 +0200
+Subject: USB: core: replace %p with %pK
+
+From: Vamsi Krishna Samavedam <vskrishn@codeaurora.org>
+
+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 <vskrishn@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/devio.c |    4 ++--
+ drivers/usb/core/hcd.c   |    4 ++--
+ drivers/usb/core/urb.c   |    2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -373,11 +373,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);
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -1642,7 +1642,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);
+       }
+@@ -1809,7 +1809,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
+@@ -336,7 +336,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-3.18/usb-ene_usb6250-fix-dma-to-the-stack.patch b/queue-3.18/usb-ene_usb6250-fix-dma-to-the-stack.patch
new file mode 100644 (file)
index 0000000..3cf2fc4
--- /dev/null
@@ -0,0 +1,298 @@
+From 628c2893d44876ddd11602400c70606ade62e129 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 16 May 2017 11:47:29 -0400
+Subject: USB: ene_usb6250: fix DMA to the stack
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+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 <stern@rowland.harvard.edu>
+Reported-and-tested-by: Andreas Hartmann <andihartmann@01019freenet.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -443,6 +443,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;
+@@ -490,8 +494,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)
+@@ -855,8 +862,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;
+       /* printk(KERN_INFO "MS --- MS_ReaderReadPage,
+@@ -899,7 +907,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;
+@@ -908,9 +916,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;
+ }
+@@ -1336,8 +1344,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];
+       /* printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum); */
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
+@@ -1352,7 +1361,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;
+@@ -1360,9 +1369,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;
+ }
+@@ -1566,9 +1575,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);
+@@ -1582,14 +1591,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);
+@@ -2072,9 +2083,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");
+@@ -2093,13 +2104,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);
+@@ -2108,15 +2119,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;
+       }
+@@ -2126,9 +2137,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 */
+@@ -2162,17 +2173,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);
+@@ -2180,7 +2191,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;
+@@ -2190,13 +2201,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);
+@@ -2312,8 +2325,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);
+@@ -2321,11 +2335,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";
+@@ -2337,12 +2356,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-3.18/watchdog-pcwd_usb-fix-null-deref-at-probe.patch b/queue-3.18/watchdog-pcwd_usb-fix-null-deref-at-probe.patch
new file mode 100644 (file)
index 0000000..c192ad9
--- /dev/null
@@ -0,0 +1,35 @@
+From 46c319b848268dab3f0e7c4a5b6e9146d3bca8a4 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 13 Mar 2017 13:49:45 +0100
+Subject: watchdog: pcwd_usb: fix NULL-deref at probe
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <johan@kernel.org>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;