SUID Disabler and Permission Hardener

1 Like

The only missing feature is: if suid / sgid was already removed during a previous run of the service and the user adds it to exactwhitelist of machwhitelist after that, it will not be re-enabled suid / sgid.

An easy fix would be to tell users “boot into admin mode”, run /usr/lib/security-misc/permission-hardening-undo and reboot. But this is a bit unsafe if other services are already started. “boot into admin mode” should probably mean “don’t start any services such as web services”? Will discuss in multiple boot modes for better security: persistent user | live user | persistent secureadmin | persistent superadmin | persistent recovery mode

We could auto-restore permissions for later added whitelist entries since permission before change are recorded in /var/lib/permission-hardening/existing_mode.

if [ "$mode_from_config" = "exactwhitelist" ]; then

could check /var/lib/permission-hardening/existing_mode. Same for

if [ "$mode_from_config" = "matchwhitelist" ]; then

But not sure if worth the effort.

1 Like

Should it do that anyway? The point of those options are for whitelisting, not adding back permissions. This doesn’t seem needed.

1 Like

fuse: failed to exec fusermount: Permission denied

Cannot mount AppImage, please check your FUSE setup.
You might still be able to extract the contents of this AppImage
if you run it with the --appimage-extract option.
See FUSE · AppImage/AppImageKit Wiki · GitHub
for more information
open dir error: No such file or directory

To fix:

sudo chmod +sx /bin/fusermount
1 Like
1 Like

Really bad bug disabling sudo. Unexplained. Non-reproducible. Not a full disk issue, plenty of free space.

Dec 29 04:17:11 debian-buster-test permission-hardening[413]: INFO: START parsing config_file: ‘/etc/permission-hardening.d/30_default.conf’
Dec 29 04:17:12 debian-buster-test permission-hardening[413]: /usr/lib/security-misc/permission-hardening: line 255: cannot create temp file for here-document: No such file or directory
Dec 29 04:17:12 debian-buster-test permission-hardening[413]: ERROR: cannot parse line: /usr/bin/sudo exactwhitelist

Probably better to abort processing the config file and immediately exit with error when that happens. Will implement that.

1 Like

Did that. And probably found the cause:

1 Like

Found bug.

/usr/bin/torbrowser: line 252: /bin/mount: Permission denied
/usr/bin/torbrowser: line 270: /bin/mount: Permission denied

/usr/bin/torbrowser (by Whonix developers) uses mount to check if Tor Browser folder is mounted noexec.

/bin/mount is SUID by Debian default.

Therefore /bin/mount makes sense as executable but with SUID removed.

1 Like


Not an ideal solution. First add /bin/mount to exactwhitelist and then below set /bin/mount 745 root root. A unintuitive config. But good enough for now?

1 Like

Anyone got time to read?

Needs a call for testers.

Polishing a few things just now.

1 Like

I think there are two security issues with SUID.

  • A) As I’ve added to the wiki just now Some SUID binaries have a history of privilege escalation security vulnerabilities..
  • B) General attack surface such as kernel attack surface.

What SUID Disabler and Permission Hardener is currently doing is disable as many SUID binaries as reasonable without breaking a Linux desktop operating system. Improving the situation for A)

To however have the full benefit, to do B) we would have to eliminate all SUID binaries. This might be reasonable and doable for CLI environments such as servers ( also think Kicksecure).

What do you think?

If you agree, I guess the configuration file of SUID Disabler and Permission Hardener should be split. The whitelist should be in a separate file. Then a system administrator could easily nuke the whitelist. Alternatively or additional perhaps a ignore_whitelist=true configuration option would be useful? Then we could document this and some users could benefit from a completely SUID free system.

1 Like

Improved documentation:

Moved to dedicated wiki page:

Please review.

1 Like

More documentation enhancements:
SUID Disabler and Permission Hardener: Difference between revisions - Whonix

1 Like

Should we add

  • /opt/ nosuid
  • /usr/local/opt nosuid


Rationale for /opt is that some manually installed software installs itself to /opt. Some lesser important functionality might require suid or sgid. The suid/sgid bit might have been accidentally set by a developer. (Or part of legacy install scripts. Useful in past, then forgotten, now obsolete.) Removal of suid / sgid might in many cases go unnoticed by the user. (In cases where that software is run as root anyhow.)

On the other hand, the /opt folder is empty on a default Debian (based) installation. One could argue if the (super) admin installs files there it should be honored by the system and kept unobstructed.

I guess it depends if (re-)mount home [and other?] with noexec (and nosuid [among other useful mount options]) for better security? would re-mount /opt with nosuid anyhow?

Other folders where suid binaries might end up?

  • /home?

But adding that I guess would be excessive because:

Also /root? Depends on outcome of this post SUID Disabler and Permission Hardener - #65 by Patrick - A) vs B).


  • /mnt?
  • /media?
  • Any others?
1 Like

It can be done for GUI environments also. Nothing really requires setuid. We can replace them with capabilities.

The admin could whitelist their binaries.

