Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 1 | ============================================================== |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 2 | Authorizing (or not) your USB devices to connect to the system |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 3 | ============================================================== |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 4 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 5 | Copyright (C) 2007 Inaky Perez-Gonzalez <inaky@linux.intel.com> Intel Corporation |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 6 | |
| 7 | This feature allows you to control if a USB device can be used (or |
| 8 | not) in a system. This feature will allow you to implement a lock-down |
| 9 | of USB devices, fully controlled by user space. |
| 10 | |
| 11 | As of now, when a USB device is connected it is configured and |
Matt LaPlante | d919588 | 2008-07-25 19:45:33 -0700 | [diff] [blame] | 12 | its interfaces are immediately made available to the users. With this |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 13 | modification, only if root authorizes the device to be configured will |
| 14 | then it be possible to use it. |
| 15 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 16 | Usage |
| 17 | ===== |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 18 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 19 | Authorize a device to connect:: |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 20 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 21 | $ echo 1 > /sys/bus/usb/devices/DEVICE/authorized |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 22 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 23 | De-authorize a device:: |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 24 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 25 | $ echo 0 > /sys/bus/usb/devices/DEVICE/authorized |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 26 | |
| 27 | Set new devices connected to hostX to be deauthorized by default (ie: |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 28 | lock down):: |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 29 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 30 | $ echo 0 > /sys/bus/usb/devices/usbX/authorized_default |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 31 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 32 | Remove the lock down:: |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 33 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 34 | $ echo 1 > /sys/bus/usb/devices/usbX/authorized_default |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 35 | |
| 36 | By default, Wired USB devices are authorized by default to |
| 37 | connect. Wireless USB hosts deauthorize by default all new connected |
| 38 | devices (this is so because we need to do an authentication phase |
Dmitry Torokhov | 7bae043 | 2019-02-16 23:21:51 -0800 | [diff] [blame] | 39 | before authorizing). Writing "2" to the authorized_default attribute |
| 40 | causes kernel to only authorize by default devices connected to internal |
| 41 | USB ports. |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 42 | |
| 43 | |
| 44 | Example system lockdown (lame) |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 45 | ------------------------------ |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 46 | |
| 47 | Imagine you want to implement a lockdown so only devices of type XYZ |
| 48 | can be connected (for example, it is a kiosk machine with a visible |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 49 | USB port):: |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 50 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 51 | boot up |
| 52 | rc.local -> |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 53 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 54 | for host in /sys/bus/usb/devices/usb* |
| 55 | do |
| 56 | echo 0 > $host/authorized_default |
| 57 | done |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 58 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 59 | Hookup an script to udev, for new USB devices:: |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 60 | |
| 61 | if device_is_my_type $DEV |
| 62 | then |
| 63 | echo 1 > $device_path/authorized |
| 64 | done |
| 65 | |
| 66 | |
| 67 | Now, device_is_my_type() is where the juice for a lockdown is. Just |
| 68 | checking if the class, type and protocol match something is the worse |
| 69 | security verification you can make (or the best, for someone willing |
| 70 | to break it). If you need something secure, use crypto and Certificate |
| 71 | Authentication or stuff like that. Something simple for an storage key |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 72 | could be:: |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 73 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 74 | function device_is_my_type() |
| 75 | { |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 76 | echo 1 > authorized # temporarily authorize it |
| 77 | # FIXME: make sure none can mount it |
| 78 | mount DEVICENODE /mntpoint |
| 79 | sum=$(md5sum /mntpoint/.signature) |
| 80 | if [ $sum = $(cat /etc/lockdown/keysum) ] |
| 81 | then |
| 82 | echo "We are good, connected" |
| 83 | umount /mntpoint |
| 84 | # Other stuff so others can use it |
| 85 | else |
| 86 | echo 0 > authorized |
| 87 | fi |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 88 | } |
Inaky Perez-Gonzalez | 732bb9e | 2007-07-31 20:34:08 -0700 | [diff] [blame] | 89 | |
| 90 | |
| 91 | Of course, this is lame, you'd want to do a real certificate |
| 92 | verification stuff with PKI, so you don't depend on a shared secret, |
| 93 | etc, but you get the idea. Anybody with access to a device gadget kit |
| 94 | can fake descriptors and device info. Don't trust that. You are |
| 95 | welcome. |
| 96 | |
Stefan Koch | 7f59c15 | 2015-08-25 21:10:10 +0200 | [diff] [blame] | 97 | |
| 98 | Interface authorization |
| 99 | ----------------------- |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 100 | |
Stefan Koch | 7f59c15 | 2015-08-25 21:10:10 +0200 | [diff] [blame] | 101 | There is a similar approach to allow or deny specific USB interfaces. |
| 102 | That allows to block only a subset of an USB device. |
| 103 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 104 | Authorize an interface:: |
Stefan Koch | 7f59c15 | 2015-08-25 21:10:10 +0200 | [diff] [blame] | 105 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 106 | $ echo 1 > /sys/bus/usb/devices/INTERFACE/authorized |
| 107 | |
| 108 | Deauthorize an interface:: |
| 109 | |
| 110 | $ echo 0 > /sys/bus/usb/devices/INTERFACE/authorized |
Stefan Koch | 7f59c15 | 2015-08-25 21:10:10 +0200 | [diff] [blame] | 111 | |
| 112 | The default value for new interfaces |
| 113 | on a particular USB bus can be changed, too. |
| 114 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 115 | Allow interfaces per default:: |
Stefan Koch | 7f59c15 | 2015-08-25 21:10:10 +0200 | [diff] [blame] | 116 | |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 117 | $ echo 1 > /sys/bus/usb/devices/usbX/interface_authorized_default |
| 118 | |
| 119 | Deny interfaces per default:: |
| 120 | |
| 121 | $ echo 0 > /sys/bus/usb/devices/usbX/interface_authorized_default |
Stefan Koch | 7f59c15 | 2015-08-25 21:10:10 +0200 | [diff] [blame] | 122 | |
| 123 | Per default the interface_authorized_default bit is 1. |
| 124 | So all interfaces would authorized per default. |
| 125 | |
| 126 | Note: |
Mauro Carvalho Chehab | d80b500 | 2019-04-15 23:56:01 -0300 | [diff] [blame] | 127 | If a deauthorized interface will be authorized so the driver probing must |
| 128 | be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe |
Stefan Koch | 7f59c15 | 2015-08-25 21:10:10 +0200 | [diff] [blame] | 129 | |
| 130 | For drivers that need multiple interfaces all needed interfaces should be |
ThiƩbaud Weksteen | 77df6d8 | 2018-11-26 15:49:26 +0100 | [diff] [blame] | 131 | authorized first. After that the drivers should be probed. |
Stefan Koch | 7f59c15 | 2015-08-25 21:10:10 +0200 | [diff] [blame] | 132 | This avoids side effects. |