(re-)mount home [and other?] with noexec (and nosuid [among other useful mount options]) for better security?

Quote Environment setup — CLIP OS 5.0.0_beta3 documentation

Make sure to work in a filesystem without any restricted features such as noexec or nodev as it will cause undefined issues throughout the building process of some parts of the CLIP OS images.


The rationale of nosuid in /home, /run, /dev/shm and /tmp (all partially user writable) is somewhat clear. Perhaps nosuid by extension too (lower attack surface).

But what’s the rationale of mounting /etc and some other folders with nodev? CLIP OS doesn’t do that. Out commented by their default. I haven’t seen /etc suggested to be mounted with nosuid, nodev anywhere.

Maybe the argument of principle of least privilege? Well, non-root users cannot write to these folders such as /etc by default anyhow. Only root can. And compromised root could also change mount options. Therefore I don’t see any advantage of mounting /etc with nosuid, nodev. Root can always create a lets say suid file in some folder (even /). The only way to prevent that would be untrusted root / appamor-profile-everything.

Maybe a useful question to ask…? Was there ever any vulnerability that would have been prevented by such mount options on such folders?

If not recommended anywhere / not helpful in any threat model, then better keep things minimal.

1 Like

Yes.

Root can leave unknown suid/devices lying around.

Not with apparmor-profile-everything.

Not that I know of but we should aim to be proactive i.e. using principle of least privilege to prevent potential future vulnerabilities rather than reactive i.e. responding to a known vulnerability.

There’s not really any legitimate reason of having devices/suid in /etc so why allow it at all?

Kurt Seifried - LASG / Installation recommends it

Brevity.

It’s good to be innovative. Such as in case of Whonix shipping kloak by default is a win. That threat model has been demonstrated through a proof of concept already. Proactive yes, but in this case of remounting /etc with nosuid the benefit of the change doesn’t have a strong rationale.

There’s a huge amount of things which won’t make sense from our point of view. For example there is the hello package which most users won’t know and won’t install. I am using it as an example here. No need to pick on that particular maintainer of that Debian package. Why allow installation of that package? What if that maintainer turned evil and somehow included a backdoor in the hello package? To prevent such a backdoor from doing damage, there could be an apt wrapper that prevents installation of that and other packages which most users will probably never need. I am not supposing to invent an apt wrapper for this hypothetical scenario. It would be worse having that code than having that risk.

The superior reason from preventing untrusted root writing anything malicious /etc is apparmor-profile-everything. Once that’s done, there is no need for an additional layer for preventive of suid creation in /etc. Many goals can be implemented in multiple ways but I don’t think we should implement every goal using duplicate implementations.

For example, remount-secure all inside initramfs (supposing that is possible) would be fine. Then that shouldn’t be fully duplicated with remount-secure again using systemd.

I cannot imagine any accident how any system administrator would create an suid binary and store it in /etc. And if a system administrator chooses for some reason to but a suid binary there then there’s no need to interfere with that choice.

It’s one valid strategy to optimize is to add safeguards for every cases no matter how likely. However, also Focus on low-effort maintainability is important which includes keeping the amount of lines of code small or even reducing it (i have some plans such as “tb-updater → binaries-freedom”…). By keeping the code size small it’s also more contributor friendly since more easy to understand, easier to review.

It’s in the table there but there’s no rationale for it either.


Keeping notes here now:


I not not sure if Mount /rw and /home with nosuid + nodev · Issue #5263 · QubesOS/qubes-issues · GitHub is indicating that flatpak and snap also break when using nosuid on /home.

1 Like

I found a rationale for /etc mounted with nodev,nosuid as well as /var. This is because some folders in /etc or /var such as /var/www are owned by other users than root. In these cases the owner of these folders shouldn’t be able to create devices or suid binaries there.

1 Like

New approach:

  • delete security-misc /lib/systemd/system/remount-secure.service
  • move security-misc /usr/lib/security-misc/remount-secure to /etc/initramfs-tools/scripts/init-bottom/30_remount-secure

Details:

Script /usr/lib/security-misc/remount-secure was probably already good enough - the only missing part is moving it to initramfs to avoid race conditions.

initramfs also uses contents from folder /usr/share/initramfs-tools/scripts/init-bottom/ (and /usr/share/initramfs-tools/).

File name 30_ prepended because we want this to be run after /usr/share/initramfs-tools/scripts/init-bottom/udev.

Can probably stay a bash script. No need to port to sh. /usr/share/initramfs-tools/hooks/resume also uses bash.

