From 8a4ca53907d4195eae4702f85f62ff47be665a52 Mon Sep 17 00:00:00 2001 From: zackees Date: Sat, 1 Aug 2026 16:01:13 -0700 Subject: [PATCH] fix(core): treat pid 0 as dead in unix pid_is_alive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kill(0, 0) probes the caller's own process group and succeeds, so the unix liveness check reported pid 0 as alive. That failed the two #1227 install-lock staleness tests on macOS/Linux (Check macOS red on PR #1229; Ubuntu masked behind the clippy error), and in production a corrupt owner record holding pid=0 would never be reclaimed — the exact #1213 deadlock class. Guard pid 0 explicitly and add a cross-platform regression test. Co-Authored-By: Claude Fable 5 --- crates/fbuild-core/src/process_identity.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/crates/fbuild-core/src/process_identity.rs b/crates/fbuild-core/src/process_identity.rs index d63d0867..bc896e33 100644 --- a/crates/fbuild-core/src/process_identity.rs +++ b/crates/fbuild-core/src/process_identity.rs @@ -25,6 +25,12 @@ use crate::path::NormalizedPath; /// `STILL_ACTIVE`. #[cfg(unix)] pub fn pid_is_alive(pid: u32) -> bool { + // kill() with pid 0 targets the caller's own process GROUP, not a + // process, so probing 0 would always report "alive". No legitimate + // owner record ever holds pid 0 — treat it as dead. + if pid == 0 { + return false; + } // SAFETY: kill(pid, 0) is a well-defined liveness probe — no signal is // delivered, the syscall just returns 0 if the pid exists and the // caller has permission to signal it. @@ -234,6 +240,14 @@ mod tests { assert!(!pid_is_alive(dead)); } + #[test] + fn pid_zero_is_never_alive() { + // Unix kill(0, 0) probes the caller's own process group and + // succeeds, which read as "alive" before the explicit guard — + // wedging any lock whose owner record held pid 0 (#1213). + assert!(!pid_is_alive(0)); + } + #[test] fn exe_stem_fails_closed_for_wrong_stem() { // Our own PID is alive, but its exe stem is the test binary, not