aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2017-01-12 08:56:13 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-05-14 08:00:18 -0400
commitb07e930d1f498e3cc3677fdf89665918aa44e244 (patch)
tree72227c701f5d95d0e4f3c6b8be2624d521a7d3b6
parent4d32e36d62627ad9730338e6f603c8b996aaf7eb (diff)
USB: serial: io_edgeport: fix epic-descriptor handling
commit e4457d9798adb96272468e93da663de9bd0a4198 upstream. Use a dedicated buffer for the DMA transfer and make sure to detect short transfers to avoid parsing a corrupt descriptor. Fixes: 6e8cf7751f9f ("USB: add EPIC support to the io_edgeport driver") Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/serial/io_edgeport.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 36dfe9972b17..653ea2e35c31 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -492,20 +492,24 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
492 int result; 492 int result;
493 struct usb_serial *serial = ep->serial; 493 struct usb_serial *serial = ep->serial;
494 struct edgeport_product_info *product_info = &ep->product_info; 494 struct edgeport_product_info *product_info = &ep->product_info;
495 struct edge_compatibility_descriptor *epic = &ep->epic_descriptor; 495 struct edge_compatibility_descriptor *epic;
496 struct edge_compatibility_bits *bits; 496 struct edge_compatibility_bits *bits;
497 struct device *dev = &serial->dev->dev; 497 struct device *dev = &serial->dev->dev;
498 498
499 ep->is_epic = 0; 499 ep->is_epic = 0;
500
501 epic = kmalloc(sizeof(*epic), GFP_KERNEL);
502 if (!epic)
503 return -ENOMEM;
504
500 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 505 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
501 USB_REQUEST_ION_GET_EPIC_DESC, 506 USB_REQUEST_ION_GET_EPIC_DESC,
502 0xC0, 0x00, 0x00, 507 0xC0, 0x00, 0x00,
503 &ep->epic_descriptor, 508 epic, sizeof(*epic),
504 sizeof(struct edge_compatibility_descriptor),
505 300); 509 300);
506 510 if (result == sizeof(*epic)) {
507 if (result > 0) {
508 ep->is_epic = 1; 511 ep->is_epic = 1;
512 memcpy(&ep->epic_descriptor, epic, sizeof(*epic));
509 memset(product_info, 0, sizeof(struct edgeport_product_info)); 513 memset(product_info, 0, sizeof(struct edgeport_product_info));
510 514
511 product_info->NumPorts = epic->NumPorts; 515 product_info->NumPorts = epic->NumPorts;
@@ -534,8 +538,16 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
534 dev_dbg(dev, " IOSPWriteLCR : %s\n", bits->IOSPWriteLCR ? "TRUE": "FALSE"); 538 dev_dbg(dev, " IOSPWriteLCR : %s\n", bits->IOSPWriteLCR ? "TRUE": "FALSE");
535 dev_dbg(dev, " IOSPSetBaudRate : %s\n", bits->IOSPSetBaudRate ? "TRUE": "FALSE"); 539 dev_dbg(dev, " IOSPSetBaudRate : %s\n", bits->IOSPSetBaudRate ? "TRUE": "FALSE");
536 dev_dbg(dev, " TrueEdgeport : %s\n", bits->TrueEdgeport ? "TRUE": "FALSE"); 540 dev_dbg(dev, " TrueEdgeport : %s\n", bits->TrueEdgeport ? "TRUE": "FALSE");
541
542 result = 0;
543 } else if (result >= 0) {
544 dev_warn(&serial->interface->dev, "short epic descriptor received: %d\n",
545 result);
546 result = -EIO;
537 } 547 }
538 548
549 kfree(epic);
550
539 return result; 551 return result;
540} 552}
541 553
@@ -2782,7 +2794,7 @@ static int edge_startup(struct usb_serial *serial)
2782 dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); 2794 dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name);
2783 2795
2784 /* Read the epic descriptor */ 2796 /* Read the epic descriptor */
2785 if (get_epic_descriptor(edge_serial) <= 0) { 2797 if (get_epic_descriptor(edge_serial) < 0) {
2786 /* memcpy descriptor to Supports structures */ 2798 /* memcpy descriptor to Supports structures */
2787 memcpy(&edge_serial->epic_descriptor.Supports, descriptor, 2799 memcpy(&edge_serial->epic_descriptor.Supports, descriptor,
2788 sizeof(struct edge_compatibility_bits)); 2800 sizeof(struct edge_compatibility_bits));