SUID Disabler and Permission Hardener

Automate vm sudo authorization setup · Issue #2695 · QubesOS/qubes-issues · GitHub has interesting ideas.

Quote Solar Designer (someone that Joanna Rutkowska respects):

Ideally, there should be no SUID binaries reachable from the user account, as otherwise significant extra attack surface inside the VM is exposed (dynamic linker, libc startup, portions of Linux kernel including ELF loader, etc.)

No idea yet.

Related:
walled garden, firewall whitelisting, application whitelisting, sudo lockdown, superuser mode, protected mode

Edit by Patrick:
See also (re-)mount home [and other?] with noexec (and nosuid [among other useful mount options]) for better security?

Edit #2 by Patrick:

2 Likes

To remove all SUID bits from binaries, we can run

chmod u-s -R / && chmod g-s -R /

This will break some binaries though. For example, ping needs to be setuid to open a socket.

These can be fixed by only giving them the needed capabilities with the setcap command. For example, we can give ping just the CAP_NET_RAW capability without having to give it full root access.

1 Like

Looks like a sledge hammer approach. I mean, implementations that are ok as a sysadmin for its own computer are not necessarily advisable to be applied by default in a Linux distribution.

Does this change survive package re-installation?

It certainly takes no effect for newly installed packages.

How to reverse this?

What kind of feature breakage is to be expected?

Are there any alternative ways to implement this?

Are there any other linux distributions implementing this so we can look at their implementation for comparison?

1 Like

Likely, no as the package manager would give it back the setuid bit.

Create a list of all current setuid and setgid binaries before running this and then you can just give the setuid/setgid bit back to them.

A list of all setuid and setgid binaries can be gotten by running

find / -type f \( -perm -4000 -o -perm -2000 \)

Assuming you haven’t given the binary the required capabilities, it will not work. Some binaries like su will pretend to work but then always give a permission denied error.

We can create a list of common setuid and setgid binaries that are usually found on a system and remove their setuid/setgid bits individually. This way, we have a lot more control over what happens but there may be certain binaries that slip past.

Not that I know of.

The Arch Wiki has a page on this that may be useful.

https://wiki.archlinux.org/index.php/Capabilities

1 Like

Good ideas.

What about (re)-mount with nosuid [among other useful mount options]?

Edit by Patrick:
Created (re-)mount home [and other?] with noexec (and nosuid [among other useful mount options]) for better security? for it.

1 Like

That sounds like something that’d be good for /etc/fstab.d, similar to hidepid.

Mounting certain directories (/bin, /usr/bin etc.) would break many things with nosuid. Mounting directories like /home with nosuid may be useful but then it wouldn’t have any effect on the other setuid binaries.

We could use one of the methods above to remove setuid bits from most binaries and then use nosuid on directories like /home.

Using multiple different mount options for increased security would be a whole other topic.

Edit by Patrick:
Created (re-)mount home [and other?] with noexec (and nosuid [among other useful mount options]) for better security? for it.

1 Like

Good news. Debian seems to use capabilities over setuid bits for most default binaries. Things like ping don’t have setuid by default.

All binaries with setuid on a fresh Whonix installation are

/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/bin/chfn
/usr/bin/sudo
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/pkexec
/usr/bin/newgrp
/usr/bin/firejail
/usr/bin/chsh
/bin/su
/bin/umount
/bin/mount

There are no setgid binaries by default.

firejail probably just needs CAP_SETUID and CAP_SETGID for user namespaces. Maybe CAP_SYS_ADMIN too but I’m not sure.

Some firejail commands will need others. For example, firejail --chroot will need CAP_SYS_CHROOT.

mount and umount will likely just need CAP_SYS_ADMIN.

su and sudo probably just need CAP_SETUID and CAP_SETGID.

These will need a lot of testing.

1 Like

Alternatively, could we identify suid binaries and then run chmod o-x [0] on them. I.e. o (“others”) (i.e. user user) may not execute them. In result only root could execute suid binaries but non-root could not. Would that help to reduce the risk of suid binaries?

Tested. It’s possible to remove executable permission for binaries for others (user user) while root can still execute the binary.

Either,

  • chmod all suid binaries except a whitelist [1], OR
  • we manually maintain a blacklist of suid binaries (the ones shipped by default but we want to disable). [2]

