diff options
-rw-r--r-- | Documentation/admin-guide/kernel-parameters.txt | 3 | ||||
-rw-r--r-- | Documentation/usb/authorization.txt | 4 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 51 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 33 | ||||
-rw-r--r-- | include/linux/usb/hcd.h | 10 |
5 files changed, 69 insertions, 32 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 858b6c0b9a15..2d28ef850781 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt | |||
@@ -4697,7 +4697,8 @@ | |||
4697 | usbcore.authorized_default= | 4697 | usbcore.authorized_default= |
4698 | [USB] Default USB device authorization: | 4698 | [USB] Default USB device authorization: |
4699 | (default -1 = authorized except for wireless USB, | 4699 | (default -1 = authorized except for wireless USB, |
4700 | 0 = not authorized, 1 = authorized) | 4700 | 0 = not authorized, 1 = authorized, 2 = authorized |
4701 | if device connected to internal port) | ||
4701 | 4702 | ||
4702 | usbcore.autosuspend= | 4703 | usbcore.autosuspend= |
4703 | [USB] The autosuspend time delay (in seconds) used | 4704 | [USB] The autosuspend time delay (in seconds) used |
diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index f901ec77439c..9dd1dc7b1009 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt | |||
@@ -34,7 +34,9 @@ $ echo 1 > /sys/bus/usb/devices/usbX/authorized_default | |||
34 | By default, Wired USB devices are authorized by default to | 34 | By default, Wired USB devices are authorized by default to |
35 | connect. Wireless USB hosts deauthorize by default all new connected | 35 | connect. Wireless USB hosts deauthorize by default all new connected |
36 | devices (this is so because we need to do an authentication phase | 36 | devices (this is so because we need to do an authentication phase |
37 | before authorizing). | 37 | before authorizing). Writing "2" to the authorized_default attribute |
38 | causes kernel to only authorize by default devices connected to internal | ||
39 | USB ports. | ||
38 | 40 | ||
39 | 41 | ||
40 | Example system lockdown (lame) | 42 | Example system lockdown (lame) |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 86f39e44f98a..3b6e3e25f59e 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -373,13 +373,19 @@ static const u8 ss_rh_config_descriptor[] = { | |||
373 | * -1 is authorized for all devices except wireless (old behaviour) | 373 | * -1 is authorized for all devices except wireless (old behaviour) |
374 | * 0 is unauthorized for all devices | 374 | * 0 is unauthorized for all devices |
375 | * 1 is authorized for all devices | 375 | * 1 is authorized for all devices |
376 | * 2 is authorized for internal devices | ||
376 | */ | 377 | */ |
377 | static int authorized_default = -1; | 378 | #define USB_AUTHORIZE_WIRED -1 |
379 | #define USB_AUTHORIZE_NONE 0 | ||
380 | #define USB_AUTHORIZE_ALL 1 | ||
381 | #define USB_AUTHORIZE_INTERNAL 2 | ||
382 | |||
383 | static int authorized_default = USB_AUTHORIZE_WIRED; | ||
378 | module_param(authorized_default, int, S_IRUGO|S_IWUSR); | 384 | module_param(authorized_default, int, S_IRUGO|S_IWUSR); |
379 | MODULE_PARM_DESC(authorized_default, | 385 | MODULE_PARM_DESC(authorized_default, |
380 | "Default USB device authorization: 0 is not authorized, 1 is " | 386 | "Default USB device authorization: 0 is not authorized, 1 is " |
381 | "authorized, -1 is authorized except for wireless USB (default, " | 387 | "authorized, 2 is authorized for internal devices, -1 is " |
382 | "old behaviour"); | 388 | "authorized except for wireless USB (default, old behaviour"); |
383 | /*-------------------------------------------------------------------------*/ | 389 | /*-------------------------------------------------------------------------*/ |
384 | 390 | ||
385 | /** | 391 | /** |
@@ -884,7 +890,7 @@ static ssize_t authorized_default_show(struct device *dev, | |||
884 | struct usb_hcd *hcd; | 890 | struct usb_hcd *hcd; |
885 | 891 | ||
886 | hcd = bus_to_hcd(usb_bus); | 892 | hcd = bus_to_hcd(usb_bus); |
887 | return snprintf(buf, PAGE_SIZE, "%u\n", !!HCD_DEV_AUTHORIZED(hcd)); | 893 | return snprintf(buf, PAGE_SIZE, "%u\n", hcd->dev_policy); |
888 | } | 894 | } |
889 | 895 | ||
890 | static ssize_t authorized_default_store(struct device *dev, | 896 | static ssize_t authorized_default_store(struct device *dev, |
@@ -900,11 +906,8 @@ static ssize_t authorized_default_store(struct device *dev, | |||
900 | hcd = bus_to_hcd(usb_bus); | 906 | hcd = bus_to_hcd(usb_bus); |
901 | result = sscanf(buf, "%u\n", &val); | 907 | result = sscanf(buf, "%u\n", &val); |
902 | if (result == 1) { | 908 | if (result == 1) { |
903 | if (val) | 909 | hcd->dev_policy = val <= USB_DEVICE_AUTHORIZE_INTERNAL ? |
904 | set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags); | 910 | val : USB_DEVICE_AUTHORIZE_ALL; |
905 | else | ||
906 | clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags); | ||
907 | |||
908 | result = size; | 911 | result = size; |
909 | } else { | 912 | } else { |
910 | result = -EINVAL; | 913 | result = -EINVAL; |
@@ -2748,18 +2751,26 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
2748 | 2751 | ||
2749 | dev_info(hcd->self.controller, "%s\n", hcd->product_desc); | 2752 | dev_info(hcd->self.controller, "%s\n", hcd->product_desc); |
2750 | 2753 | ||
2751 | /* Keep old behaviour if authorized_default is not in [0, 1]. */ | 2754 | switch (authorized_default) { |
2752 | if (authorized_default < 0 || authorized_default > 1) { | 2755 | case USB_AUTHORIZE_NONE: |
2753 | if (hcd->wireless) | 2756 | hcd->dev_policy = USB_DEVICE_AUTHORIZE_NONE; |
2754 | clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags); | 2757 | break; |
2755 | else | 2758 | |
2756 | set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags); | 2759 | case USB_AUTHORIZE_ALL: |
2757 | } else { | 2760 | hcd->dev_policy = USB_DEVICE_AUTHORIZE_ALL; |
2758 | if (authorized_default) | 2761 | break; |
2759 | set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags); | 2762 | |
2760 | else | 2763 | case USB_AUTHORIZE_INTERNAL: |
2761 | clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags); | 2764 | hcd->dev_policy = USB_DEVICE_AUTHORIZE_INTERNAL; |
2765 | break; | ||
2766 | |||
2767 | case USB_AUTHORIZE_WIRED: | ||
2768 | default: | ||
2769 | hcd->dev_policy = hcd->wireless ? | ||
2770 | USB_DEVICE_AUTHORIZE_NONE : USB_DEVICE_AUTHORIZE_ALL; | ||
2771 | break; | ||
2762 | } | 2772 | } |
2773 | |||
2763 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 2774 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
2764 | 2775 | ||
2765 | /* per default all interfaces are authorized */ | 2776 | /* per default all interfaces are authorized */ |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 4ebfbd737905..9b5852e313f5 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -46,8 +46,7 @@ | |||
46 | #include <linux/mm.h> | 46 | #include <linux/mm.h> |
47 | #include <linux/dma-mapping.h> | 47 | #include <linux/dma-mapping.h> |
48 | 48 | ||
49 | #include "usb.h" | 49 | #include "hub.h" |
50 | |||
51 | 50 | ||
52 | const char *usbcore_name = "usbcore"; | 51 | const char *usbcore_name = "usbcore"; |
53 | 52 | ||
@@ -536,6 +535,27 @@ static unsigned usb_bus_is_wusb(struct usb_bus *bus) | |||
536 | return hcd->wireless; | 535 | return hcd->wireless; |
537 | } | 536 | } |
538 | 537 | ||
538 | static bool usb_dev_authorized(struct usb_device *dev, struct usb_hcd *hcd) | ||
539 | { | ||
540 | struct usb_hub *hub; | ||
541 | |||
542 | if (!dev->parent) | ||
543 | return true; /* Root hub always ok [and always wired] */ | ||
544 | |||
545 | switch (hcd->dev_policy) { | ||
546 | case USB_DEVICE_AUTHORIZE_NONE: | ||
547 | default: | ||
548 | return false; | ||
549 | |||
550 | case USB_DEVICE_AUTHORIZE_ALL: | ||
551 | return true; | ||
552 | |||
553 | case USB_DEVICE_AUTHORIZE_INTERNAL: | ||
554 | hub = usb_hub_to_struct_hub(dev->parent); | ||
555 | return hub->ports[dev->portnum - 1]->connect_type == | ||
556 | USB_PORT_CONNECT_TYPE_HARD_WIRED; | ||
557 | } | ||
558 | } | ||
539 | 559 | ||
540 | /** | 560 | /** |
541 | * usb_alloc_dev - usb device constructor (usbcore-internal) | 561 | * usb_alloc_dev - usb device constructor (usbcore-internal) |
@@ -663,12 +683,11 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
663 | dev->connect_time = jiffies; | 683 | dev->connect_time = jiffies; |
664 | dev->active_duration = -jiffies; | 684 | dev->active_duration = -jiffies; |
665 | #endif | 685 | #endif |
666 | if (root_hub) /* Root hub always ok [and always wired] */ | 686 | |
667 | dev->authorized = 1; | 687 | dev->authorized = usb_dev_authorized(dev, usb_hcd); |
668 | else { | 688 | if (!root_hub) |
669 | dev->authorized = !!HCD_DEV_AUTHORIZED(usb_hcd); | ||
670 | dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0; | 689 | dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0; |
671 | } | 690 | |
672 | return dev; | 691 | return dev; |
673 | } | 692 | } |
674 | EXPORT_SYMBOL_GPL(usb_alloc_dev); | 693 | EXPORT_SYMBOL_GPL(usb_alloc_dev); |
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 7dc3a411bece..695931b03684 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h | |||
@@ -72,6 +72,12 @@ struct giveback_urb_bh { | |||
72 | struct usb_host_endpoint *completing_ep; | 72 | struct usb_host_endpoint *completing_ep; |
73 | }; | 73 | }; |
74 | 74 | ||
75 | enum usb_dev_authorize_policy { | ||
76 | USB_DEVICE_AUTHORIZE_NONE = 0, | ||
77 | USB_DEVICE_AUTHORIZE_ALL = 1, | ||
78 | USB_DEVICE_AUTHORIZE_INTERNAL = 2, | ||
79 | }; | ||
80 | |||
75 | struct usb_hcd { | 81 | struct usb_hcd { |
76 | 82 | ||
77 | /* | 83 | /* |
@@ -117,7 +123,6 @@ struct usb_hcd { | |||
117 | #define HCD_FLAG_RH_RUNNING 5 /* root hub is running? */ | 123 | #define HCD_FLAG_RH_RUNNING 5 /* root hub is running? */ |
118 | #define HCD_FLAG_DEAD 6 /* controller has died? */ | 124 | #define HCD_FLAG_DEAD 6 /* controller has died? */ |
119 | #define HCD_FLAG_INTF_AUTHORIZED 7 /* authorize interfaces? */ | 125 | #define HCD_FLAG_INTF_AUTHORIZED 7 /* authorize interfaces? */ |
120 | #define HCD_FLAG_DEV_AUTHORIZED 8 /* authorize devices? */ | ||
121 | 126 | ||
122 | /* The flags can be tested using these macros; they are likely to | 127 | /* The flags can be tested using these macros; they are likely to |
123 | * be slightly faster than test_bit(). | 128 | * be slightly faster than test_bit(). |
@@ -142,8 +147,7 @@ struct usb_hcd { | |||
142 | * or they require explicit user space authorization; this bit is | 147 | * or they require explicit user space authorization; this bit is |
143 | * settable through /sys/class/usb_host/X/authorized_default | 148 | * settable through /sys/class/usb_host/X/authorized_default |
144 | */ | 149 | */ |
145 | #define HCD_DEV_AUTHORIZED(hcd) \ | 150 | enum usb_dev_authorize_policy dev_policy; |
146 | ((hcd)->flags & (1U << HCD_FLAG_DEV_AUTHORIZED)) | ||
147 | 151 | ||
148 | /* Flags that get set only during HCD registration or removal. */ | 152 | /* Flags that get set only during HCD registration or removal. */ |
149 | unsigned rh_registered:1;/* is root hub registered? */ | 153 | unsigned rh_registered:1;/* is root hub registered? */ |