
High local file read: LiteBox v0.1.0 linux-userland seccomp SYS_open O_RDONLY has no host path check
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · litebox-seccomp-open-rdonly
Class: File read (sandbox FS boundary) Reach: Local
LiteBox v0.1.0 (d8556e3) - Microsoft
The documented Linux-userland runner (litebox-runner-linux-userland) installs a deny-by-default seccomp filter, then loads a guest ELF in the same process. SYS_open is on the allowlist when argument 1 (flags) is a dword equal to OFlags::RDONLY (0). There is no path predicate. A guest that issues a real syscall with flags 0 opens host VFS as the runner UID, then read / mmap those bytes. The ELF rewriter is not a security boundary on this pin. --rewrite-syscalls is -Z and off by default.
This leftover is host-FS read. It is not host write, not exec, not ptrace, not LPE, and not RCE.
| ID | no CVE yet |
| Class | File read (sandbox FS boundary) |
| Reach | Local (untrusted guest binary in the runner process) |
| CWE | CWE-284, CWE-862 |
| CVSS | High: 7.1 CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N |
| Product | microsoft/litebox |
| Affected | v0.1.0 (d8556e33676e47244bfefa139c1e9ff95bd67d53) Linux userland platform + runner |
| Auth | guest already running inside the sandbox |
| License | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 only, linux/amd64 |
Who: an untrusted guest binary in litebox-runner-linux-userland. The vendor (CvvT on GitHub #1006) and the rewriter crate docs say ELF trampolines are not a security boundary. Linux userland security is this filter. enable_seccomp_filter is deny-by-default (Errno(EINVAL) in release) with TSYNC and PR_SET_NO_NEW_PRIVS. The hole is SYS_open flags Eq 0 with no path check. The comment in page_mgmt.rs is that CoW mapping re-opens the host program file after the filter is on, instead of holding a pre-opened FD.
| Method + sink | Privilege |
|---|---|
real SYS_open("/oracle/secret", 0) then SYS_read | Host file bytes the runner UID can read. Lab: fd 3, 35 bytes, witness LITEBOX-SECCOMP-OPEN-RDONLY-WITNESS. Path is initramfs host VFS, not the guest overlay. |
| Method + sink | Privilege |
|---|---|
SYS_open("/etc/passwd", 0) then read / mmap | world-readable host files as runner UID |
SYS_open of runner-owned paths (ssh keys, .env, kubeconfig, cloud credentials, --initial-files tar) | those bytes if the UID can open them |
SYS_open("/etc/shadow", 0) | shadow hashes only if the runner is root |
SYS_open("/proc/self/maps", 0) | runner maps, including host .text / libc (same process) |
SYS_open("/proc/self/mem", 0) then mmap of the FD | runner address space the UID can read via procfs. pread is unmatched deny; SYS_mmap is allowed. |
None on this leftover. Lab-proven negatives all returned errno=22 EINVAL and did not create files:
| Method + sink | Result |
|---|---|
SYS_open O_RDWR | EINVAL |
SYS_open O_CREAT | EINVAL, no file created |
SYS_openat even with O_RDONLY | EINVAL |
SYS_execve | EINVAL |
socket, ptrace | EINVAL (extra unmatched deny) |
openat / openat2 / creat / unlink / chmod stay unmatched deny on the pin.
Not in bar.
process_vm_readv, io_uring_setup, bpf, mount, pivot_root, unshare, setns, connect, ioctl, getdentsAUDIT_ARCH_X86_64 or KILL_PROCESSclone3 inherits the filter; writing uid_map needs a blocked openin_mem + tar_ro) is unchanged. This leftover is host VFS via a real syscallI pinned microsoft/litebox v0.1.0 (d8556e3, 2026-10-07) rather than main. Eighteen source hunts. The rewriter crate and GitHub #1006 already say trampolines are not the boundary. The Linux userland filter is. SYS_open with flags 0 is there so CoW can reopen the program file. There is no path check.
Wrong turn: Docker Desktop Rosetta and qemu-user-static both refuse seccomp(SET_MODE_FILTER) on this host (EINVAL / ENOSYS). The lab therefore boots an x86_64 Alpine virt kernel under qemu-system-x86_64 TCG and runs the copied filter as PID 1 so the BPF hits a real x86_64 kernel. Copied seccompiler 0.5.0 rules, not an in-tree enable_seccomp_filter call, and not the full workspace.
cd lab
./run.sh
Loopback 127.0.0.1:19110. Compose project litebox-seccomp-open-rdonly. Platform linux/amd64. Witness LITEBOX-SECCOMP-OPEN-RDONLY-WITNESS. Last line:
SUCCESS litebox-seccomp-open-rdonly open-rdonly-ok rdwr-einval openat-einval execve-einval LITEBOX-SECCOMP-OPEN-RDONLY-WITNESS
Drop SYS_open from the filter and pre-open the CoW FDs before PR_SET_SECCOMP, or add a path predicate that cannot see host paths outside the guest FS. Unmatched deny already covers openat.
Vendor intake is MSRC (https://msrc.microsoft.com/create-report). Do not open a public GitHub issue on microsoft/litebox.
Abraxas Labs - abraxaslabs.tech - github.com/abraxas - @abraxas_null - [email protected]