lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Wed, 13 Mar 2013 08:13:40 +0100
From:	Bjørn Mork <bjorn@...k.no>
To:	Dan Williams <dcbw@...hat.com>
Cc:	linux-usb@...r.kernel.org, netdev@...r.kernel.org
Subject: Re: [RFC PATCH] qmi_wwan: set correct altsetting for Gobi 1K devices

Bjørn Mork <bjorn@...k.no> writes:

>
> Risking that I am trying to be too smart again. .. But I really think
> we can fix this in a more generic way by making the probe behave more
> like it did before. How about just letting it continue without erring
> out until it has called usbnet_get_endpoints? That should work without
> needing any quirks.

I was thinking about something like this patch, dropping both the
unnecessary verification of bNumEndpoints and of the CDC functional
descriptors.  If we find a CDC Union, then fine - we use it to locate
the data interface. If we find a CDC Ether, then fine - we use it to set
the MAC address.

This should end up calling usbnet_get_endpoints (first thing
qmi_wwan_register_subdriver does), and succeed if any data interface
altsetting have the necessary endpoints.

There really are few reasons to do any strict verification step in the
probe in this driver, because there really are no usable markers on the
functions. That's why the driver does explicit interface matching in
the first place.  So it makes sense to allow the probe to succeed if
collecting the 3 required endpoints is at all possible.

It will of course succeed on a number of unsupported interfaces if
dynamical IDs are used.  But with nothing to differentiate a QMI/wwan
function from other functions, there is really nothing we can do to
prevent that. If we are to support dynamic IDs, then there will be false
positives.  The user can manually unbind the driver from unwanted
matches in this case.

Only build tested for now. I will test on the devices I have before
submitting, if this works for you:


diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index efb5c7c..1cfa80c 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -139,18 +139,11 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
 
 	BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state)));
 
-	/* control and data is shared? */
-	if (intf->cur_altsetting->desc.bNumEndpoints == 3) {
-		info->control = intf;
-		info->data = intf;
-		goto shared;
-	}
-
-	/* else require a single interrupt status endpoint on control intf */
-	if (intf->cur_altsetting->desc.bNumEndpoints != 1)
-		goto err;
+	/* set up initial state */
+	info->control = intf;
+	info->data = intf;
 
-	/* and a number of CDC descriptors */
+	/* some vendors add CDC descriptors */
 	while (len > 3) {
 		struct usb_descriptor_header *h = (void *)buf;
 
@@ -207,25 +200,17 @@ next_desc:
 		buf += h->bLength;
 	}
 
-	/* did we find all the required ones? */
-	if (!(found & (1 << USB_CDC_HEADER_TYPE)) ||
-	    !(found & (1 << USB_CDC_UNION_TYPE))) {
-		dev_err(&intf->dev, "CDC functional descriptors missing\n");
-		goto err;
-	}
-
-	/* verify CDC Union */
-	if (desc->bInterfaceNumber != cdc_union->bMasterInterface0) {
-		dev_err(&intf->dev, "bogus CDC Union: master=%u\n", cdc_union->bMasterInterface0);
-		goto err;
-	}
-
-	/* need to save these for unbind */
-	info->control = intf;
-	info->data = usb_ifnum_to_if(dev->udev,	cdc_union->bSlaveInterface0);
-	if (!info->data) {
-		dev_err(&intf->dev, "bogus CDC Union: slave=%u\n", cdc_union->bSlaveInterface0);
-		goto err;
+	/* using two interfaces if we found a CDC Union */
+	if (cdc_union) {
+		if (desc->bInterfaceNumber != cdc_union->bMasterInterface0) {
+			dev_err(&intf->dev, "bogus CDC Union: master=%u\n", cdc_union->bMasterInterface0);
+			goto err;
+		}
+		info->data = usb_ifnum_to_if(dev->udev,	cdc_union->bSlaveInterface0);
+		if (!info->data) {
+			dev_err(&intf->dev, "bogus CDC Union: slave=%u\n", cdc_union->bSlaveInterface0);
+			goto err;
+		}
 	}
 
 	/* errors aren't fatal - we can live with the dynamic address */
@@ -234,12 +219,13 @@ next_desc:
 		usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress);
 	}
 
-	/* claim data interface and set it up */
-	status = usb_driver_claim_interface(driver, info->data, dev);
-	if (status < 0)
-		goto err;
+	/* claim separate data interface? */
+	if (info->control != info->data) {
+		status = usb_driver_claim_interface(driver, info->data, dev);
+		if (status < 0)
+			goto err;
+	}
 
-shared:
 	status = qmi_wwan_register_subdriver(dev);
 	if (status < 0 && info->control != info->data) {
 		usb_set_intfdata(info->data, NULL);
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