Hi,

This patch adds an option to usbdevs(8) to disable USB bus probing
at runtime.  The operation is restricted to the root user.

I am not sure if this approach is sensible or even correct.  Some
pointers would be much appreciated.

This was started as part of a reply by mpi on tech@

  http://marc.info/?l=openbsd-tech&m=142917883126679&w=2

I guess the reasoning behind this is to add some protection against
things like badusb?

Index: sys/dev/usb/uhub.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uhub.c,v
retrieving revision 1.83
diff -u -p -r1.83 uhub.c
--- sys/dev/usb/uhub.c  12 Feb 2015 05:07:52 -0000      1.83
+++ sys/dev/usb/uhub.c  17 Apr 2015 15:36:30 -0000
@@ -222,6 +222,7 @@ uhub_attach(struct device *parent, struc
        hub->nports = nports;
        hub->powerdelay = powerdelay;
        hub->ttthink = ttthink >> 5;
+       hub->noprobe = 0;
 
        if (!dev->self_powered && dev->powersrc->parent != NULL &&
            !dev->powersrc->parent->self_powered) {
@@ -494,6 +495,9 @@ uhub_explore(struct usbd_device *dev)
                 */
                if (speed > sc->sc_hub->speed)
                        speed = sc->sc_hub->speed;
+
+               if (dev->hub->noprobe)
+                       return (0);
 
                /* Get device info and set its address. */
                err = usbd_new_device(&sc->sc_dev, dev->bus,
Index: sys/dev/usb/usb.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb.c,v
retrieving revision 1.107
diff -u -p -r1.107 usb.c
--- sys/dev/usb/usb.c   14 Mar 2015 03:38:50 -0000      1.107
+++ sys/dev/usb/usb.c   17 Apr 2015 15:36:30 -0000
@@ -607,6 +607,17 @@ usbioctl(dev_t devt, u_long cmd, caddr_t
 #endif
                break;
 #endif /* USB_DEBUG */
+       case USB_NO_PROBE:
+       {
+               struct usbd_device *dev = sc->sc_bus->root_hub;
+
+               if ((error = suser(curproc, 0)) != 0)
+                       return (error);
+               if (!(flag & FWRITE))
+                       return (EBADF);
+               dev->hub->noprobe = !!*(unsigned int *)data;
+               break;
+       }
        case USB_REQUEST:
        {
                struct usb_ctl_request *ur = (void *)data;
Index: sys/dev/usb/usb.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb.h,v
retrieving revision 1.50
diff -u -p -r1.50 usb.h
--- sys/dev/usb/usb.h   14 Feb 2015 06:18:58 -0000      1.50
+++ sys/dev/usb/usb.h   17 Apr 2015 15:36:30 -0000
@@ -728,6 +728,7 @@ struct usb_device_stats {
 #define USB_DEVICE_GET_CDESC   _IOWR('U', 6, struct usb_device_cdesc)
 #define USB_DEVICE_GET_FDESC   _IOWR('U', 7, struct usb_device_fdesc)
 #define USB_DEVICE_GET_DDESC   _IOWR('U', 8, struct usb_device_ddesc)
+#define USB_NO_PROBE           _IOW ('U', 9, unsigned int)
 
 /* Generic HID device */
 #define USB_GET_REPORT_DESC    _IOR ('U', 21, struct usb_ctl_report_desc)
Index: sys/dev/usb/usbdivar.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdivar.h,v
retrieving revision 1.69
diff -u -p -r1.69 usbdivar.h
--- sys/dev/usb/usbdivar.h      21 Dec 2014 12:04:01 -0000      1.69
+++ sys/dev/usb/usbdivar.h      17 Apr 2015 15:36:30 -0000
@@ -94,6 +94,7 @@ struct usbd_hub {
        int                     nports;
        u_int8_t                powerdelay;
        u_int8_t                ttthink;
+       u_int8_t                noprobe;
 };
 
 struct usbd_bus {
Index: usr.sbin/usbdevs/usbdevs.8
===================================================================
RCS file: /cvs/src/usr.sbin/usbdevs/usbdevs.8,v
retrieving revision 1.9
diff -u -p -r1.9 usbdevs.8
--- usr.sbin/usbdevs/usbdevs.8  26 Jun 2008 05:42:21 -0000      1.9
+++ usr.sbin/usbdevs/usbdevs.8  17 Apr 2015 15:36:31 -0000
@@ -39,6 +39,7 @@
 .Op Fl dv
 .Op Fl a Ar addr
 .Op Fl f Ar dev
+.Op Fl p Ar on | off
 .Sh DESCRIPTION
 .Nm
 prints a listing of all USB devices connected to the system
@@ -53,6 +54,10 @@ Only print information about the device 
 Show the device drivers associated with each device.
 .It Fl f Ar dev
 Only print information for the given USB controller.
+.It Fl p Ar on | off
+Enable or disable USB bus probing.  The default
+is
+.Ar on .
 .It Fl v
 Be verbose.
 .El
Index: usr.sbin/usbdevs/usbdevs.c
===================================================================
RCS file: /cvs/src/usr.sbin/usbdevs/usbdevs.c,v
retrieving revision 1.24
diff -u -p -r1.24 usbdevs.c
--- usr.sbin/usbdevs/usbdevs.c  31 Mar 2015 13:38:27 -0000      1.24
+++ usr.sbin/usbdevs/usbdevs.c  17 Apr 2015 15:36:31 -0000
@@ -30,6 +30,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -53,6 +54,7 @@ void usage(void);
 void usbdev(int f, int a, int rec);
 void usbdump(int f);
 void dumpone(char *name, int f, int addr);
+void setprobe(unsigned int);
 int main(int, char **);
 
 extern char *__progname;
@@ -60,7 +62,7 @@ extern char *__progname;
 void
 usage(void)
 {
-       fprintf(stderr, "usage: %s [-dv] [-a addr] [-f dev]\n", __progname);
+       fprintf(stderr, "usage: %s [-dv] [-a addr] [-f dev] [-p on | off]\n", 
__progname);
        exit(1);
 }
 
@@ -177,6 +179,27 @@ dumpone(char *name, int f, int addr)
                usbdump(f);
 }
 
+void
+setprobe(unsigned int noprobe)
+{
+       char buf[PATH_MAX];
+       int i, f;
+
+       for (i = 0; i < 10; i++) {
+               snprintf(buf, sizeof(buf), "%s%d", USBDEV, i);
+               f = open(buf, O_WRONLY);
+               if (f < 0) {
+                       if (errno == ENOENT || errno == ENXIO)
+                               continue;
+                       warn("open %s", buf);
+                       continue;
+               }
+               if (ioctl(f, USB_NO_PROBE, &noprobe))
+                       warn("setprobe %s", buf);
+               close(f);
+       }
+}
+
 int
 main(int argc, char **argv)
 {
@@ -186,8 +209,9 @@ main(int argc, char **argv)
        const char *errstr;
        int addr = 0;
        int ncont;
+       unsigned int noprobe = 0;
 
-       while ((ch = getopt(argc, argv, "a:df:v?")) != -1) {
+       while ((ch = getopt(argc, argv, "a:df:p:v?")) != -1) {
                switch (ch) {
                case 'a':
                        addr = strtonum(optarg, 1, USB_MAX_DEVICES, &errstr);
@@ -200,6 +224,15 @@ main(int argc, char **argv)
                case 'f':
                        dev = optarg;
                        break;
+               case 'p':
+                       if (!strcmp(optarg, "on"))
+                               noprobe = 0;
+                       else if (!strcmp(optarg, "off"))
+                               noprobe = 1;
+                       else
+                               usage();
+                       setprobe(noprobe);
+                       exit(0);
                case 'v':
                        verbose = 1;
                        break;

Reply via email to