From: Christian Brauner Date: Tue, 11 Aug 2026 12:31:25 +0000 (+0200) Subject: bpf-restrict-fsaccess: allow execution from overlayfs on signed dm-verity (#43223) X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;p=thirdparty%2Fsystemd.git bpf-restrict-fsaccess: allow execution from overlayfs on signed dm-verity (#43223) RestrictFileSystemAccess= currently denies execution from any overlayfs mount, even when every layer sits on a signed dm-verity device. The enforcement hooks compare file->f_inode->i_sb->s_dev against the map of trusted devices and for a file on an overlay that's the overlay's own anonymous device, never the backing block device. So the fairly common image based setup where a signed DDI is the lower layer and a writable upper is stacked on top of it is out. Kernel v7.2 grew the bpf_real_data_inode() kfunc which resolves a file to the inode hosting its data. Use it from the two enforcement hooks that get to see the union-level file. Execution through such an overlay then works while anything whose data lives in an untrusted upper layer is still denied. All of it is gated on kernel support. The kfunc is a __weak __ksym and every call sits behind a const volatile .rodata flag that PID1 only sets when the kernel BTF advertises the function, so the object still loads on older kernels and keeps denying union filesystems exactly like before. If loading with resolution enabled fails anyway the loader retries with the flag off. A setup failure here is fatal to PID1 startup and I'd rather degrade than not boot. Two things worth pointing out. The mmap_file hook matters more than it looks like. binfmt_elf maps the PT_INTERP interpreter via vm_mmap() so ld.so is only ever checked there and never by bprm_check_security. And file_mprotect deliberately doesn't use the kfunc. It runs under mmap_write_lock where sleeping in d_real() would invert the documented i_rwsem -> mmap_lock order, and it doesn't need it anyway since ovl_mmap() has already installed the backing file into vma->vm_file by then. Known limitations: * With metacopy=on an untrusted upper layer can still own a trusted binary's mode, ownership and setuid bits since the resolution only follows the data. Documented in the man page, just don't build that. * composefs with a separate data directory isn't covered. That needs fs-verity digests and bpf_get_fsverity_digest() takes a struct file and gets the overlay inode, so it doesn't compose with this today. * erofs page cache sharing is denied. The inode comes from a pseudo filesystem whose s_dev is never in the verity map. * Multi-device filesystems like btrfs stay unsupported, as before. Signed-off-by: Christian Brauner (Amutable) --- 0b2d1203cbcc9a1ce5ec4c26d86070eaac0ccba5