Am 08.06.2015 um 16:40 schrieb Greg KH: > On Mon, Jun 08, 2015 at 03:24:26PM +0200, Stefan Koch wrote: >> Hi >> >> This is a patch that introduces an interface authorization for USB devices. >> >> The kernel supports already a device authorization bacause of wireless USB. >> >> But the new interface authorization allows to enable or disable individual interfaces per bitmask instead allow or deny a whole device. >> >> As example you can allow the interface for a TV signal from a USB TV card, but deny a HID for the remote control. >> >> This was added against BadUSB attacks. Refer to: https://srlabs.de/badusb/ >> >> The interface authorization is used by an usb firewall named "usbauth". >> The code and binaries for openSUSE 13.2 can be found here: https://build.opensuse.org/project/show/home:skoch_suse >> >> The patch was tested with Linux 4.1-rc3. The functionality is oriented at existing kernel code like usb_set_configuration(), the device authorization, etc. >> >> If the interface authorization is not used, the kernel behavior is the same as without the patch. >> >> Best regards >> >> Stefan Koch > Care to resend this in a format that it could be applied in (i.e. broken > up into logical chunks with the proper Signed-off-by: lines)? > > As this is, there's nothing we can do with it. > > thanks, > > greg k-h Hi I have split the patches now... The following first patch makes the manually probe of drivers with device_add() possible. Best regards Stefan Koch --------------------------- >From 3b6efdf78fe5a60174c519b1fe5f0ffaf4b141c6 Mon Sep 17 00:00:00 2001 From: Stefan Koch <skoch@xxxxxxx> Date: Mon, 8 Jun 2015 23:26:31 +0200 Subject: [PATCH 1/4] This patch allows to handle the probing of drivers manually Signed-off-by: Stefan Koch <skoch@xxxxxxx> --- drivers/base/base.h | 1 + drivers/base/bus.c | 22 +++++++++++++++--- drivers/base/core.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++---- include/linux/device.h | 6 +++++ 4 files changed, 83 insertions(+), 7 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 251c5d3..6bbedda 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -102,6 +102,7 @@ extern void container_dev_init(void); struct kobject *virtual_device_parent(struct device *dev); extern int bus_add_device(struct device *dev); +extern void bus_probe_device_opt_probe(struct device *dev, bool probe); extern void bus_probe_device(struct device *dev); extern void bus_remove_device(struct device *dev); diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 79bc203..e9e4c61 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -235,6 +235,11 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, } static DRIVER_ATTR_WO(bind); +unsigned int bus_get_drivers_autoprobe(struct bus_type *bus) { + return bus->p->drivers_autoprobe; +} +EXPORT_SYMBOL(bus_get_drivers_autoprobe); + static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) { return sprintf(buf, "%d\n", bus->p->drivers_autoprobe); @@ -540,12 +545,13 @@ out_put: } /** - * bus_probe_device - probe drivers for a new device + * bus_probe_device_opt_probe - optional probing of drivers for a new device * @dev: device to probe + * @probe: if true probe as autoprobe is set, if false do not probe as no autoprobe is set * * - Automatically probe for a driver if the bus allows it. */ -void bus_probe_device(struct device *dev) +void bus_probe_device_opt_probe(struct device *dev, bool probe) { struct bus_type *bus = dev->bus; struct subsys_interface *sif; @@ -554,7 +560,7 @@ void bus_probe_device(struct device *dev) if (!bus) return; - if (bus->p->drivers_autoprobe) { + if (bus->p->drivers_autoprobe && probe) { ret = device_attach(dev); WARN_ON(ret < 0); } @@ -567,6 +573,16 @@ void bus_probe_device(struct device *dev) } /** + * bus_probe_device - probe drivers for a new device + * @dev: device to probe + * + * - Automatically probe for a driver if the bus allows it. + */ +void bus_probe_device(struct device *dev) { + bus_probe_device_opt_probe(dev, true); +} + +/** * bus_remove_device - remove device from bus * @dev: device to be removed * diff --git a/drivers/base/core.c b/drivers/base/core.c index 21d1303..6dec2f2 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -954,6 +954,7 @@ int device_private_init(struct device *dev) /** * device_add - add device to device hierarchy. * @dev: device. + * @probe: if false probing is off, if true probing is on * * This is part 2 of device_register(), though may be called * separately _iff_ device_initialize() has been called separately. @@ -973,7 +974,7 @@ int device_private_init(struct device *dev) * if it returned an error! Always use put_device() to give up your * reference instead. */ -int device_add(struct device *dev) +int device_add_opt_probe(struct device *dev, bool probe) { struct device *parent = NULL; struct kobject *kobj; @@ -1068,7 +1069,7 @@ int device_add(struct device *dev) BUS_NOTIFY_ADD_DEVICE, dev); kobject_uevent(&dev->kobj, KOBJ_ADD); - bus_probe_device(dev); + bus_probe_device_opt_probe(dev, probe); if (parent) klist_add_tail(&dev->p->knode_parent, &parent->p->klist_children); @@ -1114,9 +1115,62 @@ name_error: dev->p = NULL; goto done; } +EXPORT_SYMBOL_GPL(device_add_opt_probe); + +/** + * device_add - add device to device hierarchy. + * @dev: device. + * + * This is part 2 of device_register(), though may be called + * separately _iff_ device_initialize() has been called separately. + * + * This adds @dev to the kobject hierarchy via kobject_add(), adds it + * to the global and sibling lists for the device, then + * adds it to the other relevant subsystems of the driver model. + * + * Do not call this routine or device_register() more than once for + * any device structure. The driver model core is not designed to work + * with devices that get unregistered and then spring back to life. + * (Among other things, it's very hard to guarantee that all references + * to the previous incarnation of @dev have been dropped.) Allocate + * and register a fresh new struct device instead. + * + * NOTE: _Never_ directly free @dev after calling this function, even + * if it returned an error! Always use put_device() to give up your + * reference instead. + */ +int device_add(struct device *dev) { + return device_add_opt_probe(dev, true); +} EXPORT_SYMBOL_GPL(device_add); /** + * device_register_opt_probe - register a device with the system. + * @dev: pointer to the device structure + * @probe: if false probing is off, if true probing is on + * + * This happens in two clean steps - initialize the device + * and add it to the system. The two steps can be called + * separately, but this is the easiest and most common. + * I.e. you should only call the two helpers separately if + * have a clearly defined need to use and refcount the device + * before it is added to the hierarchy. + * + * For more information, see the kerneldoc for device_initialize() + * and device_add(). + * + * NOTE: _Never_ directly free @dev after calling this function, even + * if it returned an error! Always use put_device() to give up the + * reference initialized in this function instead. + */ +int device_register_opt_probe(struct device *dev, bool probe) +{ + device_initialize(dev); + return device_add_opt_probe(dev, probe); +} +EXPORT_SYMBOL_GPL(device_register_opt_probe); + +/** * device_register - register a device with the system. * @dev: pointer to the device structure * @@ -1136,8 +1190,7 @@ EXPORT_SYMBOL_GPL(device_add); */ int device_register(struct device *dev) { - device_initialize(dev); - return device_add(dev); + return device_register_opt_probe(dev, true); } EXPORT_SYMBOL_GPL(device_register); diff --git a/include/linux/device.h b/include/linux/device.h index 6558af9..874f4f3 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -137,6 +137,8 @@ extern void bus_unregister(struct bus_type *bus); extern int __must_check bus_rescan_devices(struct bus_type *bus); +extern unsigned int bus_get_drivers_autoprobe(struct bus_type *bus); + /* iterator helpers for buses */ struct subsys_dev_iter { struct klist_iter ki; @@ -921,10 +923,12 @@ void driver_init(void); /* * High level routines for use by the bus drivers */ +extern int device_register_opt_probe(struct device *dev, bool probe); extern int __must_check device_register(struct device *dev); extern void device_unregister(struct device *dev); extern void device_initialize(struct device *dev); extern int __must_check device_add(struct device *dev); +extern int __must_check device_add_opt_probe(struct device *dev, bool probe); extern void device_del(struct device *dev); extern int device_for_each_child(struct device *dev, void *data, int (*fn)(struct device *dev, void *data)); @@ -976,6 +980,8 @@ extern void device_release_driver(struct device *dev); extern int __must_check device_attach(struct device *dev); extern int __must_check driver_attach(struct device_driver *drv); extern int __must_check device_reprobe(struct device *dev); +extern void bus_probe_device(struct device *dev); +extern void bus_probe_device_opt_probe(struct device *dev, bool probe); /* * Easy functions for dynamically creating devices on the fly -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html