That would prevent non-root users from executing suid binaries.

A dpkg hook or something could re-apply these changes on upgrades. But not great since malware could wait for the upgrade to happen and there would a vulnerable time window between package upgrade and suid re-disable.

Maybe ACL or something similar could enforce keeping the file permissions (chmod o-x) during upgrades?


[0] Or chmod og-x or chmod o-rx or chmod og-rwx or something?

[1] In a noroot boot mode, even sudo could be set to chmod o-x since during such sessions the user decided to trade sudo not being accessible for better security.

[2] On top, there could be a tool to search and warn against newly installed suid binaries.

1 Like

The entire point of SUID binaries are so unprivileged users can do some privileged operations so why not just remove the SUID bit instead?

This seems like the best approach as it would have minimal breakage.

The whitelist idea would be more effective in ensuring only needed SUID binaries can be executed but then it would break binaries a user creates themselves.

Unless there’s something we can make that checks if a new SUID binary has been created and says “SUID binaries are not allowed by default, see https://www.whonix.org/wiki/wiki_page and whitelist your binary” or something like that.

1 Like

Didn’t have this in mind indeed. Therefore also chmod u-s would do. chmod u-s would not limit root from using these binaries.

However, making these binaries non-executable (and/or non-readable) might have another advantage: we fail closed and loudly (with error message) rather than leading to stranger to interpret issues, such as:

1 Like

dpkg-statoverride could be used make sure SUID stays disabled after apt dist-upgrade / install anything.

https://manpages.debian.org/buster/dpkg/dpkg-statoverride.1.en.html

2 Likes

https://github.com/Whonix/security-misc/pull/44

1 Like

Added some refactoring, debugging, code simplification, and stylistic changes. Btw I make no claim that my code style is superior in any form but it is easier to grasp by my participial biased brain. Hope that is ok.

Found some issues.

