Commit e4457d97 authored by Johan Hovold's avatar Johan Hovold

USB: serial: io_edgeport: fix epic-descriptor handling

Use a dedicated buffer for the DMA transfer and make sure to detect
short transfers to avoid parsing a corrupt descriptor.

Fixes: 6e8cf775 ("USB: add EPIC support to the io_edgeport driver")
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
parent e3e574ad
...@@ -492,20 +492,24 @@ static int get_epic_descriptor(struct edgeport_serial *ep) ...@@ -492,20 +492,24 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
int result; int result;
struct usb_serial *serial = ep->serial; struct usb_serial *serial = ep->serial;
struct edgeport_product_info *product_info = &ep->product_info; struct edgeport_product_info *product_info = &ep->product_info;
struct edge_compatibility_descriptor *epic = &ep->epic_descriptor; struct edge_compatibility_descriptor *epic;
struct edge_compatibility_bits *bits; struct edge_compatibility_bits *bits;
struct device *dev = &serial->dev->dev; struct device *dev = &serial->dev->dev;
ep->is_epic = 0; ep->is_epic = 0;
epic = kmalloc(sizeof(*epic), GFP_KERNEL);
if (!epic)
return -ENOMEM;
result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
USB_REQUEST_ION_GET_EPIC_DESC, USB_REQUEST_ION_GET_EPIC_DESC,
0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00,
&ep->epic_descriptor, epic, sizeof(*epic),
sizeof(struct edge_compatibility_descriptor),
300); 300);
if (result == sizeof(*epic)) {
if (result > 0) {
ep->is_epic = 1; ep->is_epic = 1;
memcpy(&ep->epic_descriptor, epic, sizeof(*epic));
memset(product_info, 0, sizeof(struct edgeport_product_info)); memset(product_info, 0, sizeof(struct edgeport_product_info));
product_info->NumPorts = epic->NumPorts; product_info->NumPorts = epic->NumPorts;
...@@ -534,8 +538,16 @@ static int get_epic_descriptor(struct edgeport_serial *ep) ...@@ -534,8 +538,16 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
dev_dbg(dev, " IOSPWriteLCR : %s\n", bits->IOSPWriteLCR ? "TRUE": "FALSE"); dev_dbg(dev, " IOSPWriteLCR : %s\n", bits->IOSPWriteLCR ? "TRUE": "FALSE");
dev_dbg(dev, " IOSPSetBaudRate : %s\n", bits->IOSPSetBaudRate ? "TRUE": "FALSE"); dev_dbg(dev, " IOSPSetBaudRate : %s\n", bits->IOSPSetBaudRate ? "TRUE": "FALSE");
dev_dbg(dev, " TrueEdgeport : %s\n", bits->TrueEdgeport ? "TRUE": "FALSE"); dev_dbg(dev, " TrueEdgeport : %s\n", bits->TrueEdgeport ? "TRUE": "FALSE");
result = 0;
} else if (result >= 0) {
dev_warn(&serial->interface->dev, "short epic descriptor received: %d\n",
result);
result = -EIO;
} }
kfree(epic);
return result; return result;
} }
...@@ -2779,7 +2791,7 @@ static int edge_startup(struct usb_serial *serial) ...@@ -2779,7 +2791,7 @@ static int edge_startup(struct usb_serial *serial)
dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name);
/* Read the epic descriptor */ /* Read the epic descriptor */
if (get_epic_descriptor(edge_serial) <= 0) { if (get_epic_descriptor(edge_serial) < 0) {
/* memcpy descriptor to Supports structures */ /* memcpy descriptor to Supports structures */
memcpy(&edge_serial->epic_descriptor.Supports, descriptor, memcpy(&edge_serial->epic_descriptor.Supports, descriptor,
sizeof(struct edge_compatibility_bits)); sizeof(struct edge_compatibility_bits));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment