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.
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
.
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.
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.
To allow beep
ing 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 thebeep
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 groupinput
:# 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"
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 ~]# _
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 theinput
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 forbeep
in 2018 (CVE-2018-0492 and CVE-2018-1000532). Both had their impact whenbeep
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.
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 ~]$ _