Re: [PATCH 1/4] Add usb interface authorization

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux