summaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/usb.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@chromium.org>2019-02-16 23:21:51 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-02-22 09:27:55 +0100
commit7bae0432a64aa7569dbd0feb2927fd3ff913901f (patch)
tree6af0b4f35bb5eb87326f546a18597c00d06942a2 /drivers/usb/core/usb.c
parentca942a0ed019f98c156cdb3de78b3d76bf381b12 (diff)
downloadlinux-stable-7bae0432a64aa7569dbd0feb2927fd3ff913901f.tar.gz
linux-stable-7bae0432a64aa7569dbd0feb2927fd3ff913901f.tar.bz2
linux-stable-7bae0432a64aa7569dbd0feb2927fd3ff913901f.zip
usb: core: add option of only authorizing internal devices
On Chrome OS we want to use USBguard to potentially limit access to USB devices based on policy. We however to do not want to wait for userspace to come up before initializing fixed USB devices to not regress our boot times. This patch adds option to instruct the kernel to only authorize devices connected to the internal ports. Previously we could either authorize all or none (or, by default, we'd only authorize wired devices). The behavior is controlled via usbcore.authorized_default command line option. Signed-off-by: Dmitry Torokhov <dtor@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/core/usb.c')
-rw-r--r--drivers/usb/core/usb.c33
1 files changed, 26 insertions, 7 deletions
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 @@
#include <linux/mm.h>
#include <linux/dma-mapping.h>
-#include "usb.h"
-
+#include "hub.h"
const char *usbcore_name = "usbcore";
@@ -536,6 +535,27 @@ static unsigned usb_bus_is_wusb(struct usb_bus *bus)
return hcd->wireless;
}
+static bool usb_dev_authorized(struct usb_device *dev, struct usb_hcd *hcd)
+{
+ struct usb_hub *hub;
+
+ if (!dev->parent)
+ return true; /* Root hub always ok [and always wired] */
+
+ switch (hcd->dev_policy) {
+ case USB_DEVICE_AUTHORIZE_NONE:
+ default:
+ return false;
+
+ case USB_DEVICE_AUTHORIZE_ALL:
+ return true;
+
+ case USB_DEVICE_AUTHORIZE_INTERNAL:
+ hub = usb_hub_to_struct_hub(dev->parent);
+ return hub->ports[dev->portnum - 1]->connect_type ==
+ USB_PORT_CONNECT_TYPE_HARD_WIRED;
+ }
+}
/**
* usb_alloc_dev - usb device constructor (usbcore-internal)
@@ -663,12 +683,11 @@ 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] */
- dev->authorized = 1;
- else {
- dev->authorized = !!HCD_DEV_AUTHORIZED(usb_hcd);
+
+ dev->authorized = usb_dev_authorized(dev, usb_hcd);
+ if (!root_hub)
dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0;
- }
+
return dev;
}
EXPORT_SYMBOL_GPL(usb_alloc_dev);