Skip to content

TIPS: Rootless Write Access to USB Devices with udev rules

mounaiban edited this page Mar 8, 2022 · 1 revision

Background

Write access to USB printers is required for successful printing.

Attempts to establish write access to USB printers may be denied by the operating system due to insufficient privileges. A quick fix is to retry the operation as root or any other superuser, but this carries a risk of triggering attacks or an accidental corruption of important system configuration information.

Write access to USB devices can be enabled in a safer manner with udev rules.

Write Access to USB Devices

By default, write access to USB devices are restricted to prevent rogue actors from exploiting weaknesses which may be found in USB devices. With udev rules, write access may be enabled on a per-device basis.

Creating the udev Rule

To enable rootless write access a USB devices, a rule has to be established under udev. This is done by creating a plain text file in the /etc/udev/rules.d/ directory, and filling it with rules which are written in a declarative language.

Files must have a name that end with .rules to be considered by udev, and should be prefixed with a number followed by a single hyphen, to aid with sorting, which ultimately determines the precedence of the rules. A rules file named 69-hp-laserjet.rules has precedence over 99-canon-lbp.rules

In this example, a rule for a USB printer has been added to a file, /etc/udev/rules.d/99-lbp3k-qemu-rootless.rules, with only a single entry:

ACTION=="add",SUBSYSTEMS=="usb",ATTRS{idVendor}=="04a9",ATTRS{idProduct}=="1337",MODE="0666"

PROTIP: Please pay attention to the single equal between MODE and "0666". Under the udev rule language, MODE is a variable-setting operation, while the others are lookup operations.

PROTIP: If the system seems to ignore the rules file, it may be because the number at the beginning of its name is too low. Try numbers from 60 and 69 inclusive.

This effectively opens up a USB device with a vendor-product ID of 04a9:1337 to write access by all users on the system. Replugging or power-cycling the USB device may be necessary for the new rule to take effect.

Obtaining the product and vendor IDs

The product-vendor ID of a USB device may be obtained by running lsusb, as seen in the example below:

$: lsusb
...

Bus 001 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 008: ID 04a9:1337 Canon, Inc. CAPT Device

Trivia

The MODE setting in this example directly controls the permissions of the device's file. Recall that the printer was connected on Bus 001, as Device 008. This makes the device's corresponding file /dev/bus/usb/001/008.

Also recall that we have set the device permission to "0666" in udev, which means read and write for all users. Verify that fact by listing the device file:

$ ls -l /dev/bus/usb/001/008
crw-rw-rw-. 1 root lp 007, 20 Mar 20 00:00 /dev/bus/usb/001/008 

When the rule is removed, by commenting it out in the rules file or deleting it outright, the permissions should revert to locking out non-privileged users when the device is reconnected:

$ ls -l /dev/bus/usb/001/008
crw-rw-r--. 1 root lp 007, 20 Mar 20 00:00 /dev/bus/usb/001/008 

PROTIP: This corresponds with a mode of 664

With root privileges, one can subvert this using chmod, at least until the device is reconnected...

When Do I Need To Do This?

The udev rules may help with the following access issues:

Using a USB printer with a QEMU VM

A USB printer will not be usable in a VM without write access. If QEMU was started from a terminal, this problem is usually accompanied by repeated error messages if the terminal is receiving messages from stderr, like:

libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/001/008: Permission denied
libusb: error [_get_usbfs_fd] libusb requires write access to USB device nodes.
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/001/008: Permission denied
libusb: error [_get_usbfs_fd] libusb requires write access to USB device nodes.
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/001/008: Permission denied

...

Programs Using libusb

Attempts to establish a device handle or to send any data to a USB device may fail with a LIBUSB_ERROR_ACCESS (-3) code.

References

Greg Kroah-Hartman, Kay Sievers, Dan Stekloff, et. al. udev: Linux Dynamic Device Management. Accessed 2020-03-20.

Libusb Documentation. Miscellaneous.

Linux Gazette. udev rules ca't [sic] auto mount my pen drive. Accessed 2020-10-15.

This 2009 letter published on The Linux Gazette offers a good explanation on how the number prefixes on names of the rules files should be used. The unfortunate typo in the title may prevent it from appearing in search engine results, depending on the search terms used.

Mike Szczys. How To Write Udev Rules. Accessed 2020-10-15.

Bookmarks

Installation Guide

Targeted Printers

Essential Test Suite

Unofficial Introduction to CAPT (Executive Summary)

Support Levels

Rootless Write Access To USB Devices

Miscellaneous Tips

Wishlists

Other Canon Printer-Related Projects

SPECS: 0xA1A1 Command and Response Format

Home Page

Search for pages starting with

  • SPECS for notes on the operation of the CAPT data formats and communications protocol
  • TESTING for guidelines on testing Captdriver
  • TIPS for potentially helpful information on studying the project or the CAPT format-protocol
Clone this wiki locally