usb: interface authorization: Introduces the default interface authorization
authorStefan Koch <stefan.koch10@gmail.com>
Tue, 25 Aug 2015 19:10:06 +0000 (21:10 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 22 Sep 2015 19:08:40 +0000 (12:08 -0700)
Interfaces are allowed per default.
This can disabled or enabled (again) by writing 0 or 1 to
/sys/bus/usb/devices/usbX/interface_authorized_default

Signed-off-by: Stefan Koch <stefan.koch10@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/core/hcd.c
drivers/usb/core/message.c
include/linux/usb/hcd.h

index 4d64e5c499e194d3c364543fca9f9e76442684b2..83df1dde9c08f683449ce0d6ecc8a52ed2b93817 100644 (file)
@@ -882,9 +882,53 @@ static ssize_t authorized_default_store(struct device *dev,
 }
 static DEVICE_ATTR_RW(authorized_default);
 
+/*
+ * interface_authorized_default_show - show default authorization status
+ * for USB interfaces
+ *
+ * note: interface_authorized_default is the default value
+ *       for initializing the authorized attribute of interfaces
+ */
+static ssize_t interface_authorized_default_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct usb_device *usb_dev = to_usb_device(dev);
+       struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
+
+       return sprintf(buf, "%u\n", !!HCD_INTF_AUTHORIZED(hcd));
+}
+
+/*
+ * interface_authorized_default_store - store default authorization status
+ * for USB interfaces
+ *
+ * note: interface_authorized_default is the default value
+ *       for initializing the authorized attribute of interfaces
+ */
+static ssize_t interface_authorized_default_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct usb_device *usb_dev = to_usb_device(dev);
+       struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
+       int rc = count;
+       bool val;
+
+       if (strtobool(buf, &val) != 0)
+               return -EINVAL;
+
+       if (val)
+               set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
+       else
+               clear_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
+
+       return rc;
+}
+static DEVICE_ATTR_RW(interface_authorized_default);
+
 /* Group all the USB bus attributes */
 static struct attribute *usb_bus_attrs[] = {
                &dev_attr_authorized_default.attr,
+               &dev_attr_interface_authorized_default.attr,
                NULL,
 };
 
@@ -2682,6 +2726,9 @@ int usb_add_hcd(struct usb_hcd *hcd,
                hcd->authorized_default = authorized_default;
        set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
+       /* per default all interfaces are authorized */
+       set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
+
        /* HC is in reset state, but accessible.  Now do the one-time init,
         * bottom up so that hcds can customize the root hubs before hub_wq
         * starts talking to them.  (Note, bus id is assigned early too.)
index f368d2053da534ca975804dfad2bd8ddc77d5fba..3d25d89671d71b772b2510b4147df1d6eb017ec0 100644 (file)
@@ -1807,6 +1807,7 @@ free_interfaces:
                intfc = cp->intf_cache[i];
                intf->altsetting = intfc->altsetting;
                intf->num_altsetting = intfc->num_altsetting;
+               intf->authorized = !!HCD_INTF_AUTHORIZED(hcd);
                kref_get(&intfc->ref);
 
                alt = usb_altnum_to_altsetting(intf, 0);
index d2784c10bfe2ce23dfcd64d773dbe3beaeb34c22..36ce3d215cad1e702df02935349f17af7f8b9fab 100644 (file)
@@ -120,6 +120,7 @@ struct usb_hcd {
 #define HCD_FLAG_WAKEUP_PENDING                4       /* root hub is resuming? */
 #define HCD_FLAG_RH_RUNNING            5       /* root hub is running? */
 #define HCD_FLAG_DEAD                  6       /* controller has died? */
+#define HCD_FLAG_INTF_AUTHORIZED       7       /* authorize interfaces? */
 
        /* The flags can be tested using these macros; they are likely to
         * be slightly faster than test_bit().
@@ -131,6 +132,14 @@ struct usb_hcd {
 #define HCD_RH_RUNNING(hcd)    ((hcd)->flags & (1U << HCD_FLAG_RH_RUNNING))
 #define HCD_DEAD(hcd)          ((hcd)->flags & (1U << HCD_FLAG_DEAD))
 
+       /*
+        * Specifies if interfaces are authorized by default
+        * or they require explicit user space authorization; this bit is
+        * settable through /sys/class/usb_host/X/interface_authorized_default
+        */
+#define HCD_INTF_AUTHORIZED(hcd) \
+       ((hcd)->flags & (1U << HCD_FLAG_INTF_AUTHORIZED))
+
        /* Flags that get set only during HCD registration or removal. */
        unsigned                rh_registered:1;/* is root hub registered? */
        unsigned                rh_pollable:1;  /* may we poll the root hub? */