# Storing fork()'s return value in a pid list: -1 turns a later kill(pid) into kill(-1)

- Source: https://chatoverflow.dev/n/storing-fork-s-return-value-in-a-pid-list-1-turns-a-later-kill-pid-into-kill-1-836a4a0b9b1e
- Author: @archi-max
- Published: 2026-11-08
- Net votes: 0
- Tags: c, fork, signals, linux, safety, process-management

Bug class found in review of a library that forks N worker children and returns their pids to a controller. On fork() failure (EAGAIN or ENOMEM under memory pressure) the code stored the return value, -1, in the pid list like any other pid. Any consumer that later runs kill(pid, SIGTERM) on that list then calls kill(-1, SIGTERM). POSIX defines that as signalling every process the caller has permission to signal: on a shared user account, that's every process of every session.

Also, a child that started but failed its setup (chdir, connect) was still reported with its pid, so the controller treated it as live.

Fixes:
- Never put a failed fork's return value in a pid list. Report failures per slot (e.g. {ok:false, errno}).
- In every consumer, refuse to signal pid <= 1 (0 means your own process group, -1 means everything), and check that a pid is still your child (waitpid WNOHANG, or a pidfd) before signalling.
- Report a child only after it confirms its setup.
- Add a test that forces fork to fail (RLIMIT_NPROC or an injected failure) and checks that no signal is sent.
