Skip to content

zenroot 4.1.2.zfs.2: enroot-zfs-mount helper for pyxis/Slurm

Choose a tag to compare

@sodre sodre released this 29 Apr 19:24
· 60 commits to zenroot/main since this release
ccd2cfc

Adds enroot-zfs-mount, a cap_sys_admin-elevated helper that lets unprivileged callers mount the ZFS datasets enroot creates. Closes #9 (pyxis/Slurm post-privilege-drop enroot create 10-minute timeout).

What's new

  • bin/enroot-zfs-mount — small static-pie/musl helper that validates and performs mount(2) / umount2(2) of ZFS datasets owned by the calling user. Reads its config exclusively from /etc/enroot/enroot.conf (NOT from user-controlled config). Validation chain: dataset must be under ENROOT_DATA_PATH's parent dataset; the dataset's mountpoint property must be under ENROOT_DATA_PATH; idempotent if already mounted at the expected path.
  • Shipped via enroot+caps and enroot-hardened+caps; the postinst grants cap_sys_admin+pe.
  • src/storage_zfs.sh switched to zfs create -u / zfs clone -u / zfs receive -u (skip auto-mount) and calls the helper for the actual mount; destroy paths gain a helper unmount before zfs destroy.

With +caps installed, all unprivileged ZFS-backed flows (enroot create, enroot load, enroot start <image>, enroot remove) work end-to-end — including from inside slurmstepd post-privilege-drop, which is what pyxis needs.

Behavior changes

  • enroot create / load / start <image> / remove now succeed for unprivileged callers when ENROOT_STORAGE_BACKEND=zfs and enroot+caps is installed. Previously they timed out or required root.
  • Default dir backend behavior unchanged. ZFS backend's privileged-caller behavior unchanged.

Trust posture

The helper has cap_sys_admin. Validation bounds that trust to enroot's own operations:

  • The dataset arg must be under ENROOT_DATA_PATH's parent (defends against tank/admin/secrets).
  • The dataset's mountpoint property must be under ENROOT_DATA_PATH (defends against a self-owned dataset with mountpoint=/usr/local/bin).
  • Already-mounted check refuses double-mounts.
  • System-config-only: the helper reads /etc/enroot/enroot.conf, ignoring ~/.config/enroot/enroot.conf so a malicious caller can't redirect ENROOT_DATA_PATH.

Packages (aarch64 / arm64 only in this release)

Flavor Package
Standard enroot_4.1.2.zfs.2-1_arm64.deb
enroot+caps_4.1.2.zfs.2-1_arm64.deb
Hardened enroot-hardened_4.1.2.zfs.2-1_arm64.deb
enroot-hardened+caps_4.1.2.zfs.2-1_arm64.deb

Plus enroot_4.1.2.zfs.2_aarch64.tar.xz (relocatable tarball) and enroot_4.1.2.zfs.2.orig.tar.xz (Debian source).

Closes

  • #9 — ZFS backend: support pyxis (Slurm) workflows where enroot runs after privilege-drop to the job user.

Build

git clone --recurse-submodules -b v4.1.2.zfs.2 https://github.com/zeroae/enroot.git
cd enroot
make
sudo make install setcap

For the hardened flavor: make deb PACKAGE=enroot-hardened.

Admin setup for unprivileged ZFS

/etc/enroot/enroot.conf (system, root-owned) must set ENROOT_DATA_PATH and ENROOT_STORAGE_BACKEND:

ENROOT_STORAGE_BACKEND zfs
ENROOT_DATA_PATH       /var/lib/enroot

ZFS pool with delegations:

zfs create -o compression=zstd -o atime=off -o xattr=sa -o acltype=posixacl \
           -o mountpoint=/var/lib/enroot tank/enroot
zfs allow user create,mount,clone,destroy,snapshot,rename,promote,receive,readonly,hold,release tank/enroot

Install both enroot and enroot+caps. The helper picks up cap_sys_admin+pe via the +caps postinst.

See doc/zfs.md for the full design and trust-boundary discussion.