mirror of https://gitee.com/openkylin/linux.git
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: 6e8cf7751f
("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>
This commit is contained in:
parent
e3e574ad85
commit
e4457d9798
|
@ -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)
|
||||||
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)
|
||||||
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));
|
||||||
|
|
Loading…
Reference in New Issue