if [ -e /etc/remount-disable ] || [ -e /usr/local/etc/remount-disable ]; then

Does this need ${rootmnt}? Likely not because at initramfs stage init-bottom, initramfs already moved everything to its final place?

Kernel parameter break=bottom might give a initramfs rescue shell which could be used for experimentation, i.e. manually running mount commands.

Might also be possible to add command bash followed to /etc/initramfs-tools/scripts/init-bottom/30_remount-secure to easily get shell for experimentation.

Adding sleep 10 or so during development to the end of the script might help to easily see what the script is doing, to have sufficient time to read its debug output.

Could you try please? @madaidan

1 Like

That doesn’t work. The mount options are only set when running update-initramfs. Nothing happens during boot.

1 Like

madaidan via Whonix Forum:

That doesn’t work. The mount options are only set when running update-initramfs. Nothing happens during boot.

Strange. Was it set to chmod +x?

Then how did you implement
/etc/initramfs-tools/scripts/init-bottom/sysctl-initramfs which is
kinda similar (as far as starts during initramfs)? Why would
sysctl-initramfs work but remote-secure not?

1 Like

Yes.

Dunno. sysctl-initramfs is just writing to a few files. This is more complicated.

1 Like

The actual script task, mounting might be more complicated indeed but at least the script should equally be executed? Is it a script execution issue or script functionality issue?

1 Like

Seems like an execution issue. I tried simply writing to a file to check and it didn’t work. Could be because sysctl-initramfs uses /bin/sh whereas remount-secure uses /bin/bash?

1 Like

This worked with /bin/sh although the mounts still don’t.

1 Like

Could very well be the reason. Although I was hoping that’s a non-issue:

Could either port to sh or make bash work inside initramfs if that is possible.

Perhaps try this to easily get a shell:

#!/bin/sh
echo remount-secure
sleep 10
sh
sleep 10

The script could run mount before and after running any actual mount commands to see if it actually has any effect. And the sleep 10 (or more) at the end to have a fair chance to read what’s happening. Perhaps the script is functional but then systemd or something is undoing it.

1 Like

That doesn’t seem to work. I can’t get a shell in initramfs. Nothing happens.

1 Like

Could you try a “proper” initramfs shell instead please?

From initramfs-tools(7) — initramfs-tools-core — Debian buster — Debian Manpages

Kernel parameter break=bottom might give a initramfs rescue shell which could be used for experimentation, i.e. manually running mount commands.

1 Like

That doesn’t work either. It just makes it hang during boot.

1 Like

Figured out how to get an initramfs shell from the GRUB command line:

root=(hd0,msdos1)
linux /boot/vmlinuz-4.19.0-11-amd64
initrd /boot/initrd.img-4.19.0-11-amd64
boot

Will investigate the remount-secure issue now.

1 Like

Remounting /run from initramfs definitely works.

grub> root=(hd0,msdos1)
grub> linux /boot/vmlinuz-4.19.0-11-amd64
grub> initrd /boot/initrd.img-4.19.0-11-amd64
grub> boot

(initramfs) echo "BOOT_IMAGE=/boot/vmlinuz-$(uname -r) root=/dev/vda1" > /cmdline-fake
(initramfs) mount -o bind /cmdline-fake /proc/cmdline
(initramfs) sh /scripts/functions
(initramfs) mount -o remount,nosuid,nodev,noexec /run
(initramfs) /init
(initramfs) exit

/tmp doesn’t seem to work however (probably being overwritten by systemd or something).

1 Like

Got them all:

grub> root=(hd0,msdos1)
grub> linux /boot/vmlinuz-4.19.0-11-amd64
grub> initrd /boot/initrd.img-4.19.0-11-amd64
grub> boot

(initramfs) echo "BOOT_IMAGE=/boot/vmlinuz-$(uname -r) root=/dev/vda1" > /cmdline-fake
(initramfs) mount -o bind /cmdline-fake /proc/cmdline
(initramfs) sh /scripts/functions
(initramfs) mount -o remount,nosuid,nodev,noexec /run
(initramfs) /init
(initramfs) chroot /root

root@(none) mount -o bind,nosuid,noexec,nodev /home /home
root@(none) mount -o bind,nosuid,noexec,nodev /tmp /tmp
root@(none) mkdir /dev/shm
root@(none) mount -t tmpfs -o nosuid,noexec,nodev /dev/shm /dev/shm
root@(none) exit

(initramfs) exit
2 Likes