Page MenuHomeVyOS Platform

ISO built in a container without CAP_SYS_MODULE has an initrd without kernel modules and does not boot
In progress, NormalPublicBUG

Description

When an ISO is built in a container whose capability bounding set lacks CAP_SYS_MODULE, the build succeeds but the image doesn't boot. A Proxmox LXC with default settings is one such container: it drops sys_module, sys_time, sys_rawio, mac_admin and mac_override.

The initrd it produces contains no kernel modules. squashfs, isofs, sr_mod, overlay and virtio_blk are all built as modules (=m), so live-boot can't find or mount the boot medium and the system stops at the (initramfs) prompt.

Root cause

  • vyos-1x's postinst runs setcap cap_sys_module=pe /bin/kmod and setcap cap_sys_time=pe /bin/date.
  • The kernel refuses to exec a binary with effective file capabilities that aren't in the caller's bounding set, so modprobe and date fail with EPERM inside the build chroot, even as root.
  • mkinitramfs ignores the modprobe failures and still exits 0, so no module is added and the build doesn't fail.
  • date is affected the same way, so the hooks that use it (40-init-geoip-database, 93-sb-sign-kernel) get empty values.
  • Removing the capability from the container's drop list would avoid this, but it lets the build container load modules into the host kernel which is a bad thing!

Proposed fix

  • A new hook, 00-drop-file-caps.chroot, records the file capabilities on kmod and date and removes them for the duration of the chroot hooks.
  • A new hook, 99-restore-file-caps.chroot, rebuilds the initramfs itself and fails the build if squashfs is missing. It then sets live-build's initrd.img_has_already_been_regenerated marker so chroot_hacks doesn't rebuild it again with the capabilities restored, and finally puts the original capabilities back. The final image keeps exactly the capabilities vyos-1x intends.

LXC container configuration

$ cat /etc/pve/lxc/100.conf 
arch: amd64
cores: 6
features: nesting=1,keyctl=1,fuse=1
hostname: build.vyos.net
memory: 8192
nameserver: 192.0.2.1,192.0.2.2
net0: name=eth0,bridge=vmbr0,gw=192.0.2.1,gw6=2001:db8::1,hwaddr=BC:24:11:2E:FF:FF,ip=192.0.2.10/25,ip6=2001:db8::10/64,tag=810,type=veth
ostype: debian
rootfs: ld-nvme-001:subvol-100-disk-0,size=250G
searchdomain: vyos.net
swap: 0
lxc.cgroup2.devices.allow: c 195:* rwm
lxc.cgroup2.devices.allow: c 10:232 rwm
lxc.mount.entry: /dev/kvm dev/kvm none bind,optional,create=file

Details

Version
rolling
Is it a breaking change?
Perfectly compatible
Issue type
Internal change (not visible to end users)