A I’ve been working on a little side project that uses a PC’s audio port to read the control signals from a radio control transmitter via the PC’s audio input and use it to control a virtual joystick. I had to do a refresher on how Linux handles input devices and search for what C libraries and Python module were available. I found python’s uinput and evdev modules would fit my need. However, these modules require root privileges on most Linux systems. So I needed some kind of workaround to allow normal users to access the virtual input device. This is what I came up with to solve my issues.
By default, on most *nix systems, only the root user has permission to access the uinput device. However, I learned that you can allow non-root users to access the uinput device by creating a udev rule.
Before we begin I want to point out that in the code windows below I have user the ‘#’ (hash/pound) symbol to represent the root user is running the command. I also use the ‘$’ (dollar) symbol to represent when a normal user is running the command.
Let’s get started! Here are the steps to create a udev rule:
Open a terminal and create a new file in the /etc/udev/rules.d/ directory. Name the file “99-input.rules”:
$ sudo touch /etc/udev/rules.d/99-input.rules
Add the following rule to the file:
KERNEL=="uinput", MODE="0660", GROUP="input" This rule sets the permissions of the uinput device to allow read and write access for users in the “input” group.
# echo "KERNEL=="uinput", MODE="0660", GROUP="input" > /etc/udev/rules.d/99-input.rules
Reload the udev rules by running the following command:
# udevadm control --reload-rules
Add your user to the “input” group by running the following command:
# usermod -a -G input <username>
Next we need to check that our user is in the input group. Close the terminal and open a new one, as the user who needs input access to the uinput device and run:
This should return a list of groups the current user is in. If you do not see “input’ in the list, something has gone wrong. We can try again with:
$ sudo newgrp input
Now the groups should exists, so now go back and run the ‘usermod’ command above once more. Then verify you are in the input group by opening a new terminal and running the groups command again.
Now we need to make sure our input group has permissions to access the /dev/uinput device:
$ sudo chmode 0660 /dev/uinput $ sudo chgrp input /dev/uinput
These commands will change the permissions and groups for the /dev/uinput device. Now log out and back in, and your user should have access to uinput devices. After completing these steps, your user should have access to the uinput device without root privileges. You can check this with the command:
$ ls -l /dev/uinput
This should give you the following output:
$ crw-rw---- 1 root input 10, 223 Apr 28 21:02 /dev/uinput
If you should see the the ‘-rw’ right after the ‘crw’. This indicates that a group has read (r) and write (w) privileges for the /dev/uinput device.
Before I go, I am documenting this here for myself and others who may find it useful. But I should mention that allowing users access to input devices can create security issues and care must be taken to ensure you know where the input is coming from and that it is sanitized before sending it to any input device. However, for many projects this will be helpful. But you have been warned! Use at your own risk without warranty of any kind!