run: dpkg-statoverride --add --update root root 0755 /home
run: dpkg-statoverride --add --update user user 0700 /home/user
run: dpkg-statoverride --add --update root root 0700 /root
run: dpkg-statoverride --add --update root root 0700 /boot
run: dpkg-statoverride --add --update root root 0600 /etc/permission-hardening.conf
run: dpkg-statoverride --remove /bin/
fso: /bin/
suid - file_name: ‘/bin/mount’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /bin/mount
suid - file_name: ‘/bin/ntfs-3g’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /bin/ntfs-3g
suid - file_name: ‘/bin/umount’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /bin/umount
run: dpkg-statoverride --remove /usr/bin/
fso: /usr/bin/
suid - file_name: ‘/usr/bin/atrm’ | existing_mode: ‘777’ | existing_mode:1: ‘77’
run: dpkg-statoverride --add --update root root 77 /usr/bin/atrm
suid - file_name: ‘/usr/bin/bwrap’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/bwrap
suid - file_name: ‘/usr/bin/chfn’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/chfn
suid - file_name: ‘/usr/bin/chsh’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/chsh
suid - file_name: ‘/usr/bin/dotlock’ | existing_mode: ‘777’ | existing_mode:1: ‘77’
run: dpkg-statoverride --add --update root root 77 /usr/bin/dotlock
suid - file_name: ‘/usr/bin/dotlock.mailutils’ | existing_mode: ‘2755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/dotlock.mailutils
suid - file_name: ‘/usr/bin/firejail’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/firejail
suid - file_name: ‘/usr/bin/gpasswd’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/gpasswd
suid - file_name: ‘/usr/bin/newaliases’ | existing_mode: ‘777’ | existing_mode:1: ‘77’
run: dpkg-statoverride --add --update root root 77 /usr/bin/newaliases
suid - file_name: ‘/usr/bin/newgrp’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/newgrp
suid - file_name: ‘/usr/bin/pkexec.security-misc-orig’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/pkexec.security-misc-orig
suid - file_name: ‘/usr/bin/sg’ | existing_mode: ‘777’ | existing_mode:1: ‘77’
run: dpkg-statoverride --add --update root root 77 /usr/bin/sg
suid - file_name: ‘/usr/bin/sudo’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/sudo
suid - file_name: ‘/usr/bin/write’ | existing_mode: ‘777’ | existing_mode:1: ‘77’
run: dpkg-statoverride --add --update root root 77 /usr/bin/write
INFO: fso ‘/usr/local/bin/’ does not exist!
fso: /sbin/
suid - file_name: ‘/sbin/mount.nfs’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /sbin/mount.nfs
suid - file_name: ‘/sbin/mount.ntfs’ | existing_mode: ‘777’ | existing_mode:1: ‘77’
run: dpkg-statoverride --add --update root root 77 /sbin/mount.ntfs
suid - file_name: ‘/sbin/umount.nfs4’ | existing_mode: ‘777’ | existing_mode:1: ‘77’
run: dpkg-statoverride --add --update root root 77 /sbin/umount.nfs4
suid - file_name: ‘/sbin/unix_chkpwd’ | existing_mode: ‘2755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root shadow 755 /sbin/unix_chkpwd
fso: /usr/sbin/
suid - file_name: ‘/usr/sbin/exim4’ | existing_mode: ‘4755’ | existing_mode:1: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/sbin/exim4
suid - file_name: ‘/usr/sbin/runq’ | existing_mode: ‘777’ | existing_mode:1: ‘77’
run: dpkg-statoverride --add --update root root 77 /usr/sbin/runq
INFO: fso ‘/usr/local/sbin/’ does not exist!
run: dpkg-statoverride --remove /lib/
fso: /lib/
usr/lib/security-misc/permission-hardening: line 19: /usr/bin/stat: Argument list too long
fso: /lib32/
fso: /lib64/
run: dpkg-statoverride --remove /usr/lib/
fso: /usr/lib/
usr/lib/security-misc/permission-hardening: line 19: /usr/bin/stat: Argument list too long
fso: /usr/lib32/
INFO: fso ‘/usr/lib64/’ does not exist!
INFO: fso ‘/usr/local/lib/’ does not exist!
INFO: fso ‘/usr/local/lib32/’ does not exist!
INFO: fso ‘/usr/local/lib64/’ does not exist!
run: dpkg-statoverride --add --update root root 4755 /usr/bin/sudo
run: dpkg-statoverride --add --update root root 4755 /usr/bin/bwrap
run: dpkg-statoverride --add --update root root 4755 /usr/lib/policykit-1/polkit-agent-helper-1
run: dpkg-statoverride --remove /usr/lib/dbus-1.0/dbus-daemon-launch-helper
run: dpkg-statoverride --add --update root messagebus 4754 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
INFO: fso ‘/usr/lib/spice-gtk/spice-client-glib-usb-acl-helper’ does not exist!
run: dpkg-statoverride --add --update root utmp 2755 /usr/lib/x86_64-linux-gnu/utempter/utempter


run: dpkg-statoverride --remove /bin/

Do we want to do this?

suid - file_name: ‘/usr/bin/atrm’ | existing_mode: ‘777’ | existing_mode:1: ‘77’
run: dpkg-statoverride --add --update root root 77 /usr/bin/atrm

This is because:

stat -c "%n %a %U %G" /usr/bin/atrm

/usr/bin/atrm 777 root root

Therefore need to check string length of permission variable. I will fix this very soon.

fso: /lib/
usr/lib/security-misc/permission-hardening: line 19: /usr/bin/stat: Argument list too long

Can reproduce manually too.

