diff --git a/pkgs/by-name/bunpen/restrict/ns/namespace.ha b/pkgs/by-name/bunpen/restrict/ns/namespace.ha index c9d2db2e8..eb878fd77 100644 --- a/pkgs/by-name/bunpen/restrict/ns/namespace.ha +++ b/pkgs/by-name/bunpen/restrict/ns/namespace.ha @@ -170,7 +170,7 @@ type ns_ctx = struct { // fork and: // - in the child: continue execution as normal // - in the parent: wait for the child, then propagate its exit status. -// forward any signals, including SIGTERM, to the child. +// forward any signals, including SIGKILL, to the child. fn fork_and_propagate() (void | os::exec::error | rt::errno) = { let outer_pid = rt::getpid(); match (os::exec::fork()?) { @@ -180,8 +180,15 @@ fn fork_and_propagate() (void | os::exec::error | rt::errno) = { // configure that when the parent dies, we receive SIGTERM. // this ensures that the parent process behaves transparently; // when someone `kill`s the sandbox wrapper, it will properly kill the - // actual sandboxed application - rt::prctl(rt::PR_SET_PDEATHSIG, rt::SIGTERM: u64, 0, 0, 0)?; + // actual sandboxed application. + // + // in the normal mode of operation, SIGKILL is not sent. rather, the + // parent will receive SIGTERM, SIGHUP, etc, in `wait_and_propagate`, + // forward that to the child, the child gracefully exits, and the parent + // forwards the exit status. + // SIGKILL is sent to the child only when the parent exits without waiting + // for the child, likely because it was killed by SIGKILL, itself. + rt::prctl(rt::PR_SET_PDEATHSIG, rt::SIGKILL: u64, 0, 0, 0)?; let parent_pid = rt::getppid(); if (parent_pid != outer_pid && !(parent_pid == 0 && rt::getpid() == 1)) { // ppid=0 only when we fork a new PID namespace, where this child is the new PID 1