[GH-ISSUE #5282] [Bug] Rizin exit proof can hide post-detach protocol failures #3220

Closed
opened 2026-10-31 00:38:00 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @gensokyo-dev on GitHub (Oct 19, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/5282

Before submitting

  • Searched related reports; this is a follow-up regression in #5281, separate from the original missing-proc case #5277.
  • No credentials or sensitive target data.

Area

Process capture or runtime observation

Observed behavior

Reproduced through the production manager with an injected native protocol producer and a real owned inferior: the post-detach catch in current main covers both process checks and #verifyInferiorOutputConfiguration, including its internal e dbg.exitkills protocol readback. If that readback fails or is ambiguous while the identified inferior ends, process-end proof can turn the failure into successful close.

Actionable review, introduced by #5281.

Reproduction

Executed on e84e17e30 with the new RizinInferiorExit boundary case:

  1. Start a real owned inferior whose descriptors point to the selected PTY, with an injected Rizin protocol producer.
  2. Return a valid initial descriptor inventory and policy; confirm detach with an empty inventory while keeping the inferior alive.
  3. During the final e dbg.exitkills readback, request the controlled inferior to exit and wait for observed exit, then emit ambiguous with complete framing.
  4. manager.close incorrectly returns ok: true; the expected retained-failure assertion fails (expected true to be false).

Result: 1 genuine regression failure, 2 unchanged controls passed; owned process-family cleanup verified, OOM kills 0. Negative reproduction uses a simulated native producer; no claim of real Rizin emitting the ambiguous sequence.

Expected behavior

Keep native protocol/policy checks outside process-exit recovery. Proven inferior exit may retire process identity/descriptor checks, but must not hide failed or ambiguous native readback.

Impact and scope

Potentially hides a cleanup protocol failure. Scope derived from source; real-provider frequency and exploitation are NOT_ENOUGH_INFO. No claim that ordinary Rizin 0.9.1 currently emits this sequence.

REA version

e84e17e30f

Runtime and platform

Linux x86-64; Node 24.18.0; Rizin cleanup code. Injected-producer negative reproduced; real-provider occurrence remains unverified.

Target and artifact context

An identified inferior ends during post-detach policy readback; native producer and controlled inferior fixture will establish the exact transition.

Interface

MCP / shared CLI provider manager

Earliest failure stage

Cleanup, cancellation, or lifecycle

Relevant output or evidence

Source: RizinDebugSessionManager.ts. The catch invokes verifyOwnedInferiorsEnded for any error from the final combined identity/TTY/policy block. #verifyInferiorOutputConfiguration also performs an internal command; these are distinct failure boundaries.

Typed outcome or recovery expected

A failed protocol readback must keep the existing cleanup_incomplete outcome and retained debugger ownership. Healthy readback plus proven inferior end must continue to close successfully.

Analysis or suspected cause

Observed in source: a shared helper couples native protocol readback and Linux descriptor verification, making a broad process-exit catch absorb both. Proposed structural fix: distinct protocol-policy and filesystem-descriptor helpers, with the final protocol check outside the exit-recovery block. Remove the combined helper.

Additional context

This is our own follow-up bug and will be fixed before further audit work. Original positive real-provider coverage is retained. Add a deterministic negative reproduction and repeat real first-close/CLI and post-close TTY checks.

Originally created by @gensokyo-dev on GitHub (Oct 19, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5282 ### Before submitting - [x] Searched related reports; this is a follow-up regression in #5281, separate from the original missing-proc case #5277. - [x] No credentials or sensitive target data. ### Area Process capture or runtime observation ### Observed behavior Reproduced through the production manager with an injected native protocol producer and a real owned inferior: the post-detach catch in current main covers both process checks and `#verifyInferiorOutputConfiguration`, including its internal `e dbg.exitkills` protocol readback. If that readback fails or is ambiguous while the identified inferior ends, process-end proof can turn the failure into successful close. [Actionable review](https://github.com/morluto/rea/pull/5281#discussion_r4317377510), introduced by #5281. ### Reproduction Executed on e84e17e30 with the new RizinInferiorExit boundary case: 1. Start a real owned inferior whose descriptors point to the selected PTY, with an injected Rizin protocol producer. 2. Return a valid initial descriptor inventory and policy; confirm detach with an empty inventory while keeping the inferior alive. 3. During the final `e dbg.exitkills` readback, request the controlled inferior to exit and wait for observed exit, then emit `ambiguous` with complete framing. 4. `manager.close` incorrectly returns `ok: true`; the expected retained-failure assertion fails (`expected true to be false`). Result: 1 genuine regression failure, 2 unchanged controls passed; owned process-family cleanup verified, OOM kills 0. Negative reproduction uses a simulated native producer; no claim of real Rizin emitting the ambiguous sequence. ### Expected behavior Keep native protocol/policy checks outside process-exit recovery. Proven inferior exit may retire process identity/descriptor checks, but must not hide failed or ambiguous native readback. ### Impact and scope Potentially hides a cleanup protocol failure. Scope derived from source; real-provider frequency and exploitation are NOT_ENOUGH_INFO. No claim that ordinary Rizin 0.9.1 currently emits this sequence. ### REA version e84e17e30f7de41ad9ac801eda235574fa5d4dad ### Runtime and platform Linux x86-64; Node 24.18.0; Rizin cleanup code. Injected-producer negative reproduced; real-provider occurrence remains unverified. ### Target and artifact context An identified inferior ends during post-detach policy readback; native producer and controlled inferior fixture will establish the exact transition. ### Interface MCP / shared CLI provider manager ### Earliest failure stage Cleanup, cancellation, or lifecycle ### Relevant output or evidence Source: [RizinDebugSessionManager.ts](https://github.com/morluto/rea/blob/e84e17e30f7de41ad9ac801eda235574fa5d4dad/src/rizin/RizinDebugSessionManager.ts#L1206). The catch invokes `verifyOwnedInferiorsEnded` for any error from the final combined identity/TTY/policy block. `#verifyInferiorOutputConfiguration` also performs an internal command; these are distinct failure boundaries. ### Typed outcome or recovery expected A failed protocol readback must keep the existing `cleanup_incomplete` outcome and retained debugger ownership. Healthy readback plus proven inferior end must continue to close successfully. ### Analysis or suspected cause Observed in source: a shared helper couples native protocol readback and Linux descriptor verification, making a broad process-exit catch absorb both. Proposed structural fix: distinct protocol-policy and filesystem-descriptor helpers, with the final protocol check outside the exit-recovery block. Remove the combined helper. ### Additional context This is our own follow-up bug and will be fixed before further audit work. Original positive real-provider coverage is retained. Add a deterministic negative reproduction and repeat real first-close/CLI and post-close TTY checks.
bsakaguchi 2026-10-31 00:38:00 +00:00
  • closed this issue
  • added the
    triage
    bug
    labels
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3220
No description provided.