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-next>] [day] [month] [year] [list]
Date:	Mon, 26 Apr 2010 10:29:05 +0200
From:	Michał Nazarewicz <m.nazarewicz@...sung.com>
To:	Marek Szyprowski <m.szyprowski@...sung.com>
Subject: USB gadget with drivers "on board"

Hello everyone,

I need to create an USB gadget with drivers for Windows included
"on board".  In particular, when the gadget is connected to Windows
host it is detected as mass storage and mounted drive include the
drivers.  However, when the drivers are installed, it is detected
as some other device.

Now, it seems that a simple composite device with two configurations
is enough -- the first containing mass storage and the second other
functions.  My tests show that Windows manages to set the first
configuration and detect the mass storage interface.

Unfortunately, Linux does the same thing -- chooses the first
configuration and detects the mass storage interface.  What I'd
like to see is Linux choosing the second configuration which is
more functional.

Is there any way to accomplish that?

I came up with an idea of swapping bConfigurationValues (so that mass
storage configuration has it set to 2 and the other configuration
has it set to 1) but still retaining the order those are given to
host (a bit like with g_ether).

This however did not work, as Linux pretty much ignores those values
when choosing configuration.

So can it be done differently?

I think the following change would achieve the result I am seeking:

diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index bdf87a8..38fd44e 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -121,21 +121,22 @@ int usb_choose_configuration(struct usb_device *udev)
                   		else if (udev->descriptor.bDeviceClass !=
                   						USB_CLASS_VENDOR_SPEC &&
                   				(!desc || desc->bInterfaceClass !=
                   						USB_CLASS_VENDOR_SPEC)) {
                   			best = c;
                   			break;
                   		}

                   		/* If all the remaining configs are vendor-specific,
                   		 * choose the first one. */
-		else if (!best)
+		else if (!best || best->desc.bConfigurationValue > c->desc.bConfigurationValue)
                   			best = c;
                   	}

                   	if (insufficient_power > 0)
                   		dev_info(&udev->dev, "rejected %d configuration%s "
                   			"due to insufficient available bus power\n",
                   			insufficient_power, plural(insufficient_power));

                   	if (best) {
                   		i = best->desc.bConfigurationValue;

Or maybe it'd be a good idea to prefer configurations with bigger
number of interfaces?

So what do you think? Does anyone know a (better) solution?

-- 
Best regards,                                           _     _
--.--| Liege of Serenely Enlightened Majesty of       o' \,=./ `o
---.-| Computer Science,  Michał "mina86" Nazarewicz     (o o)
-...-+---[mina86@...a86.com]---[mina86@...ber.org]---ooO--(_)--Ooo--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