nixos/stage-1: Ensure correct ZFS mount options
Consider ZFS filesystems meant to be mounted with zfs.mount(8), e.g. ``` config.fileSystems."/media".options = [ "zfsutil" ]; config.fileSystems."/nix".options = [ "zfsutil" ]; ``` `zfsutil` uses dataset properties as mount options such that zfsprops(7) do not have to be duplicated in fstab(5) entries or manual mount(8) invocations. Given the example configuation above, /media is correctly mounted with `setuid=off` translated into `nosuid`: ``` $ zfs get -Ho value setuid /media off $ findmnt -t zfs -no options /media rw,nosuid,nodev,noexec,noatime,xattr,posixacl ``` /nix however was mounted with default mount(8) options: ``` $ zfs get -Ho value setuid /nix off $ findmnt -t zfs -no options /nix rw,relatime,xattr,noacl ``` This holds true for all other ZFS properties/mount options, including `exec/[no]exec`, `devices/[no]dev`, `atime/[no]atime`, etc. /nix is mounted using BusyBox's `mount` during stage 1 init while /media is mounted later using proper systemd and/or util-linux's `mount`. Tracing stage 1 init showed that BusyBox never tried to execute mount.zfs(8) as intended by `zfsutil`. Replacing it with util-linux's `mount` and adding the mount helper showed attempts to execute mount.zfs(8). Ensure ZFS filesystems are mounted with correct options iff `zfsutil` is used.
This commit is contained in:
parent
af02d617c7
commit
9553106832
@ -31,6 +31,9 @@ let
|
||||
# mounting `/`, like `/` on a loopback).
|
||||
fileSystems = filter utils.fsNeededForBoot config.system.build.fileSystems;
|
||||
|
||||
# Determine whether zfs-mount(8) is needed.
|
||||
zfsRequiresMountHelper = any (fs: lib.elem "zfsutil" fs.options) fileSystems;
|
||||
|
||||
# A utility for enumerating the shared-library dependencies of a program
|
||||
findLibs = pkgs.buildPackages.writeShellScriptBin "find-libs" ''
|
||||
set -euo pipefail
|
||||
@ -107,6 +110,22 @@ let
|
||||
copy_bin_and_libs $BIN
|
||||
done
|
||||
|
||||
${optionalString zfsRequiresMountHelper ''
|
||||
# Filesystems using the "zfsutil" option are mounted regardless of the
|
||||
# mount.zfs(8) helper, but it is required to ensure that ZFS properties
|
||||
# are used as mount options.
|
||||
#
|
||||
# BusyBox does not use the ZFS helper in the first place.
|
||||
# util-linux searches /sbin/ as last path for helpers (stage-1-init.sh
|
||||
# must symlink it to the store PATH).
|
||||
# Without helper program, both `mount`s silently fails back to internal
|
||||
# code, using default options and effectively ignore security relevant
|
||||
# ZFS properties such as `setuid=off` and `exec=off` (unless manually
|
||||
# duplicated in `fileSystems.*.options`, defeating "zfsutil"'s purpose).
|
||||
copy_bin_and_libs ${pkgs.util-linux}/bin/mount
|
||||
copy_bin_and_libs ${pkgs.zfs}/bin/mount.zfs
|
||||
''}
|
||||
|
||||
# Copy some util-linux stuff.
|
||||
copy_bin_and_libs ${pkgs.util-linux}/sbin/blkid
|
||||
|
||||
@ -221,7 +240,12 @@ let
|
||||
echo "testing patched programs..."
|
||||
$out/bin/ash -c 'echo hello world' | grep "hello world"
|
||||
export LD_LIBRARY_PATH=$out/lib
|
||||
$out/bin/mount --help 2>&1 | grep -q "BusyBox"
|
||||
${if zfsRequiresMountHelper then ''
|
||||
$out/bin/mount -V 1>&1 | grep -q "mount from util-linux"
|
||||
$out/bin/mount.zfs -h 2>&1 | grep -q "Usage: mount.zfs"
|
||||
'' else ''
|
||||
$out/bin/mount --help 2>&1 | grep -q "BusyBox"
|
||||
''}
|
||||
$out/bin/blkid -V 2>&1 | grep -q 'libblkid'
|
||||
$out/bin/udevadm --version
|
||||
$out/bin/dmsetup --version 2>&1 | tee -a log | grep -q "version:"
|
||||
|
Loading…
Reference in New Issue
Block a user