I had a problem with my scanner. Xsane worked only as root. Using it as normal user it didn't find any devices. Adding the user to the groups saned or scanner didn't help.

Finally I solved the problem by changing

# 'libusb' device nodes
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664"


# 'libusb' device nodes
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0666"

in /lib/udev/rules.d/50-udev-default.rules

However I do not understand why this works and if it has any negative side effects. I guess that this gives write permissions to all users on any usb device, but I don't know if and why this is correct and why this solves the scanner problem.

Could anyone explain in detail why this works and whether it has any side effects.

My system is: ubuntu 12.04, the scanner is a HP PSC 1200 all in one device hplip is installed from the repository.

  • Ugh, twain scanners are an abomination.
    – Tim
    Jul 30, 2012 at 16:42

3 Answers 3


It seems that Udev (which is in the man) manages dynamic devices like USB devices when they're plugged in. It'll then instantiate them in /dev somewhere. (Like /dev/bus/usb/002 in my case.) This /dev node has to have some permissions, Udev takes the permissions from the files in /lib/udev/rules.d/, there's some arcane syntax which matches a device to an entry.

In this case anything from the usb subsystem with a type of usb_device gets the file mode specified. (Standard permissions, 664 is rw-rw-r--, 666 is rw-rw-rw-.) So you're giving all and sundry write permissions to all usb devices. This does not sound like a good thing, if you don't trust all your users. If you're the only user, you can probably trust yourself. Libusb seems to want write permissions to the usb device node to do its thing, and refuses to do anything if it doesn't. That sounds not quite right as I'm only trying to read from the device.

It is possible to be more specific with the permissions, you can specify a device by things like USB vendor (VID) and product ID (PID). So it would be possible to make a file which would work for just your scanner, and leave all other USB devices with the default permissions. There's a page about Udev at https://wiki.archlinux.org/index.php/udev which looks useful for all this. If you make a file which starts with a higher number, like "60-my-usb-scanner.rules" (higher numbers take priority) and have a rule which lists you scanner like:

SUBSYSTEM=="usb", ATTRS{idVendor}=="F1E2", ATTRS{idProduct}=="1F2E", MODE="0666"

That should just set the permissions for the device specified (VID=0xF1E2, PID=0x1F2E). You can then make Udev take notice of this change by executing:

udevadm control --reload-rules
  • 2
    A note for the latecomer: those hex numbers in the attributes are probably in lowercase! It didn't work for me until I saw the same attributes as udev, which you see using this command: udevadm info -a -p $(udevadm info -q path -n /dev/bus/usb/001/009)
    – oligofren
    Sep 7, 2018 at 0:15
  • I also find it only working while I use lowercase for those hex numbers.
    – chunjiw
    Apr 8, 2019 at 7:19

libusb is designed to allow user-space drivers for USB devices: in other words, it allows applications to send commands libusb itself does not understand to the device.

As a result, libusb must treat any data that passes from the computer to the USB device as a write operation. This includes even trivial writes, like sending a command for the scanner to describe its scanning capabilities.

Read-only access to libusb devices would only work with devices which will spontaneously send data to the computer, like a keyboard or mouse.


Just sharing an answer that works for me.

OS: Ubunutu 20.04

To find the corresponding attributes that can be used to filter out the device, first use lsusb to find what your device is in the /dev/bus/usb:

Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 003: ID 13d3:56d5 IMC Networks Integrated Camera
Bus 003 Device 002: ID 0fc5:b080 Delcom Engineering USB FS IO # <-- My device

Then, use the command udevadm info -a -n /dev/bus/usb/<bus_num>/<device_num>(in my case udevadm info -a -n /dev/bus/usb/003/002) to acquire the udev rules key table. Because the table will walk through parent devices, the first device should be the one you want.

looking at device '/devices/pci0000:00/0000:00:08.1/0000:04:00.4/usb3/3-2':
ATTR{product}=="USB FS IO"
ATTR{bNumInterfaces}==" 1"
ATTR{version}==" 2.00"
ATTR{manufacturer}=="Delcom Products Inc."   # <--- help me id the device

Keep in mind that to set the rule you need to use the exact format provided here, i.e., if it is SUBSYSTEM=="usb" and ATTR{idVendor}, it should be the format in your .rules file, not SUBSYSTEMS=="usb" and ATTRS{idVendor}.

Finally, create your own udev rule with sudo <editor_you_like> /etc/udev/rules.d/<order_to_be_executed>-<hint_name>.rules. For me, I use 99-Delcom_dev.rules because I want it to be executed later than other rules and can easily remind me what this rule is about. In the rule file write something like:

SUBSYSTEM=="usb", ATTR{idVendor}=="0fc5", ATTR{idProduct}=="b080", MODE="0666"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.