Unlikely. We could cover /root since that’s a bit more likely to contain suid binaries and it wouldn’t increase scan time much since most users would be storing their files in an unprivileged user’s home directory.

That would break a lot of things. For example, if I mounted a drive containing another Linux system to /mnt in order to debug an issue, permission hardener would kill all suid binaries in it and become extremely slow. A better solution would be mounting those filesystems with the nosuid option since it’s much easier to revert (mount -o remount,suid /mnt vs. resetting all file permissions).


Nice changes by @madaidan:
SUID Disabler and Permission Hardener: Difference between revisions - Whonix

Inspired me to improve a bit more:
SUID Disabler and Permission Hardener: Difference between revisions - Whonix

Great idea!

dpkg-statoverride does not support that yet. feature request: dpkg-statoverride: support for capabilities

Meaning there might be no standard way in which packages implement setting capabilities yet. Therefore I wanted to look at a package that sets capabilities. For example package iputils-ping contains capability enabled binary ping. From the package postinst script:



set -e

if [ "$1" = configure ]; then
    # If we have setcap is installed, try setting cap_net_raw+ep,
    # which allows us to install our binaries without the setuid
    # bit.
    if command -v setcap > /dev/null; then
        if setcap cap_net_raw+ep /bin/ping; then
            chmod u-s /bin/ping
            echo "Setcap failed on /bin/ping, falling back to setuid" >&2
            chmod u+s /bin/ping
        echo "Setcap is not installed, falling back to setuid" >&2
        chmod u+s /bin/ping

exit 0

# Local variables:
# mode: shell-script
# tab-width: 4
# indent-tabs-mode: nil
# end:

dpkg -S /sbin/setcap

libcap2-bin: /sbin/setcap

cat debian/control | grep cap

Recommends: libcap2-bin

So if libcap2-bin does not get installed early enough (before iputils-ping) is installed, the Debian maintainer script will set SUID instead of using capabilities. Assuming that other packages might be implemented in a similar way, we should find a way to make sure package libcap2-bin is installed during the build process as early as possible.

Other random examples having a similar use of setcap:

grep -rl setcap /var/lib/dpkg/info


Meanwhile for packages by Whonix or Kicksecure we can just add Depends: libcap2-bin in debian/control and run setcap during postinst.

Happy to work towards a completely SUID / SGID free by default system. Worthwhile development goal to even get rid of Whonix / Kicksecure requiring sudo / any /etc/sudoers.d exceptions?

Would be specifically interesting in context of:

Now this list of sudoers exceptions needs to be ported to capabilities.


Help welcome!

Would we need a wrapper around setcap? Because mentions several conditions under which setcap can fail.

  • Take into account systems no supporting fcaps, this includes:
    • (for now) non-Linux systems,
    • Linux w/ old kernels or kernels w/o fcap compiled in,
    • file systems not supporting fcaps, and/or w/o mount time enabled

Or don’t care much about this and just ignore errors using setcap [...] || true?

Added to wiki:

  • It does not search folders /root because no SUID binaries should be there by default. That folder is by default readable only by root. If root was to create a custom SUID and move it there, then root should be able to execute it.

Good point. Now mentioned in wiki.

1 Like

Permission Hardener does already support setting capabilities:

This is used by anon-apps-config to remove capabilities from ping: anon-apps-config/30_ping.conf at master · Whonix/anon-apps-config · GitHub

The lack of dpkg-statoverride support is an issue however. Maybe we can implement something ourselves via an apt / dpkg hook? I.e. on package upgrade, it checks /etc/permission-hardening.d/ for any needed capabilities and if so, sets them.

Capabilities don’t have the same configurability as sudoers exceptions. We cannot restrict which user can execute the program with higher privileges or what arguments they can use.

It may even be better to replace capabilities or setuid with sudoers exceptions as we can restrict execution of those binaries to specific users. For example, if /bin/example is setuid, it can be executed by any user and potentially exploited whereas if a sudoers exception was made, it will only be able to be executed by user user, preventing a compromised sdwdate user from exploiting that program.

Those conditions seem rather niche so yes.

1 Like

We should add support for basic bash/AppArmor-style regex so we can, for example, shorten:

/bin/ nosuid
/usr/local/bin/ nosuid
/usr/bin/ nosuid
/usr/local/usr/bin/ nosuid
/sbin/ nosuid
/usr/local/sbin/ nosuid
/usr/sbin/ nosuid
/usr/local/usr/sbin/ nosuid
/lib/ nosuid
/usr/local/lib/ nosuid
/lib32/ nosuid
/usr/local/lib32/ nosuid
/lib64/ nosuid
/usr/local/lib64/ nosuid
/usr/lib/ nosuid
/usr/local/usr/lib/ nosuid
/usr/lib32/ nosuid
/usr/local/usr/lib32/ nosuid
/usr/lib64/ nosuid
/usr/local/usr/lib64/ nosuid


/{,usr/,usr/local/}{,s}bin/ nosuid
/{,usr/,usr/local/}lib{,32,64}/ nosuid

like in apparmor-profile-everything.

Also, do directories like /usr/local/usr/bin/ even exist?

1 Like