[PATCH v2 2/5] usb: Add usb interface authorization: Introduces the default interface authorization

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

 



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 <skoch@xxxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




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

  Powered by Linux