diff options
author | Johan Hovold <johan@kernel.org> | 2017-01-12 08:56:14 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-14 08:00:19 -0400 |
commit | 6fa44d4ba2126f3e56c6cd39cf54991bbf3bbc46 (patch) | |
tree | 9cdbd2e98b66ecd394a5bd42d4850108d1b15745 | |
parent | 62b8b773ebde042ef7e016c9bed6327306885fee (diff) |
USB: serial: io_edgeport: fix descriptor error handling
commit 3c0e25d883d06a1fbd1ad35257e8abaa57befb37 upstream.
Make sure to detect short control-message transfers and log an error
when reading incomplete manufacturer and boot descriptors.
Note that the default all-zero descriptors will now be used after a
short transfer is detected instead of partially initialised ones.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
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, 15 insertions, 9 deletions
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 653ea2e35c31..464db17b5328 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -2105,8 +2105,7 @@ static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, | |||
2105 | * rom_read | 2105 | * rom_read |
2106 | * reads a number of bytes from the Edgeport device starting at the given | 2106 | * reads a number of bytes from the Edgeport device starting at the given |
2107 | * address. | 2107 | * address. |
2108 | * If successful returns the number of bytes read, otherwise it returns | 2108 | * Returns zero on success or a negative error number. |
2109 | * a negative error number of the problem. | ||
2110 | ****************************************************************************/ | 2109 | ****************************************************************************/ |
2111 | static int rom_read(struct usb_serial *serial, __u16 extAddr, | 2110 | static int rom_read(struct usb_serial *serial, __u16 extAddr, |
2112 | __u16 addr, __u16 length, __u8 *data) | 2111 | __u16 addr, __u16 length, __u8 *data) |
@@ -2131,12 +2130,17 @@ static int rom_read(struct usb_serial *serial, __u16 extAddr, | |||
2131 | USB_REQUEST_ION_READ_ROM, | 2130 | USB_REQUEST_ION_READ_ROM, |
2132 | 0xC0, addr, extAddr, transfer_buffer, | 2131 | 0xC0, addr, extAddr, transfer_buffer, |
2133 | current_length, 300); | 2132 | current_length, 300); |
2134 | if (result < 0) | 2133 | if (result < current_length) { |
2134 | if (result >= 0) | ||
2135 | result = -EIO; | ||
2135 | break; | 2136 | break; |
2137 | } | ||
2136 | memcpy(data, transfer_buffer, current_length); | 2138 | memcpy(data, transfer_buffer, current_length); |
2137 | length -= current_length; | 2139 | length -= current_length; |
2138 | addr += current_length; | 2140 | addr += current_length; |
2139 | data += current_length; | 2141 | data += current_length; |
2142 | |||
2143 | result = 0; | ||
2140 | } | 2144 | } |
2141 | 2145 | ||
2142 | kfree(transfer_buffer); | 2146 | kfree(transfer_buffer); |
@@ -2590,9 +2594,10 @@ static void get_manufacturing_desc(struct edgeport_serial *edge_serial) | |||
2590 | EDGE_MANUF_DESC_LEN, | 2594 | EDGE_MANUF_DESC_LEN, |
2591 | (__u8 *)(&edge_serial->manuf_descriptor)); | 2595 | (__u8 *)(&edge_serial->manuf_descriptor)); |
2592 | 2596 | ||
2593 | if (response < 1) | 2597 | if (response < 0) { |
2594 | dev_err(dev, "error in getting manufacturer descriptor\n"); | 2598 | dev_err(dev, "error in getting manufacturer descriptor: %d\n", |
2595 | else { | 2599 | response); |
2600 | } else { | ||
2596 | char string[30]; | 2601 | char string[30]; |
2597 | dev_dbg(dev, "**Manufacturer Descriptor\n"); | 2602 | dev_dbg(dev, "**Manufacturer Descriptor\n"); |
2598 | dev_dbg(dev, " RomSize: %dK\n", | 2603 | dev_dbg(dev, " RomSize: %dK\n", |
@@ -2649,9 +2654,10 @@ static void get_boot_desc(struct edgeport_serial *edge_serial) | |||
2649 | EDGE_BOOT_DESC_LEN, | 2654 | EDGE_BOOT_DESC_LEN, |
2650 | (__u8 *)(&edge_serial->boot_descriptor)); | 2655 | (__u8 *)(&edge_serial->boot_descriptor)); |
2651 | 2656 | ||
2652 | if (response < 1) | 2657 | if (response < 0) { |
2653 | dev_err(dev, "error in getting boot descriptor\n"); | 2658 | dev_err(dev, "error in getting boot descriptor: %d\n", |
2654 | else { | 2659 | response); |
2660 | } else { | ||
2655 | dev_dbg(dev, "**Boot Descriptor:\n"); | 2661 | dev_dbg(dev, "**Boot Descriptor:\n"); |
2656 | dev_dbg(dev, " BootCodeLength: %d\n", | 2662 | dev_dbg(dev, " BootCodeLength: %d\n", |
2657 | le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength)); | 2663 | le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength)); |