From 41f677ec5daccaeae616a0bbf508d2a2d54bdac7 Mon Sep 17 00:00:00 2001 From: Valentin Lab Date: Sat, 31 May 2025 09:56:09 +0800 Subject: crond: reap orphaned grandchildren to prevent zombie buildup If a cron job launches a background task, e.g. `sh -c "sleep 5 &"`, the shell exits immediately and the `sleep` process is re-parented to PID 1. When BusyBox `crond` itself happens to be PID 1 (common in a minimal container), those orphans become direct children of `crond`. Because `crond` only calls waitpid() for the PIDs it explicitly tracks, these processes remain forever in Z state and the container slowly fills with zombies. Add a small `while (waitpid(-1, NULL, WNOHANG) > 0)` sweep at the end of check_completions() so any stray children are reaped. When `crond` is not PID 1 the loop returns -ECHILD immediately, so behaviour and overhead on a normal system are unchanged. Size impact: +12 bytes on x86-64 (gcc 13.3.0 -Os, static) Signed-off-by: Valentin Lab Signed-off-by: Denys Vlasenko --- miscutils/crond.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'miscutils') diff --git a/miscutils/crond.c b/miscutils/crond.c index 96131cae4..b29745576 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c @@ -1001,6 +1001,10 @@ static int check_completions(void) /* else: r == 0: "process is still running" */ file->cf_has_running = 1; } + + /* Reap any other children we don't actively track */ + while (waitpid(-1, NULL, WNOHANG) > 0); + //FIXME: if !file->cf_has_running && file->deleted: delete it! //otherwise deleted entries will stay forever, right? num_still_running += file->cf_has_running; -- cgit v1.2.3-55-g6feb