Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4457d97 authored by Johan Hovold's avatar Johan Hovold
Browse files

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
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -492,20 +492,24 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
	int result;
	struct usb_serial *serial = ep->serial;
	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 device *dev = &serial->dev->dev;

	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),
				 USB_REQUEST_ION_GET_EPIC_DESC,
				 0xC0, 0x00, 0x00,
				 &ep->epic_descriptor,
				 sizeof(struct edge_compatibility_descriptor),
				 epic, sizeof(*epic),
				 300);

	if (result > 0) {
	if (result == sizeof(*epic)) {
		ep->is_epic = 1;
		memcpy(&ep->epic_descriptor, epic, sizeof(*epic));
		memset(product_info, 0, sizeof(struct edgeport_product_info));

		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, "  IOSPSetBaudRate  : %s\n", bits->IOSPSetBaudRate	? "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;
}

@@ -2779,7 +2791,7 @@ static int edge_startup(struct usb_serial *serial)
	dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name);

	/* Read the epic descriptor */
	if (get_epic_descriptor(edge_serial) <= 0) {
	if (get_epic_descriptor(edge_serial) < 0) {
		/* memcpy descriptor to Supports structures */
		memcpy(&edge_serial->epic_descriptor.Supports, descriptor,
		       sizeof(struct edge_compatibility_bits));