But the talk linked to mainly focuses on the second possibility: "the OS automatically loads the driver for keyboards and network adapterse", and this is trivially defended against, at least on Linux. I assume you can do similar/identical things on other operating systems (e.g. Windows probably has a registry key for that, because it always has registry keys for everything...)
# echo 0 >/sys/bus/usb/drivers_autoprobe
Now, no drivers are bound to USB devices automatically. Just try it. I plugged in peripherals into the computer, the only thing you'll get (running 3.15.8-1-ARCH, archlinux x64) is the following text in the dmesg: [ 6765.949361] usb 5-1: new low-speed USB device number 3 using uhci_hcd **mouse**
[ 6846.469357] usb 6-1: new high-speed USB device number 3 using ehci-pci **harddisk**
[ 7062.616021] usb 7-4.4: new high-speed USB device number 7 using ehci-pci **eth/network**
Now, if I am convinced that one of the devices hasn't been tampered with, I'll run the following command, that triggers automatic probing for a single USB device (1.0 is configuration 1, function 0, I think...) # echo 7-4.4:1.0 >/sys/bus/usb/drivers_probe
dmesg shows.... [ 7193.076584] ax88179_178a 7-4.4:1.0 eth0: register 'ax88179_178a' at usb-0000:00:1d.7-4.4, ASIX AX88179 USB 3.0 Gigabit Ethernet, 00:0a:cd:22:b4:40
[ 7193.099754] systemd-udevd[10470]: renamed network interface eth0 to enp0s29f7u4u4
But if I only want to allow USB storage devices, I can manually bind to the usb storage driver. # modprobe usb-storage # was not loaded on my machine, yet...
# echo 1 >/sys/bus/usb/devices/6-1/bConfigurationValue # enable 1st configuration
# echo 6-1:1.0 >/sys/bus/usb/drivers/usb-storage/bind
dmesg, again... [ 7583.801824] usbcore: registered new interface driver usb-storage
[ 7729.898188] usb-storage 6-1:1.0: USB Mass Storage device detected
[ 7729.898404] scsi6 : usb-storage 6-1:1.0
[ 7730.900552] scsi 6:0:0:0: Direct-Access TOSHIBA MK4309MAT G5.0 PQ: 0 ANSI: 0 CCS
[ 7730.904913] sd 6:0:0:0: [sdd] 8452080 512-byte logical blocks: (4.32 GB/4.02 GiB)
Now, this of course is completely ridiculous, from a user-interface perspective, but, I think if you only want to cover mounting of USB sticks, you can script this in shell/perl/python/awk, using "lsusb -v" for parsing the binary USB descriptors and only start usb-storage on USB sticks.EDIT/ADDED: -----
And also note: The mechanism described above concerns the binding of drivers to devices. There's a different facility in place to make USB devices inaccessible to the drivers/the user, and that's using the "authorized" flags: You set the "autorized_default" flag in /sys/bus/usb/devices/usb<N> to 0, then every device that is connected to the machine is initially disabled:
[ 9162.809251] usb 7-4.4: new high-speed USB device number 11 using ehci-pci
[ 9162.912337] usb 7-4.4: Device is not authorized for usage
If you are sure that this particular device is allowed to connect, authorize it... # echo 1 >/sys/bus/usb/devices/7-4.4/authorized
[ 9214.302656] ax88179_178a 7-4.4:1.0 eth0: register 'ax88179_178a' at usb-0000:00:1d.7-4.4, ASIX AX88179 USB 3.0 Gigabit Ethernet, 00:0a:cd:22:b4:40
[ 9214.302678] usb 7-4.4: authorized to connect
[ 9214.326028] systemd-udevd[10771]: renamed network interface eth0 to enp0s29f7u4u4
That way, you could have the publicly accessible USB connectors (say... usb2 and usb4) in "autorized_default=0" mode, and the internal USB connectors, or the ones on the back of a device that is somewhat physically secured set to "autorized_default=1" to not impede usage and comfort... But, of course, if you have scripts in place implementing a "USB ACL", that doesn't really sound as if it's worth the added complexity?