diff options
author | Johan Hovold <johan@kernel.org> | 2017-01-12 08:56:13 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-14 08:00:18 -0400 |
commit | b07e930d1f498e3cc3677fdf89665918aa44e244 (patch) | |
tree | 72227c701f5d95d0e4f3c6b8be2624d521a7d3b6 | |
parent | 4d32e36d62627ad9730338e6f603c8b996aaf7eb (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.c | 24 |
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)); |