Skip to content

fix: compare getppid() against actual parent pid, not hardcoded 1#53

Open
mrsimpson wants to merge 1 commit into
multikernel:devfrom
mrsimpson:fix/container-getppid
Open

fix: compare getppid() against actual parent pid, not hardcoded 1#53
mrsimpson wants to merge 1 commit into
multikernel:devfrom
mrsimpson:fix/container-getppid

Conversation

@mrsimpson
Copy link
Copy Markdown

Summary

Fixes Sandbox.run() failure in containerized server processes (e.g. uvicorn running as PID 1). The child's confine_child checked getppid() == 1 to detect parent death, but in containers the entrypoint process commonly runs as PID 1 itself — causing a false positive and silent child exit with read notif fd from child: pipe closed before 4 bytes read.

Root cause

context.rs line 788: if unsafe { libc::getppid() } == 1 { fail!("parent died before confinement"); }

When the server process is PID 1 (container entrypoint), any forked child legitimately has getppid() == 1. Sandlock interprets this as "parent was reparented to init" and aborts the child.

Fix

Capture the actual parent PID with getpid() before the fork and pass it through ChildSpawnArgs. The child compares against that value instead of hardcoded 1.

Testing

  • Verified on k3s pod with Kubernetes RuntimeDefault seccomp, Landlock ABI v7, uvicorn running as PID 1
  • Sandbox.run() now succeeds directly from the uvicorn process without any subprocess workaround
  • Multiple consecutive tool calls confirmed working

Related

The check 'getppid() == 1' intends to detect parent death (where the
child is reparented to init/PID 1). In containers the entrypoint process
commonly runs as PID 1 itself, so a child forked from it legitimately
has getppid() == 1 — causing a false positive and silent child exit.

Fix: capture getpid() in the parent before fork and pass it through
ChildSpawnArgs so the child compares against the actual parent pid.

Fixes: sandlock running from within a containerized server process (e.g.
uvicorn as PID 1) where direct Sandbox.run() calls always failed with
'read notif fd from child: pipe closed before 4 bytes read'.
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