Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions crates/sandlock-core/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,10 @@ pub(crate) struct ChildSpawnArgs<'a> {
/// Merged into the child's BPF notif list so the kernel actually
/// raises USER_NOTIF for them.
pub extra_syscalls: &'a [u32],
/// PID of the parent process captured before fork. Used to detect
/// parent death in the child without assuming PID 1 is always init
/// (incorrect in containers where the entrypoint runs as PID 1).
pub parent_pid: libc::pid_t,
}

/// Apply irreversible confinement (Landlock + seccomp) then exec the command.
Expand All @@ -750,6 +754,7 @@ pub(crate) fn confine_child(args: ChildSpawnArgs<'_>) -> ! {
keep_fds,
sandbox_name,
extra_syscalls,
parent_pid,
} = args;
// Helper: abort child on error. Includes the OS error automatically.
macro_rules! fail {
Expand Down Expand Up @@ -784,8 +789,11 @@ pub(crate) fn confine_child(args: ChildSpawnArgs<'_>) -> ! {
fail!("prctl(PR_SET_PDEATHSIG)");
}

// 3. Check parent didn't die between fork and prctl
if unsafe { libc::getppid() } == 1 {
// 3. Check parent didn't die between fork and prctl.
// Compare against the actual parent PID captured before fork rather than
// hardcoding 1, since containers often run the entrypoint as PID 1 and a
// child forked from it legitimately has getppid() == 1.
if unsafe { libc::getppid() } != parent_pid {
fail!("parent died before confinement");
}

Expand Down
5 changes: 5 additions & 0 deletions crates/sandlock-core/src/sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,10 @@ impl Sandbox {
(None, None)
};

// Capture our PID before fork so the child can detect parent death
// without assuming PID 1 is always init (wrong in containers).
let parent_pid = unsafe { libc::getpid() };

let pid = unsafe { libc::fork() };
if pid < 0 {
return Err(SandboxRuntimeError::Fork(std::io::Error::last_os_error()).into());
Expand Down Expand Up @@ -1570,6 +1574,7 @@ impl Sandbox {
keep_fds: &gather_keep_fds,
sandbox_name: Some(sandbox_name.as_str()),
extra_syscalls: &extra_syscalls,
parent_pid,
});
}

Expand Down