chroot: mediate path-based xattr syscalls under fs_mount#86
Merged
Conversation
Signed-off-by: Cong Wang <cwang@multikernel.io>
dmitrykruglov
approved these changes
Jun 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #84.
Problem
Under
chroot/fs_mount, the supervisor rewrites paths foropenat/statx/newfstatat/readlinkat/etc., but not thexattrfamily. Path-basedgetxattr/lgetxattr/listxattron a path under anfs_mounttarget therefore resolved against the real (empty) mount point and returnedENOENT, even thoughstatxon the same path succeeded. This surfaced asls -lprinting a spuriousNo such file or directory(it probes xattrs for the ACL+/ SELinux.indicator) and exiting non-zero.Root cause
chroot_path_syscalls()enumerated every path-bearing syscall except the xattr family, so those syscalls never raisedSECCOMP_RET_USER_NOTIFand fell straight through to the kernel with an un-rewritten path.Fix
Three production changes, mirroring the existing
statx/readlinkhandlers:context.rs— add the 8 path-based xattr syscalls ({,l}{get,set,list,remove}xattr) to the chroot notify set. The fd-basedf*xattrvariants are intentionally left unmediated (their fd already points at the resolved file).chroot/dispatch.rs—handle_chroot_xattr: a single unified handler that classifies the syscall into one of four ops, resolves the path through the chroot/fs_mount/COW layers, gates oncan_read/can_write, then re-issues the real syscall on the rewritten host path, marshalling the value/name/list buffers across the child boundary.seccomp/dispatch.rs— register the handler for all 8 syscalls.Edge cases handled:
size == 0probe semantics preserved (passesNULL, returns the kernel's length); output buffer sized from the child'ssizearg and clamped toXATTR_MAX(64 KiB), which bounds allocation and can never cause a spuriousERANGE; failures on the resolve path return a proper errno rather than falling through to the kernel (which would re-expose the bug).Tests
TDD: added
getxattr/listxattr/setxattrapplets to the test helper and three regression tests intest_fs_mount.py(read, list, and write-through), each watched failing (ENOENT, exit 1) before implementing. They skip cleanly on filesystems without user-xattr support.Verified: exact issue repro now exits 0 with empty stderr; full suites green (315 core lib + 221 chroot integration + 328 Python).