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

Commit c8d204b3 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'usb-serial-4.10-rc3' of...

Merge tag 'usb-serial-4.10-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial

 into usb-linus

Johan writes:

USB-serial fixes for v4.10-rc3

These fixes address a number of long-standing issues in various
USB-serial drivers which would lead to crashes should a malicious device
lack the expected endpoints.

Included are also a few related fixes, and a couple of unrelated ones
that were found during my survey (e.g. a memleak and a
sleep-while-atomic).

A compiler warning revealed an error-handling issue in the new f81534
driver which is also fixed.

Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
parents 29fc1aa4 ef079936
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@
#define CYBERJACK_PRODUCT_ID	0x0100

/* Function prototypes */
static int cyberjack_attach(struct usb_serial *serial);
static int cyberjack_port_probe(struct usb_serial_port *port);
static int cyberjack_port_remove(struct usb_serial_port *port);
static int  cyberjack_open(struct tty_struct *tty,
@@ -77,6 +78,7 @@ static struct usb_serial_driver cyberjack_device = {
	.description =		"Reiner SCT Cyberjack USB card reader",
	.id_table =		id_table,
	.num_ports =		1,
	.attach =		cyberjack_attach,
	.port_probe =		cyberjack_port_probe,
	.port_remove =		cyberjack_port_remove,
	.open =			cyberjack_open,
@@ -100,6 +102,14 @@ struct cyberjack_private {
	short		wrsent;		/* Data already sent */
};

static int cyberjack_attach(struct usb_serial *serial)
{
	if (serial->num_bulk_out < serial->num_ports)
		return -ENODEV;

	return 0;
}

static int cyberjack_port_probe(struct usb_serial_port *port)
{
	struct cyberjack_private *priv;
+5 −3
Original line number Diff line number Diff line
@@ -1237,6 +1237,7 @@ static int f81534_attach(struct usb_serial *serial)
static int f81534_port_probe(struct usb_serial_port *port)
{
	struct f81534_port_private *port_priv;
	int ret;

	port_priv = devm_kzalloc(&port->dev, sizeof(*port_priv), GFP_KERNEL);
	if (!port_priv)
@@ -1246,10 +1247,11 @@ static int f81534_port_probe(struct usb_serial_port *port)
	mutex_init(&port_priv->mcr_mutex);

	/* Assign logic-to-phy mapping */
	port_priv->phy_num = f81534_logic_to_phy_port(port->serial, port);
	if (port_priv->phy_num < 0 || port_priv->phy_num >= F81534_NUM_PORT)
		return -ENODEV;
	ret = f81534_logic_to_phy_port(port->serial, port);
	if (ret < 0)
		return ret;

	port_priv->phy_num = ret;
	usb_set_serial_port_data(port, port_priv);
	dev_dbg(&port->dev, "%s: port_number: %d, phy_num: %d\n", __func__,
			port->port_number, port_priv->phy_num);
+1 −0
Original line number Diff line number Diff line
@@ -1043,6 +1043,7 @@ static int garmin_write_bulk(struct usb_serial_port *port,
		   "%s - usb_submit_urb(write bulk) failed with status = %d\n",
				__func__, status);
		count = status;
		kfree(buffer);
	}

	/* we are done with this urb, so let the host driver
+5 −0
Original line number Diff line number Diff line
@@ -2751,6 +2751,11 @@ static int edge_startup(struct usb_serial *serial)
					EDGE_COMPATIBILITY_MASK1,
					EDGE_COMPATIBILITY_MASK2 };

	if (serial->num_bulk_in < 1 || serial->num_interrupt_in < 1) {
		dev_err(&serial->interface->dev, "missing endpoints\n");
		return -ENODEV;
	}

	dev = serial->dev;

	/* create our private serial structure */
+17 −5
Original line number Diff line number Diff line
@@ -1499,8 +1499,7 @@ static int do_boot_mode(struct edgeport_serial *serial,

		dev_dbg(dev, "%s - Download successful -- Device rebooting...\n", __func__);

		/* return an error on purpose */
		return -ENODEV;
		return 1;
	}

stayinbootmode:
@@ -1508,7 +1507,7 @@ static int do_boot_mode(struct edgeport_serial *serial,
	dev_dbg(dev, "%s - STAYING IN BOOT MODE\n", __func__);
	serial->product_info.TiMode = TI_MODE_BOOT;

	return 0;
	return 1;
}

static int ti_do_config(struct edgeport_port *port, int feature, int on)
@@ -2546,6 +2545,13 @@ static int edge_startup(struct usb_serial *serial)
	int status;
	u16 product_id;

	/* Make sure we have the required endpoints when in download mode. */
	if (serial->interface->cur_altsetting->desc.bNumEndpoints > 1) {
		if (serial->num_bulk_in < serial->num_ports ||
				serial->num_bulk_out < serial->num_ports)
			return -ENODEV;
	}

	/* create our private serial structure */
	edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL);
	if (!edge_serial)
@@ -2553,14 +2559,18 @@ static int edge_startup(struct usb_serial *serial)

	mutex_init(&edge_serial->es_lock);
	edge_serial->serial = serial;
	INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work);
	usb_set_serial_data(serial, edge_serial);

	status = download_fw(edge_serial);
	if (status) {
	if (status < 0) {
		kfree(edge_serial);
		return status;
	}

	if (status > 0)
		return 1;	/* bind but do not register any ports */

	product_id = le16_to_cpu(
			edge_serial->serial->dev->descriptor.idProduct);

@@ -2572,7 +2582,6 @@ static int edge_startup(struct usb_serial *serial)
		}
	}

	INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work);
	edge_heartbeat_schedule(edge_serial);

	return 0;
@@ -2580,6 +2589,9 @@ static int edge_startup(struct usb_serial *serial)

static void edge_disconnect(struct usb_serial *serial)
{
	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);

	cancel_delayed_work_sync(&edge_serial->heartbeat_work);
}

static void edge_release(struct usb_serial *serial)
Loading