Accessing a USB device with libusb-1.0 as a non-root user

Dan Gorman picture Dan Gorman · Nov 16, 2012 · Viewed 12.3k times · Source

I am trying to interface with a USB device as a non-root user on RHEL5. The device is a GPIO interface (its documentation can be found at http://www.xdimax.com/sub20/sub20.html) which uses libusb-1.0. The procedure for opening the device, using its API, is:

sub_device d;
d = sub_find_devices(0);
sub_handle h = sub_open(d);

When I do this, the sub_find_devices() call works, but on the sub_open() call, I get the libusb error -3, which indicates that I do not have permissions to open the device for writing.

I did some research on this problem, and found that I should create a udev rule. Using udevinfo on the device's sysfs node, I got:

looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2':
KERNEL=="2-1.2"
SUBSYSTEM=="usb"
SYSFS{configuration}==""
SYSFS{serial}=="15F2"
SYSFS{product}=="SUB-20"
SYSFS{manufacturer}=="XDIMAX"
SYSFS{maxchild}=="0"
SYSFS{version}==" 1.10"
SYSFS{devnum}=="6"
SYSFS{speed}=="12"
SYSFS{bMaxPacketSize0}=="64"
SYSFS{bNumConfigurations}=="1"
SYSFS{bDeviceProtocol}=="00"
SYSFS{bDeviceSubClass}=="00"
SYSFS{bDeviceClass}=="ff"
SYSFS{bcdDevice}=="0001"
SYSFS{idProduct}=="ffc3"
SYSFS{idVendor}=="04d8"
SYSFS{bMaxPower}=="100mA"
SYSFS{bmAttributes}=="80"
SYSFS{bConfigurationValue}=="1"
SYSFS{bNumInterfaces}==" 1"

I then created the following udev rule, in the file /etc/udev/rules.d/991-local.rules:

SYSFS{idVendor}=="04d8", SYSFS{idProduct}=="ffc3", NAME="sub20", GROUP="582", MODE="0660"

582 is the GID of a group that my normal user belongs to. I also tried the rule with the group name and it did not work. After creating this rule, the device file /dev/sub20 is created with the correct permissions, but only exists when the device is plugged in, which gives me reasonable confidence that the udev rule is matching on the correct device. However, my code still gets error -3.

Doing an strace on the code revealed this call:

open("/dev/bus/usb/002/006", O_RDWR)    = -1 EACCES (Permission denied)

The permissions on the /dev/bus/usb... node are still root:root, so maybe this is an indication that there is a problem with my udev rule, although I don't know what that could be.

If I try doing a call to open("/dev/sub20", O_RDWR), I get the return value ENXIO (No such device or address), another possible indicator of an error in the udev rule, although the /dev/sub20 file clearly is associated with the correct device somehow, since it only exists when the device is plugged in.

What else can I do to try and get this to work?

Answer

holgero picture holgero · Nov 30, 2012

The udev rules I use to be able to access devices with libusb look like this: SUBSYSTEMS=="usb", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="ffc3", SYMLINK+="sub20", GROUP="usb", MODE="660". It's supposed to just add a symlink to the device, but the permissions are also working for me afterwards (I am a member of the group usb).