]>
Commit | Line | Data |
---|---|---|
857a8367 GKH |
1 | From e4457d9798adb96272468e93da663de9bd0a4198 Mon Sep 17 00:00:00 2001 |
2 | From: Johan Hovold <johan@kernel.org> | |
3 | Date: Thu, 12 Jan 2017 14:56:13 +0100 | |
4 | Subject: USB: serial: io_edgeport: fix epic-descriptor handling | |
5 | ||
6 | From: Johan Hovold <johan@kernel.org> | |
7 | ||
8 | commit e4457d9798adb96272468e93da663de9bd0a4198 upstream. | |
9 | ||
10 | Use a dedicated buffer for the DMA transfer and make sure to detect | |
11 | short transfers to avoid parsing a corrupt descriptor. | |
12 | ||
13 | Fixes: 6e8cf7751f9f ("USB: add EPIC support to the io_edgeport driver") | |
14 | Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
15 | Signed-off-by: Johan Hovold <johan@kernel.org> | |
16 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
17 | ||
18 | --- | |
19 | drivers/usb/serial/io_edgeport.c | 24 ++++++++++++++++++------ | |
20 | 1 file changed, 18 insertions(+), 6 deletions(-) | |
21 | ||
22 | --- a/drivers/usb/serial/io_edgeport.c | |
23 | +++ b/drivers/usb/serial/io_edgeport.c | |
24 | @@ -492,20 +492,24 @@ static int get_epic_descriptor(struct ed | |
25 | int result; | |
26 | struct usb_serial *serial = ep->serial; | |
27 | struct edgeport_product_info *product_info = &ep->product_info; | |
28 | - struct edge_compatibility_descriptor *epic = &ep->epic_descriptor; | |
29 | + struct edge_compatibility_descriptor *epic; | |
30 | struct edge_compatibility_bits *bits; | |
31 | struct device *dev = &serial->dev->dev; | |
32 | ||
33 | ep->is_epic = 0; | |
34 | + | |
35 | + epic = kmalloc(sizeof(*epic), GFP_KERNEL); | |
36 | + if (!epic) | |
37 | + return -ENOMEM; | |
38 | + | |
39 | result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | |
40 | USB_REQUEST_ION_GET_EPIC_DESC, | |
41 | 0xC0, 0x00, 0x00, | |
42 | - &ep->epic_descriptor, | |
43 | - sizeof(struct edge_compatibility_descriptor), | |
44 | + epic, sizeof(*epic), | |
45 | 300); | |
46 | - | |
47 | - if (result > 0) { | |
48 | + if (result == sizeof(*epic)) { | |
49 | ep->is_epic = 1; | |
50 | + memcpy(&ep->epic_descriptor, epic, sizeof(*epic)); | |
51 | memset(product_info, 0, sizeof(struct edgeport_product_info)); | |
52 | ||
53 | product_info->NumPorts = epic->NumPorts; | |
54 | @@ -534,8 +538,16 @@ static int get_epic_descriptor(struct ed | |
55 | dev_dbg(dev, " IOSPWriteLCR : %s\n", bits->IOSPWriteLCR ? "TRUE": "FALSE"); | |
56 | dev_dbg(dev, " IOSPSetBaudRate : %s\n", bits->IOSPSetBaudRate ? "TRUE": "FALSE"); | |
57 | dev_dbg(dev, " TrueEdgeport : %s\n", bits->TrueEdgeport ? "TRUE": "FALSE"); | |
58 | + | |
59 | + result = 0; | |
60 | + } else if (result >= 0) { | |
61 | + dev_warn(&serial->interface->dev, "short epic descriptor received: %d\n", | |
62 | + result); | |
63 | + result = -EIO; | |
64 | } | |
65 | ||
66 | + kfree(epic); | |
67 | + | |
68 | return result; | |
69 | } | |
70 | ||
71 | @@ -2789,7 +2801,7 @@ static int edge_startup(struct usb_seria | |
72 | dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); | |
73 | ||
74 | /* Read the epic descriptor */ | |
75 | - if (get_epic_descriptor(edge_serial) <= 0) { | |
76 | + if (get_epic_descriptor(edge_serial) < 0) { | |
77 | /* memcpy descriptor to Supports structures */ | |
78 | memcpy(&edge_serial->epic_descriptor.Supports, descriptor, | |
79 | sizeof(struct edge_compatibility_bits)); |