Skip to content

Fix COW statx and execve for files in the upper layer#58

Merged
congwang-mk merged 1 commit into
mainfrom
fix-cow-statx-execve-upper-layer
May 24, 2026
Merged

Fix COW statx and execve for files in the upper layer#58
congwang-mk merged 1 commit into
mainfrom
fix-cow-statx-execve-upper-layer

Conversation

@congwang-mk
Copy link
Copy Markdown
Contributor

Problem

With the seccomp COW backend active (any --workdir run with fs_isolation=None), a file created inside the sandbox was visible to open()/read() and newfstatat, but:

  • invisible to statx (used by ls, stat, most modern coreutils), returning ENOENT
  • not executable via execve, returning ENOENT

This broke the create-then-use / compile-and-run workflow (e.g. gcc writing a.out then the shell stat/exec'ing it).

Root causes

  1. handle_cow_statx returned Continue when the file existed in the upper layer, so the kernel re-ran statx against the un-redirected lower path and saw nothing.
  2. execve/execveat were not in the COW seccomp notification set, so the supervisor was never consulted and there was no COW handler at all.
  3. Once a handler was added, Landlock evaluates execve(/proc/self/fd/N) against the target file's real path, so the COW upper dir has to be in the allowlist.
  4. handle_cow_open hardcoded creation mode 0o666, so a binary copied into the workdir landed in the upper layer non-executable.

Changes

  • handle_cow_statx: run statx on the resolved upper path in the supervisor and write the buffer back, mirroring the chroot statx handler. Handles AT_EMPTY_PATH.
  • New handle_cow_exec for execve/execveat: redirect to the upper file via an injected fd (/proc/self/fd/N) when the target resolves into the upper layer; pass through lower-layer files; return ENOENT for files deleted in the COW layer.
  • Add execve/execveat to the COW notification set so the handler is reachable.
  • handle_cow_open: honor the child's requested O_CREAT mode instead of 0o666.
  • Create the seccomp COW branch before fork and add its upper dir to the child's Landlock allowlist (read access includes execute).

Audited readlink and getdents64: both resolve and write their results directly, so they do not have the same fall-through bug.

Testing

Added two regression tests (statx on a COW-created file, exec of a COW-created binary) that fail before and pass after. Full suite green: 275 lib, 218 integration, 321 Python.

🤖 Generated with Claude Code

Signed-off-by: Cong Wang <cwang@multikernel.io>
@congwang-mk congwang-mk merged commit 2102f0a into main May 24, 2026
8 checks passed
@congwang-mk congwang-mk deleted the fix-cow-statx-execve-upper-layer branch May 24, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant