by OK Ryoko, revision 2024-11-24.1
Assumed audience: Linux system administrators, Linux utility authors and Fedora Linux package maintainers. Familiarity with credentials, capabilities, syscalls, strace, Linux PAM and SELinux is assumed.
In this report, I build on the work described in SUID-root Binaries in Fedora Workstation 39. Once again, my goal is to characterize the SUID-root binaries present on the system and establish minimal file capability sets for those binaries.
I provide a high-level summary of outcomes in the “The findings at a glance” section.
Appendix A expands the abbreviations that appear in this report.
Appendix B presents metadata for the SUID-root binaries not covered in the main text.
- Characterization of environments
- Conventions for presenting results
- The SUID-root binaries in detail
- The findings at a glance
- Supporting information
- Feedback and support
- Funding sources
- Licensing
- Revision history
My findings are for an installation of Fedora Workstation 40 1.14, virtualized using the libvirt 10.6.0 API with the QEMU/KVM driver from the image obtained via the following torrent:
https://torrent.fedoraproject.org/torrents/Fedora-Workstation-Live-x86_64-40.torrent
This image had SHA256 checksum dd1faca950d1a8c3d169adf2df4c3644ebb62f8aac04c401f2393e521395d613.
When creating the virtual machine, I added a virtiofs shared file system so that I could extract traces and logs easily.
Here’s some basic system information:
user@fedora:~$ uname -a # a: all
Linux fedora 6.8.5-301.fc40.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Apr 11 20:00:10 UTC 2024 x86_64 GNU/Linux
SELinux is enabled and enforcing:
user@fedora:~$ sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Memory protection checking: actual (secure)
Max kernel policy version: 33
The selinux-policy-targeted-40.13-1.fc40.noarch package provides the loaded policy.
On the first boot of the new system, I created a single unprivileged and unconfined user who was configured automatically:
user@fedora:~$ id
uid=1000(user) gid=1000(user) groups=1000(user),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
By default, the Anaconda installer locks the root account:
user@fedora:~$ sudo passwd -S root # S: status
root L never 0 99999 7 -1
In a virtual console, my login shell had all capabilities in the bounding set and one capability in the inheritable set:
user@fedora:~$ cat /proc/$$/status | grep '^Cap'
CapInh: 0000000800000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
user@fedora:~$ capsh --decode=0000000800000000
0x0000000800000000=cap_wake_alarm
Nonlogin shells under GNOME Terminal had a full bounding capability set and no other capabilities:
user@fedora:~$ cat /proc/$$/status | grep '^Cap'
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
In either case, no securebits base or locked flags had been set. For example, in a login shell:
user@fedora:~$ capsh --print | grep '^Securebits'
Securebits: 00/0x0/1'b0 (no-new-privs=0)
I didn’t upgrade any packages on the system explicitly after the installation procedure.
I installed the following packages from the fedora repository to gain access to utilities and development headers for my analyses:
- bcc-0.29.1-2.fc40.x86_64 for the BPF Compiler Collection
- bcc-tools-0.29.1-2.fc40.x86_64 for the capable utility
- fuse-devel-2.9.9-21.fc40.x86_64 and fuse3-devel-3.16.2-3.fc40.x86_64 for FUSE development headers
- gcc-14.2.1-3.fc40.x86_64 for the GNU Compiler Collection
- pam-devel-1.6.0-2.fc40.x86_64 for PAM development headers
- setools-console-4.5.1-2.fc40.x86_64 for sesearch(1) and seinfo(1)
- strace-6.10-1.fc40.x86_64 for strace(1)
I disabled automatic software updates in GNOME Software to preserve the environment.
I examined the userhelper(8) program in the live environment, which differs from the system installed to a disk as follows:
- the host name is
localhost-live
; - the user name is
liveuser
, and - the root account is unlocked and has an empty password.
I obfuscated dates and times because they were irrelevant to the analyses.
I omitted all sudo(8) password prompts for brevity.
I normalized all hard tabs to spaces in command output.
I always had strace(1) write output to a file using the --output
option, which I omitted from reported commands because it doesn’t change the content of the trace.
In a virtual console, I searched the root file system for SUID-root binaries using find(1):
user@fedora:~$ sudo find / -ignore_readdir_race -perm /u=s -user root 2>/dev/null
/usr/bin/chage
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/fusermount
/usr/bin/fusermount-glusterfs
/usr/bin/fusermount3
/usr/bin/gpasswd
/usr/bin/mount
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/pkexec
/usr/bin/su
/usr/bin/sudo
/usr/bin/umount
/usr/bin/vmware-user-suid-wrapper
/usr/lib/polkit-1/polkit-agent-helper-1
/usr/libexec/dbus-1/dbus-daemon-launch-helper
/usr/libexec/openssh/ssh-keysign
/usr/libexec/spice-gtk-x86_64/spice-client-glib-usb-acl-helper
/usr/libexec/Xorg.wrap
/usr/libexec/libgtop_server2
/usr/libexec/qemu-bridge-helper
/usr/sbin/grub2-set-bootflag
/usr/sbin/mount.nfs
/usr/sbin/pam_timestamp_check
/usr/sbin/unix_chkpwd
/usr/sbin/userhelper
Unless stated otherwise, all these binaries have owner root
, group root
and mode -rwsr-xr-x
with no extended attributes other than security.selinux
.
Below, I discuss how these binaries have changed since prior work.
I defer mention of binaries that haven’t changed significantly since Fedora Workstation 39 with respect to my reference use cases to Appendix B.
- Program to administer user groups
- Provided by shadow-utils-2:4.15.1-1.fc40.x86_64
- Has SHA256 checksum 923048cba8f38267513e43f1e6de6a9e90f38a3f360360f49bcfcd451de881ad
- Has security context
system_u:object_r:groupadd_exec_t:s0
set by the usermanage 1.19.0 module
gpasswd(1) no longer forks into sss_cache(8) because the new default authselect(8) profile, local
, is not based on the sssd
profile.
- Program to update authentication tokens using PAM
- Provided by shadow-utils-2:4.15.1-1.fc40.x86_64
- Has SHA256 checksum 8004006b391f52f70d17d7bad800a89d16f2a37cfa473c7d5b83518ab2ddbdbd
- Has security context
system_u:object_r:passwd_exec_t:s0
set by the usermanage 1.19.0 module
This binary is now provided by the shadow-utils package. The passwd package has been removed.
Like gpasswd(1), passwd(1) tries unsuccessfully to set the hard limit on the maximum file descriptor that passwd(1) can open above the value in /proc/sys/fs/nr_open:
1876<passwd> prlimit64(0, RLIMIT_NOFILE, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}, NULL) = -1 EPERM (Operation not permitted)
Source:
sudo strace -u user -fyY passwd
, where-u
is short for--user
and-fyY
for--follow-forks --decode-fds=path --decode-pids=comm
Neither setting CAP_SYS_RESOURCE
on /usr/bin/passwd nor running passwd(1) SUID-root ensures the success of this operation.
- Program to execute a command as another user following authorization by Polkit
- Provided by polkit-124-2.fc40.x86_64
- Has SHA256 checksum 5f992eee0efa76f49100636e450a2664d80f7c18bd31c57d280a48d30ed33699
- Has security context
system_u:object_r:bin_t:s0
The PAM stack previously at /etc/pam.d/polkit-1 is now at /usr/lib/pam.d/polkit-1.
I previously used the following command to confirm that a process executed as the superuser by pkexec(1) will have full effective and permitted capability sets:
[user@fedora ~]$ pkexec getpcaps "\${BASHPID}"
This command no longer works. Instead, I now take the following approach:
user@fedora:~$ pkexec bash -ir # r: restricted
root@fedora:~# getpcaps $$
2034: =ep cap_wake_alarm+i
- Program to run a new shell or a command within a new shell as another user or group
- Provided by util-linux-2.40-0.9.rc1.fc40.x86_64
- Has SHA256 checksum ed35ef74178f8a6a3818ef6b7ad1f91501a03d3da9211a14091180ba5c12bb3d
- Has security context
system_u:object_r:su_exec_t:s0
set by the su 1.12.0 module
su(1) has not changed in a way that invalidates previously reported information. However, the steps to unlock root in order to test su(1) must be adjusted to accord with the new passwd(1) program’s CLI:
user@fedora:~$ sudo passwd -u root # u: unlock
user@fedora:~$ sudo passwd root
user@fedora:~$ sudo passwd -S root
- Program to run the VMware user process
- Provided by open-vm-tools-desktop-12.3.5-3.fc40.x86_64
- Has SHA256 checksum d05bb890deb63bee2b0a459e64d57648e529108d49b46b1682a2c973d2d671f6
- Has security context
system_u:object_r:vmtools_helper_exec_t:s0
set by the vmtools 1.0.0 module
Following a fix of CVE-2023-34059, vmware-user-suid-wrapper no longer drops privileges via setreuid(2) and setregid(2).
- Program to set a bootflag in the GRUB environment block
- Provided by grub2-tools-minimal-1:2.06-119.fc40.x86_64
- Has SHA256 checksum f17ab1e73f287666d7d555cb9813f59c453399c7ee9ea91bc48af7114618824b
- Has security context
system_u:object_r:bootloader_exec_t:s0
set by the bootloader 1.14.0 module
Following a revised fix of CVE-2019-14865, grub2-set-bootflag(1) now expects to run SUID-root unconditionally1 and calls setegid(2) in place of setuid(2) and setgid(2).2 In the strace(1) output, this appears as a setresgid(2) call:
2918<grub2-set-bootf> setresgid(-1, 0, -1) = 0
Source:
sudo strace -u user -fyY grub2-set-bootflag boot_success
The following modifications to this binary ensure the reproducibility of the previously reported procedure:
user@fedora:~$ sudo chmod u+s /usr/sbin/grub2-set-bootflag
user@fedora:~$ sudo setcap cap_setgid /usr/sbin/grub2-set-bootflag
1 In grub/util/grub-set-bootflag.c after applying the patches in src.fedoraproject.org/rpms/grub2@de8520b, main
exits with code 0 if the EUID is not 0 (lines 106–110)
2 main
exits with code 1 if it can’t set the EGID to 0 (lines 115–119)
- Helper for the
pam_unix
PAM module that verifies the running user’s password - Provided by pam-1.6.0-2.fc40.x86_64
- Has SHA256 checksum 43b67f438d04351436865cbfc51c36513d86d4d61a00cfcf27fd1078c0864271
- Has security context
system_u:object_r:chkpwd_exec_t:s0
set by the authlogin 2.5.1 module
unix_chkpwd(8) now restores both the UID(s) and GID(s) to the RUID and RGID, respectively, when dropping privileges.1 Previously, unix_chkpwd(8) restored only the UID(s) to the RUID.
1 Lines 105–121 in linux-pam/modules/pam_unix/[email protected]
I identified 27 SUID-root binaries on an installation of Fedora Workstation 40 1.14 to a VirtIO disk.
Over the course of prior work, I had already seen all of these binaries.
I identified one significant change: /usr/sbin/grub2-set-bootflag must now run SUID-root but requires only CAP_SETGID
to succeed.
In total, 11/27 SUID-root binaries required SUID-root execution to succeed. These were:
- /usr/bin/mount
- /usr/bin/passwd
- /usr/bin/pkexec
- /usr/bin/su
- /usr/bin/sudo
- /usr/bin/umount
- /usr/lib/polkit-1/polkit-agent-helper-1
- /usr/libexec/dbus-1/dbus-daemon-launch-helper
- /usr/sbin/grub2-set-bootflag
- /usr/sbin/mount.nfs
- /usr/sbin/pam_timestamp_check
To get a high-level idea of the privileges needed by the SUID-root binaries that come with Fedora Workstation 40, I tallied the file capabilities that I ended up setting to enable the reference use cases:
CAP_CHOWN ┤████████████████ 8
CAP_DAC_OVERRIDE ┤██████████████ 7
CAP_DAC_READ_SEARCH ┤████████ 4
CAP_FOWNER ┤████████ 4
CAP_SETGID ┤████████████ 6
CAP_SETUID ┤████████████████ 8
CAP_NET_ADMIN ┤██ 1
CAP_SYS_ADMIN ┤████████████ 6
CAP_SYS_RESOURCE ┤██ 1
CAP_AUDIT_WRITE ┤████████████████████ 10
API Application programming interface
BCC BPF Compiler Collection
BPF Berkeley Packet Filter
CC Creative Commons
CLI Command-line interface
CVE Common Vulnerabilities and Exposures
DAC Discretionary access control
EGID Effective GID
EUID Effective UID
FUSE Filesystem in Userspace
GCC GNU Compiler Collection
GECOS General Comprehensive Operating System
GID Group ID
GNU GNU’s Not Unix
GRUB Grand Unified Bootloader
ID Identifier
KVM Kernel-based Virtual Machine
NFS Network File System
PAM Pluggable Authentication Modules
QEMU Quick Emulator
RGID Real GID
RUID Real UID
SELinux Security-Enhanced Linux
SHA Secure Hash Algorithm
SPICE Simple Protocol for Independent Computing Environments
SSH Secure Shell
SUID Set-UID
UID User ID
USB Universal Serial Bus
VM Virtual machine
- Program to display and change user password expiry information
- Provided by shadow-utils-2:4.15.1-1.fc40.x86_64
- Has SHA256 checksum 22d89219771067b2898b1d7de943c4a428b5e6218eca6aa6612de67e48d5753b
- Has security context
system_u:object_r:passwd_exec_t:s0
set by the usermanage 1.19.0 module
- Program to change a user’s finger information, i.e., the GECOS field in /etc/passwd
- Provided by util-linux-2.40-0.9.rc1.fc40.x86_64
- Installed with mode
-rws--x--x
- Has SHA256 checksum ea64384b47ed2d0b6c36dab320b1f23a7f8eed1e9fd89b5a7b5993b68c4874cd
- Has security context
system_u:object_r:chfn_exec_t:s0
set by the usermanage 1.19.0 module
- Program to change a user’s login shell
- Provided by util-linux-2.40-0.9.rc1.fc40.x86_64
- Installed with mode
-rws--x--x
- Has SHA256 checksum 0ba1e67fc4aba1697a0dce245445760ef6bfffdbac7dea9251e6ef846818392e
- Has security context
system_u:object_r:chfn_exec_t:s0
set by the usermanage 1.19.0 module
- Program to mount and unmount FUSE v2 file systems
- Provided by fuse-2.9.9-21.fc40.x86_64
- Has SHA256 checksum 0a36f1e9adedf512fbc296ef863b25dd59c119054ceb669dc8d40b2f1ad4bb2d
- Has security context
system_u:object_r:fusermount_exec_t:s0
set by the mount 1.16.1 module
- Program to mount and unmount Gluster file systems
- Provided by glusterfs-fuse-11.1-3.fc40.x86_64
- Has SHA256 checksum 5eb194e6fef11135c2a4f7f74be564faa6267b411adb43aeaca04c150fb94198
- Has security context
system_u:object_r:bin_t:s0
- Program to mount and unmount FUSE v3 file systems
- Provided by fuse3-3.16.2-3.fc40.x86_64
- Has SHA256 checksum 09e38564776080c99d7122262bde107acf3ecb216c5115f2637ab4a03a729430
- Has security context
system_u:object_r:fusermount_exec_t:s0
set by the mount 1.16.1 module
- Program to mount file systems
- Provided by util-linux-core-2.40-0.9.rc1.fc40.x86_64
- Has SHA256 checksum 60aeec78c87b098c124b666dcd55fea29aa0d1b0b067cfef1804d83b26e573bd
- Has security context
system_u:object_r:mount_exec_t:s0
set by the mount 1.16.1 module
- Program to change the GIDs during a login session
- Provided by shadow-utils-2:4.15.1-1.fc40.x86_64
- Has SHA256 checksum 32958f01b2d0382caf6ec7f0f32c1cc1f29a01072c47ad4aaee20e5b23975d25
- Has security context
system_u:object_r:bin_t:s0
- Program to execute a command as another user or group in a configurable manner
- Provided by sudo-1.9.15-2.p5.fc40.x86_64
- Installed with mode
---s--x--x
- Has SHA256 checksum 26b3f9a3af73ee38aefd9f0c9b964bb3abf1bb5582cca43b2f305f6ddc2bb5c8
- Has security context
system_u:object_r:sudo_exec_t:s0
set by the sudo 1.10.0 module
- Program to unmount file systems
- Provided by util-linux-core-2.40-0.9.rc1.fc40.x86_64
- Has SHA256 checksum 17c27cb0e651d80183e6915e1393d87a065ef68b66d8ab7b1e41c870494031cf
- Has security context
system_u:object_r:mount_exec_t:s0
set by the mount 1.16.1 module
- Polkit agent helper to re-authenticate a user
- Provided by polkit-124-2.fc40.x86_64
- Has SHA256 checksum e01afde2db84328138af43c057553aa7c3cd592125b936067b3ee84f3b2a18e7
- Has security context
system_u:object_r:policykit_auth_exec_t:s0
set by the policykit 1.3.0 module
- Program to help dbus-daemon(1) start a D-Bus service on demand as another user
- Provided by dbus-daemon-1:1.14.10-3.fc40.x86_64
- Installed with group
dbus
and mode-rwsr-x---
- Has SHA256 checksum 4865ffabf942d07c97d03bd86421d4993f35fcbdb23a11b9462606702c46757d
- Has security context
system_u:object_r:dbusd_exec_t:s0
set by the dbus 1.19.0 module
- OpenSSH helper for host-based authentication
- Provided by openssh-9.6p1-1.fc40.2.x86_64
- Installed with mode
-r-sr-xr-x
- Has SHA256 checksum f3508d697a8ac362f9d5632e4bf982d0ea46a19fc62c30f1b56c827f9afa4c94
- Has security context
system_u:object_r:ssh_keysign_exec_t:s0
set by the ssh 2.4.2 module
- SPICE helper for USB redirection
- Provided by spice-glib-0.42-4.fc40.x86_64
- Has SHA256 checksum e818b8ce6fb01eb44603c829ecb52a1a2062c01e0630dc482a2de71c01a88a3f
- Has security context
system_u:object_r:bin_t:s0
- Program to run Xorg(1), the reference implementation of the X Window System, possibly as root
- Provided by xorg-x11-server-Xorg-1.20.14-32.fc40.x86_64
- Has SHA256 checksum accea7f4ed384263bb1b8f4586d91831e2045e4041c022908ea43b6e941085c5
- Has security context
system_u:object_r:xserver_exec_t:s0
set by the xserver 3.9.4 module
- Program to collect system monitoring data, e.g., resource usage
- Provided by libgtop2-2.41.3-1.fc40.x86_64
- Has SHA256 checksum acc9fab6b55321aa882105a924afb7512687b3218042f2707fe4bede0653675e
- Has security context
system_u:object_r:bin_t:s0
- QEMU helper to let unprivileged users connect a QEMU VM to a bridged network interface
- Provided by qemu-common-2:8.2.2-1.fc40.x86_64
- Has SHA256 checksum 461eb9627e9ae2a8d8e3dd4860cf3383c30d136c0af505eff0af5f52eeb8e738
- Has security context
system_u:object_r:virt_bridgehelper_exec_t:s0
set by the virt_supplementary 1.5.0 module
- Program to mount NFS file systems
- Provided by nfs-utils-1:2.6.4-0.rc5.fc40.x86_64
- Has SHA256 checksum 7acd87c3aff520b441cab4614846dee4df0cc548e9302e99f666a0cd7094a102
- Has security context
system_u:object_r:mount_exec_t:s0
set by the mount 1.16.1 module
- Program to validate or remove the default timestamp (for cached authentication results)
- Provided by pam-1.6.0-2.fc40.x86_64
- Has SHA256 checksum 08d7f9bc8b84c345b0c0cb145a2a6d1280e71fef9d40cadc3ba4d47061b12d11
- Has security context
system_u:object_r:pam_timestamp_exec_t:s0
set by the authlogin 2.5.1 module
- Program to help other programs interface with PAM
- Provided by usermode-1.114-9.fc40.x86_64
- Installed with mode
-rws--x--x
- Has SHA256 checksum e56fa96841c9ac34230b7f6e1e75083ab66040e9f4056cbe90c1b63fa51af0da
- Has security context
system_u:object_r:userhelper_exec_t:s0
set by the userhelper 1.8.1 module
Please connect with me if you have constructive comments about this article, especially if you have a use case I didn’t cover or are unable to reproduce a procedure in an identical environment.
I will maintain this article until Fedora Linux 40 reaches end of life on 28 May 2025.
The author acknowledges private funding by one anonymous sponsor.
All original copyrightable content in this document is marked with CC0 1.0 Universal.
- Clarify setegid(2) call made by grub2-set-bootflag(1)
- Update capabilities histogram to accord with new findings for Fedora Workstation 39
- Expand BCC and GCC abbreviations in Appendix A
Initial revision