Source: debian-installer
Version: 20241227
Severity: wishlist

Dear Maintainer,

This bugreport addresses two interrelated issues:
1) The default mount point for the EFI System Partition (ESP).
2) The default mount options for the ESP.

The proposed modifications aim to achieve the following:
1) Align the actual filesystem layout with existing documentation and
standards.
2) Enhance compatibility with other distributions, such as fedora and
archlinux.
3) Improve security through more secure mount options.
4) Improve filesystem resiliency in the event of system crashes.

Debian unstable (future trixie) creates the ESP with a FAT32 (vfat) filesystem.
vfat supports the general umask mount option, and also the more specific
fmask,dmask mount options for files and directories separately.

Currently, the only mount option specified for the ESP is umask=0077:
$ grep /boot/efi /etc/fstab
# /boot/efi was on /dev/vda1 during installation
UUID=0123-4567  /boot/efi  vfat  umask=0077  0  1

When mounted, it appears as:
$ findmnt /boot/efi
TARGET     SOURCE     FSTYPE  OPTIONS
/boot/efi  /dev/vda1  vfat    
rw,relatime,fmask=0077,dmask=0077,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro

The umask=0077 is a good generic mount option for ESP, because it protects the
files from being read or modified by non-root users. One such file that
benefits from the protection is seeds for randomness when using systemd-boot,
and `bootctl` warns about unsafe filesystem permissions on the ESP. However,
umask=0077 does not remove the executable bit from files, which means that all
files, including even non-executable files such as text files like grub.cfg,
have the same coloring as executable files in the output of `ls`, contrary to
typical user expectations. The output of `ls -l /boot/efi/EFI/debian` is
displayed in the attached image before.png.

The ESP is currently mounted through an entry in /etc/fstab, which can be
disabled:
# sed -i '\,/boot/efi,s,^,#,' /etc/fstab

systemd will then automatically mount the ESP at /efi instead:
$ findmnt /efi
TARGET  SOURCE     FSTYPE  OPTIONS
/efi    systemd-1  autofs  
rw,relatime,fd=52,pgrp=1,timeout=120,minproto=5,maxproto=5,direct,pipe_ino=2979
/efi    /dev/vda1  vfat    
rw,nosuid,nodev,noexec,relatime,nosymfollow,fmask=0077,dmask=0077,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro

The use of /efi mountpoint instead of the legacy /boot/efi mountpoint is
documented in `man file-hierarchy` and [1] and [2] and was reported to debian
in [3]. In scenarios where /boot is a separate partition (e.g. due to LUKS
encryption being used for the rest of the system), this leads to undesirable
nesting of partitions (/boot is one partition, and /boot/efi is another
partition, and the two partitions use different filesystems, namely ext2/ext4
and FAT32). All documentation advises against this nesting.

Notably, systemd mounts the ESP with these characteristics:
1) It uses the nodev,nosuid,noexec mount options, which are appropriate for
ESP.
2) It uses autofs for automatic mounting with 120s idle timeout, making it more
likely that the ESP is only mounted when needed and unmounted afterwards. Given
the poor properties of FAT32 regarding filesystem integrity and crash recovery,
such an approach is advisable.

Recently [4] systemd has adopted the fmask=0177,dmask=0077 mount options for
ESP, eliminating the unnecessary executable bit on files. This makes even more
sense when you consider that the ESP is mounted with the noexec mount option.

This change aligns the color output of `ls -l /efi/EFI/debian` with user
expectations (see attached image after.png).

Considering all the above, I propose:
1) Debian installer should create the /efi mountpoint, discontinue the creation
of /boot/efi mountpoint, and utilize /efi as the default mountpoint for the
ESP. This aligns debian with systemd documentation regarding the ESP, and
prevents nesting of partitions (where /boot and /boot/efi are separate
partitions).
2) The ESP should be mounted with nodev,nosuid,noexec mount options in
/etc/fstab, as these are considered safe and secure defaults, and are
consistent with systemd's approach to mounting the ESP.
3) The ESP should be mounted with fmask=0177,dmask=0077 mount options in
/etc/fstab, to prevent all files from having the executable bit set. This is
also in line with systemd approach to mounting the ESP.
4) The ESP should be mounted with
x-systemd.automount,x-systemd.idle-timeout=120 mount options in /etc/fstab,
allowing on-demand mounting and automatic unmounting when not in use. This too
is what systemd does by default.

In summary, the proposed entry for ESP in /etc/fstab is:
UUID=0123-4567  /efi  vfat  
nodev,nosuid,noexec,fmask=0177,dmask=0077,x-systemd.automount,x-systemd.idle-timeout=120
  0  2

Alternatively, the ESP can be omitted from /etc/fstab entirely, letting systemd
handle the automatic discovery of the ESP. In this case, systemd generates the
same mount options as I described above. This approach relies on the ESP having
the correct GPT Type-UUID c12a7328-f81f-11d2-ba4b-00a0c93ec93b, which the
debian installer already sets. However, for the purposes of this bugreport, I
do not recommend omitting the ESP from /etc/fstab, as it would create an
inconsistency, given that all other partitions are listed there. This method is
suitable for containers and virtual machines, where /etc can start empty, or
/etc/fstab is empty, and systemd is used to autodetect all partitions and
create suitable mountpoints - this bugreport does not pertain to that scenario.

Regarding the value of the x-systemd.idle-timeout= mount option, I chose 120
seconds as it is the default. However, a longer duration, such as 600 seconds,
could also be considered if deemed more appropriate. I have not encountered any
unexpected mount/unmount/mount/unmount/... cycles when performing operations on
the ESP, nor during typical system use, with a 120s timeout.

Regarding the nodev,nosuid mount options, the FAT32 filesystem does not support
suid nor device nodes, rendering these options effectively redundant. However,
UEFI firmware can include drivers for various filesystems, potentially allowing
the ESP to be formatted (and subsequently mounted) as a filesystem that does
support suid and device nodes. In debian, there is no reasonable use case for
having suid or device nodes on the ESP (as they cannot function on the majority
of systems with a FAT32-formatted ESP). Therefore, it is prudent to err on the
side of caution and implement a defense-in-depth strategy by utilizing the
nodev,nosuid mount options.

Additionally, the noatime mount option would be more suitable for the ESP than
the implicit default relatime, as access times for the ESP are not meaningful.
While discussing noatime is not the primary focus of this bugreport, it would
make sense to consider this option too alongside the other proposed changes.

Concerning bootloaders, implementing the proposed changes will not require any
modifications to systemd-boot, as it manages everything automatically already.
Similarly, rEFInd also keeps working with no modifications to it necessary.

Conversely, grub2 will require adjustments due to its current hardcoding of the
/boot/efi path on debian, which becomes particularly evident during grub
package updates.

This means that the naive installation of grub2 fails:
# grub-install
Installing for x86_64-efi platform.
grub-install: error: cannot find EFI directory.

A simple modification resolves this issue:
# grub-install --efi-directory=/efi
Installing for x86_64-efi platform.
Installation finished. No error reported.

This hardcoding is undesirable and should be revised regardless of other
changes, making grub autodetect the ESP based on the GPT Type-UUID, similarly
to how systemd-boot handles it.

Until grub2 is fixed, a temporary workaround involves creating a symlink from
/boot/efi to /efi, enabling grub2 to function with the new layout without
requiring any further changes. Ideally, this symlink would be relative,
/boot/efi->../efi, to make working with chroots safer by preventing unintended
modification of the /efi of the system outside of the chroot. However, debian
policy currently prohibits relative symlinks in this location, as noted in
section 10.5 in [5]. There is an open bug regarding improvements to this policy
[6], and maintainers have previously faced issues due to its enforcement [7].
An absolute symlink /boot/efi->/efi is also functional but less than optimal.

The reason this symlink is only a temporary solution is that it assumes the
filesystem of /boot supports symlinks. This has been the case in debian so far,
where /boot is either a standard directory within the root filesystem (which
must support symlinks) or is created as another linux filesystem (typically
ext2 or ext4) for more complex boot setups, such as those involving LUKS
encryption. However, in the future, the ESP could be mounted on /boot as
mentioned in [1], and since the ESP is typically formatted as FAT32, which does
not support symlinks, this temporary workaround would hinder such a setup.
Therefore, it is essential to address the issues with grub2 instead of
permanently rely on this temporary workaround.

As a side note, there are additional limitations in debian, primarily related
to dpkg [8] and the kernel packages [9], that prevent the use of a
FAT32-formatted ESP as /boot. While fixes for these issues are available [10],
they have not yet been accepted into debian.

I've been using the proposed mount options for the ESP for over a year, in both
bookworm and sid, without any negative effects.

[1] 
https://uapi-group.org/specifications/specs/boot_loader_specification/#mount-points
[2] 
https://uapi-group.org/specifications/specs/discoverable_partitions_specification/#suggested-mode-of-operation
[3] https://bugs.debian.org/1055583
[4] 
https://github.com/systemd/systemd/commit/96963e5615caf96d487da920f0c94e3063b80317
[5] https://www.debian.org/doc/debian-policy/ch-files.html#symbolic-links
[6] https://bugs.debian.org/922674
[7] https://bugs.debian.org/690345
[8] 
https://wiki.debian.org/Teams/Dpkg/FAQ#Q:_What_are_the_filesystem_requirements_by_dpkg.3F
[9] https://lists.debian.org/debian-kernel/2022/09/msg00062.html
[10] https://salsa.debian.org/kernel-team/linux/-/merge_requests/570

Reply via email to