Re: [PATCH v11] Added forgotten parameter description for authorized attribute in usb.h
Hi what does this error mean? Should I correct it? Best regards Stefan Am Dienstag, den 29.09.2015, 10:42 +0800 schrieb kbuild test robot: > Hi Stefan, > > [auto build test results on v4.3-rc3 -- if it's inappropriate base, please > ignore] > > reproduce: make htmldocs > > All warnings (new ones prefixed by >>): > > >> include/linux/usb.h:188: warning: Excess struct/union/enum/typedef member > >> 'authorized' description in 'usb_interface' > > vim +188 include/linux/usb.h > > 165fe97e Craig W. Nadler 2007-06-15 172 > b724ae77 Alan Stern 2005-10-24 173 int minor; > /* minor number this interface is > b724ae77 Alan Stern 2005-10-24 174 > * bound to */ > ^1da177e Linus Torvalds 2005-04-16 175 enum > usb_interface_condition condition; /* state of binding */ > 7e61559f Alan Stern 2007-11-06 176 unsigned > sysfs_files_created:1; /* the sysfs attributes exist */ > 3b23dd6f Alan Stern 2008-12-05 177 unsigned > ep_devs_created:1; /* endpoint "devices" exist */ > 352d0263 Alan Stern 2008-10-29 178 unsigned > unregistering:1; /* unregistration is in progress */ > 645daaab Alan Stern 2006-08-30 179 unsigned > needs_remote_wakeup:1; /* driver requires remote wakeup */ > 55151d7d Alan Stern 2008-08-12 180 unsigned > needs_altsetting0:1; /* switch to altsetting 0 is pending */ > 78d9a487 Alan Stern 2008-06-23 181 unsigned > needs_binding:1; /* needs delayed unbind/rebind */ > 04a723ea Sarah Sharp 2010-01-06 182 unsigned > resetting_device:1;/* true: bandwidth alloc after reset */ > 4d064c08 Alan Stern 2006-07-01 183 > ^1da177e Linus Torvalds 2005-04-16 184 struct device dev; > /* interface specific device info */ > 969ab2ee Greg Kroah-Hartman 2008-01-30 185 struct device *usb_dev; > ccf5b801 Alan Stern 2009-06-29 186 atomic_t pm_usage_cnt; > /* usage counter for autosuspend */ > dc023dce Inaky Perez-Gonzalez 2008-11-13 187 struct work_struct > reset_ws;/* for resets in atomic context */ > ^1da177e Linus Torvalds 2005-04-16 @188 }; > ^1da177e Linus Torvalds 2005-04-16 189 #define > to_usb_interface(d) container_of(d, struct usb_interface, dev) > ^1da177e Linus Torvalds 2005-04-16 190 > ^1da177e Linus Torvalds 2005-04-16 191 static inline void > *usb_get_intfdata(struct usb_interface *intf) > ^1da177e Linus Torvalds 2005-04-16 192 { > ^1da177e Linus Torvalds 2005-04-16 193 return > dev_get_drvdata(>dev); > ^1da177e Linus Torvalds 2005-04-16 194 } > ^1da177e Linus Torvalds 2005-04-16 195 > ^1da177e Linus Torvalds 2005-04-16 196 static inline void > usb_set_intfdata(struct usb_interface *intf, void *data) > > :: The code at line 188 was first introduced by commit > :: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2 > > :: TO: Linus Torvalds> :: CC: Linus Torvalds > > --- > 0-DAY kernel test infrastructureOpen Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v12 1/7] usb: interface authorization: Declare authorized attribute
The attribute authorized shows the authorization state for an interface. Signed-off-by: Stefan Koch <stefan.koc...@gmail.com> --- include/linux/usb.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 447fe29..a2068d7 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -122,6 +122,7 @@ enum usb_interface_condition { * has been deferred. * @needs_binding: flag set when the driver should be re-probed or unbound * following a reset or suspend operation it doesn't support. + * @authorized: this flag determines if the USB interface will be authorized * @dev: driver model's view of this device * @usb_dev: if an interface is bound to the USB major, this will point * to the sysfs representation for that device. @@ -178,6 +179,7 @@ struct usb_interface { unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned resetting_device:1;/* true: bandwidth alloc after reset */ + unsigned authorized:1; /* used for interface authorization */ struct device dev; /* interface specific device info */ struct device *usb_dev; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v12 5/7] usb: interface authorization: SysFS part of USB interface authorization
This introduces an attribute for each interface to authorize (1) or deauthorize (0) it: /sys/bus/usb/devices/INTERFACE/authorized Signed-off-by: Stefan Koch <stefan.koc...@gmail.com> --- drivers/usb/core/sysfs.c | 36 1 file changed, 36 insertions(+) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d269738..3ddaada 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -926,6 +926,41 @@ static ssize_t supports_autosuspend_show(struct device *dev, } static DEVICE_ATTR_RO(supports_autosuspend); +/* + * interface_authorized_show - show authorization status of an USB interface + * 1 is authorized, 0 is deauthorized + */ +static ssize_t interface_authorized_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + + return sprintf(buf, "%u\n", intf->authorized); +} + +/* + * interface_authorized_store - authorize or deauthorize an USB interface + */ +static ssize_t interface_authorized_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + bool val; + + if (strtobool(buf, ) != 0) + return -EINVAL; + + if (val) + usb_authorize_interface(intf); + else + usb_deauthorize_interface(intf); + + return count; +} +static struct device_attribute dev_attr_interface_authorized = + __ATTR(authorized, S_IRUGO | S_IWUSR, + interface_authorized_show, interface_authorized_store); + static struct attribute *intf_attrs[] = { _attr_bInterfaceNumber.attr, _attr_bAlternateSetting.attr, @@ -935,6 +970,7 @@ static struct attribute *intf_attrs[] = { _attr_bInterfaceProtocol.attr, _attr_modalias.attr, _attr_supports_autosuspend.attr, + _attr_interface_authorized.attr, NULL, }; static struct attribute_group intf_attr_grp = { -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v12 2/7] usb: interface authorization: Introduces the default interface authorization
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.koc...@gmail.com> --- drivers/usb/core/hcd.c | 47 ++ drivers/usb/core/message.c | 1 + include/linux/usb/hcd.h| 9 + 3 files changed, 57 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index cbcd092..84b5923 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -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, ) != 0) + return -EINVAL; + + if (val) + set_bit(HCD_FLAG_INTF_AUTHORIZED, >flags); + else + clear_bit(HCD_FLAG_INTF_AUTHORIZED, >flags); + + return rc; +} +static DEVICE_ATTR_RW(interface_authorized_default); + /* Group all the USB bus attributes */ static struct attribute *usb_bus_attrs[] = { _attr_authorized_default.attr, + _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, >flags); + /* per default all interfaces are authorized */ + set_bit(HCD_FLAG_INTF_AUTHORIZED, >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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..3d25d89 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -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(>ref); alt = usb_altnum_to_altsetting(intf, 0); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index c9aa779..e56c6b2 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* 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. */ unsignedrh_registered:1;/* is root hub registered? */ unsignedrh_pollable:1; /* may we poll the root hub? */ -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v12 3/7] usb: interface authorization: Control interface probing and claiming
Driver probings and interface claims get rejected if an interface is not authorized. Signed-off-by: Stefan Koch <stefan.koc...@gmail.com> --- drivers/usb/core/driver.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 818369a..9908e74 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -295,6 +295,10 @@ static int usb_probe_interface(struct device *dev) if (udev->authorized == 0) { dev_err(>dev, "Device is not authorized for usage\n"); return error; + } else if (intf->authorized == 0) { + dev_err(>dev, "Interface %d is not authorized for usage\n", + intf->altsetting->desc.bInterfaceNumber); + return error; } id = usb_match_dynamic_id(intf, driver); @@ -507,6 +511,10 @@ int usb_driver_claim_interface(struct usb_driver *driver, if (dev->driver) return -EBUSY; + /* reject claim if interface is not authorized */ + if (!iface->authorized) + return -ENODEV; + udev = interface_to_usbdev(iface); dev->driver = >drvwrap.driver; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v12 4/7] usb: interface authorization: Introduces the USB interface authorization
The kernel supports the device authorization because of wireless USB. These is usable for wired USB devices, too. These new interface authorization allows to enable or disable individual interfaces instead a whole device. If a deauthorized interface will be authorized so the driver probing must be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe Signed-off-by: Stefan Koch <stefan.koc...@gmail.com> --- drivers/usb/core/message.c | 38 ++ drivers/usb/core/usb.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3d25d89..c090f50 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1555,6 +1555,44 @@ static void usb_release_interface(struct device *dev) kfree(intf); } +/* + * usb_deauthorize_interface - deauthorize an USB interface + * + * @intf: USB interface structure + */ +void usb_deauthorize_interface(struct usb_interface *intf) +{ + struct device *dev = >dev; + + device_lock(dev->parent); + + if (intf->authorized) { + device_lock(dev); + intf->authorized = 0; + device_unlock(dev); + + usb_forced_unbind_intf(intf); + } + + device_unlock(dev->parent); +} + +/* + * usb_authorize_interface - authorize an USB interface + * + * @intf: USB interface structure + */ +void usb_authorize_interface(struct usb_interface *intf) +{ + struct device *dev = >dev; + + if (!intf->authorized) { + device_lock(dev); + intf->authorized = 1; /* authorize interface */ + device_unlock(dev); + } +} + static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 457255a..05b5e17 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -27,6 +27,8 @@ extern void usb_release_interface_cache(struct kref *ref); extern void usb_disable_device(struct usb_device *dev, int skip_ep0); extern int usb_deauthorize_device(struct usb_device *); extern int usb_authorize_device(struct usb_device *); +extern void usb_deauthorize_interface(struct usb_interface *); +extern void usb_authorize_interface(struct usb_interface *); extern void usb_detect_quirks(struct usb_device *udev); extern void usb_detect_interface_quirks(struct usb_device *udev); extern int usb_remove_device(struct usb_device *udev); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v12 7/7] usb: interface authorization: Use a flag for the default device authorization
With this patch a flag instead of a variable is used for the default device authorization. Signed-off-by: Stefan Koch <stefan.koc...@gmail.com> --- drivers/usb/core/hcd.c | 31 +-- drivers/usb/core/usb.c | 2 +- include/linux/usb/hcd.h | 16 +--- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 84b5923..a567647 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -854,10 +854,10 @@ static ssize_t authorized_default_show(struct device *dev, { struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev->bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); - return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default); + hcd = bus_to_hcd(usb_bus); + return snprintf(buf, PAGE_SIZE, "%u\n", !!HCD_DEV_AUTHORIZED(hcd)); } static ssize_t authorized_default_store(struct device *dev, @@ -868,12 +868,16 @@ static ssize_t authorized_default_store(struct device *dev, unsigned val; struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev->bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); + hcd = bus_to_hcd(usb_bus); result = sscanf(buf, "%u\n", ); if (result == 1) { - usb_hcd->authorized_default = val ? 1 : 0; + if (val) + set_bit(HCD_FLAG_DEV_AUTHORIZED, >flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, >flags); + result = size; } else { result = -EINVAL; @@ -2720,10 +2724,17 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_info(hcd->self.controller, "%s\n", hcd->product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ - if (authorized_default < 0 || authorized_default > 1) - hcd->authorized_default = hcd->wireless ? 0 : 1; - else - hcd->authorized_default = authorized_default; + if (authorized_default < 0 || authorized_default > 1) { + if (hcd->wireless) + clear_bit(HCD_FLAG_DEV_AUTHORIZED, >flags); + else + set_bit(HCD_FLAG_DEV_AUTHORIZED, >flags); + } else { + if (authorized_default) + set_bit(HCD_FLAG_DEV_AUTHORIZED, >flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, >flags); + } set_bit(HCD_FLAG_HW_ACCESSIBLE, >flags); /* per default all interfaces are authorized */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8d5b2f4..f8bbd0b 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -510,7 +510,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, if (root_hub) /* Root hub always ok [and always wired] */ dev->authorized = 1; else { - dev->authorized = usb_hcd->authorized_default; + dev->authorized = !!HCD_DEV_AUTHORIZED(usb_hcd); dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0; } return dev; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index e56c6b2..09a51a4 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -58,12 +58,6 @@ * * Since "struct usb_bus" is so thin, you can't share much code in it. * This framework is a layer over that, and should be more sharable. - * - * @authorized_default: Specifies if new devices are authorized to - * connect by default or they require explicit - * user space authorization; this bit is settable - * through /sys/class/usb_host/X/authorized_default. - * For the rest is RO, so we don't lock to r/w it. */ /*-*/ @@ -121,6 +115,7 @@ struct usb_hcd { #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ #define HCD_FLAG_INTF_AUTHORIZED 7 /* authorize interfaces? */ +#define HCD_FLAG_DEV_AUTHORIZED8 /* authorize devices? */ /* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -140,6 +135,14 @@ struct usb_hcd { #define HCD_INTF_AUTHORIZED(hcd) \ ((hcd)->flags & (1U << HCD_FLAG_INTF_AUTHORIZED)) + /* +* Specifies if devices are authorized by default +* or they require explicit user space authorization; this bit
[PATCH v12 0/7] usb: interface authorization
This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. v5 was acked-by Alan Stern: http://comments.gmane.org/gmane.linux.usb.general/127144 http://permalink.gmane.org/gmane.linux.usb.general/127151 Changes since v11: - Added parameter description Changes since v10: - Implemented spell suggestions from Krzysztof Opasiak Changes since v9: - Implemented suggestions from Greg K-H and Sergei Shtylyov Changes since v8: - Implemented suggestions from Greg K-H (number and doc issue) Changes since v7: - Implemented suggestions from Alan Stern and Sergei Shtylyov Changes since v6: - Implemented suggestions from Alan Stern and Sergei Shtylyov Changes since v5: - Implemented suggestions from Greg K-H - Changed device authorization to save the default bit in the same flag as the interface authorization does this (recommended by Alan Stern http://permalink.gmane.org/gmane.linux.usb.general/127086) Stefan Koch (7): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization usb: interface authorization: SysFS part of USB interface authorization usb: interface authorization: Documentation part usb: interface authorization: Use a flag for the default device authorization Documentation/ABI/testing/sysfs-bus-usb | 20 + Documentation/usb/authorization.txt | 31 + drivers/usb/core/driver.c | 8 drivers/usb/core/hcd.c | 78 - drivers/usb/core/message.c | 39 + drivers/usb/core/sysfs.c| 36 +++ drivers/usb/core/usb.c | 2 +- drivers/usb/core/usb.h | 2 + include/linux/usb.h | 2 + include/linux/usb/hcd.h | 25 --- 10 files changed, 225 insertions(+), 18 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v12 6/7] usb: interface authorization: Documentation part
This part adds the documentation for the interface authorization. Signed-off-by: Stefan Koch <stefan.koc...@gmail.com> --- Documentation/ABI/testing/sysfs-bus-usb | 20 Documentation/usb/authorization.txt | 31 +++ 2 files changed, 51 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index e5cc763..b5690d3 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -1,3 +1,23 @@ +What: /sys/bus/usb/devices/INTERFACE/authorized +Date: August 2015 +Description: + This allows to authorize (1) or deauthorize (0) + individual interfaces instead a whole device + in contrast to the device authorization. + If a deauthorized interface will be authorized + so the driver probing must be triggered manually + by writing INTERFACE to /sys/bus/usb/drivers_probe + This allows to avoid side-effects with drivers + that need multiple interfaces. + A deauthorized interface cannot be probed or claimed. + +What: /sys/bus/usb/devices/usbX/interface_authorized_default +Date: August 2015 +Description: + This is used as value that determines if interfaces + would be authorized by default. + The value can be 1 or 0. It's by default 1. + What: /sys/bus/usb/device/.../authorized Date: July 2008 KernelVersion: 2.6.26 diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index c069b68..c7e985f 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt @@ -90,3 +90,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit can fake descriptors and device info. Don't trust that. You are welcome. + +Interface authorization +--- +There is a similar approach to allow or deny specific USB interfaces. +That allows to block only a subset of an USB device. + +Authorize an interface: +$ echo 1 > /sys/bus/usb/devices/INTERFACE/authorized + +Deauthorize an interface: +$ echo 0 > /sys/bus/usb/devices/INTERFACE/authorized + +The default value for new interfaces +on a particular USB bus can be changed, too. + +Allow interfaces per default: +$ echo 1 > /sys/bus/usb/devices/usbX/interface_authorized_default + +Deny interfaces per default: +$ echo 0 > /sys/bus/usb/devices/usbX/interface_authorized_default + +Per default the interface_authorized_default bit is 1. +So all interfaces would authorized per default. + +Note: +If a deauthorized interface will be authorized so the driver probing must +be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe + +For drivers that need multiple interfaces all needed interfaces should be +authroized first. After that the drivers should be probed. +This avoids side effects. -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11] Added forgotten parameter description for authorized attribute in usb.h
Signed-off-by: Stefan Koch <stefan.koc...@gmail.com> --- include/linux/usb.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 3deccab..2cbcf8d 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -122,6 +122,8 @@ enum usb_interface_condition { * has been deferred. * @needs_binding: flag set when the driver should be re-probed or unbound * following a reset or suspend operation it doesn't support. + * @authorized: This allows to (de)authorize individual interfaces instead + * a whole device in contrast to the device authorization. * @dev: driver model's view of this device * @usb_dev: if an interface is bound to the USB major, this will point * to the sysfs representation for that device. -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [usb:usb-testing 2/8] include/linux/usb.h:187: warning: No description found for parameter 'authorized'
Hi Greg, should I correct this? Thanks Stefan Koch Am Mittwoch, den 23.09.2015, 03:40 +0800 schrieb kbuild test robot: > tree: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git > usb-testing > head: ff8e2c560eca32043ed097099debac488a4bd99f > commit: 4ad2ddce1a096dea71d42969515d3a64f0d9246f [2/8] usb: interface > authorization: Declare authorized attribute > config: i386-allnoconfig (attached as .config) > reproduce: > git checkout 4ad2ddce1a096dea71d42969515d3a64f0d9246f > # save the attached .config to linux build tree > make ARCH=i386 > > All warnings (new ones prefixed by >>): > > >> include/linux/usb.h:187: warning: No description found for parameter > >> 'authorized' > > vim +/authorized +187 include/linux/usb.h > > b724ae77 Alan Stern 2005-10-24 171 int minor; > /* minor number this interface is > b724ae77 Alan Stern 2005-10-24 172 > * bound to */ > ^1da177e Linus Torvalds 2005-04-16 173 enum > usb_interface_condition condition; /* state of binding */ > 7e61559f Alan Stern 2007-11-06 174 unsigned > sysfs_files_created:1; /* the sysfs attributes exist */ > 3b23dd6f Alan Stern 2008-12-05 175 unsigned > ep_devs_created:1; /* endpoint "devices" exist */ > 352d0263 Alan Stern 2008-10-29 176 unsigned > unregistering:1; /* unregistration is in progress */ > 645daaab Alan Stern 2006-08-30 177 unsigned > needs_remote_wakeup:1; /* driver requires remote wakeup */ > 55151d7d Alan Stern 2008-08-12 178 unsigned > needs_altsetting0:1; /* switch to altsetting 0 is pending */ > 78d9a487 Alan Stern 2008-06-23 179 unsigned > needs_binding:1; /* needs delayed unbind/rebind */ > 04a723ea Sarah Sharp 2010-01-06 180 unsigned > resetting_device:1;/* true: bandwidth alloc after reset */ > 4ad2ddce Stefan Koch 2015-08-25 181 unsigned authorized:1; > /* used for interface authorization */ > 4d064c08 Alan Stern 2006-07-01 182 > ^1da177e Linus Torvalds 2005-04-16 183 struct device dev; > /* interface specific device info */ > 969ab2ee Greg Kroah-Hartman 2008-01-30 184 struct device *usb_dev; > ccf5b801 Alan Stern 2009-06-29 185 atomic_t pm_usage_cnt; > /* usage counter for autosuspend */ > dc023dce Inaky Perez-Gonzalez 2008-11-13 186 struct work_struct > reset_ws;/* for resets in atomic context */ > ^1da177e Linus Torvalds 2005-04-16 @187 }; > ^1da177e Linus Torvalds 2005-04-16 188 #define > to_usb_interface(d) container_of(d, struct usb_interface, dev) > ^1da177e Linus Torvalds 2005-04-16 189 > ^1da177e Linus Torvalds 2005-04-16 190 static inline void > *usb_get_intfdata(struct usb_interface *intf) > ^1da177e Linus Torvalds 2005-04-16 191 { > ^1da177e Linus Torvalds 2005-04-16 192 return > dev_get_drvdata(>dev); > ^1da177e Linus Torvalds 2005-04-16 193 } > ^1da177e Linus Torvalds 2005-04-16 194 > ^1da177e Linus Torvalds 2005-04-16 195 static inline void > usb_set_intfdata(struct usb_interface *intf, void *data) > > :: The code at line 187 was first introduced by commit > :: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2 > > :: TO: Linus Torvalds <torva...@ppc970.osdl.org> > :: CC: Linus Torvalds <torva...@ppc970.osdl.org> > > --- > 0-DAY kernel test infrastructureOpen Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v10 4/7] usb: interface authorization: Introduces the USB interface authorization
Am Dienstag, den 25.08.2015, 11:58 +0200 schrieb Krzysztof Opasiak: On 08/24/2015 11:09 PM, Stefan Koch wrote: The kernel supports the device authorization because of wireless USB. These is usable for wired USB devices, too. These new interface authorization allows to enable or disable individual interfaces instead a whole device. If a deauthorized interface will be authorized so the driver probing must be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- drivers/usb/core/message.c | 38 ++ drivers/usb/core/usb.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3d25d89..c090f50 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1555,6 +1555,44 @@ static void usb_release_interface(struct device *dev) kfree(intf); } +/* + * usb_deauthorize_interface - deauthorize an USB interface + * + * @intf: USB interface structure + */ +void usb_deauthorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + device_lock(dev-parent); + + if (intf-authorized) { + device_lock(dev); + intf-authorized = 0; + device_unlock(dev); + + usb_forced_unbind_intf(intf); + } + + device_unlock(dev-parent); +} + +/* + * usb_authorize_interface - authorize an USB interface + * + * @intf: USB interface structure + */ +void usb_authorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + if (!intf-authorized) { + device_lock(dev); + intf-authorized = 1; /* authorize interface */ + device_unlock(dev); + } +} + Why usb_deauthorize_interface() takes both dev-parent and dev locks and usb_authorize_interface() takes only dev lock? Because usb_forced_unbind_intf() needs the devices lock... In the auth case, we change only a flag. -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 3/7] usb: interface authorization: Control interface probing and claiming
Driver probings and interface claims get rejected if an interface is not authorized. Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- drivers/usb/core/driver.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 818369a..9908e74 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -295,6 +295,10 @@ static int usb_probe_interface(struct device *dev) if (udev-authorized == 0) { dev_err(intf-dev, Device is not authorized for usage\n); return error; + } else if (intf-authorized == 0) { + dev_err(intf-dev, Interface %d is not authorized for usage\n, + intf-altsetting-desc.bInterfaceNumber); + return error; } id = usb_match_dynamic_id(intf, driver); @@ -507,6 +511,10 @@ int usb_driver_claim_interface(struct usb_driver *driver, if (dev-driver) return -EBUSY; + /* reject claim if interface is not authorized */ + if (!iface-authorized) + return -ENODEV; + udev = interface_to_usbdev(iface); dev-driver = driver-drvwrap.driver; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 5/7] usb: interface authorization: SysFS part of USB interface authorization
This introduces an attribute for each interface to authorize (1) or deauthorize (0) it: /sys/bus/usb/devices/INTERFACE/authorized Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- drivers/usb/core/sysfs.c | 36 1 file changed, 36 insertions(+) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d269738..3ddaada 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -926,6 +926,41 @@ static ssize_t supports_autosuspend_show(struct device *dev, } static DEVICE_ATTR_RO(supports_autosuspend); +/* + * interface_authorized_show - show authorization status of an USB interface + * 1 is authorized, 0 is deauthorized + */ +static ssize_t interface_authorized_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + + return sprintf(buf, %u\n, intf-authorized); +} + +/* + * interface_authorized_store - authorize or deauthorize an USB interface + */ +static ssize_t interface_authorized_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + bool val; + + if (strtobool(buf, val) != 0) + return -EINVAL; + + if (val) + usb_authorize_interface(intf); + else + usb_deauthorize_interface(intf); + + return count; +} +static struct device_attribute dev_attr_interface_authorized = + __ATTR(authorized, S_IRUGO | S_IWUSR, + interface_authorized_show, interface_authorized_store); + static struct attribute *intf_attrs[] = { dev_attr_bInterfaceNumber.attr, dev_attr_bAlternateSetting.attr, @@ -935,6 +970,7 @@ static struct attribute *intf_attrs[] = { dev_attr_bInterfaceProtocol.attr, dev_attr_modalias.attr, dev_attr_supports_autosuspend.attr, + dev_attr_interface_authorized.attr, NULL, }; static struct attribute_group intf_attr_grp = { -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 2/7] usb: interface authorization: Introduces the default interface authorization
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.koc...@gmail.com --- drivers/usb/core/hcd.c | 47 ++ drivers/usb/core/message.c | 1 + include/linux/usb/hcd.h| 9 + 3 files changed, 57 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index cbcd092..84b5923 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..3d25d89 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -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); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index c9aa779..e56c6b2 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* 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. */ unsignedrh_registered:1;/* is root hub registered? */ unsignedrh_pollable:1; /* may we poll the root hub? */ -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 6/7] usb: interface authorization: Documentation part
This part adds the documentation for the interface authorization. Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- Documentation/ABI/testing/sysfs-bus-usb | 20 Documentation/usb/authorization.txt | 31 +++ 2 files changed, 51 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index e5cc763..b5690d3 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -1,3 +1,23 @@ +What: /sys/bus/usb/devices/INTERFACE/authorized +Date: August 2015 +Description: + This allows to authorize (1) or deauthorize (0) + individual interfaces instead a whole device + in contrast to the device authorization. + If a deauthorized interface will be authorized + so the driver probing must be triggered manually + by writing INTERFACE to /sys/bus/usb/drivers_probe + This allows to avoid side-effects with drivers + that need multiple interfaces. + A deauthorized interface cannot be probed or claimed. + +What: /sys/bus/usb/devices/usbX/interface_authorized_default +Date: August 2015 +Description: + This is used as value that determines if interfaces + would be authorized by default. + The value can be 1 or 0. It's by default 1. + What: /sys/bus/usb/device/.../authorized Date: July 2008 KernelVersion: 2.6.26 diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index c069b68..c7e985f 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt @@ -90,3 +90,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit can fake descriptors and device info. Don't trust that. You are welcome. + +Interface authorization +--- +There is a similar approach to allow or deny specific USB interfaces. +That allows to block only a subset of an USB device. + +Authorize an interface: +$ echo 1 /sys/bus/usb/devices/INTERFACE/authorized + +Deauthorize an interface: +$ echo 0 /sys/bus/usb/devices/INTERFACE/authorized + +The default value for new interfaces +on a particular USB bus can be changed, too. + +Allow interfaces per default: +$ echo 1 /sys/bus/usb/devices/usbX/interface_authorized_default + +Deny interfaces per default: +$ echo 0 /sys/bus/usb/devices/usbX/interface_authorized_default + +Per default the interface_authorized_default bit is 1. +So all interfaces would authorized per default. + +Note: +If a deauthorized interface will be authorized so the driver probing must +be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe + +For drivers that need multiple interfaces all needed interfaces should be +authroized first. After that the drivers should be probed. +This avoids side effects. -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 7/7] usb: interface authorization: Use a flag for the default device authorization
With this patch a flag instead of a variable is used for the default device authorization. Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- drivers/usb/core/hcd.c | 31 +-- drivers/usb/core/usb.c | 2 +- include/linux/usb/hcd.h | 16 +--- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 84b5923..a567647 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -854,10 +854,10 @@ static ssize_t authorized_default_show(struct device *dev, { struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); - return snprintf(buf, PAGE_SIZE, %u\n, usb_hcd-authorized_default); + hcd = bus_to_hcd(usb_bus); + return snprintf(buf, PAGE_SIZE, %u\n, !!HCD_DEV_AUTHORIZED(hcd)); } static ssize_t authorized_default_store(struct device *dev, @@ -868,12 +868,16 @@ static ssize_t authorized_default_store(struct device *dev, unsigned val; struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); + hcd = bus_to_hcd(usb_bus); result = sscanf(buf, %u\n, val); if (result == 1) { - usb_hcd-authorized_default = val ? 1 : 0; + if (val) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + result = size; } else { result = -EINVAL; @@ -2720,10 +2724,17 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_info(hcd-self.controller, %s\n, hcd-product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ - if (authorized_default 0 || authorized_default 1) - hcd-authorized_default = hcd-wireless ? 0 : 1; - else - hcd-authorized_default = authorized_default; + if (authorized_default 0 || authorized_default 1) { + if (hcd-wireless) + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } else { + if (authorized_default) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); /* per default all interfaces are authorized */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8d5b2f4..f8bbd0b 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -510,7 +510,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, if (root_hub) /* Root hub always ok [and always wired] */ dev-authorized = 1; else { - dev-authorized = usb_hcd-authorized_default; + dev-authorized = !!HCD_DEV_AUTHORIZED(usb_hcd); dev-wusb = usb_bus_is_wusb(bus) ? 1 : 0; } return dev; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index e56c6b2..09a51a4 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -58,12 +58,6 @@ * * Since struct usb_bus is so thin, you can't share much code in it. * This framework is a layer over that, and should be more sharable. - * - * @authorized_default: Specifies if new devices are authorized to - * connect by default or they require explicit - * user space authorization; this bit is settable - * through /sys/class/usb_host/X/authorized_default. - * For the rest is RO, so we don't lock to r/w it. */ /*-*/ @@ -121,6 +115,7 @@ struct usb_hcd { #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ #define HCD_FLAG_INTF_AUTHORIZED 7 /* authorize interfaces? */ +#define HCD_FLAG_DEV_AUTHORIZED8 /* authorize devices? */ /* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -140,6 +135,14 @@ struct usb_hcd { #define HCD_INTF_AUTHORIZED(hcd) \ ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) + /* +* Specifies if devices are authorized by default +* or they require explicit user space authorization; this bit is +* settable through /sys/class/usb_host/X/authorized_default +*/ +#define HCD_DEV_AUTHORIZED(hcd) \ + ((hcd)-flags (1U
[PATCH v11 1/7] usb: interface authorization: Declare authorized attribute
The attribute authorized shows the authorization state for an interface. Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 447fe29..3deccab 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -178,6 +178,7 @@ struct usb_interface { unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned resetting_device:1;/* true: bandwidth alloc after reset */ + unsigned authorized:1; /* used for interface authorization */ struct device dev; /* interface specific device info */ struct device *usb_dev; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 0/7] usb: interface authorization
This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. v5 was acked-by Alan Stern: http://comments.gmane.org/gmane.linux.usb.general/127144 http://permalink.gmane.org/gmane.linux.usb.general/127151 Changes since v10: - Implemented spell suggestions from Krzysztof Opasiak Changes since v9: - Implemented suggestions from Greg K-H and Sergei Shtylyov Changes since v8: - Implemented suggestions from Greg K-H (number and doc issue) Changes since v7: - Implemented suggestions from Alan Stern and Sergei Shtylyov Changes since v6: - Implemented suggestions from Alan Stern and Sergei Shtylyov Changes since v5: - Implemented suggestions from Greg K-H - Changed device authorization to save the default bit in the same flag as the interface authorization does this (recommended by Alan Stern http://permalink.gmane.org/gmane.linux.usb.general/127086) Stefan Koch (7): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization usb: interface authorization: SysFS part of USB interface authorization usb: interface authorization: Documentation part usb: interface authorization: Use a flag for the default device authorization Documentation/ABI/testing/sysfs-bus-usb | 20 + Documentation/usb/authorization.txt | 31 + drivers/usb/core/driver.c | 8 drivers/usb/core/hcd.c | 78 - drivers/usb/core/message.c | 39 + drivers/usb/core/sysfs.c| 36 +++ drivers/usb/core/usb.c | 2 +- drivers/usb/core/usb.h | 2 + include/linux/usb.h | 1 + include/linux/usb/hcd.h | 25 --- 10 files changed, 224 insertions(+), 18 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 4/7] usb: interface authorization: Introduces the USB interface authorization
The kernel supports the device authorization because of wireless USB. These is usable for wired USB devices, too. These new interface authorization allows to enable or disable individual interfaces instead a whole device. If a deauthorized interface will be authorized so the driver probing must be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- drivers/usb/core/message.c | 38 ++ drivers/usb/core/usb.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3d25d89..c090f50 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1555,6 +1555,44 @@ static void usb_release_interface(struct device *dev) kfree(intf); } +/* + * usb_deauthorize_interface - deauthorize an USB interface + * + * @intf: USB interface structure + */ +void usb_deauthorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + device_lock(dev-parent); + + if (intf-authorized) { + device_lock(dev); + intf-authorized = 0; + device_unlock(dev); + + usb_forced_unbind_intf(intf); + } + + device_unlock(dev-parent); +} + +/* + * usb_authorize_interface - authorize an USB interface + * + * @intf: USB interface structure + */ +void usb_authorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + if (!intf-authorized) { + device_lock(dev); + intf-authorized = 1; /* authorize interface */ + device_unlock(dev); + } +} + static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 457255a..05b5e17 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -27,6 +27,8 @@ extern void usb_release_interface_cache(struct kref *ref); extern void usb_disable_device(struct usb_device *dev, int skip_ep0); extern int usb_deauthorize_device(struct usb_device *); extern int usb_authorize_device(struct usb_device *); +extern void usb_deauthorize_interface(struct usb_interface *); +extern void usb_authorize_interface(struct usb_interface *); extern void usb_detect_quirks(struct usb_device *udev); extern void usb_detect_interface_quirks(struct usb_device *udev); extern int usb_remove_device(struct usb_device *udev); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 1/7] usb: interface authorization: Declare authorized attribute
Am Montag, den 17.08.2015, 09:34 -0700 schrieb Greg KH: On Sat, Aug 08, 2015 at 11:32:50AM +0200, Stefan Koch wrote: The attribute authorized shows the authorization state for an interface. Signed-off-by: Stefan Koch sk...@suse.de This email bounces, so I have to rip this series out of the tree :( Please resend this with a working email for a signed-off-by line. greg k-h OK, I will resend the patch and include the doc corrections from Sergei. Thanks for the help Stefan -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 0/7] usb: interface authorization
This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. v5 was acked-by Alan Stern: http://comments.gmane.org/gmane.linux.usb.general/127144 http://permalink.gmane.org/gmane.linux.usb.general/127151 Changes since v9: - Implemented suggestions from Greg K-H and Sergei Shtylyov Changes since v8: - Implemented suggestions from Greg K-H (number and doc issue) Changes since v7: - Implemented suggestions from Alan Stern and Sergei Shtylyov Changes since v6: - Implemented suggestions from Alan Stern and Sergei Shtylyov Changes since v5: - Implemented suggestions from Greg K-H - Changed device authorization to save the default bit in the same flag as the interface authorization does this (recommended by Alan Stern http://permalink.gmane.org/gmane.linux.usb.general/127086) Stefan Koch (7): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization usb: interface authorization: SysFS part of USB interface authorization usb: interface authorization: Documentation part usb: interface authorization: Use a flag for the default device authorization Documentation/ABI/testing/sysfs-bus-usb | 20 + Documentation/usb/authorization.txt | 31 + drivers/usb/core/driver.c | 8 drivers/usb/core/hcd.c | 78 - drivers/usb/core/message.c | 39 + drivers/usb/core/sysfs.c| 36 +++ drivers/usb/core/usb.c | 2 +- drivers/usb/core/usb.h | 2 + include/linux/usb.h | 1 + include/linux/usb/hcd.h | 25 --- 10 files changed, 224 insertions(+), 18 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 5/7] usb: interface authorization: SysFS part of USB interface authorization
This introduces an attribute for each interface to authorize (1) or deauthorize (0) it: /sys/bus/usb/devices/INTERFACE/authorized Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- drivers/usb/core/sysfs.c | 36 1 file changed, 36 insertions(+) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d269738..3ddaada 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -926,6 +926,41 @@ static ssize_t supports_autosuspend_show(struct device *dev, } static DEVICE_ATTR_RO(supports_autosuspend); +/* + * interface_authorized_show - show authorization status of an USB interface + * 1 is authorized, 0 is deauthorized + */ +static ssize_t interface_authorized_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + + return sprintf(buf, %u\n, intf-authorized); +} + +/* + * interface_authorized_store - authorize or deauthorize an USB interface + */ +static ssize_t interface_authorized_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + bool val; + + if (strtobool(buf, val) != 0) + return -EINVAL; + + if (val) + usb_authorize_interface(intf); + else + usb_deauthorize_interface(intf); + + return count; +} +static struct device_attribute dev_attr_interface_authorized = + __ATTR(authorized, S_IRUGO | S_IWUSR, + interface_authorized_show, interface_authorized_store); + static struct attribute *intf_attrs[] = { dev_attr_bInterfaceNumber.attr, dev_attr_bAlternateSetting.attr, @@ -935,6 +970,7 @@ static struct attribute *intf_attrs[] = { dev_attr_bInterfaceProtocol.attr, dev_attr_modalias.attr, dev_attr_supports_autosuspend.attr, + dev_attr_interface_authorized.attr, NULL, }; static struct attribute_group intf_attr_grp = { -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 6/7] usb: interface authorization: Documentation part
This part adds the documentation for the interface authorization. Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- Documentation/ABI/testing/sysfs-bus-usb | 20 Documentation/usb/authorization.txt | 31 +++ 2 files changed, 51 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index e5cc763..b5690d3 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -1,3 +1,23 @@ +What: /sys/bus/usb/devices/INTERFACE/authorized +Date: August 2015 +Description: + This allows to authorize (1) or deauthorize (0) + individual interfaces instead a whole device + in contrast to the device authorization. + If a deauthorized interface will be authorized + so the driver probing must be triggered manually + by writing INTERFACE to /sys/bus/usb/drivers_probe + This allows to avoid side-effects with drivers + that need multiple interfaces. + A deauthorized interface cannot be probed or claimed. + +What: /sys/bus/usb/devices/usbX/interface_authorized_default +Date: August 2015 +Description: + This is used as value that determines if interfaces + would be authorized by default. + The value can be 1 or 0. It's by default 1. + What: /sys/bus/usb/device/.../authorized Date: July 2008 KernelVersion: 2.6.26 diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index c069b68..c7e985f 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt @@ -90,3 +90,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit can fake descriptors and device info. Don't trust that. You are welcome. + +Interface authorization +--- +There is a similar approach to allow or deny specific USB interfaces. +That allows to block only a subset of an USB device. + +Authorize an interface: +$ echo 1 /sys/bus/usb/devices/INTERFACE/authorized + +Deauthorize an interface: +$ echo 0 /sys/bus/usb/devices/INTERFACE/authorized + +The default value for new interfaces +on a particular USB bus can be changed, too. + +Allow interfaces per default: +$ echo 1 /sys/bus/usb/devices/usbX/interface_authorized_default + +Deny interfaces per default: +$ echo 0 /sys/bus/usb/devices/usbX/interface_authorized_default + +Per default the interface_authorized_default bit is 1. +So all interfaces would authorized per default. + +Note: +If a deauthorized interface will be authorized so the driver probing must +be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe + +For drivers that need multiple interfaces all needed interfaces should be +authroized first. After that the drivers should be probed. +This avoids side effects. -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 1/7] usb: interface authorization: Declare authorized attribute
The attribute authorized shows the authorization state for an interface. Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 447fe29..3deccab 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -178,6 +178,7 @@ struct usb_interface { unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned resetting_device:1;/* true: bandwidth alloc after reset */ + unsigned authorized:1; /* used for interface authorization */ struct device dev; /* interface specific device info */ struct device *usb_dev; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 7/7] usb: interface authorization: Use a flag for the default device authorization
With this patch a flag instead of a variable is used for the default device authorization. Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- drivers/usb/core/hcd.c | 31 +-- drivers/usb/core/usb.c | 2 +- include/linux/usb/hcd.h | 16 +--- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 84b5923..a567647 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -854,10 +854,10 @@ static ssize_t authorized_default_show(struct device *dev, { struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); - return snprintf(buf, PAGE_SIZE, %u\n, usb_hcd-authorized_default); + hcd = bus_to_hcd(usb_bus); + return snprintf(buf, PAGE_SIZE, %u\n, !!HCD_DEV_AUTHORIZED(hcd)); } static ssize_t authorized_default_store(struct device *dev, @@ -868,12 +868,16 @@ static ssize_t authorized_default_store(struct device *dev, unsigned val; struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); + hcd = bus_to_hcd(usb_bus); result = sscanf(buf, %u\n, val); if (result == 1) { - usb_hcd-authorized_default = val ? 1 : 0; + if (val) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + result = size; } else { result = -EINVAL; @@ -2720,10 +2724,17 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_info(hcd-self.controller, %s\n, hcd-product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ - if (authorized_default 0 || authorized_default 1) - hcd-authorized_default = hcd-wireless ? 0 : 1; - else - hcd-authorized_default = authorized_default; + if (authorized_default 0 || authorized_default 1) { + if (hcd-wireless) + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } else { + if (authorized_default) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); /* per default all interfaces are authorized */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8d5b2f4..f8bbd0b 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -510,7 +510,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, if (root_hub) /* Root hub always ok [and always wired] */ dev-authorized = 1; else { - dev-authorized = usb_hcd-authorized_default; + dev-authorized = !!HCD_DEV_AUTHORIZED(usb_hcd); dev-wusb = usb_bus_is_wusb(bus) ? 1 : 0; } return dev; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index e56c6b2..09a51a4 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -58,12 +58,6 @@ * * Since struct usb_bus is so thin, you can't share much code in it. * This framework is a layer over that, and should be more sharable. - * - * @authorized_default: Specifies if new devices are authorized to - * connect by default or they require explicit - * user space authorization; this bit is settable - * through /sys/class/usb_host/X/authorized_default. - * For the rest is RO, so we don't lock to r/w it. */ /*-*/ @@ -121,6 +115,7 @@ struct usb_hcd { #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ #define HCD_FLAG_INTF_AUTHORIZED 7 /* authorize interfaces? */ +#define HCD_FLAG_DEV_AUTHORIZED8 /* authorize devices? */ /* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -140,6 +135,14 @@ struct usb_hcd { #define HCD_INTF_AUTHORIZED(hcd) \ ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) + /* +* Specifies if devices are authorized by default +* or they require explicit user space authorization; this bit is +* settable through /sys/class/usb_host/X/authorized_default +*/ +#define HCD_DEV_AUTHORIZED(hcd) \ + ((hcd)-flags (1U
[PATCH v10 2/7] usb: interface authorization: Introduces the default interface authorization
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.koc...@gmail.com --- drivers/usb/core/hcd.c | 47 ++ drivers/usb/core/message.c | 1 + include/linux/usb/hcd.h| 9 + 3 files changed, 57 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index cbcd092..84b5923 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..3d25d89 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -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); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index c9aa779..e56c6b2 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* 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. */ unsignedrh_registered:1;/* is root hub registered? */ unsignedrh_pollable:1; /* may we poll the root hub? */ -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 4/7] usb: interface authorization: Introduces the USB interface authorization
The kernel supports the device authorization because of wireless USB. These is usable for wired USB devices, too. These new interface authorization allows to enable or disable individual interfaces instead a whole device. If a deauthorized interface will be authorized so the driver probing must be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- drivers/usb/core/message.c | 38 ++ drivers/usb/core/usb.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3d25d89..c090f50 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1555,6 +1555,44 @@ static void usb_release_interface(struct device *dev) kfree(intf); } +/* + * usb_deauthorize_interface - deauthorize an USB interface + * + * @intf: USB interface structure + */ +void usb_deauthorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + device_lock(dev-parent); + + if (intf-authorized) { + device_lock(dev); + intf-authorized = 0; + device_unlock(dev); + + usb_forced_unbind_intf(intf); + } + + device_unlock(dev-parent); +} + +/* + * usb_authorize_interface - authorize an USB interface + * + * @intf: USB interface structure + */ +void usb_authorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + if (!intf-authorized) { + device_lock(dev); + intf-authorized = 1; /* authorize interface */ + device_unlock(dev); + } +} + static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 457255a..05b5e17 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -27,6 +27,8 @@ extern void usb_release_interface_cache(struct kref *ref); extern void usb_disable_device(struct usb_device *dev, int skip_ep0); extern int usb_deauthorize_device(struct usb_device *); extern int usb_authorize_device(struct usb_device *); +extern void usb_deauthorize_interface(struct usb_interface *); +extern void usb_authorize_interface(struct usb_interface *); extern void usb_detect_quirks(struct usb_device *udev); extern void usb_detect_interface_quirks(struct usb_device *udev); extern int usb_remove_device(struct usb_device *udev); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 3/7] usb: interface authorization: Control interface probing and claiming
Driver probings and interface claims get rejected if an interface is not authorized. Signed-off-by: Stefan Koch stefan.koc...@gmail.com --- drivers/usb/core/driver.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 818369a..d542d43 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -295,6 +295,10 @@ static int usb_probe_interface(struct device *dev) if (udev-authorized == 0) { dev_err(intf-dev, Device is not authorized for usage\n); return error; + } else if (intf-authorized == 0) { + dev_err(intf-dev, Interface %d is not authorized for usage\n, + intf-altsetting-desc.bInterfaceNumber); + return error; } id = usb_match_dynamic_id(intf, driver); @@ -507,6 +511,10 @@ int usb_driver_claim_interface(struct usb_driver *driver, if (dev-driver) return -EBUSY; + /* reject claim if not iterface is not authorized */ + if (!iface-authorized) + return -ENODEV; + udev = interface_to_usbdev(iface); dev-driver = driver-drvwrap.driver; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v9 1/7] usb: interface authorization: Declare authorized attribute
The attribute authorized shows the authorization state for an interface. Signed-off-by: Stefan Koch sk...@suse.de --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 447fe29..3deccab 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -178,6 +178,7 @@ struct usb_interface { unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned resetting_device:1;/* true: bandwidth alloc after reset */ + unsigned authorized:1; /* used for interface authorization */ struct device dev; /* interface specific device info */ struct device *usb_dev; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v9 0/7] usb: interface authorization
This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. v5 was acked-by Alan Stern: http://comments.gmane.org/gmane.linux.usb.general/127144 http://permalink.gmane.org/gmane.linux.usb.general/127151 Changes since v8: - Implemented suggestions from Greg K-H (number and doc issue) Changes since v7: - Implemented suggestions from Alan Stern and Sergei Shtylyov Changes since v6: - Implemented suggestions from Alan Stern and Sergei Shtylyov Changes since v5: - Implemented suggestions from Greg K-H - Changed device authorization to save the default bit in the same flag as the interface authorization does this (recommended by Alan Stern http://permalink.gmane.org/gmane.linux.usb.general/127086) Stefan Koch (7): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization usb: interface authorization: SysFS part of USB interface authorization usb: interface authorization: Documentation part usb: interface authorization: Use a flag for the default device authorization Documentation/ABI/testing/sysfs-bus-usb | 22 ++ Documentation/usb/authorization.txt | 34 ++ drivers/usb/core/driver.c | 8 drivers/usb/core/hcd.c | 78 - drivers/usb/core/message.c | 39 + drivers/usb/core/sysfs.c| 36 +++ drivers/usb/core/usb.c | 2 +- drivers/usb/core/usb.h | 2 + include/linux/usb.h | 1 + include/linux/usb/hcd.h | 25 --- 10 files changed, 229 insertions(+), 18 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v9 2/7] usb: interface authorization: Introduces the default interface authorization
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 sk...@suse.de --- drivers/usb/core/hcd.c | 47 ++ drivers/usb/core/message.c | 1 + include/linux/usb/hcd.h| 9 + 3 files changed, 57 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index cbcd092..84b5923 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..3d25d89 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -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); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index c9aa779..e56c6b2 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* 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. */ unsignedrh_registered:1;/* is root hub registered? */ unsignedrh_pollable:1; /* may we poll the root hub? */ -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v9 3/7] usb: interface authorization: Control interface probing and claiming
Driver probings and interface claims get rejected if an interface is not authorized. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/driver.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 818369a..d542d43 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -295,6 +295,10 @@ static int usb_probe_interface(struct device *dev) if (udev-authorized == 0) { dev_err(intf-dev, Device is not authorized for usage\n); return error; + } else if (intf-authorized == 0) { + dev_err(intf-dev, Interface %d is not authorized for usage\n, + intf-altsetting-desc.bInterfaceNumber); + return error; } id = usb_match_dynamic_id(intf, driver); @@ -507,6 +511,10 @@ int usb_driver_claim_interface(struct usb_driver *driver, if (dev-driver) return -EBUSY; + /* reject claim if not iterface is not authorized */ + if (!iface-authorized) + return -ENODEV; + udev = interface_to_usbdev(iface); dev-driver = driver-drvwrap.driver; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v9 7/7] usb: interface authorization: Use a flag for the default device authorization
With this patch a flag instead of a variable is used for the default device authorization. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/hcd.c | 31 +-- drivers/usb/core/usb.c | 2 +- include/linux/usb/hcd.h | 16 +--- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 84b5923..a567647 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -854,10 +854,10 @@ static ssize_t authorized_default_show(struct device *dev, { struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); - return snprintf(buf, PAGE_SIZE, %u\n, usb_hcd-authorized_default); + hcd = bus_to_hcd(usb_bus); + return snprintf(buf, PAGE_SIZE, %u\n, !!HCD_DEV_AUTHORIZED(hcd)); } static ssize_t authorized_default_store(struct device *dev, @@ -868,12 +868,16 @@ static ssize_t authorized_default_store(struct device *dev, unsigned val; struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); + hcd = bus_to_hcd(usb_bus); result = sscanf(buf, %u\n, val); if (result == 1) { - usb_hcd-authorized_default = val ? 1 : 0; + if (val) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + result = size; } else { result = -EINVAL; @@ -2720,10 +2724,17 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_info(hcd-self.controller, %s\n, hcd-product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ - if (authorized_default 0 || authorized_default 1) - hcd-authorized_default = hcd-wireless ? 0 : 1; - else - hcd-authorized_default = authorized_default; + if (authorized_default 0 || authorized_default 1) { + if (hcd-wireless) + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } else { + if (authorized_default) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); /* per default all interfaces are authorized */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8d5b2f4..f8bbd0b 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -510,7 +510,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, if (root_hub) /* Root hub always ok [and always wired] */ dev-authorized = 1; else { - dev-authorized = usb_hcd-authorized_default; + dev-authorized = !!HCD_DEV_AUTHORIZED(usb_hcd); dev-wusb = usb_bus_is_wusb(bus) ? 1 : 0; } return dev; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index e56c6b2..09a51a4 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -58,12 +58,6 @@ * * Since struct usb_bus is so thin, you can't share much code in it. * This framework is a layer over that, and should be more sharable. - * - * @authorized_default: Specifies if new devices are authorized to - * connect by default or they require explicit - * user space authorization; this bit is settable - * through /sys/class/usb_host/X/authorized_default. - * For the rest is RO, so we don't lock to r/w it. */ /*-*/ @@ -121,6 +115,7 @@ struct usb_hcd { #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ #define HCD_FLAG_INTF_AUTHORIZED 7 /* authorize interfaces? */ +#define HCD_FLAG_DEV_AUTHORIZED8 /* authorize devices? */ /* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -140,6 +135,14 @@ struct usb_hcd { #define HCD_INTF_AUTHORIZED(hcd) \ ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) + /* +* Specifies if devices are authorized by default +* or they require explicit user space authorization; this bit is +* settable through /sys/class/usb_host/X/authorized_default +*/ +#define HCD_DEV_AUTHORIZED(hcd) \ + ((hcd)-flags (1U HCD_FLAG_DEV_AUTHORIZED
[PATCH v9 4/7] usb: interface authorization: Introduces the USB interface authorization
The kernel supports the device authorization because of wireless USB. These is usable for wired USB devices, too. These new interface authorization allows to enable or disable individual interfaces instead a whole device. If a deauthorized interface will be authorized so the driver probing must be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/message.c | 38 ++ drivers/usb/core/usb.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3d25d89..c090f50 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1555,6 +1555,44 @@ static void usb_release_interface(struct device *dev) kfree(intf); } +/* + * usb_deauthorize_interface - deauthorize an USB interface + * + * @intf: USB interface structure + */ +void usb_deauthorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + device_lock(dev-parent); + + if (intf-authorized) { + device_lock(dev); + intf-authorized = 0; + device_unlock(dev); + + usb_forced_unbind_intf(intf); + } + + device_unlock(dev-parent); +} + +/* + * usb_authorize_interface - authorize an USB interface + * + * @intf: USB interface structure + */ +void usb_authorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + if (!intf-authorized) { + device_lock(dev); + intf-authorized = 1; /* authorize interface */ + device_unlock(dev); + } +} + static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 457255a..05b5e17 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -27,6 +27,8 @@ extern void usb_release_interface_cache(struct kref *ref); extern void usb_disable_device(struct usb_device *dev, int skip_ep0); extern int usb_deauthorize_device(struct usb_device *); extern int usb_authorize_device(struct usb_device *); +extern void usb_deauthorize_interface(struct usb_interface *); +extern void usb_authorize_interface(struct usb_interface *); extern void usb_detect_quirks(struct usb_device *udev); extern void usb_detect_interface_quirks(struct usb_device *udev); extern int usb_remove_device(struct usb_device *udev); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v9 6/7] usb: interface authorization: Documentation part
This part adds the documentation for the interface authorization. Signed-off-by: Stefan Koch sk...@suse.de --- Documentation/ABI/testing/sysfs-bus-usb | 22 + Documentation/usb/authorization.txt | 34 + 2 files changed, 56 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index e5cc763..ca8c8d3 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -1,3 +1,25 @@ +What: /sys/bus/usb/devices/INTERFACE/authorized +Date: June 2015 +KernelVersion: 4.2 +Description: + This allows to authorize (1) or deauthorize (0) + individual interfaces instead a whole device + in contrast to the device authorization. + If a deauthorized interface will be authorized + so the driver probing must be triggered manually + by writing INTERFACE to /sys/bus/usb/drivers_probe + This allows to avoid side-effects with drivers + that need multiple interfaces. + A deauthorized interface cannot be probed or claimed. + +What: /sys/bus/usb/devices/usbX/interface_authorized_default +Date: June 2015 +KernelVersion: 4.2 +Description: + This is used as default value that determines + if interfaces would authorized per default. + The value can be 1 or 0. It is per default 1. + What: /sys/bus/usb/device/.../authorized Date: July 2008 KernelVersion: 2.6.26 diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index c069b68..020cec5 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt @@ -3,6 +3,9 @@ Authorizing (or not) your USB devices to connect to the system (C) 2007 Inaky Perez-Gonzalez in...@linux.intel.com Intel Corporation +Interface authorization part: + (C) 2015 Stefan Koch sk...@suse.de SUSE LLC + This feature allows you to control if a USB device can be used (or not) in a system. This feature will allow you to implement a lock-down of USB devices, fully controlled by user space. @@ -90,3 +93,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit can fake descriptors and device info. Don't trust that. You are welcome. + +Interface authorization +--- +There is a similar approach to allow or deny specific USB interfaces. +That allows to block only a subset of an USB device. + +Authorize an interface: +$ echo 1 /sys/bus/usb/devices/INTERFACE/authorized + +Deauthorize an interface: +$ echo 0 /sys/bus/usb/devices/INTERFACE/authorized + +The default value for new interfaces +on a particular USB bus can be changed, too. + +Allow interfaces per default: +$ echo 1 /sys/bus/usb/devices/usbX/interface_authorized_default + +Deny interfaces per default: +$ echo 0 /sys/bus/usb/devices/usbX/interface_authorized_default + +Per default the interface_authorized_default bit is 1. +So all interfaces would authorized per default. + +Note: +If a deauthorized interface will be authorized so the driver probing must +be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe + +For drivers that need multiple interfaces all needed interfaces should be +authroized first. After that the drivers should be probed. +This avoids side effects. -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v9 5/7] usb: interface authorization: SysFS part of USB interface authorization
This introduces an attribute for each interface to authorize (1) or deauthorize (0) it: /sys/bus/usb/devices/INTERFACE/authorized Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/sysfs.c | 36 1 file changed, 36 insertions(+) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d269738..3ddaada 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -926,6 +926,41 @@ static ssize_t supports_autosuspend_show(struct device *dev, } static DEVICE_ATTR_RO(supports_autosuspend); +/* + * interface_authorized_show - show authorization status of an USB interface + * 1 is authorized, 0 is deauthorized + */ +static ssize_t interface_authorized_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + + return sprintf(buf, %u\n, intf-authorized); +} + +/* + * interface_authorized_store - authorize or deauthorize an USB interface + */ +static ssize_t interface_authorized_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + bool val; + + if (strtobool(buf, val) != 0) + return -EINVAL; + + if (val) + usb_authorize_interface(intf); + else + usb_deauthorize_interface(intf); + + return count; +} +static struct device_attribute dev_attr_interface_authorized = + __ATTR(authorized, S_IRUGO | S_IWUSR, + interface_authorized_show, interface_authorized_store); + static struct attribute *intf_attrs[] = { dev_attr_bInterfaceNumber.attr, dev_attr_bAlternateSetting.attr, @@ -935,6 +970,7 @@ static struct attribute *intf_attrs[] = { dev_attr_bInterfaceProtocol.attr, dev_attr_modalias.attr, dev_attr_supports_autosuspend.attr, + dev_attr_interface_authorized.attr, NULL, }; static struct attribute_group intf_attr_grp = { -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v8 2/7] usb: interface authorization: Introduces the default interface authorization
Am Montag, den 03.08.2015, 15:06 -0700 schrieb Greg KH: On Thu, Jul 30, 2015 at 08:19:19AM +0200, Stefan Koch wrote: 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 sk...@suse.de --- drivers/usb/core/hcd.c | 47 ++ drivers/usb/core/message.c | 1 + include/linux/usb/hcd.h| 3 +++ 3 files changed, 51 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index cbcd092..84b5923 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..3d25d89 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -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); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index c9aa779..7b8ddae 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ Again, what happened to this being '7'? Don't skip bits for no reason. thanks, greg k-h Because this reason patch 7 was developed. It changes the device authorization to use a flag with the desired number 6. Is this ok or not? Thanks Stefan -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v8 2/7] usb: interface authorization: Introduces the default interface authorization
Am Dienstag, den 04.08.2015, 12:14 -0700 schrieb Greg KH: On Tue, Aug 04, 2015 at 08:55:38PM +0200, Stefan Koch wrote: Am Montag, den 03.08.2015, 15:06 -0700 schrieb Greg KH: On Thu, Jul 30, 2015 at 08:19:19AM +0200, Stefan Koch wrote: 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 sk...@suse.de --- drivers/usb/core/hcd.c | 47 ++ drivers/usb/core/message.c | 1 + include/linux/usb/hcd.h| 3 +++ 3 files changed, 51 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index cbcd092..84b5923 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..3d25d89 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -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); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index c9aa779..7b8ddae 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ Again, what happened to this being '7'? Don't skip bits for no reason. thanks, greg k-h Because this reason patch 7 was developed. It changes the device authorization to use a flag with the desired number 6. 6? Sorry desired was 7. Parch 7 introduces flag nr. 7 +#define HCD_FLAG_DEV_AUTHORIZED7 /* authorize devices? */ #define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ Is this ok
Re: [PATCH v8 7/7] usb: interface authorization: Use a flag for the default device authorization
Am Montag, den 03.08.2015, 15:11 -0700 schrieb Greg KH: On Thu, Jul 30, 2015 at 08:19:24AM +0200, Stefan Koch wrote: With this patch a flag instead of a variable is used for the default device authorization. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/hcd.c | 31 +-- drivers/usb/core/usb.c | 2 +- include/linux/usb/hcd.h | 6 -- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 84b5923..a567647 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -854,10 +854,10 @@ static ssize_t authorized_default_show(struct device *dev, { struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); - return snprintf(buf, PAGE_SIZE, %u\n, usb_hcd-authorized_default); + hcd = bus_to_hcd(usb_bus); + return snprintf(buf, PAGE_SIZE, %u\n, !!HCD_DEV_AUTHORIZED(hcd)); } static ssize_t authorized_default_store(struct device *dev, @@ -868,12 +868,16 @@ static ssize_t authorized_default_store(struct device *dev, unsigned val; struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); + hcd = bus_to_hcd(usb_bus); result = sscanf(buf, %u\n, val); if (result == 1) { - usb_hcd-authorized_default = val ? 1 : 0; + if (val) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + result = size; } else { result = -EINVAL; @@ -2720,10 +2724,17 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_info(hcd-self.controller, %s\n, hcd-product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ - if (authorized_default 0 || authorized_default 1) - hcd-authorized_default = hcd-wireless ? 0 : 1; - else - hcd-authorized_default = authorized_default; + if (authorized_default 0 || authorized_default 1) { + if (hcd-wireless) + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } else { + if (authorized_default) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); /* per default all interfaces are authorized */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8d5b2f4..f8bbd0b 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -510,7 +510,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, if (root_hub) /* Root hub always ok [and always wired] */ dev-authorized = 1; else { - dev-authorized = usb_hcd-authorized_default; + dev-authorized = !!HCD_DEV_AUTHORIZED(usb_hcd); dev-wusb = usb_bus_is_wusb(bus) ? 1 : 0; } return dev; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 7b8ddae..f7c6dd1 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -59,7 +59,7 @@ * Since struct usb_bus is so thin, you can't share much code in it. * This framework is a layer over that, and should be more sharable. * - * @authorized_default: Specifies if new devices are authorized to + * @HCD_DEV_AUTHORIZED: Specifies if new devices are authorized to That's not really the way to specify a field in this structure. I agree it still should be documented, but docbook will complain about this change. thanks, greg k-h What way should be choosen for documentating it? Thanks Stefan -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 4/7] usb: interface authorization: Introduces the USB interface authorization
The kernel supports the device authorization because of wireless USB. These is usable for wired USB devices, too. These new interface authorization allows to enable or disable individual interfaces instead a whole device. If a deauthorized interface will be authorized so the driver probing must be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/message.c | 38 ++ drivers/usb/core/usb.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3d25d89..c090f50 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1555,6 +1555,44 @@ static void usb_release_interface(struct device *dev) kfree(intf); } +/* + * usb_deauthorize_interface - deauthorize an USB interface + * + * @intf: USB interface structure + */ +void usb_deauthorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + device_lock(dev-parent); + + if (intf-authorized) { + device_lock(dev); + intf-authorized = 0; + device_unlock(dev); + + usb_forced_unbind_intf(intf); + } + + device_unlock(dev-parent); +} + +/* + * usb_authorize_interface - authorize an USB interface + * + * @intf: USB interface structure + */ +void usb_authorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + if (!intf-authorized) { + device_lock(dev); + intf-authorized = 1; /* authorize interface */ + device_unlock(dev); + } +} + static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 457255a..05b5e17 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -27,6 +27,8 @@ extern void usb_release_interface_cache(struct kref *ref); extern void usb_disable_device(struct usb_device *dev, int skip_ep0); extern int usb_deauthorize_device(struct usb_device *); extern int usb_authorize_device(struct usb_device *); +extern void usb_deauthorize_interface(struct usb_interface *); +extern void usb_authorize_interface(struct usb_interface *); extern void usb_detect_quirks(struct usb_device *udev); extern void usb_detect_interface_quirks(struct usb_device *udev); extern int usb_remove_device(struct usb_device *udev); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 5/7] usb: interface authorization: SysFS part of USB interface authorization
This introduces an attribute for each interface to authorize (1) or deauthorize (0) it: /sys/bus/usb/devices/INTERFACE/authorized Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/sysfs.c | 36 1 file changed, 36 insertions(+) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d269738..3ddaada 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -926,6 +926,41 @@ static ssize_t supports_autosuspend_show(struct device *dev, } static DEVICE_ATTR_RO(supports_autosuspend); +/* + * interface_authorized_show - show authorization status of an USB interface + * 1 is authorized, 0 is deauthorized + */ +static ssize_t interface_authorized_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + + return sprintf(buf, %u\n, intf-authorized); +} + +/* + * interface_authorized_store - authorize or deauthorize an USB interface + */ +static ssize_t interface_authorized_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + bool val; + + if (strtobool(buf, val) != 0) + return -EINVAL; + + if (val) + usb_authorize_interface(intf); + else + usb_deauthorize_interface(intf); + + return count; +} +static struct device_attribute dev_attr_interface_authorized = + __ATTR(authorized, S_IRUGO | S_IWUSR, + interface_authorized_show, interface_authorized_store); + static struct attribute *intf_attrs[] = { dev_attr_bInterfaceNumber.attr, dev_attr_bAlternateSetting.attr, @@ -935,6 +970,7 @@ static struct attribute *intf_attrs[] = { dev_attr_bInterfaceProtocol.attr, dev_attr_modalias.attr, dev_attr_supports_autosuspend.attr, + dev_attr_interface_authorized.attr, NULL, }; static struct attribute_group intf_attr_grp = { -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 2/7] usb: interface authorization: Introduces the default interface authorization
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 sk...@suse.de --- drivers/usb/core/hcd.c | 47 ++ drivers/usb/core/message.c | 1 + include/linux/usb/hcd.h| 3 +++ 3 files changed, 51 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index cbcd092..84b5923 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..3d25d89 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -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); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index c9aa779..7b8ddae 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ /* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -130,6 +131,8 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd)((hcd)-flags (1U HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd)((hcd)-flags (1U HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)-flags (1U HCD_FLAG_DEAD)) +#define HCD_INTF_AUTHORIZED(hcd) \ + ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) /* Flags that get set only during HCD registration or removal. */ unsignedrh_registered:1;/* is root hub registered? */ -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 3/7] usb: interface authorization: Control interface probing and claiming
Driver probings and interface claims get rejected if an interface is not authorized. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/driver.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 818369a..d542d43 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -295,6 +295,10 @@ static int usb_probe_interface(struct device *dev) if (udev-authorized == 0) { dev_err(intf-dev, Device is not authorized for usage\n); return error; + } else if (intf-authorized == 0) { + dev_err(intf-dev, Interface %d is not authorized for usage\n, + intf-altsetting-desc.bInterfaceNumber); + return error; } id = usb_match_dynamic_id(intf, driver); @@ -507,6 +511,10 @@ int usb_driver_claim_interface(struct usb_driver *driver, if (dev-driver) return -EBUSY; + /* reject claim if not iterface is not authorized */ + if (!iface-authorized) + return -ENODEV; + udev = interface_to_usbdev(iface); dev-driver = driver-drvwrap.driver; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 6/7] usb: interface authorization: Documentation part
This part adds the documentation for the interface authorization. Signed-off-by: Stefan Koch sk...@suse.de --- Documentation/ABI/testing/sysfs-bus-usb | 22 + Documentation/usb/authorization.txt | 34 + 2 files changed, 56 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index e5cc763..ca8c8d3 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -1,3 +1,25 @@ +What: /sys/bus/usb/devices/INTERFACE/authorized +Date: June 2015 +KernelVersion: 4.2 +Description: + This allows to authorize (1) or deauthorize (0) + individual interfaces instead a whole device + in contrast to the device authorization. + If a deauthorized interface will be authorized + so the driver probing must be triggered manually + by writing INTERFACE to /sys/bus/usb/drivers_probe + This allows to avoid side-effects with drivers + that need multiple interfaces. + A deauthorized interface cannot be probed or claimed. + +What: /sys/bus/usb/devices/usbX/interface_authorized_default +Date: June 2015 +KernelVersion: 4.2 +Description: + This is used as default value that determines + if interfaces would authorized per default. + The value can be 1 or 0. It is per default 1. + What: /sys/bus/usb/device/.../authorized Date: July 2008 KernelVersion: 2.6.26 diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index c069b68..020cec5 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt @@ -3,6 +3,9 @@ Authorizing (or not) your USB devices to connect to the system (C) 2007 Inaky Perez-Gonzalez in...@linux.intel.com Intel Corporation +Interface authorization part: + (C) 2015 Stefan Koch sk...@suse.de SUSE LLC + This feature allows you to control if a USB device can be used (or not) in a system. This feature will allow you to implement a lock-down of USB devices, fully controlled by user space. @@ -90,3 +93,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit can fake descriptors and device info. Don't trust that. You are welcome. + +Interface authorization +--- +There is a similar approach to allow or deny specific USB interfaces. +That allows to block only a subset of an USB device. + +Authorize an interface: +$ echo 1 /sys/bus/usb/devices/INTERFACE/authorized + +Deauthorize an interface: +$ echo 0 /sys/bus/usb/devices/INTERFACE/authorized + +The default value for new interfaces +on a particular USB bus can be changed, too. + +Allow interfaces per default: +$ echo 1 /sys/bus/usb/devices/usbX/interface_authorized_default + +Deny interfaces per default: +$ echo 0 /sys/bus/usb/devices/usbX/interface_authorized_default + +Per default the interface_authorized_default bit is 1. +So all interfaces would authorized per default. + +Note: +If a deauthorized interface will be authorized so the driver probing must +be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe + +For drivers that need multiple interfaces all needed interfaces should be +authroized first. After that the drivers should be probed. +This avoids side effects. -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 1/7] usb: interface authorization: Declare authorized attribute
The attribute authorized shows the authorization state for an interface. Signed-off-by: Stefan Koch sk...@suse.de --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 447fe29..3deccab 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -178,6 +178,7 @@ struct usb_interface { unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned resetting_device:1;/* true: bandwidth alloc after reset */ + unsigned authorized:1; /* used for interface authorization */ struct device dev; /* interface specific device info */ struct device *usb_dev; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 7/7] usb: interface authorization: Use a flag for the default device authorization
With this patch a flag instead of a variable is used for the default device authorization. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/hcd.c | 31 +-- drivers/usb/core/usb.c | 2 +- include/linux/usb/hcd.h | 6 -- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 84b5923..a567647 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -854,10 +854,10 @@ static ssize_t authorized_default_show(struct device *dev, { struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); - return snprintf(buf, PAGE_SIZE, %u\n, usb_hcd-authorized_default); + hcd = bus_to_hcd(usb_bus); + return snprintf(buf, PAGE_SIZE, %u\n, !!HCD_DEV_AUTHORIZED(hcd)); } static ssize_t authorized_default_store(struct device *dev, @@ -868,12 +868,16 @@ static ssize_t authorized_default_store(struct device *dev, unsigned val; struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); + hcd = bus_to_hcd(usb_bus); result = sscanf(buf, %u\n, val); if (result == 1) { - usb_hcd-authorized_default = val ? 1 : 0; + if (val) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + result = size; } else { result = -EINVAL; @@ -2720,10 +2724,17 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_info(hcd-self.controller, %s\n, hcd-product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ - if (authorized_default 0 || authorized_default 1) - hcd-authorized_default = hcd-wireless ? 0 : 1; - else - hcd-authorized_default = authorized_default; + if (authorized_default 0 || authorized_default 1) { + if (hcd-wireless) + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } else { + if (authorized_default) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); /* per default all interfaces are authorized */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8d5b2f4..f8bbd0b 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -510,7 +510,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, if (root_hub) /* Root hub always ok [and always wired] */ dev-authorized = 1; else { - dev-authorized = usb_hcd-authorized_default; + dev-authorized = !!HCD_DEV_AUTHORIZED(usb_hcd); dev-wusb = usb_bus_is_wusb(bus) ? 1 : 0; } return dev; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 7b8ddae..f7c6dd1 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -59,7 +59,7 @@ * Since struct usb_bus is so thin, you can't share much code in it. * This framework is a layer over that, and should be more sharable. * - * @authorized_default: Specifies if new devices are authorized to + * @HCD_DEV_AUTHORIZED: Specifies if new devices are authorized to * connect by default or they require explicit * user space authorization; this bit is settable * through /sys/class/usb_host/X/authorized_default. @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_DEV_AUTHORIZED7 /* authorize devices? */ #define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ /* The flags can be tested using these macros; they are likely to @@ -131,6 +132,8 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd)((hcd)-flags (1U HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd)((hcd)-flags (1U HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)-flags (1U HCD_FLAG_DEAD)) +#define HCD_DEV_AUTHORIZED(hcd) \ + ((hcd)-flags (1U HCD_FLAG_DEV_AUTHORIZED)) #define HCD_INTF_AUTHORIZED(hcd) \ ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) @@ -144,7 +147,6 @@ struct usb_hcd { * support the new
[PATCH v8 0/7] usb: interface authorization
This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. v5 was acked-by Alan Stern: http://comments.gmane.org/gmane.linux.usb.general/127144 http://permalink.gmane.org/gmane.linux.usb.general/127151 Changes since v7: - Implemented suggestions from Alan Stern and Sergei Shtylyov Changes since v6: - Implemented suggestions from Alan Stern and Sergei Shtylyov Changes since v5: - Implemented suggestions from Greg K-H - Changed device authorization to save the default bit in the same flag as the interface authorization does this (recommended by Alan Stern http://permalink.gmane.org/gmane.linux.usb.general/127086) Stefan Koch (7): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization usb: interface authorization: SysFS part of USB interface authorization usb: interface authorization: Documentation part usb: interface authorization: Use a flag for the default device authorization Documentation/ABI/testing/sysfs-bus-usb | 22 ++ Documentation/usb/authorization.txt | 34 ++ drivers/usb/core/driver.c | 8 drivers/usb/core/hcd.c | 78 - drivers/usb/core/message.c | 39 + drivers/usb/core/sysfs.c| 36 +++ drivers/usb/core/usb.c | 2 +- drivers/usb/core/usb.h | 2 + include/linux/usb.h | 1 + include/linux/usb/hcd.h | 9 +++- 10 files changed, 218 insertions(+), 13 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH RESEND v7 5/7] usb: interface authorization: SysFS part of USB interface authorization
Am Mittwoch, den 29.07.2015, 10:12 -0400 schrieb Alan Stern: On Wed, 29 Jul 2015, Stefan Koch wrote: This introduces an attribute for each interface to authorize (1) or deauthorize (0) it: /sys/bus/usb/devices/INTERFACE/authorized Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/sysfs.c | 39 +-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d269738..0c15b8e 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -633,8 +633,6 @@ static ssize_t authorized_show(struct device *dev, /* * Authorize a device to be used in the system - * - * Writing a 0 deauthorizes the device, writing a 1 authorizes it. */ Why did you leave this change in the patch? Didn't you see my message yesterday saying that this was unrelated to the rest of the patch and did not belong here? Alan Stern OK It was the wrong place. I have edited the comment of the device auth instead of the interface auth. I'll correct this. Thanks for remembering. -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 0/7] usb: interface authorization
This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. v5 was acked-by Alan Stern: http://comments.gmane.org/gmane.linux.usb.general/127144 http://permalink.gmane.org/gmane.linux.usb.general/127151 Changes since v6: - Implemented suggestions from Alan Stern and Sergei Shtylyov Changes since v5: - Implemented suggestions from Greg K-H - Changed device authorization to save the default bit in the same flag as the interface authorization does this (recommended by Alan Stern http://permalink.gmane.org/gmane.linux.usb.general/127086) Stefan Koch (7): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization usb: interface authorization: SysFS part of USB interface authorization usb: interface authorization: Documentation part usb: interface authorization: Use a flag for the default device authorization Documentation/ABI/testing/sysfs-bus-usb | 22 ++ Documentation/usb/authorization.txt | 34 ++ drivers/usb/core/driver.c | 8 drivers/usb/core/hcd.c | 78 - drivers/usb/core/message.c | 39 + drivers/usb/core/sysfs.c| 43 +- drivers/usb/core/usb.c | 2 +- drivers/usb/core/usb.h | 2 + include/linux/usb.h | 1 + include/linux/usb/hcd.h | 9 +++- 10 files changed, 223 insertions(+), 15 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 2/7] usb: interface authorization: Introduces the default interface authorization
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 sk...@suse.de --- drivers/usb/core/hcd.c | 47 ++ drivers/usb/core/message.c | 1 + include/linux/usb/hcd.h| 3 +++ 3 files changed, 51 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index cbcd092..4f5ba47 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -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_auhorized_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_auhorized_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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..3d25d89 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -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); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index c9aa779..7b8ddae 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ /* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -130,6 +131,8 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd)((hcd)-flags (1U HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd)((hcd)-flags (1U HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)-flags (1U HCD_FLAG_DEAD)) +#define HCD_INTF_AUTHORIZED(hcd) \ + ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) /* Flags that get set only during HCD registration or removal. */ unsignedrh_registered:1;/* is root hub registered? */ -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 4/7] usb: interface authorization: Introduces the USB interface authorization
The kernel supports the device authorization because of wireless USB. These is usable for wired USB devices, too. These new interface authorization allows to enable or disable individual interfaces instead a whole device. If a deauthorized interface will be authorized so the driver probing must be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/message.c | 38 ++ drivers/usb/core/usb.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3d25d89..c090f50 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1555,6 +1555,44 @@ static void usb_release_interface(struct device *dev) kfree(intf); } +/* + * usb_deauthorize_interface - deauthorize an USB interface + * + * @intf: USB interface structure + */ +void usb_deauthorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + device_lock(dev-parent); + + if (intf-authorized) { + device_lock(dev); + intf-authorized = 0; + device_unlock(dev); + + usb_forced_unbind_intf(intf); + } + + device_unlock(dev-parent); +} + +/* + * usb_authorize_interface - authorize an USB interface + * + * @intf: USB interface structure + */ +void usb_authorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + if (!intf-authorized) { + device_lock(dev); + intf-authorized = 1; /* authorize interface */ + device_unlock(dev); + } +} + static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 457255a..05b5e17 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -27,6 +27,8 @@ extern void usb_release_interface_cache(struct kref *ref); extern void usb_disable_device(struct usb_device *dev, int skip_ep0); extern int usb_deauthorize_device(struct usb_device *); extern int usb_authorize_device(struct usb_device *); +extern void usb_deauthorize_interface(struct usb_interface *); +extern void usb_authorize_interface(struct usb_interface *); extern void usb_detect_quirks(struct usb_device *udev); extern void usb_detect_interface_quirks(struct usb_device *udev); extern int usb_remove_device(struct usb_device *udev); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 1/7] usb: interface authorization: Declare authorized attribute
The attribute authorized shows the authorization state for an interface. Signed-off-by: Stefan Koch sk...@suse.de --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 447fe29..3deccab 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -178,6 +178,7 @@ struct usb_interface { unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned resetting_device:1;/* true: bandwidth alloc after reset */ + unsigned authorized:1; /* used for interface authorization */ struct device dev; /* interface specific device info */ struct device *usb_dev; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 5/7] usb: interface authorization: SysFS part of USB interface authorization
This introduces an attribute for each interface to authorize (1) or deauthorize (0) it: /sys/bus/usb/devices/INTERFACE/authorized Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/sysfs.c | 43 +-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d269738..b11105e 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -633,8 +633,6 @@ static ssize_t authorized_show(struct device *dev, /* * Authorize a device to be used in the system - * - * Writing a 0 deauthorizes the device, writing a 1 authorizes it. */ static ssize_t authorized_store(struct device *dev, struct device_attribute *attr, const char *buf, @@ -926,6 +924,46 @@ static ssize_t supports_autosuspend_show(struct device *dev, } static DEVICE_ATTR_RO(supports_autosuspend); +/* + * interface_authorized_show - show authorization status of an USB interface + * 1 is authorized, 0 is deauthorized + */ +static ssize_t interface_authorized_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + + return sprintf(buf, %u\n, intf-authorized); +} + +/* + * interface_authorized_store - authorize or deauthorize an USB interface + * 1 is to authorize, 0 is to deauthorize + */ +static ssize_t interface_authorized_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + bool val; + + if (strtobool(buf, val) != 0) + return -EINVAL; + + switch (val) { + case false: + usb_deauthorize_interface(intf); + break; + case true: + usb_authorize_interface(intf); + break; + } + + return count; +} +static struct device_attribute dev_attr_interface_authorized = + __ATTR(authorized, S_IRUGO | S_IWUSR, + interface_authorized_show, interface_authorized_store); + static struct attribute *intf_attrs[] = { dev_attr_bInterfaceNumber.attr, dev_attr_bAlternateSetting.attr, @@ -935,6 +973,7 @@ static struct attribute *intf_attrs[] = { dev_attr_bInterfaceProtocol.attr, dev_attr_modalias.attr, dev_attr_supports_autosuspend.attr, + dev_attr_interface_authorized.attr, NULL, }; static struct attribute_group intf_attr_grp = { -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 3/7] usb: interface authorization: Control interface probing and claiming
Driver probings and interface claims get rejected if an interface is not authorized. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/driver.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 818369a..d542d43 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -295,6 +295,10 @@ static int usb_probe_interface(struct device *dev) if (udev-authorized == 0) { dev_err(intf-dev, Device is not authorized for usage\n); return error; + } else if (intf-authorized == 0) { + dev_err(intf-dev, Interface %d is not authorized for usage\n, + intf-altsetting-desc.bInterfaceNumber); + return error; } id = usb_match_dynamic_id(intf, driver); @@ -507,6 +511,10 @@ int usb_driver_claim_interface(struct usb_driver *driver, if (dev-driver) return -EBUSY; + /* reject claim if not iterface is not authorized */ + if (!iface-authorized) + return -ENODEV; + udev = interface_to_usbdev(iface); dev-driver = driver-drvwrap.driver; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 6/7] usb: interface authorization: Documentation part
This part adds the documentation for the interface authorization. Signed-off-by: Stefan Koch sk...@suse.de --- Documentation/ABI/testing/sysfs-bus-usb | 22 + Documentation/usb/authorization.txt | 34 + 2 files changed, 56 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index e5cc763..ca8c8d3 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -1,3 +1,25 @@ +What: /sys/bus/usb/devices/INTERFACE/authorized +Date: June 2015 +KernelVersion: 4.2 +Description: + This allows to authorize (1) or deauthorize (0) + individual interfaces instead a whole device + in contrast to the device authorization. + If a deauthorized interface will be authorized + so the driver probing must be triggered manually + by writing INTERFACE to /sys/bus/usb/drivers_probe + This allows to avoid side-effects with drivers + that need multiple interfaces. + A deauthorized interface cannot be probed or claimed. + +What: /sys/bus/usb/devices/usbX/interface_authorized_default +Date: June 2015 +KernelVersion: 4.2 +Description: + This is used as default value that determines + if interfaces would authorized per default. + The value can be 1 or 0. It is per default 1. + What: /sys/bus/usb/device/.../authorized Date: July 2008 KernelVersion: 2.6.26 diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index c069b68..020cec5 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt @@ -3,6 +3,9 @@ Authorizing (or not) your USB devices to connect to the system (C) 2007 Inaky Perez-Gonzalez in...@linux.intel.com Intel Corporation +Interface authorization part: + (C) 2015 Stefan Koch sk...@suse.de SUSE LLC + This feature allows you to control if a USB device can be used (or not) in a system. This feature will allow you to implement a lock-down of USB devices, fully controlled by user space. @@ -90,3 +93,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit can fake descriptors and device info. Don't trust that. You are welcome. + +Interface authorization +--- +There is a similar approach to allow or deny specific USB interfaces. +That allows to block only a subset of an USB device. + +Authorize an interface: +$ echo 1 /sys/bus/usb/devices/INTERFACE/authorized + +Deauthorize an interface: +$ echo 0 /sys/bus/usb/devices/INTERFACE/authorized + +The default value for new interfaces +on a particular USB bus can be changed, too. + +Allow interfaces per default: +$ echo 1 /sys/bus/usb/devices/usbX/interface_authorized_default + +Deny interfaces per default: +$ echo 0 /sys/bus/usb/devices/usbX/interface_authorized_default + +Per default the interface_authorized_default bit is 1. +So all interfaces would authorized per default. + +Note: +If a deauthorized interface will be authorized so the driver probing must +be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe + +For drivers that need multiple interfaces all needed interfaces should be +authroized first. After that the drivers should be probed. +This avoids side effects. -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 7/7] usb: interface authorization: Use a flag for the default device authorization
With this patch a flag instead of a variable is used for the default device authorization. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/hcd.c | 31 +-- drivers/usb/core/usb.c | 2 +- include/linux/usb/hcd.h | 6 -- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 4f5ba47..e5f83fa 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -854,10 +854,10 @@ static ssize_t authorized_default_show(struct device *dev, { struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); - return snprintf(buf, PAGE_SIZE, %u\n, usb_hcd-authorized_default); + hcd = bus_to_hcd(usb_bus); + return snprintf(buf, PAGE_SIZE, %u\n, !!HCD_DEV_AUTHORIZED(hcd)); } static ssize_t authorized_default_store(struct device *dev, @@ -868,12 +868,16 @@ static ssize_t authorized_default_store(struct device *dev, unsigned val; struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); + hcd = bus_to_hcd(usb_bus); result = sscanf(buf, %u\n, val); if (result == 1) { - usb_hcd-authorized_default = val ? 1 : 0; + if (val) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + result = size; } else { result = -EINVAL; @@ -2720,10 +2724,17 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_info(hcd-self.controller, %s\n, hcd-product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ - if (authorized_default 0 || authorized_default 1) - hcd-authorized_default = hcd-wireless ? 0 : 1; - else - hcd-authorized_default = authorized_default; + if (authorized_default 0 || authorized_default 1) { + if (hcd-wireless) + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } else { + if (authorized_default) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); /* per default all interfaces are authorized */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8d5b2f4..f8bbd0b 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -510,7 +510,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, if (root_hub) /* Root hub always ok [and always wired] */ dev-authorized = 1; else { - dev-authorized = usb_hcd-authorized_default; + dev-authorized = !!HCD_DEV_AUTHORIZED(usb_hcd); dev-wusb = usb_bus_is_wusb(bus) ? 1 : 0; } return dev; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 7b8ddae..f7c6dd1 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -59,7 +59,7 @@ * Since struct usb_bus is so thin, you can't share much code in it. * This framework is a layer over that, and should be more sharable. * - * @authorized_default: Specifies if new devices are authorized to + * @HCD_DEV_AUTHORIZED: Specifies if new devices are authorized to * connect by default or they require explicit * user space authorization; this bit is settable * through /sys/class/usb_host/X/authorized_default. @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_DEV_AUTHORIZED7 /* authorize devices? */ #define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ /* The flags can be tested using these macros; they are likely to @@ -131,6 +132,8 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd)((hcd)-flags (1U HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd)((hcd)-flags (1U HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)-flags (1U HCD_FLAG_DEAD)) +#define HCD_DEV_AUTHORIZED(hcd) \ + ((hcd)-flags (1U HCD_FLAG_DEV_AUTHORIZED)) #define HCD_INTF_AUTHORIZED(hcd) \ ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) @@ -144,7 +147,6 @@ struct usb_hcd { * support the new
Re: [PATCH v7 0/7] usb: interface authorization
Am Mittwoch, den 29.07.2015, 13:40 +0300 schrieb Sergei Shtylyov: Hello. On 7/29/2015 11:16 AM, Stefan Koch wrote: This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. v5 was acked-by Alan Stern: http://comments.gmane.org/gmane.linux.usb.general/127144 http://permalink.gmane.org/gmane.linux.usb.general/127151 Changes since v6: - Implemented suggestions from Alan Stern and Sergei Shtylyov I don't see where you implemented mine -- in the patch #5 unjustified *switch* is still used... :-( MBR, Sergei Oh, I have removed a switch in patch 2 instead. I will resend the patch without the switch in patch 5, too. Thanks. -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v7 7/7] usb: interface authorization: Use a flag for the default device authorization
With this patch a flag instead of a variable is used for the default device authorization. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/hcd.c | 31 +-- drivers/usb/core/usb.c | 2 +- include/linux/usb/hcd.h | 6 -- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 84b5923..a567647 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -854,10 +854,10 @@ static ssize_t authorized_default_show(struct device *dev, { struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); - return snprintf(buf, PAGE_SIZE, %u\n, usb_hcd-authorized_default); + hcd = bus_to_hcd(usb_bus); + return snprintf(buf, PAGE_SIZE, %u\n, !!HCD_DEV_AUTHORIZED(hcd)); } static ssize_t authorized_default_store(struct device *dev, @@ -868,12 +868,16 @@ static ssize_t authorized_default_store(struct device *dev, unsigned val; struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); + hcd = bus_to_hcd(usb_bus); result = sscanf(buf, %u\n, val); if (result == 1) { - usb_hcd-authorized_default = val ? 1 : 0; + if (val) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + result = size; } else { result = -EINVAL; @@ -2720,10 +2724,17 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_info(hcd-self.controller, %s\n, hcd-product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ - if (authorized_default 0 || authorized_default 1) - hcd-authorized_default = hcd-wireless ? 0 : 1; - else - hcd-authorized_default = authorized_default; + if (authorized_default 0 || authorized_default 1) { + if (hcd-wireless) + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } else { + if (authorized_default) + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); /* per default all interfaces are authorized */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8d5b2f4..f8bbd0b 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -510,7 +510,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, if (root_hub) /* Root hub always ok [and always wired] */ dev-authorized = 1; else { - dev-authorized = usb_hcd-authorized_default; + dev-authorized = !!HCD_DEV_AUTHORIZED(usb_hcd); dev-wusb = usb_bus_is_wusb(bus) ? 1 : 0; } return dev; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 7b8ddae..f7c6dd1 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -59,7 +59,7 @@ * Since struct usb_bus is so thin, you can't share much code in it. * This framework is a layer over that, and should be more sharable. * - * @authorized_default: Specifies if new devices are authorized to + * @HCD_DEV_AUTHORIZED: Specifies if new devices are authorized to * connect by default or they require explicit * user space authorization; this bit is settable * through /sys/class/usb_host/X/authorized_default. @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_DEV_AUTHORIZED7 /* authorize devices? */ #define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ /* The flags can be tested using these macros; they are likely to @@ -131,6 +132,8 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd)((hcd)-flags (1U HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd)((hcd)-flags (1U HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)-flags (1U HCD_FLAG_DEAD)) +#define HCD_DEV_AUTHORIZED(hcd) \ + ((hcd)-flags (1U HCD_FLAG_DEV_AUTHORIZED)) #define HCD_INTF_AUTHORIZED(hcd) \ ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) @@ -144,7 +147,6 @@ struct usb_hcd { * support the new
[PATCH RESEND v7 3/7] usb: interface authorization: Control interface probing and claiming
Driver probings and interface claims get rejected if an interface is not authorized. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/driver.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 818369a..d542d43 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -295,6 +295,10 @@ static int usb_probe_interface(struct device *dev) if (udev-authorized == 0) { dev_err(intf-dev, Device is not authorized for usage\n); return error; + } else if (intf-authorized == 0) { + dev_err(intf-dev, Interface %d is not authorized for usage\n, + intf-altsetting-desc.bInterfaceNumber); + return error; } id = usb_match_dynamic_id(intf, driver); @@ -507,6 +511,10 @@ int usb_driver_claim_interface(struct usb_driver *driver, if (dev-driver) return -EBUSY; + /* reject claim if not iterface is not authorized */ + if (!iface-authorized) + return -ENODEV; + udev = interface_to_usbdev(iface); dev-driver = driver-drvwrap.driver; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v7 6/7] usb: interface authorization: Documentation part
This part adds the documentation for the interface authorization. Signed-off-by: Stefan Koch sk...@suse.de --- Documentation/ABI/testing/sysfs-bus-usb | 22 + Documentation/usb/authorization.txt | 34 + 2 files changed, 56 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index e5cc763..ca8c8d3 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -1,3 +1,25 @@ +What: /sys/bus/usb/devices/INTERFACE/authorized +Date: June 2015 +KernelVersion: 4.2 +Description: + This allows to authorize (1) or deauthorize (0) + individual interfaces instead a whole device + in contrast to the device authorization. + If a deauthorized interface will be authorized + so the driver probing must be triggered manually + by writing INTERFACE to /sys/bus/usb/drivers_probe + This allows to avoid side-effects with drivers + that need multiple interfaces. + A deauthorized interface cannot be probed or claimed. + +What: /sys/bus/usb/devices/usbX/interface_authorized_default +Date: June 2015 +KernelVersion: 4.2 +Description: + This is used as default value that determines + if interfaces would authorized per default. + The value can be 1 or 0. It is per default 1. + What: /sys/bus/usb/device/.../authorized Date: July 2008 KernelVersion: 2.6.26 diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index c069b68..020cec5 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt @@ -3,6 +3,9 @@ Authorizing (or not) your USB devices to connect to the system (C) 2007 Inaky Perez-Gonzalez in...@linux.intel.com Intel Corporation +Interface authorization part: + (C) 2015 Stefan Koch sk...@suse.de SUSE LLC + This feature allows you to control if a USB device can be used (or not) in a system. This feature will allow you to implement a lock-down of USB devices, fully controlled by user space. @@ -90,3 +93,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit can fake descriptors and device info. Don't trust that. You are welcome. + +Interface authorization +--- +There is a similar approach to allow or deny specific USB interfaces. +That allows to block only a subset of an USB device. + +Authorize an interface: +$ echo 1 /sys/bus/usb/devices/INTERFACE/authorized + +Deauthorize an interface: +$ echo 0 /sys/bus/usb/devices/INTERFACE/authorized + +The default value for new interfaces +on a particular USB bus can be changed, too. + +Allow interfaces per default: +$ echo 1 /sys/bus/usb/devices/usbX/interface_authorized_default + +Deny interfaces per default: +$ echo 0 /sys/bus/usb/devices/usbX/interface_authorized_default + +Per default the interface_authorized_default bit is 1. +So all interfaces would authorized per default. + +Note: +If a deauthorized interface will be authorized so the driver probing must +be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe + +For drivers that need multiple interfaces all needed interfaces should be +authroized first. After that the drivers should be probed. +This avoids side effects. -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v7 1/7] usb: interface authorization: Declare authorized attribute
The attribute authorized shows the authorization state for an interface. Signed-off-by: Stefan Koch sk...@suse.de --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 447fe29..3deccab 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -178,6 +178,7 @@ struct usb_interface { unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned resetting_device:1;/* true: bandwidth alloc after reset */ + unsigned authorized:1; /* used for interface authorization */ struct device dev; /* interface specific device info */ struct device *usb_dev; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v7 2/7] usb: interface authorization: Introduces the default interface authorization
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 sk...@suse.de --- drivers/usb/core/hcd.c | 47 ++ drivers/usb/core/message.c | 1 + include/linux/usb/hcd.h| 3 +++ 3 files changed, 51 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index cbcd092..84b5923 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..3d25d89 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -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); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index c9aa779..7b8ddae 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ /* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -130,6 +131,8 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd)((hcd)-flags (1U HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd)((hcd)-flags (1U HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)-flags (1U HCD_FLAG_DEAD)) +#define HCD_INTF_AUTHORIZED(hcd) \ + ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) /* Flags that get set only during HCD registration or removal. */ unsignedrh_registered:1;/* is root hub registered? */ -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v7 0/7] usb: interface authorization
This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. v5 was acked-by Alan Stern: http://comments.gmane.org/gmane.linux.usb.general/127144 http://permalink.gmane.org/gmane.linux.usb.general/127151 Changes since v6: - Implemented suggestions from Alan Stern and Sergei Shtylyov Changes since v5: - Implemented suggestions from Greg K-H - Changed device authorization to save the default bit in the same flag as the interface authorization does this (recommended by Alan Stern http://permalink.gmane.org/gmane.linux.usb.general/127086) Stefan Koch (7): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization usb: interface authorization: SysFS part of USB interface authorization usb: interface authorization: Documentation part usb: interface authorization: Use a flag for the default device authorization Documentation/ABI/testing/sysfs-bus-usb | 22 ++ Documentation/usb/authorization.txt | 34 ++ drivers/usb/core/driver.c | 8 drivers/usb/core/hcd.c | 78 - drivers/usb/core/message.c | 39 + drivers/usb/core/sysfs.c| 39 - drivers/usb/core/usb.c | 2 +- drivers/usb/core/usb.h | 2 + include/linux/usb.h | 1 + include/linux/usb/hcd.h | 9 +++- 10 files changed, 219 insertions(+), 15 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v7 4/7] usb: interface authorization: Introduces the USB interface authorization
The kernel supports the device authorization because of wireless USB. These is usable for wired USB devices, too. These new interface authorization allows to enable or disable individual interfaces instead a whole device. If a deauthorized interface will be authorized so the driver probing must be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/message.c | 38 ++ drivers/usb/core/usb.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3d25d89..c090f50 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1555,6 +1555,44 @@ static void usb_release_interface(struct device *dev) kfree(intf); } +/* + * usb_deauthorize_interface - deauthorize an USB interface + * + * @intf: USB interface structure + */ +void usb_deauthorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + device_lock(dev-parent); + + if (intf-authorized) { + device_lock(dev); + intf-authorized = 0; + device_unlock(dev); + + usb_forced_unbind_intf(intf); + } + + device_unlock(dev-parent); +} + +/* + * usb_authorize_interface - authorize an USB interface + * + * @intf: USB interface structure + */ +void usb_authorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + if (!intf-authorized) { + device_lock(dev); + intf-authorized = 1; /* authorize interface */ + device_unlock(dev); + } +} + static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 457255a..05b5e17 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -27,6 +27,8 @@ extern void usb_release_interface_cache(struct kref *ref); extern void usb_disable_device(struct usb_device *dev, int skip_ep0); extern int usb_deauthorize_device(struct usb_device *); extern int usb_authorize_device(struct usb_device *); +extern void usb_deauthorize_interface(struct usb_interface *); +extern void usb_authorize_interface(struct usb_interface *); extern void usb_detect_quirks(struct usb_device *udev); extern void usb_detect_interface_quirks(struct usb_device *udev); extern int usb_remove_device(struct usb_device *udev); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v7 5/7] usb: interface authorization: SysFS part of USB interface authorization
This introduces an attribute for each interface to authorize (1) or deauthorize (0) it: /sys/bus/usb/devices/INTERFACE/authorized Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/sysfs.c | 39 +-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d269738..0c15b8e 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -633,8 +633,6 @@ static ssize_t authorized_show(struct device *dev, /* * Authorize a device to be used in the system - * - * Writing a 0 deauthorizes the device, writing a 1 authorizes it. */ static ssize_t authorized_store(struct device *dev, struct device_attribute *attr, const char *buf, @@ -926,6 +924,42 @@ static ssize_t supports_autosuspend_show(struct device *dev, } static DEVICE_ATTR_RO(supports_autosuspend); +/* + * interface_authorized_show - show authorization status of an USB interface + * 1 is authorized, 0 is deauthorized + */ +static ssize_t interface_authorized_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + + return sprintf(buf, %u\n, intf-authorized); +} + +/* + * interface_authorized_store - authorize or deauthorize an USB interface + * 1 is to authorize, 0 is to deauthorize + */ +static ssize_t interface_authorized_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + bool val; + + if (strtobool(buf, val) != 0) + return -EINVAL; + + if (val) + usb_authorize_interface(intf); + else + usb_deauthorize_interface(intf); + + return count; +} +static struct device_attribute dev_attr_interface_authorized = + __ATTR(authorized, S_IRUGO | S_IWUSR, + interface_authorized_show, interface_authorized_store); + static struct attribute *intf_attrs[] = { dev_attr_bInterfaceNumber.attr, dev_attr_bAlternateSetting.attr, @@ -935,6 +969,7 @@ static struct attribute *intf_attrs[] = { dev_attr_bInterfaceProtocol.attr, dev_attr_modalias.attr, dev_attr_supports_autosuspend.attr, + dev_attr_interface_authorized.attr, NULL, }; static struct attribute_group intf_attr_grp = { -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v6 6/7] usb: interface authorization: Documentation part
This part adds the documentation for the interface authorization. Signed-off-by: Stefan Koch sk...@suse.de --- Documentation/ABI/testing/sysfs-bus-usb | 22 + Documentation/usb/authorization.txt | 34 + 2 files changed, 56 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index e5cc763..ca8c8d3 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -1,3 +1,25 @@ +What: /sys/bus/usb/devices/INTERFACE/authorized +Date: June 2015 +KernelVersion: 4.2 +Description: + This allows to authorize (1) or deauthorize (0) + individual interfaces instead a whole device + in contrast to the device authorization. + If a deauthorized interface will be authorized + so the driver probing must be triggered manually + by writing INTERFACE to /sys/bus/usb/drivers_probe + This allows to avoid side-effects with drivers + that need multiple interfaces. + A deauthorized interface cannot be probed or claimed. + +What: /sys/bus/usb/devices/usbX/interface_authorized_default +Date: June 2015 +KernelVersion: 4.2 +Description: + This is used as default value that determines + if interfaces would authorized per default. + The value can be 1 or 0. It is per default 1. + What: /sys/bus/usb/device/.../authorized Date: July 2008 KernelVersion: 2.6.26 diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index c069b68..020cec5 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt @@ -3,6 +3,9 @@ Authorizing (or not) your USB devices to connect to the system (C) 2007 Inaky Perez-Gonzalez in...@linux.intel.com Intel Corporation +Interface authorization part: + (C) 2015 Stefan Koch sk...@suse.de SUSE LLC + This feature allows you to control if a USB device can be used (or not) in a system. This feature will allow you to implement a lock-down of USB devices, fully controlled by user space. @@ -90,3 +93,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit can fake descriptors and device info. Don't trust that. You are welcome. + +Interface authorization +--- +There is a similar approach to allow or deny specific USB interfaces. +That allows to block only a subset of an USB device. + +Authorize an interface: +$ echo 1 /sys/bus/usb/devices/INTERFACE/authorized + +Deauthorize an interface: +$ echo 0 /sys/bus/usb/devices/INTERFACE/authorized + +The default value for new interfaces +on a particular USB bus can be changed, too. + +Allow interfaces per default: +$ echo 1 /sys/bus/usb/devices/usbX/interface_authorized_default + +Deny interfaces per default: +$ echo 0 /sys/bus/usb/devices/usbX/interface_authorized_default + +Per default the interface_authorized_default bit is 1. +So all interfaces would authorized per default. + +Note: +If a deauthorized interface will be authorized so the driver probing must +be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe + +For drivers that need multiple interfaces all needed interfaces should be +authroized first. After that the drivers should be probed. +This avoids side effects. -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v6 2/7] usb: interface authorization: Introduces the default interface authorization
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 sk...@suse.de --- drivers/usb/core/hcd.c | 51 ++ drivers/usb/core/message.c | 1 + include/linux/usb/hcd.h| 3 +++ 3 files changed, 55 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index cbcd092..14357d4 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -882,9 +882,57 @@ 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_auhorized_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) ? 1 : 0); +} + +/* + * interface_authorized_default_store - store default authorization status + * for USB interfaces + * + * note: interface_auhorized_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; + + switch (val) { + case false: + clear_bit(HCD_FLAG_INTF_AUTHORIZED, hcd-flags); + break; + case true: + set_bit(HCD_FLAG_INTF_AUTHORIZED, hcd-flags); + break; + } + + 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 +2730,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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..a4995bc 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -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) ? 1 : 0; kref_get(intfc-ref); alt = usb_altnum_to_altsetting(intf, 0); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index c9aa779..7b8ddae 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ /* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -130,6 +131,8 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd)((hcd)-flags (1U HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd)((hcd)-flags (1U HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)-flags (1U HCD_FLAG_DEAD)) +#define HCD_INTF_AUTHORIZED(hcd) \ + ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) /* Flags that get set only during HCD registration or removal. */ unsignedrh_registered:1;/* is root hub registered? */ -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v6 0/7] usb: interface authorization
This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. v5 was acked-by Alan Stern: http://comments.gmane.org/gmane.linux.usb.general/127144 http://permalink.gmane.org/gmane.linux.usb.general/127151 Changes since v5: - Implemented suggestions from Greg K-H - Changed device authorization to save the default bit in the same flag as the interface authorization does this (recommended by Alan Stern http://permalink.gmane.org/gmane.linux.usb.general/127086) Stefan Koch (7): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization usb: interface authorization: SysFS part of USB interface authorization usb: interface authorization: Documentation part usb: interface authorization: Use a flag for the default device authorization Documentation/ABI/testing/sysfs-bus-usb | 22 + Documentation/usb/authorization.txt | 34 ++ drivers/usb/core/driver.c | 8 drivers/usb/core/hcd.c | 79 - drivers/usb/core/message.c | 39 drivers/usb/core/sysfs.c| 43 +- drivers/usb/core/usb.c | 2 +- drivers/usb/core/usb.h | 2 + include/linux/usb.h | 1 + include/linux/usb/hcd.h | 9 +++- 10 files changed, 224 insertions(+), 15 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v6 4/7] usb: interface authorization: Introduces the USB interface authorization
The kernel supports the device authorization because of wireless USB. These is usable for wired USB devices, too. These new interface authorization allows to enable or disable individual interfaces instead a whole device. If a deauthorized interface will be authorized so the driver probing must be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/message.c | 38 ++ drivers/usb/core/usb.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index a4995bc..8caedf4 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1555,6 +1555,44 @@ static void usb_release_interface(struct device *dev) kfree(intf); } +/* + * usb_deauthorize_interface - deauthorize an USB interface + * + * @intf: USB interface structure + */ +void usb_deauthorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + device_lock(dev-parent); + + if (intf-authorized) { + device_lock(dev); + intf-authorized = 0; + device_unlock(dev); + + usb_forced_unbind_intf(intf); + } + + device_unlock(dev-parent); +} + +/* + * usb_authorize_interface - authorize an USB interface + * + * @intf: USB interface structure + */ +void usb_authorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + if (!intf-authorized) { + device_lock(dev); + intf-authorized = 1; /* authorize interface */ + device_unlock(dev); + } +} + static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 457255a..05b5e17 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -27,6 +27,8 @@ extern void usb_release_interface_cache(struct kref *ref); extern void usb_disable_device(struct usb_device *dev, int skip_ep0); extern int usb_deauthorize_device(struct usb_device *); extern int usb_authorize_device(struct usb_device *); +extern void usb_deauthorize_interface(struct usb_interface *); +extern void usb_authorize_interface(struct usb_interface *); extern void usb_detect_quirks(struct usb_device *udev); extern void usb_detect_interface_quirks(struct usb_device *udev); extern int usb_remove_device(struct usb_device *udev); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v6 1/7] usb: interface authorization: Declare authorized attribute
The attribute authorized shows the authorization state for an interface. Signed-off-by: Stefan Koch sk...@suse.de --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 447fe29..3deccab 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -178,6 +178,7 @@ struct usb_interface { unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned resetting_device:1;/* true: bandwidth alloc after reset */ + unsigned authorized:1; /* used for interface authorization */ struct device dev; /* interface specific device info */ struct device *usb_dev; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v6 7/7] usb: interface authorization: Use a flag for the default device authorization
With this patch a flag instead of a variable is used for the default device authorization. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/hcd.c | 28 ++-- drivers/usb/core/usb.c | 2 +- include/linux/usb/hcd.h | 6 -- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 14357d4..c63d87e 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -854,10 +854,11 @@ static ssize_t authorized_default_show(struct device *dev, { struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); - return snprintf(buf, PAGE_SIZE, %u\n, usb_hcd-authorized_default); + hcd = bus_to_hcd(usb_bus); + return snprintf(buf, PAGE_SIZE, %u\n, + HCD_DEV_AUTHORIZED(hcd) ? 1 : 0); } static ssize_t authorized_default_store(struct device *dev, @@ -868,12 +869,14 @@ static ssize_t authorized_default_store(struct device *dev, unsigned val; struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); + hcd = bus_to_hcd(usb_bus); result = sscanf(buf, %u\n, val); if (result == 1) { - usb_hcd-authorized_default = val ? 1 : 0; + val ? set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags) : + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + result = size; } else { result = -EINVAL; @@ -2724,10 +2727,15 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_info(hcd-self.controller, %s\n, hcd-product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ - if (authorized_default 0 || authorized_default 1) - hcd-authorized_default = hcd-wireless ? 0 : 1; - else - hcd-authorized_default = authorized_default; + if (authorized_default 0 || authorized_default 1) { + hcd-wireless ? + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags) : + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } else { + authorized_default ? + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags) : + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); /* per default all interfaces are authorized */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8d5b2f4..967c81c 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -510,7 +510,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, if (root_hub) /* Root hub always ok [and always wired] */ dev-authorized = 1; else { - dev-authorized = usb_hcd-authorized_default; + dev-authorized = HCD_DEV_AUTHORIZED(usb_hcd) ? 1 : 0; dev-wusb = usb_bus_is_wusb(bus) ? 1 : 0; } return dev; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 7b8ddae..f7c6dd1 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -59,7 +59,7 @@ * Since struct usb_bus is so thin, you can't share much code in it. * This framework is a layer over that, and should be more sharable. * - * @authorized_default: Specifies if new devices are authorized to + * @HCD_DEV_AUTHORIZED: Specifies if new devices are authorized to * connect by default or they require explicit * user space authorization; this bit is settable * through /sys/class/usb_host/X/authorized_default. @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_DEV_AUTHORIZED7 /* authorize devices? */ #define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ /* The flags can be tested using these macros; they are likely to @@ -131,6 +132,8 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd)((hcd)-flags (1U HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd)((hcd)-flags (1U HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)-flags (1U HCD_FLAG_DEAD)) +#define HCD_DEV_AUTHORIZED(hcd) \ + ((hcd)-flags (1U HCD_FLAG_DEV_AUTHORIZED)) #define HCD_INTF_AUTHORIZED(hcd) \ ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) @@ -144,7 +147,6 @@ struct usb_hcd { * support the new root-hub polling mechanism. */ unsigned
[PATCH RESEND v6 3/7] usb: interface authorization: Control interface probing and claiming
Driver probings and interface claims get rejected if an interface is not authorized. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/driver.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 818369a..d542d43 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -295,6 +295,10 @@ static int usb_probe_interface(struct device *dev) if (udev-authorized == 0) { dev_err(intf-dev, Device is not authorized for usage\n); return error; + } else if (intf-authorized == 0) { + dev_err(intf-dev, Interface %d is not authorized for usage\n, + intf-altsetting-desc.bInterfaceNumber); + return error; } id = usb_match_dynamic_id(intf, driver); @@ -507,6 +511,10 @@ int usb_driver_claim_interface(struct usb_driver *driver, if (dev-driver) return -EBUSY; + /* reject claim if not iterface is not authorized */ + if (!iface-authorized) + return -ENODEV; + udev = interface_to_usbdev(iface); dev-driver = driver-drvwrap.driver; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v6 5/7] usb: interface authorization: SysFS part of USB interface authorization
This introduces an attribute for each interface to authorize (1) or deauthorize (0) it: /sys/bus/usb/devices/INTERFACE/authorized Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/sysfs.c | 43 +-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d269738..b11105e 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -633,8 +633,6 @@ static ssize_t authorized_show(struct device *dev, /* * Authorize a device to be used in the system - * - * Writing a 0 deauthorizes the device, writing a 1 authorizes it. */ static ssize_t authorized_store(struct device *dev, struct device_attribute *attr, const char *buf, @@ -926,6 +924,46 @@ static ssize_t supports_autosuspend_show(struct device *dev, } static DEVICE_ATTR_RO(supports_autosuspend); +/* + * interface_authorized_show - show authorization status of an USB interface + * 1 is authorized, 0 is deauthorized + */ +static ssize_t interface_authorized_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + + return sprintf(buf, %u\n, intf-authorized); +} + +/* + * interface_authorized_store - authorize or deauthorize an USB interface + * 1 is to authorize, 0 is to deauthorize + */ +static ssize_t interface_authorized_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + bool val; + + if (strtobool(buf, val) != 0) + return -EINVAL; + + switch (val) { + case false: + usb_deauthorize_interface(intf); + break; + case true: + usb_authorize_interface(intf); + break; + } + + return count; +} +static struct device_attribute dev_attr_interface_authorized = + __ATTR(authorized, S_IRUGO | S_IWUSR, + interface_authorized_show, interface_authorized_store); + static struct attribute *intf_attrs[] = { dev_attr_bInterfaceNumber.attr, dev_attr_bAlternateSetting.attr, @@ -935,6 +973,7 @@ static struct attribute *intf_attrs[] = { dev_attr_bInterfaceProtocol.attr, dev_attr_modalias.attr, dev_attr_supports_autosuspend.attr, + dev_attr_interface_authorized.attr, NULL, }; static struct attribute_group intf_attr_grp = { -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 3/7] usb: interface authorization: Control interface probing and claiming
Driver probings and interface claims get rejected if an interface is not authorized. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/driver.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 818369a..d542d43 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -295,6 +295,10 @@ static int usb_probe_interface(struct device *dev) if (udev-authorized == 0) { dev_err(intf-dev, Device is not authorized for usage\n); return error; + } else if (intf-authorized == 0) { + dev_err(intf-dev, Interface %d is not authorized for usage\n, + intf-altsetting-desc.bInterfaceNumber); + return error; } id = usb_match_dynamic_id(intf, driver); @@ -507,6 +511,10 @@ int usb_driver_claim_interface(struct usb_driver *driver, if (dev-driver) return -EBUSY; + /* reject claim if not iterface is not authorized */ + if (!iface-authorized) + return -ENODEV; + udev = interface_to_usbdev(iface); dev-driver = driver-drvwrap.driver; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 5/7] usb: interface authorization: SysFS part of USB interface authorization
This introduces an attribute for each interface to authorize (1) or deauthorize (0) it: /sys/bus/usb/devices/INTERFACE/authorized Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/sysfs.c | 43 +-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d269738..b11105e 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -633,8 +633,6 @@ static ssize_t authorized_show(struct device *dev, /* * Authorize a device to be used in the system - * - * Writing a 0 deauthorizes the device, writing a 1 authorizes it. */ static ssize_t authorized_store(struct device *dev, struct device_attribute *attr, const char *buf, @@ -926,6 +924,46 @@ static ssize_t supports_autosuspend_show(struct device *dev, } static DEVICE_ATTR_RO(supports_autosuspend); +/* + * interface_authorized_show - show authorization status of an USB interface + * 1 is authorized, 0 is deauthorized + */ +static ssize_t interface_authorized_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + + return sprintf(buf, %u\n, intf-authorized); +} + +/* + * interface_authorized_store - authorize or deauthorize an USB interface + * 1 is to authorize, 0 is to deauthorize + */ +static ssize_t interface_authorized_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + bool val; + + if (strtobool(buf, val) != 0) + return -EINVAL; + + switch (val) { + case false: + usb_deauthorize_interface(intf); + break; + case true: + usb_authorize_interface(intf); + break; + } + + return count; +} +static struct device_attribute dev_attr_interface_authorized = + __ATTR(authorized, S_IRUGO | S_IWUSR, + interface_authorized_show, interface_authorized_store); + static struct attribute *intf_attrs[] = { dev_attr_bInterfaceNumber.attr, dev_attr_bAlternateSetting.attr, @@ -935,6 +973,7 @@ static struct attribute *intf_attrs[] = { dev_attr_bInterfaceProtocol.attr, dev_attr_modalias.attr, dev_attr_supports_autosuspend.attr, + dev_attr_interface_authorized.attr, NULL, }; static struct attribute_group intf_attr_grp = { -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 2/7] usb: interface authorization: Introduces the default interface authorization
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 sk...@suse.de --- drivers/usb/core/hcd.c | 51 ++ drivers/usb/core/message.c | 1 + include/linux/usb/hcd.h| 3 +++ 3 files changed, 55 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index cbcd092..14357d4 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -882,9 +882,57 @@ 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_auhorized_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) ? 1 : 0); +} + +/* + * interface_authorized_default_store - store default authorization status + * for USB interfaces + * + * note: interface_auhorized_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; + + switch (val) { + case false: + clear_bit(HCD_FLAG_INTF_AUTHORIZED, hcd-flags); + break; + case true: + set_bit(HCD_FLAG_INTF_AUTHORIZED, hcd-flags); + break; + } + + 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 +2730,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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..a4995bc 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -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) ? 1 : 0; kref_get(intfc-ref); alt = usb_altnum_to_altsetting(intf, 0); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index c9aa779..7b8ddae 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ /* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -130,6 +131,8 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd)((hcd)-flags (1U HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd)((hcd)-flags (1U HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)-flags (1U HCD_FLAG_DEAD)) +#define HCD_INTF_AUTHORIZED(hcd) \ + ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) /* Flags that get set only during HCD registration or removal. */ unsignedrh_registered:1;/* is root hub registered? */ -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 1/7] usb: interface authorization: Declare authorized attribute
The attribute authorized shows the authorization state for an interface. Signed-off-by: Stefan Koch sk...@suse.de --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 447fe29..3deccab 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -178,6 +178,7 @@ struct usb_interface { unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned resetting_device:1;/* true: bandwidth alloc after reset */ + unsigned authorized:1; /* used for interface authorization */ struct device dev; /* interface specific device info */ struct device *usb_dev; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 0/7] usb: interface authorization
This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. Stefan Koch (7): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization usb: interface authorization: SysFS part of USB interface authorization usb: interface authorization: Documentation part usb: interface authorization: Use a flag for the default device authorization Documentation/ABI/testing/sysfs-bus-usb | 22 + Documentation/usb/authorization.txt | 34 ++ drivers/usb/core/driver.c | 8 drivers/usb/core/hcd.c | 79 - drivers/usb/core/message.c | 39 drivers/usb/core/sysfs.c| 43 +- drivers/usb/core/usb.c | 2 +- drivers/usb/core/usb.h | 2 + include/linux/usb.h | 1 + include/linux/usb/hcd.h | 9 +++- 10 files changed, 224 insertions(+), 15 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 4/7] usb: interface authorization: Introduces the USB interface authorization
The kernel supports the device authorization because of wireless USB. These is usable for wired USB devices, too. These new interface authorization allows to enable or disable individual interfaces instead a whole device. If a deauthorized interface will be authorized so the driver probing must be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/message.c | 38 ++ drivers/usb/core/usb.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index a4995bc..8caedf4 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1555,6 +1555,44 @@ static void usb_release_interface(struct device *dev) kfree(intf); } +/* + * usb_deauthorize_interface - deauthorize an USB interface + * + * @intf: USB interface structure + */ +void usb_deauthorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + device_lock(dev-parent); + + if (intf-authorized) { + device_lock(dev); + intf-authorized = 0; + device_unlock(dev); + + usb_forced_unbind_intf(intf); + } + + device_unlock(dev-parent); +} + +/* + * usb_authorize_interface - authorize an USB interface + * + * @intf: USB interface structure + */ +void usb_authorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + if (!intf-authorized) { + device_lock(dev); + intf-authorized = 1; /* authorize interface */ + device_unlock(dev); + } +} + static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 457255a..05b5e17 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -27,6 +27,8 @@ extern void usb_release_interface_cache(struct kref *ref); extern void usb_disable_device(struct usb_device *dev, int skip_ep0); extern int usb_deauthorize_device(struct usb_device *); extern int usb_authorize_device(struct usb_device *); +extern void usb_deauthorize_interface(struct usb_interface *); +extern void usb_authorize_interface(struct usb_interface *); extern void usb_detect_quirks(struct usb_device *udev); extern void usb_detect_interface_quirks(struct usb_device *udev); extern int usb_remove_device(struct usb_device *udev); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 7/7] usb: interface authorization: Use a flag for the default device authorization
With this patch a flag instead of a variable is used for the default device authorization. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/hcd.c | 28 ++-- drivers/usb/core/usb.c | 2 +- include/linux/usb/hcd.h | 6 -- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 14357d4..c63d87e 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -854,10 +854,11 @@ static ssize_t authorized_default_show(struct device *dev, { struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); - return snprintf(buf, PAGE_SIZE, %u\n, usb_hcd-authorized_default); + hcd = bus_to_hcd(usb_bus); + return snprintf(buf, PAGE_SIZE, %u\n, + HCD_DEV_AUTHORIZED(hcd) ? 1 : 0); } static ssize_t authorized_default_store(struct device *dev, @@ -868,12 +869,14 @@ static ssize_t authorized_default_store(struct device *dev, unsigned val; struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev-bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); + hcd = bus_to_hcd(usb_bus); result = sscanf(buf, %u\n, val); if (result == 1) { - usb_hcd-authorized_default = val ? 1 : 0; + val ? set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags) : + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + result = size; } else { result = -EINVAL; @@ -2724,10 +2727,15 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_info(hcd-self.controller, %s\n, hcd-product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ - if (authorized_default 0 || authorized_default 1) - hcd-authorized_default = hcd-wireless ? 0 : 1; - else - hcd-authorized_default = authorized_default; + if (authorized_default 0 || authorized_default 1) { + hcd-wireless ? + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags) : + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } else { + authorized_default ? + set_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags) : + clear_bit(HCD_FLAG_DEV_AUTHORIZED, hcd-flags); + } set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); /* per default all interfaces are authorized */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8d5b2f4..967c81c 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -510,7 +510,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, if (root_hub) /* Root hub always ok [and always wired] */ dev-authorized = 1; else { - dev-authorized = usb_hcd-authorized_default; + dev-authorized = HCD_DEV_AUTHORIZED(usb_hcd) ? 1 : 0; dev-wusb = usb_bus_is_wusb(bus) ? 1 : 0; } return dev; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 7b8ddae..f7c6dd1 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -59,7 +59,7 @@ * Since struct usb_bus is so thin, you can't share much code in it. * This framework is a layer over that, and should be more sharable. * - * @authorized_default: Specifies if new devices are authorized to + * @HCD_DEV_AUTHORIZED: Specifies if new devices are authorized to * connect by default or they require explicit * user space authorization; this bit is settable * through /sys/class/usb_host/X/authorized_default. @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_DEV_AUTHORIZED7 /* authorize devices? */ #define HCD_FLAG_INTF_AUTHORIZED 8 /* authorize interfaces? */ /* The flags can be tested using these macros; they are likely to @@ -131,6 +132,8 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd)((hcd)-flags (1U HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd)((hcd)-flags (1U HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)-flags (1U HCD_FLAG_DEAD)) +#define HCD_DEV_AUTHORIZED(hcd) \ + ((hcd)-flags (1U HCD_FLAG_DEV_AUTHORIZED)) #define HCD_INTF_AUTHORIZED(hcd) \ ((hcd)-flags (1U HCD_FLAG_INTF_AUTHORIZED)) @@ -144,7 +147,6 @@ struct usb_hcd { * support the new root-hub polling mechanism. */ unsigned
[PATCH v6 6/7] usb: interface authorization: Documentation part
This part adds the documentation for the interface authorization. Signed-off-by: Stefan Koch sk...@suse.de --- Documentation/ABI/testing/sysfs-bus-usb | 22 + Documentation/usb/authorization.txt | 34 + 2 files changed, 56 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index e5cc763..ca8c8d3 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -1,3 +1,25 @@ +What: /sys/bus/usb/devices/INTERFACE/authorized +Date: June 2015 +KernelVersion: 4.2 +Description: + This allows to authorize (1) or deauthorize (0) + individual interfaces instead a whole device + in contrast to the device authorization. + If a deauthorized interface will be authorized + so the driver probing must be triggered manually + by writing INTERFACE to /sys/bus/usb/drivers_probe + This allows to avoid side-effects with drivers + that need multiple interfaces. + A deauthorized interface cannot be probed or claimed. + +What: /sys/bus/usb/devices/usbX/interface_authorized_default +Date: June 2015 +KernelVersion: 4.2 +Description: + This is used as default value that determines + if interfaces would authorized per default. + The value can be 1 or 0. It is per default 1. + What: /sys/bus/usb/device/.../authorized Date: July 2008 KernelVersion: 2.6.26 diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index c069b68..020cec5 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt @@ -3,6 +3,9 @@ Authorizing (or not) your USB devices to connect to the system (C) 2007 Inaky Perez-Gonzalez in...@linux.intel.com Intel Corporation +Interface authorization part: + (C) 2015 Stefan Koch sk...@suse.de SUSE LLC + This feature allows you to control if a USB device can be used (or not) in a system. This feature will allow you to implement a lock-down of USB devices, fully controlled by user space. @@ -90,3 +93,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit can fake descriptors and device info. Don't trust that. You are welcome. + +Interface authorization +--- +There is a similar approach to allow or deny specific USB interfaces. +That allows to block only a subset of an USB device. + +Authorize an interface: +$ echo 1 /sys/bus/usb/devices/INTERFACE/authorized + +Deauthorize an interface: +$ echo 0 /sys/bus/usb/devices/INTERFACE/authorized + +The default value for new interfaces +on a particular USB bus can be changed, too. + +Allow interfaces per default: +$ echo 1 /sys/bus/usb/devices/usbX/interface_authorized_default + +Deny interfaces per default: +$ echo 0 /sys/bus/usb/devices/usbX/interface_authorized_default + +Per default the interface_authorized_default bit is 1. +So all interfaces would authorized per default. + +Note: +If a deauthorized interface will be authorized so the driver probing must +be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe + +For drivers that need multiple interfaces all needed interfaces should be +authroized first. After that the drivers should be probed. +This avoids side effects. -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 0/7] usb: interface authorization
Am Montag, den 27.07.2015, 09:58 -0700 schrieb Greg KH: On Mon, Jul 27, 2015 at 01:29:48PM +0200, Stefan Koch wrote: This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. What did you change in this version from the last one? Please list that somewhere, otherwise we have no idea what changed. thanks, greg k-h - the changes that you have recommended - the seventh patch introduces the flag thing for the device authorization Does this clear this. Or should I resend the description again? -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 2/6] usb: interface authorization: Introduces the default interface authorization
Am Montag, den 27.07.2015, 10:00 -0700 schrieb Greg KH: On Mon, Jul 27, 2015 at 09:50:44AM +0200, Stefan Koch wrote: Am Mittwoch, den 22.07.2015, 16:40 -0700 schrieb Greg KH: On Thu, Jun 18, 2015 at 07:23:22PM +0200, Stefan Koch wrote: 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 sk...@suse.de --- drivers/usb/core/hcd.c | 52 ++ drivers/usb/core/message.c | 2 ++ include/linux/usb/hcd.h| 3 +++ 3 files changed, 57 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 45a915c..4ceb753 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -882,9 +882,58 @@ 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_auhorized_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); + unsigned def = HCD_INTERFACE_AUTHORIZED_DEFAULT(hcd) ? 1 : 0; + + return sprintf(buf, %u\n, def); +} + +/* + * interface_authorized_default_store - store default authorization status + * for USB interfaces + * + * note: interface_auhorized_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; + + switch (val) { + case 0: + clear_bit(HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT, hcd-flags); + break; + case 1: + set_bit(HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT, hcd-flags); + break; + } + + 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, }; @@ -2679,6 +2728,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_INTERFACE_AUTHORIZED_DEFAULT, 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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..1e85f62 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1807,6 +1807,8 @@ free_interfaces: intfc = cp-intf_cache[i]; intf-altsetting = intfc-altsetting; intf-num_altsetting = intfc-num_altsetting; + intf-authorized = + HCD_INTERFACE_AUTHORIZED_DEFAULT(hcd) ? 1 : 0; kref_get(intfc-ref); alt = usb_altnum_to_altsetting(intf, 0); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 68b1e83..93c19b2 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT 8 Why not pick 7? And that's a huge name, how about 'HCD_FLAG_INTF_AUTHORIZED'? 7 is used that 6 can used later for the device authorization. What does that mean? We don't plan ahead for things that might someday come
Re: [PATCH v5 2/6] usb: interface authorization: Introduces the default interface authorization
Am Mittwoch, den 22.07.2015, 16:40 -0700 schrieb Greg KH: On Thu, Jun 18, 2015 at 07:23:22PM +0200, Stefan Koch wrote: 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 sk...@suse.de --- drivers/usb/core/hcd.c | 52 ++ drivers/usb/core/message.c | 2 ++ include/linux/usb/hcd.h| 3 +++ 3 files changed, 57 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 45a915c..4ceb753 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -882,9 +882,58 @@ 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_auhorized_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); + unsigned def = HCD_INTERFACE_AUTHORIZED_DEFAULT(hcd) ? 1 : 0; + + return sprintf(buf, %u\n, def); +} + +/* + * interface_authorized_default_store - store default authorization status + * for USB interfaces + * + * note: interface_auhorized_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; + + switch (val) { + case 0: + clear_bit(HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT, hcd-flags); + break; + case 1: + set_bit(HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT, hcd-flags); + break; + } + + 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, }; @@ -2679,6 +2728,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_INTERFACE_AUTHORIZED_DEFAULT, 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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..1e85f62 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1807,6 +1807,8 @@ free_interfaces: intfc = cp-intf_cache[i]; intf-altsetting = intfc-altsetting; intf-num_altsetting = intfc-num_altsetting; + intf-authorized = + HCD_INTERFACE_AUTHORIZED_DEFAULT(hcd) ? 1 : 0; kref_get(intfc-ref); alt = usb_altnum_to_altsetting(intf, 0); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 68b1e83..93c19b2 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT 8 Why not pick 7? And that's a huge name, how about 'HCD_FLAG_INTF_AUTHORIZED'? 7 is used that 6 can used later for the device authorization. Furthermore see Alan's second reply to [PATCH v3 2/6]. What do you think? -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 5/6] usb: interface authorization: SysFS part of USB interface authorization.
Am Mittwoch, den 22.07.2015, 16:43 -0700 schrieb Greg KH: On Thu, Jun 18, 2015 at 07:23:25PM +0200, Stefan Koch wrote: This introduces an attribute for each interface to authorize (1) or deauthorize (0) it: /sys/bus/usb/devices/INTERFACE/authorized Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/sysfs.c | 41 + 1 file changed, 41 insertions(+) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d269738..457bff5 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -926,6 +926,46 @@ static ssize_t supports_autosuspend_show(struct device *dev, } static DEVICE_ATTR_RO(supports_autosuspend); +/* + * interface_authorized_show - show authorization status of an USB interface + * 1 is authorized, 0 is deauthorized + */ +static ssize_t interface_authorized_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + + return sprintf(buf, %u\n, intf-authorized); +} + +/* + * interface_authorized_store - authorize or deauthorize an USB interface + * 1 is to authorize, 0 is to deauthorize Not only 1/0, but Y/N, y/n and other combinations that strtobool handles. No need to have this comment line at all. + */ +static ssize_t interface_authorized_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + bool val; + + if (strtobool(buf, val) != 0) + return -EINVAL; + + switch (val) { + case 0: true and false as this is a boolean? And because it is, just turn this into a simple if/else statement, it's less lines. + usb_deauthorize_interface(intf); + break; + case 1: + usb_authorize_interface(intf); + break; + } + + return count; +} +static struct device_attribute dev_attr_interface_authorized = + __ATTR(authorized, S_IRUGO | S_IWUSR, __ATTR_RW()? __ATTR because __ATTR_RW allows not to set different function names. This would conflict with device authorization function names. -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 0/6] usb: interface authorization
Am Montag, den 29.06.2015, 15:41 -0700 schrieb Greg KH: On Mon, Jun 29, 2015 at 11:23:47PM +0200, Stefan Koch wrote: Am Donnerstag, den 18.06.2015, 13:30 -0400 schrieb Alan Stern: On Thu, 18 Jun 2015, Stefan Koch wrote: This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. Stefan Koch (6): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization. usb: interface authorization: SysFS part of USB interface authorization. usb: interface authorization: Documentation part Documentation/ABI/testing/sysfs-bus-usb | 22 ++ Documentation/usb/authorization.txt | 34 + drivers/usb/core/driver.c | 11 +++ drivers/usb/core/hcd.c | 52 + drivers/usb/core/message.c | 48 ++ drivers/usb/core/sysfs.c| 41 ++ drivers/usb/core/usb.h | 2 ++ include/linux/usb.h | 1 + include/linux/usb/hcd.h | 3 ++ 9 files changed, 214 insertions(+) Acked-by: Alan Stern st...@rowland.harvard.edu Other people may still have some comments. Alan Stern Hi is there any current merging state? In what git tree the patch will submitted at the first step? I can't do anything at the moment due to the merge window. I'll review it after 4.2-rc1 is out (usually a week or so afterward, as my queue is quite large). Don't worry, it's not lost. greg k-h Are there any news about the merge state? Is there enogh time for testing to get the patch into 4.2? If not the documentation must changed (Documentation/ABI/testing/sysfs-bus-usb) because there is noted 4.2 Thanks Stefan -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 0/6] usb: interface authorization
Am Donnerstag, den 18.06.2015, 13:30 -0400 schrieb Alan Stern: On Thu, 18 Jun 2015, Stefan Koch wrote: This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. Stefan Koch (6): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization. usb: interface authorization: SysFS part of USB interface authorization. usb: interface authorization: Documentation part Documentation/ABI/testing/sysfs-bus-usb | 22 ++ Documentation/usb/authorization.txt | 34 + drivers/usb/core/driver.c | 11 +++ drivers/usb/core/hcd.c | 52 + drivers/usb/core/message.c | 48 ++ drivers/usb/core/sysfs.c| 41 ++ drivers/usb/core/usb.h | 2 ++ include/linux/usb.h | 1 + include/linux/usb/hcd.h | 3 ++ 9 files changed, 214 insertions(+) Acked-by: Alan Stern st...@rowland.harvard.edu Other people may still have some comments. Alan Stern Hi is there any current merging state? In what git tree the patch will submitted at the first step? Best regards Stefan Koch -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 0/6] usb: interface authorization
This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. Stefan Koch (6): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization. usb: interface authorization: SysFS part of USB interface authorization. usb: interface authorization: Documentation part Documentation/ABI/testing/sysfs-bus-usb | 22 ++ Documentation/usb/authorization.txt | 34 + drivers/usb/core/driver.c | 11 +++ drivers/usb/core/hcd.c | 54 + drivers/usb/core/message.c | 54 + drivers/usb/core/sysfs.c| 41 + drivers/usb/core/usb.h | 2 ++ include/linux/usb.h | 2 ++ include/linux/usb/hcd.h | 4 +++ 9 files changed, 224 insertions(+) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/6] usb: interface authorization: Introduces the default interface authorization
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 sk...@suse.de --- drivers/usb/core/hcd.c | 54 ++ drivers/usb/core/message.c | 2 ++ include/linux/usb/hcd.h| 4 3 files changed, 60 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 45a915c..f00819c 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -882,9 +882,60 @@ 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_auhorized_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); + unsigned def = HCD_INTERFACE_AUTHORIZED_DEFAULT(hcd) ? 1 : 0; + + return sprintf(buf, %u\n, def); +} + +/* + * interface_authorized_default_store - store default authorization status + * for USB interfaces + * + * note: interface_auhorized_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 (!usb_dev || !hcd) + return -ENODEV; + else if (strtobool(buf, val) != 0) + return -EINVAL; + + switch (val) { + case 0: + clear_bit(HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT, hcd-flags); + break; + case 1: + set_bit(HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT, hcd-flags); + break; + } + + 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, }; @@ -2679,6 +2730,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_INTERFACE_AUTHORIZED_DEFAULT, 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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..1e85f62 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1807,6 +1807,8 @@ free_interfaces: intfc = cp-intf_cache[i]; intf-altsetting = intfc-altsetting; intf-num_altsetting = intfc-num_altsetting; + intf-authorized = + HCD_INTERFACE_AUTHORIZED_DEFAULT(hcd) ? 1 : 0; kref_get(intfc-ref); alt = usb_altnum_to_altsetting(intf, 0); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 68b1e83..87b52ac 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT 8 /* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -130,6 +131,8 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd)((hcd)-flags (1U HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd)((hcd)-flags (1U HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)-flags (1U HCD_FLAG_DEAD)) +#define HCD_INTERFACE_AUTHORIZED_DEFAULT(hcd) \ + ((hcd)-flags (1U HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT)) /* Flags that get set only during HCD registration or removal. */ unsignedrh_registered:1;/* is root hub registered? */ @@ -142,6 +145,7 @@ struct usb_hcd { unsigneduses_new_polling:1; unsignedwireless:1; /* Wireless USB HCD */ unsignedauthorized_default:1; + unsigned
[PATCH v4 4/6] usb: interface authorization: Introduces the USB interface authorization.
The kernel supports the device authorization because of wireless USB. These is usable for wired USB devices, too. These new interface authorization allows to enable or disable individual interfaces instead a whole device. If a deauthorized interface will be authorized so the driver probing must be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/message.c | 52 ++ drivers/usb/core/usb.h | 2 ++ 2 files changed, 54 insertions(+) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 1e85f62..333957a 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1555,6 +1555,58 @@ static void usb_release_interface(struct device *dev) kfree(intf); } +/* + * usb_deauthorize_interface - deauthorize an USB interface + * + * @intf: USB interface structure + * + * Returns: 0 at success, 0 at failure + */ +int usb_deauthorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + if (!dev || !dev-parent) + return -ENODEV; + + device_lock(dev-parent); + + if (intf-authorized) { + device_lock(dev); + intf-authorized = 0; + device_unlock(dev); + + usb_forced_unbind_intf(intf); + } + + device_unlock(dev-parent); + + return 0; +} + +/* + * usb_authorize_interface - authorize an USB interface + * + * @intf: USB interface structure + * + * Returns: 0 at success, 0 at failure + */ +int usb_authorize_interface(struct usb_interface *intf) +{ + struct device *dev = intf-dev; + + if (!dev) + return -ENODEV; + + if (!intf-authorized) { + device_lock(dev); + intf-authorized = 1; /* authorize interface */ + device_unlock(dev); + } + + return 0; +} + static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 7eb1e26..37b0055 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -27,6 +27,8 @@ extern void usb_release_interface_cache(struct kref *ref); extern void usb_disable_device(struct usb_device *dev, int skip_ep0); extern int usb_deauthorize_device(struct usb_device *); extern int usb_authorize_device(struct usb_device *); +extern int usb_deauthorize_interface(struct usb_interface *); +extern int usb_authorize_interface(struct usb_interface *); extern void usb_detect_quirks(struct usb_device *udev); extern void usb_detect_interface_quirks(struct usb_device *udev); extern int usb_remove_device(struct usb_device *udev); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 5/6] usb: interface authorization: SysFS part of USB interface authorization.
This introduces an attribute for each interface to authorize (1) or deauthorize (0) it: /sys/bus/usb/devices/INTERFACE/authorized Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/sysfs.c | 41 + 1 file changed, 41 insertions(+) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d269738..457bff5 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -926,6 +926,46 @@ static ssize_t supports_autosuspend_show(struct device *dev, } static DEVICE_ATTR_RO(supports_autosuspend); +/* + * interface_authorized_show - show authorization status of an USB interface + * 1 is authorized, 0 is deauthorized + */ +static ssize_t interface_authorized_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + + return sprintf(buf, %u\n, intf-authorized); +} + +/* + * interface_authorized_store - authorize or deauthorize an USB interface + * 1 is to authorize, 0 is to deauthorize + */ +static ssize_t interface_authorized_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + bool val; + + if (strtobool(buf, val) != 0) + return -EINVAL; + + switch (val) { + case 0: + usb_deauthorize_interface(intf); + break; + case 1: + usb_authorize_interface(intf); + break; + } + + return count; +} +static struct device_attribute dev_attr_interface_authorized = + __ATTR(authorized, S_IRUGO | S_IWUSR, + interface_authorized_show, interface_authorized_store); + static struct attribute *intf_attrs[] = { dev_attr_bInterfaceNumber.attr, dev_attr_bAlternateSetting.attr, @@ -935,6 +975,7 @@ static struct attribute *intf_attrs[] = { dev_attr_bInterfaceProtocol.attr, dev_attr_modalias.attr, dev_attr_supports_autosuspend.attr, + dev_attr_interface_authorized.attr, NULL, }; static struct attribute_group intf_attr_grp = { -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 6/6] usb: interface authorization: Documentation part
This part adds the documentation for the interface authorization. Signed-off-by: Stefan Koch sk...@suse.de --- Documentation/ABI/testing/sysfs-bus-usb | 22 + Documentation/usb/authorization.txt | 34 + 2 files changed, 56 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index e5cc763..ca8c8d3 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -1,3 +1,25 @@ +What: /sys/bus/usb/devices/INTERFACE/authorized +Date: June 2015 +KernelVersion: 4.2 +Description: + This allows to authorize (1) or deauthorize (0) + individual interfaces instead a whole device + in contrast to the device authorization. + If a deauthorized interface will be authorized + so the driver probing must be triggered manually + by writing INTERFACE to /sys/bus/usb/drivers_probe + This allows to avoid side-effects with drivers + that need multiple interfaces. + A deauthorized interface cannot be probed or claimed. + +What: /sys/bus/usb/devices/usbX/interface_authorized_default +Date: June 2015 +KernelVersion: 4.2 +Description: + This is used as default value that determines + if interfaces would authorized per default. + The value can be 1 or 0. It is per default 1. + What: /sys/bus/usb/device/.../authorized Date: July 2008 KernelVersion: 2.6.26 diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index c069b68..020cec5 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt @@ -3,6 +3,9 @@ Authorizing (or not) your USB devices to connect to the system (C) 2007 Inaky Perez-Gonzalez in...@linux.intel.com Intel Corporation +Interface authorization part: + (C) 2015 Stefan Koch sk...@suse.de SUSE LLC + This feature allows you to control if a USB device can be used (or not) in a system. This feature will allow you to implement a lock-down of USB devices, fully controlled by user space. @@ -90,3 +93,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit can fake descriptors and device info. Don't trust that. You are welcome. + +Interface authorization +--- +There is a similar approach to allow or deny specific USB interfaces. +That allows to block only a subset of an USB device. + +Authorize an interface: +$ echo 1 /sys/bus/usb/devices/INTERFACE/authorized + +Deauthorize an interface: +$ echo 0 /sys/bus/usb/devices/INTERFACE/authorized + +The default value for new interfaces +on a particular USB bus can be changed, too. + +Allow interfaces per default: +$ echo 1 /sys/bus/usb/devices/usbX/interface_authorized_default + +Deny interfaces per default: +$ echo 0 /sys/bus/usb/devices/usbX/interface_authorized_default + +Per default the interface_authorized_default bit is 1. +So all interfaces would authorized per default. + +Note: +If a deauthorized interface will be authorized so the driver probing must +be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe + +For drivers that need multiple interfaces all needed interfaces should be +authroized first. After that the drivers should be probed. +This avoids side effects. -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 3/6] usb: interface authorization: Control interface probing and claiming
Driver probings and interface claims get rejected if an interface is not authorized. Signed-off-by: Stefan Koch sk...@suse.de --- drivers/usb/core/driver.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 818369a..74169a5 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -295,6 +295,13 @@ static int usb_probe_interface(struct device *dev) if (udev-authorized == 0) { dev_err(intf-dev, Device is not authorized for usage\n); return error; + } else if (intf-authorized == 0) { + unsigned intf_num = intf-altsetting-desc.bInterfaceNumber; + + dev_err(intf-dev, Interface 0x%02x is not authorized for usage\n, + intf_num); + + return error; } id = usb_match_dynamic_id(intf, driver); @@ -507,6 +514,10 @@ int usb_driver_claim_interface(struct usb_driver *driver, if (dev-driver) return -EBUSY; + /* reject claim if not iterface is not authorized */ + if (!iface-authorized) + return -ENODEV; + udev = interface_to_usbdev(iface); dev-driver = driver-drvwrap.driver; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/6] usb: interface authorization: Declare authorized attribute
The attribute authorized shows the authorization state for an interface. Signed-off-by: Stefan Koch sk...@suse.de --- include/linux/usb.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 447fe29..2a991cb 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -179,6 +179,8 @@ struct usb_interface { unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned resetting_device:1;/* true: bandwidth alloc after reset */ + unsigned authorized:1; /* used for interface authorization */ + struct device dev; /* interface specific device info */ struct device *usb_dev; atomic_t pm_usage_cnt; /* usage counter for autosuspend */ -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 0/5] usb: Add usb interface authorization
Am Mittwoch, den 17.06.2015, 11:38 -0400 schrieb Alan Stern: On Wed, 17 Jun 2015, Stefan Koch wrote: You write in another mail: You could probe all the interfaces whenever any interface is authorized. Or there could be a separate mechanism to initiate probing. The first is the actual approach and this works fine. It is regardless in which order the interfaces for USB-Tethering are authorized. Both works. Before probing *all* interfaces it was needed to authorize interface 1 before interface 0. Also btusb works fine. What do you think? I think it's inelegant and will cause unnecessary probing with errors whenever a driver needs to claim multiple interfaces. However, I would like to hear what other people on the mailing list think. Alan Stern I'll send a fourth patch without automatically probing. An option could be to implement the automatically probing and enable or disable it by another sysfs attribute. (not included in the fourth patch) -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 6/6] usb: interface authorization: Documentation part
This part adds the documentation for the interface authorization. Signed-off-by: Stefan Koch sk...@suse.de --- Documentation/ABI/testing/sysfs-bus-usb | 22 + Documentation/usb/authorization.txt | 34 + 2 files changed, 56 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index e5cc763..ca8c8d3 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -1,3 +1,25 @@ +What: /sys/bus/usb/devices/INTERFACE/authorized +Date: June 2015 +KernelVersion: 4.2 +Description: + This allows to authorize (1) or deauthorize (0) + individual interfaces instead a whole device + in contrast to the device authorization. + If a deauthorized interface will be authorized + so the driver probing must be triggered manually + by writing INTERFACE to /sys/bus/usb/drivers_probe + This allows to avoid side-effects with drivers + that need multiple interfaces. + A deauthorized interface cannot be probed or claimed. + +What: /sys/bus/usb/devices/usbX/interface_authorized_default +Date: June 2015 +KernelVersion: 4.2 +Description: + This is used as default value that determines + if interfaces would authorized per default. + The value can be 1 or 0. It is per default 1. + What: /sys/bus/usb/device/.../authorized Date: July 2008 KernelVersion: 2.6.26 diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index c069b68..020cec5 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt @@ -3,6 +3,9 @@ Authorizing (or not) your USB devices to connect to the system (C) 2007 Inaky Perez-Gonzalez in...@linux.intel.com Intel Corporation +Interface authorization part: + (C) 2015 Stefan Koch sk...@suse.de SUSE LLC + This feature allows you to control if a USB device can be used (or not) in a system. This feature will allow you to implement a lock-down of USB devices, fully controlled by user space. @@ -90,3 +93,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit can fake descriptors and device info. Don't trust that. You are welcome. + +Interface authorization +--- +There is a similar approach to allow or deny specific USB interfaces. +That allows to block only a subset of an USB device. + +Authorize an interface: +$ echo 1 /sys/bus/usb/devices/INTERFACE/authorized + +Deauthorize an interface: +$ echo 0 /sys/bus/usb/devices/INTERFACE/authorized + +The default value for new interfaces +on a particular USB bus can be changed, too. + +Allow interfaces per default: +$ echo 1 /sys/bus/usb/devices/usbX/interface_authorized_default + +Deny interfaces per default: +$ echo 0 /sys/bus/usb/devices/usbX/interface_authorized_default + +Per default the interface_authorized_default bit is 1. +So all interfaces would authorized per default. + +Note: +If a deauthorized interface will be authorized so the driver probing must +be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe + +For drivers that need multiple interfaces all needed interfaces should be +authroized first. After that the drivers should be probed. +This avoids side effects. -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 2/6] usb: interface authorization: Introduces the default interface authorization
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 sk...@suse.de --- drivers/usb/core/hcd.c | 52 ++ drivers/usb/core/message.c | 2 ++ include/linux/usb/hcd.h| 3 +++ 3 files changed, 57 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 45a915c..4ceb753 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -882,9 +882,58 @@ 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_auhorized_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); + unsigned def = HCD_INTERFACE_AUTHORIZED_DEFAULT(hcd) ? 1 : 0; + + return sprintf(buf, %u\n, def); +} + +/* + * interface_authorized_default_store - store default authorization status + * for USB interfaces + * + * note: interface_auhorized_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; + + switch (val) { + case 0: + clear_bit(HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT, hcd-flags); + break; + case 1: + set_bit(HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT, hcd-flags); + break; + } + + 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, }; @@ -2679,6 +2728,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_INTERFACE_AUTHORIZED_DEFAULT, 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.) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..1e85f62 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1807,6 +1807,8 @@ free_interfaces: intfc = cp-intf_cache[i]; intf-altsetting = intfc-altsetting; intf-num_altsetting = intfc-num_altsetting; + intf-authorized = + HCD_INTERFACE_AUTHORIZED_DEFAULT(hcd) ? 1 : 0; kref_get(intfc-ref); alt = usb_altnum_to_altsetting(intf, 0); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 68b1e83..93c19b2 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -120,6 +120,7 @@ struct usb_hcd { #define HCD_FLAG_WAKEUP_PENDING4 /* root hub is resuming? */ #define HCD_FLAG_RH_RUNNING5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ +#define HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT 8 /* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -130,6 +131,8 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd)((hcd)-flags (1U HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd)((hcd)-flags (1U HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)-flags (1U HCD_FLAG_DEAD)) +#define HCD_INTERFACE_AUTHORIZED_DEFAULT(hcd) \ + ((hcd)-flags (1U HCD_FLAG_INTERFACE_AUTHORIZED_DEFAULT)) /* Flags that get set only during HCD registration or removal. */ unsignedrh_registered:1;/* is root hub registered? */ -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 1/6] usb: interface authorization: Declare authorized attribute
The attribute authorized shows the authorization state for an interface. Signed-off-by: Stefan Koch sk...@suse.de --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 447fe29..135c50c 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -178,6 +178,7 @@ struct usb_interface { unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned resetting_device:1;/* true: bandwidth alloc after reset */ + unsigned authorized:1; /* used for interface authorization */ struct device dev; /* interface specific device info */ struct device *usb_dev; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 0/6] usb: interface authorization
This patch introduces an interface authorization for USB devices. The kernel supports a device authorization because of wireless USB. But the new interface authorization allows to authorize or deauthorize individual interfaces instead authorization or deauthorize a whole device. Therefore the authorized attribute is introduced for each interface. Each patch depends on all patches with a lesser number. Stefan Koch (6): usb: interface authorization: Declare authorized attribute usb: interface authorization: Introduces the default interface authorization usb: interface authorization: Control interface probing and claiming usb: interface authorization: Introduces the USB interface authorization. usb: interface authorization: SysFS part of USB interface authorization. usb: interface authorization: Documentation part Documentation/ABI/testing/sysfs-bus-usb | 22 ++ Documentation/usb/authorization.txt | 34 + drivers/usb/core/driver.c | 11 +++ drivers/usb/core/hcd.c | 52 + drivers/usb/core/message.c | 48 ++ drivers/usb/core/sysfs.c| 41 ++ drivers/usb/core/usb.h | 2 ++ include/linux/usb.h | 1 + include/linux/usb/hcd.h | 3 ++ 9 files changed, 214 insertions(+) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html