shopt -s globstar
stat -c "%n %a %U %G" /lib/**

bash: /usr/bin/stat: Argument list too long

1 Like

symlinks are probably (a or the) cause for the permission variable length issue above.

stat -c "%n %a %U %G" /usr/bin/sg

/usr/bin/sg 777 root root

test -u /usr/bin/sg ; echo $?

0

test -g /usr/bin/sg ; echo $?

1

test -h /usr/bin/sg ; echo $?

0

ls -la /usr/bin/sg

lrwxrwxrwx 1 root root 6 Jul 27 2018 /usr/bin/sg → newgrp

realpath /usr/bin/sg

/usr/bin/newgrp

The question is, how should we handle symlinks?

Should we just skip symlinks in nosuid mode? That is what I have implemented for now. Config entries such as /bin/ nosuid should catch such entries anyhow since these would be in other folders which config will “run nosuid” on anyhow. Except, it would miss custom made symlinks linking to folders which we don’t parse.

Otherwise we could resolve the symlink (maybe using realpath) and then “run nosuid” on wherever it links to even if a weird path such as hypothetically /usr/share/somesuid/somesuidbinary. Such entries however would likely never be updated/removed when the symlink changed.

1 Like

Let’s not use add_statoverride_entry for both, case of nosuid and regular modes. That is because when we’re using nosuid that is totally different. In that case we iterate over folders. For other modes, we don’t iterate but set specific modes. There is not any code that would be repeated. Therefore made that add_nosuid_statoverride_entry.

This is fixed.

For now, no longer doing this. That was only only a bug when using nosuid entries. Not a deliberate choice in config. If this was wanted, another entry should be added to config (similar to /boot/ 0700 root root but would have to think about mode/owner/group but there may be no fitting config file and does not seem important).

1 Like

I don’t think we should support iterating over folders for nosuid while at the same time setting specific modes/owner/groups. To specific what I mean:

This is OK:

/bin/ nosuid

This is also OK:

/etc/permission-hardening.conf 0600 root root

This does not seem useful:

/bin/ nosuid 0600 root root

This does not seem useful:

/bin/ nosuid root root

If both nosuid and a mode/owner/group change is wanted, better add another config line.

1 Like

We are hitting ARG_MAX

getconf ARG_MAX

more info:
https://www.linuxjournal.com/article/6060

How can I prevent arguments to `xargs` from being prefixed with spaces? - Unix & Linux Stack Exchange said xargs can split it up.

Will use

done < <( find "${fso_without_trailing_slash}/" -print0 | xargs -I{} -0 stat -c "%n %a %U %G" {} )

to fix it.

1 Like

It’s fixed. But by fixing the parsing of /lib it’s also very slow. Needs 3 minutes to finish.

(And only using dry mode, i.e. not running the dpkg-statoverwrite --add / --remove commands yet actuary. I don’t think that would change much to the worse, though.)

time sudo usr/lib/security-misc/permission-hardening

fso: /home/
run: dpkg-statoverride --add --update root root 0755 /home
fso: /home/user/
run: dpkg-statoverride --add --update user user 0700 /home/user
fso: /root/
run: dpkg-statoverride --add --update root root 0700 /root
fso: /boot/
run: dpkg-statoverride --add --update root root 0700 /boot
fso: /etc/permission-hardening.conf
run: dpkg-statoverride --add --update root root 0600 /etc/permission-hardening.conf
fso: /bin/
suid - file_name: ‘/bin/fusermount’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /bin/fusermount
suid - file_name: ‘/bin/su’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /bin/su
suid - file_name: ‘/bin/ntfs-3g’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /bin/ntfs-3g
fso: /usr/bin/
suid - file_name: ‘/usr/bin/sudo’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/sudo
suid - file_name: ‘/usr/bin/chsh’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/chsh
suid - file_name: ‘/usr/bin/crontab’ | existing_mode: ‘2755’ | new_mode: ‘755’
run: dpkg-statoverride --remove /usr/bin/crontab
run: dpkg-statoverride --add --update root crontab 755 /usr/bin/crontab
suid - file_name: ‘/usr/bin/chfn’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/chfn
suid - file_name: ‘/usr/bin/ssh-agent’ | existing_mode: ‘2755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root ssh 755 /usr/bin/ssh-agent
suid - file_name: ‘/usr/bin/newuidmap’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/newuidmap
suid - file_name: ‘/usr/bin/pkexec.security-misc-orig’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/pkexec.security-misc-orig
suid - file_name: ‘/usr/bin/bwrap’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/bin/bwrap
suid - file_name: ‘/usr/bin/chage’ | existing_mode: ‘2755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root shadow 755 /usr/bin/chage
INFO: fso ‘/usr/local/bin/’ does not exist!
fso: /sbin/
suid - file_name: ‘/sbin/mount.nfs’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /sbin/mount.nfs
fso: /usr/sbin/
INFO: fso ‘/usr/local/sbin/’ does not exist!
fso: /lib/
fso: /lib32/
fso: /lib64/
fso: /usr/lib/
suid - file_name: ‘/usr/lib/policykit-1/polkit-agent-helper-1’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/policykit-1/polkit-agent-helper-1
suid - file_name: ‘/usr/lib/eject/dmcrypt-get-device’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/eject/dmcrypt-get-device
suid - file_name: ‘/usr/lib/virtualbox/VBoxNetDHCP’ | existing_mode: ‘6755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/virtualbox/VBoxNetDHCP
suid - file_name: ‘/usr/lib/virtualbox/VBoxNetNAT’ | existing_mode: ‘6755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/virtualbox/VBoxNetNAT
suid - file_name: ‘/usr/lib/virtualbox/VBoxHeadless’ | existing_mode: ‘6755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/virtualbox/VBoxHeadless
suid - file_name: ‘/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
suid - file_name: ‘/usr/lib/dbus-1.0/dbus-daemon-launch-helper’ | existing_mode: ‘4754’ | new_mode: ‘754’
run: dpkg-statoverride --remove /usr/lib/dbus-1.0/dbus-daemon-launch-helper
run: dpkg-statoverride --add --update root messagebus 754 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
suid - file_name: ‘/usr/lib/kde4/libexec/fileshareset’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/kde4/libexec/fileshareset
suid - file_name: ‘/usr/lib/kde4/libexec/kdesud’ | existing_mode: ‘2755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root nogroup 755 /usr/lib/kde4/libexec/kdesud
suid - file_name: ‘/usr/lib/chromium/chrome-sandbox’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/chromium/chrome-sandbox
suid - file_name: ‘/usr/lib/qubes/qfile-unpacker’ | existing_mode: ‘4755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root root 755 /usr/lib/qubes/qfile-unpacker
suid - file_name: ‘/usr/lib/evolution/camel-lock-helper-1.2’ | existing_mode: ‘2755’ | new_mode: ‘755’
run: dpkg-statoverride --add --update root mail 755 /usr/lib/evolution/camel-lock-helper-1.2
fso: /usr/lib32/
INFO: fso ‘/usr/lib64/’ does not exist!
INFO: fso ‘/usr/local/lib/’ does not exist!
INFO: fso ‘/usr/local/lib32/’ does not exist!
INFO: fso ‘/usr/local/lib64/’ does not exist!
fso: /usr/bin/sudo
run: dpkg-statoverride --add --update root root 4755 /usr/bin/sudo
fso: /usr/bin/bwrap
run: dpkg-statoverride --add --update root root 4755 /usr/bin/bwrap
fso: /usr/lib/policykit-1/polkit-agent-helper-1
run: dpkg-statoverride --add --update root root 4755 /usr/lib/policykit-1/polkit-agent-helper-1
fso: /usr/lib/dbus-1.0/dbus-daemon-launch-helper
INFO: fso ‘/usr/lib/spice-gtk/spice-client-glib-usb-acl-helper’ does not exist!
fso: /usr/lib/x86_64-linux-gnu/utempter/utempter
run: dpkg-statoverride --add --update root utmp 2755 /usr/lib/x86_64-linux-gnu/utempter/utempter

real 3m3.306s
user 1m12.419s
sys 1m57.067s

The xtrace (sudo bash -x usr/lib/security-misc/permission-hardening or setting set -x) at the top of the script looks efficient. We don’t call stat a million times and we are using bash built-ins.

1 Like

Added some benchmarking code (but not clean, will not publish unless deemed required).

fso: /bin/ | benchmark: 00:00:01
fso: /usr/bin/ | benchmark: 00:00:05
fso: /sbin/ | benchmark: 00:00:00
fso: /usr/sbin/ | benchmark: 00:00:01
fso: /lib/ | benchmark: 00:00:57
fso: /lib32/ | benchmark: 00:00:00
fso: /lib64/ | benchmark: 00:00:00
fso: /usr/lib/ | benchmark: 00:02:01
fso: /usr/lib32/ | benchmark: 00:00:00

Parsing /lib/ and /usr/lib/ takes far most of the time.

Fortunately /lib does not have any suid binaries by default on my system.

Maybe we can mount /lib as nodev,nosuid. As per Kurt Seifried - LASG / Installation we can. Then we could remove /lib from permission hardening config and safe 1 minute.

Related: (re-)mount home [and other?] with noexec (and nosuid [among other useful mount options]) for better security? - #21 by madaidan

Parsing /usr/lib though seems important.

1 Like
1 Like