Interfaces would allowed per default. This can disabled or enabled by writing 0 or 1 to /sys/bus/usb/devices/usb*/interface_authorized_default
Signed-off-by: Stefan Koch <sk...@suse.de> --- drivers/usb/core/hcd.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/core/message.c | 8 ++++++++ drivers/usb/core/usb.c | 22 ++++++++++++++++++++-- include/linux/usb/hcd.h | 1 + 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 45a915c..024cce5 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); +/* + * show default authorization status of usb interface + * + * note: interface_auhorized_default is the default value + * for initialising interface_authorized + */ +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; + + return sprintf(buf, "%u\n", def); +} + +/* + * store default authorization status of usb interface + * + * note: interface_auhorized_default is the default value + * for initialising interface_authorized + */ +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; + unsigned val; + + if (!usb_dev || !hcd) + rc = -ENODEV; + else if (sscanf(buf, "%u\n", &val) != 1) + rc = -EINVAL; + else + hcd->interface_authorized_default = val ? 1 : 0; + + 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 +2723,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 */ + hcd->interface_authorized_default = 1; + /* 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..a353a42 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1804,9 +1804,17 @@ free_interfaces: struct usb_host_interface *alt; cp->interface[i] = intf = new_interfaces[i]; + + /* update device's mask at configuration change */ + if (hcd->interface_authorized_default) + dev->mask |= (1 << i); + else + dev->mask &= ~(1 << i); + intfc = cp->intf_cache[i]; intf->altsetting = intfc->altsetting; intf->num_altsetting = intfc->num_altsetting; + intf->authorized = dev->mask & (1 << i) ? true : false; kref_get(&intfc->ref); alt = usb_altnum_to_altsetting(intf, 0); diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8d5b2f4..f633b0b 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -507,12 +507,30 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, dev->connect_time = jiffies; dev->active_duration = -jiffies; #endif - if (root_hub) /* Root hub always ok [and always wired] */ + if (root_hub) { /* Root hub always ok [and always wired] */ dev->authorized = 1; - else { + dev->mask = 0; + + /* invert the mask. each bit of the mask is now TRUE. + * all interfaces should be allowed. */ + dev->mask = ~dev->mask; + } else { dev->authorized = usb_hcd->authorized_default; dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0; + dev->mask = 0; + + /* invert the mask if interface_authorized_default is TRUE + * each bit of the mask is now TRUE + * all interfaces should be allowed + * + * do not invert the mask + * if interface_authorized_default is FALSE + * each bit of the mask is now FALSE + * no interface should be allowed */ + dev->mask = usb_hcd->interface_authorized_default + ? ~dev->mask : dev->mask; } + dev->mask_changed = 0; /* changed during usb_device_set_mask() */ return dev; } EXPORT_SYMBOL_GPL(usb_alloc_dev); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 68b1e83..85eff49 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -142,6 +142,7 @@ struct usb_hcd { unsigned uses_new_polling:1; unsigned wireless:1; /* Wireless USB HCD */ unsigned authorized_default:1; + unsigned interface_authorized_default:1; unsigned has_tt:1; /* Integrated TT in root hub */ unsigned amd_resume_bug:1; /* AMD remote wakeup quirk */ unsigned can_do_streams:1; /* HC supports streams */ -- 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