123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- Linux specific installation information
- by Linus Walleij
- covering libusb 0.1.10
- ========================================
- Since libusb is accessing the raw device nodes exported by the kernel
- in order to identify connected USB busses, functions and such, it
- needs to find these nodes. During the history of the Linux kernel,
- the placement and the way of accessing these nodes have changed.
- This placement is closely related to hotplugging: i.e. addition and
- removal of USB functions at runtime.
- Most current solution: use udev
- ===============================
- The latest and greatest way of managing hotplugged (and cold-plugged)
- devices under Linux is called "udev". This is a development of the
- older "hotplug" system (see below).
- When a device is connected, the kernel will call the program
- /sbin/udev in order to create a device node in the /dev/ file
- hirerarchy. It will also remove devices from this hierarchy when
- they are unplugged.
- Traditionally, all devices plugged into a Linux system are expected
- to have a kernel device driver, or to load one on-the-fly when a
- new device is connected. Libusb cannot use these device drivers,
- instead it attempts to access the raw device nodes from user mode,
- not as a kernel module.
- In order for libusb to find the device node, it needs to locate it
- in the /dev filesystem. The recommended way to let udev create nodes
- in the /dev filesystem is to add a udev rule like the following into
- some foo.rules file inside the /etc/udev/rules.d/ directory:
- # usbfs-like devices
- SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; \
- printf bus/usb/%%03i/%%03i $${K%%%%.*} $${K#*.}'", \
- NAME="%c"
- This layout is used by for example the Debian distribution and Fedora
- Core. This rule creates a device tree identical to the earlier
- /proc/bus/usb/ tree, but under /dev/bus/usb/ instead. If this device
- tree exists, libusb will default to use it. It will look like this:
- /dev
- /bus
- /usb
- /001
- /001
- /002
- /003
- /002
- /001
- /002
- ...
- However notice that the permissions on the nodes will be default
- permissions: often this means they are only accessible for writing
- by the root user, whereas non-root users often can access it
- read-only.
- The way of controlling access to a device node differs between
- systems, but a typical way of complementing udev rules with
- apropriate permissions is to use PAM (pluggable Authentication
- Modules), with some sort of configuration under /etc/security/.
- (For details on this, see below.)
- The use of /dev nodes is also different from the old usbfs
- solution in that it enables the use of ACL:s (Access Control
- Lists) to control access for the USB device nodes. ACL:s could
- not be used on the /proc filesystem.
- A less good alternative that may however be useful for debugging
- would be to supply the argument MODE="666" to the above udev
- rule, or, slightly better, to tag on:
- MODE="660", GROUP="foo"
- where "foo" is a group of users (e.g. desktop users) that need
- to access the device in read/write mode.
- If libusb cannot find a device hierarchy below /dev/bus/usb/
- (as is the case if you are not using udev, or not using it with
- the above rule), it will fall back on using /proc/bus/usb/
- instead.
- Additionally, you may want to trigger unique actions for your
- device at the same time. To do this, create a rules file
- /etc/udev/rules.d/bar.rules with these lines:
- SUBSYSTEM=="usb_device", ACTION=="add", SYSFS{idVendor}=="1234", \
- SYSFS{idProduct}=="4321"
- At the end of this line you can then tag on any device-specific
- actions for device 1234/4321, for example:
- MODE="660", GROUP="baz" to set mode and group
- RUN="/usr/local/bin/baz" to run a script on plug-in
- SYMLINK+="foo" to create a symlink device node with
- this name in /dev
- You can read more about udev in its own documentation.
- Permissions setting with PAM
- ============================
- In addition to the udev rule for creating the device node you
- will want to change the permissions on the new node, unless it
- defaults to something that is globally writeable and readable.
- Making anything that is plugged in on the USB bus writeable and
- readable by ALL users is typically a bad idea, because what you
- most typically want to do is to make it writeable and readable
- for the console user, i.e. the person that happens to sit behind
- the screen and keyboard of this very computer.
- Managing this by groups is a bit kludgy: it means you set up a
- group for all console users and add all users that may use the
- console to this group. This also mean that one user that is a
- member of this group could be at the console plugging his USB
- keydrive in, while another user of the same group is logged in
- remotely, and making a blank copy of the same keydrive at the
- same time, for example.
- Since Linux is used in a strict multi-user context, this has to
- be solved: give permissions to hotplugged devices only to the
- console user.
- Fedora Core 5 and later does this by using PAM. Whenever
- something happens in udev, PAM is called to modify the
- permissions on anything that appeared in the file system in
- accordance to a set of security rules.
- The trick is to create a symbolic link for your new device,
- then let PAM match the name of this link and change the
- permissions of it. For example, in /etc/udev/rules.d/foo.rules
- you write:
- SUBSYSTEM=="usb_device", ACTION=="add", SYSFS{idVendor}=="1234", \
- SYSFS{idProduct}=="4321", SYMLINK+="foo-%k"
- This will create a symlink named "/dev/foo-nn" where nn is some
- unique number for each added device matching this VID and PID.
- You then set up PAM console rules in accordance, by adding
- a /etc/security/console.perms.d/foo.perms containing:
- <foo>=/dev/foo*
- <console> 0600 <foo> 0600 root
- This instructs PAM to give the console user (and root) read and
- write permissions to the new symlink, whenever it appears. The
- permission change on the symlink will then fall through to the
- new device node.
- Previous solution: use hotplug
- ==============================
- Before udev another system, generally considered less elegant,
- known simply as "hotplug" was used. In this case the program
- /sbin/hotplug would be called whenever devices were connected
- or removed from the system, and the corresponding configuration
- lives in /etc/hotplug/.
- With hotplug not using udev at the same time, all devices are
- accessed using the usbfs hierarchy below /proc/bus/usb/. Again,
- this will be used by libusb, since libusb does not use any device
- drivers. The hierarchy will look like this:
- /proc
- /bus
- /usb
- /001
- /001
- /002
- /003
- /002
- /001
- /002
- ...
- When USB devices are plugged in, their corresponding device
- node is created in /proc/bus/usb/ by the kernel, without any
- external program intervention (as is the case with udev).
- However, to correct the permissions on these device nodes, if
- your device requires anything else than read access, you need
- to supply a script in /etc/hotplug/usb/ that detects your
- device and change its permissions, for example this
- /etc/hotplug/usb/foo.usermap
- # Foo device with VID=1234 and PID=4321
- bar 0x0003 0x1234 0x4321 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
- (All this need to be in one line.)
- The first string "bar" points out the name of a script placed
- in /etc/hotplug/usb/bar, with for example the following contents:
- #!/bin/bash
- if [ "${ACTION}" = "add" ] && [ -f "${DEVICE}" ]
- then
- chgrp baz "${DEVICE}"
- chmod 660 "${DEVICE}"
- fi
- to let users in the group "baz" access the device for reading
- and writing. There exist solutions similar to the PAM permission
- change for hotplug, but they are all kind of hackish.
- You can read more about hotplug and its usermaps in the
- hotplug documentation.
|