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

There are at least 6 different approaches to mount options hardening, 3 different types of mount points (API, partition, folder) and various different environment. Overview created:

1 Like
1 Like

Just looked at the secure mount discussions. Some thoughts from looking through that might be useful:

  • The current remount-secure script implementation is doing blacklisting rather than whitelisting. Listed directories are remounted with secure mount options, but a user might have, for instance, additional drives or similar that they also want to remount securely. Systems with multiple drives or multiple partitions in non-standard spots are probably not rare. We should be scanning through mounts and remounting everything except things that are explicitly configured as “don’t remount this”.
  • I do not think a “pre-boot” implementation (i.e. in the initramfs or using the kernel command line) is in our best interest. systemd can and probably will mount filesystems that aren’t known about prior to bootup, such as additional filesystems listed in /etc/fstab or that the user has made mount units for. We probably want those to be remounted securely too. I like how the current remount-secure systemd unit does things (although I’d have it run Before=sysinit.target, not after, so that we don’t start too late).
  • What about filesystems that are mounted by the end user well after the system is booted? I.e., the user mounts a network drive (NFS), or plugs in a USB drive or SD card, etc. Those should be (re)mounted securely too IMO.
  • If we take a whitelisting approach, the end user will need to be able to configure this, because otherwise they’ll be unable to run programs from external drives, which is a somewhat common use case.

Most of this is pretty easy, except for the third point - mount does not provide any configuration files that can be used to adjust defaults, the defaults are hardcoded in various parts of the system (i.e. in the mount binary itself, or in the kernel). Due to that, we have to take a slightly different approach, but one that I think is probably still decent.

Why don’t we make remount-secure into a daemon? It would start Before=sysinit.target and After=local-fs.target, but not advertise itself as fully started until it was done with its first remount run. After that, it would monitor /proc/self/mounts for new changes to the system mounts, automatically remounting newly mounted filesystems with secure mount settings. That would allow it to handle removable media and network drives transparently. It would have some room for race conditions sadly, but it’s the best that can be done aside from contributing changes to the Linux kernel and/or util-linux (which isn’t necessarily easy). The race would also be pretty short, short enough that it would most likely not ever actually be hit unless there was a malicious process intentionally trying to hit it. (For instance, a malicious user process that waited for a drive to be mounted that it could then immediately run a suid-root binary on.)

The remount-secure daemon would need to have some configuration files. That would allow whitelisting real mountpoints so that they could have more lax permissions applied, and would allow configuring bind-mounts. We would probably need to use a configuration directory rather than a single config file, so that the end-user can make exceptions for drives they do need exec, suid, or dev permissions on.

It might also be worth it to try to contribute feature additions to mount, but I somewhat doubt if it’s even possible. We could probably develop such a feature, but actually getting it accepted could be a substantial challenge given that it requires the ability to get the attention of maintainers, and in my experience it can be quite frustrating trying to get the attention of a maintainer in a project as large as the Linux kernel.