Skip to content

[MEDIUM] Do not treat stopped children as exited - #201

Open
OskarEichler wants to merge 2 commits into
enkessler:masterfrom
OskarEichler:codex/ignore-stopped-children
Open

OskarEichler wants to merge 2 commits into
enkessler:masterfrom
OskarEichler:codex/ignore-stopped-children

Conversation

@OskarEichler

@OskarEichler OskarEichler commented Aug 29, 2026 •

Copy link
Copy Markdown

Summary

Stops treating a merely suspended POSIX child as exited by removing WUNTRACED from nonblocking exit polling.

Security impact

MEDIUM: an untrusted or compromised child can suspend itself. waitpid2(..., WNOHANG | WUNTRACED) then reports the stopped PID, and ChildProcess returns true from exited? even though the process still exists. poll_for_exit and the graceful phase of stop can therefore report completion without escalating to KILL, leaving the child and its resources present after the supervisor believes termination succeeded.

Waiting only for termination preserves the intended contract: stopped children remain alive until continued or killed.

Reproduction

On 5.1.0, start a Ruby child that sends itself STOP, wait for suspension, and call exited?. The baseline returns true; this branch returns false.

Verification

  • Ruby 4.0.6 upstream suite: 71 examples, 0 failures.
  • Focused stop/continue/exit lifecycle reproduction passes.
  • The added regression example observes the OS process state before asserting it remains unexited.
  • git diff --check passes.

All Ruby-backed checks used rbenv.

Limitations

The regression exercise is POSIX-specific. Windows, JRuby, and TruffleRuby were not run locally; the change uses the existing portable waitpid2 interface and only removes the stopped-child flag.

Breaking changes

Code that relied on exited? returning true for a suspended child will now receive false, matching the documented termination meaning. Public signatures are unchanged.

@eregon

eregon commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Would need a test demonstrating the issue

@OskarEichler

Copy link
Copy Markdown
Author

Added a real lifecycle regression: it starts a child, sends SIGSTOP, waits until ps reports the stopped state, verifies exited? remains false, then continues and stops the child. The focused Unix spec passes (6 examples).

@OskarEichler OskarEichler changed the title Do not treat stopped children as exited [MEDIUM] Do not treat stopped children as exited Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants