Skip to content

Latest commit

 

History

History
236 lines (175 loc) · 8.52 KB

PERMISSIONS.md

File metadata and controls

236 lines (175 loc) · 8.52 KB

Permission setup for beep

The beep command needs write access to the /dev/input/by-path/platform-pcspkr-event-spkr device special file which will be a symlink to the actual device special file called something like /dev/input/event20.

This device special file is created when the pcspkr.ko PC speaker driver kernel module is loaded. The permissions given to that device special file can be changed by adding some udev(7) rules.

The beep package suggests the udev rules mentioned in the sections Users currently logged into virtual console and All other users below are installed by distro package or manually by the system administrator.

Then the system administrator can easily give users access to the PC speaker device as described in the Add users to beep group section at the bottom of this file.

udev rules

udev rule basics

Whenever a new device is added to or removed from the system, the udev(7) system will apply its rules to the device.

Every rule consists of a part to match a particular type of device (with comparison operators such as ==), and a part which does something about that device, such as modifying or setting one or more variable (e.g. +=' or =`), which can change the device file's mode or ownership or file ACL.

See the sections below for example rules suggested for beep.

Where to install udev rules

There are two locations where udev(7) rules can be installed:

  • /usr/lib/udev/rules.d/*.rules or /lib/udev/rules.d/*.rules
    This is the distribution dependent directory where distribution binary packages will install their static rules which are not to be modified by the system administrator.

  • /etc/udev/rules.d/*.rules
    This where the system administrator will install their special rules independent of any distribution packages.

    This location is suitable when a system administrator is installing beep from source tree, or when the system administrator wants to install their own rules to override the distro package provided ones.

    This is also where a sysadmin can override a file from /usr/lib/udev/rules.d/ or /lib/udev/rules.d/ by creating a file of the same name in /etc/udev/rules.d/. This file can contain different udev rules, or be empty (or a symlink to /dev/null) to just disable the rules from that file.

Users currently logged into virtual console

Making use of modern GNU/Linux/freedesktop/etc. systems' session and udev magic, you can give the user logged into the currently active virtual console session access to the PC speaker by dropping the following rule into a udev rule file like /usr/lib/udev/rules.d/70-pcspkr-beep.rules or /lib/udev/rules.d/70-pcspkr-beep.rules (the exact location depends on your distribution):

# Give write access to the PC speaker to the user logged in on the current virtual console
ACTION=="add", SUBSYSTEM=="input", ATTRS{name}=="PC Speaker", ENV{DEVNAME}!="", TAG+="uaccess"

This allows beep to run for the user currently logged in locally without any user specific setup required.

However, it will not allow users logged remotely (e.g. via ssh) or processes running in the background to beep the PC speaker, unless the same user happens to be logged in on the currently active virtual console session at the time beep opens the device special file.

All other users

To allow beeping for users logged in remotely (e.g. via ssh) or processes running as any user other than the one logged into the currently active virtual console session, the best way is to set up a system user group beep and give that group write access to the device special file.

The exact command to add the group varies from system to system. Choose whatever works on your system:

[root@host ~]# addgroup --system beep    # Debian, Ubuntu, etc.

[root@host ~]# groupadd --system beep    # Fedora, RHEL, etc.

Now to allow writing to the device special file for members of the beep user group, you have the choice between the following two udev rules for /usr/lib/udev/rules.d/90-pcspkr-beep.rules or /lib/udev/rules.d/90-pcspkr-beep.rules (the exact location depends on your distribution).

  • This rule uses setfacl(1) to add an ACL entry to grant write access for the beep group without changing the standard user/group access granted by the default system setup:

    # Add write access to the PC speaker for the "beep" group
    ACTION=="add", SUBSYSTEM=="input", ATTRS{name}=="PC Speaker", ENV{DEVNAME}!="", RUN+="/usr/bin/setfacl -m g:beep:w '$env{DEVNAME}'"
    

    This ACL based rule requires installing the acl package on those distributions which do not install it by default yet.

    The nice part about just adding this one ACL is that it does not need to possibly interfere with whatever else the system does to the device, e.g. to implement the effects of TAG+="uaccess".

  • The following non-ACL rule grants access to the beep group by changing the owning group, removing access for the default group input:

    # Give write access to the PC speaker only to the "beep" group
    ACTION=="add", SUBSYSTEM=="input", ATTRS{name}=="PC Speaker", ENV{DEVNAME}!="", GROUP="beep", MODE="0620"
    

Verifying the udev rules work

You will have to (re-)load the pcspkr.ko module to (re-)add the device so that the new rule is invoked:

[root@host ~]# modprobe -r pcspkr; sleep 2; modprobe pcspkr
[root@host ~]# _

Check that the device has the desired permissions with ls and/or getfacl (getfacl only if you are using ACLs).

A working non-ACL setup might look something like

[root@host ~]# ls -lH /dev/input/by-path/platform-pcspkr-event-spkr
crw-rw----. 1 jane beep 13, 84 Apr  8 07:35 /dev/input/by-path/platform-pcspkr-event-spkr
[root@host ~]# _

and a working ACL setup might look something like

[root@host ~]# ls -lH /dev/input/by-path/platform-pcspkr-event-spkr
crw-rw----+ 1 root input 13, 84 Apr  8 07:35 /dev/input/by-path/platform-pcspkr-event-spkr
[root@host ~]# getfacl /dev/input/by-path/platform-pcspkr-event-spkr
getfacl: Removing leading '/' from absolute path names
# file: dev/input/by-path/platform-pcspkr-event-spkr
# owner: root
# group: input
user::rw-
user:jane:rw-
group::rw-
group:beep:-w-
mask::rw-
other::---

[root@host ~]# _

General rules for permissions setup

To keep your system secure, try to keep your permissions as restrictive as possible, while allowing for what you want. Give access to a single user. Give access to a special group of users.

Here are a few bad ideas you should avoid when you change the permissions setup:

  • DO NOT add users to the input group
    This would allow the users from the input group access to all input devices. This includes keyboards and mice which are none of their business (think keyloggers or reprogramming programmable keyboards).

  • DO NOT run beep setuid root or via sudo-root
    There have been a few serious security issues for beep in 2018 (CVE-2018-0492 and CVE-2018-1000532). Both had their impact when beep was run setuid root or via sudo-root.

    Therefore, beep now checks whether it is being run setuid root or via sudo-root, and if so, beep aborts without doing anything else, because that something else might turn out to be harmful. Also, this reminds people still using setuid-root or sudo-root setups to switch to the new more granular permission setup.

Add users to beep group

The suggested way to regulate permissions to the speaker device is to have the system administrator add all users who should be able to run beep to the beep group.

To add user jane to the beep group, the system administrator has to run a command like

[root@host ~]# usermod jane -a -G beep

After having user jane log out (and after killing user jane's running tmux instances, killing system --user sessions for user jane, or just plain rebooting), user jane can log back in and check whether she now is a beep group member:

[jane@host ~]$ id
uid=1000(jane) gid=1000(jane) groups=1000(jane),10(wheel),942(beep) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[jane@host ~]$ ./beep -f 220 -n -f 275 -n -f 330 -n -f 440 -n -f 550 -n -f 660 -n -f 880
[jane@host ~]$ _