[GH-ISSUE #4945] [Bug] Shared pwntools cancellation drops reasons and can replace physical failures #3069

Closed
opened 2026-10-31 00:35:51 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @morluto on GitHub (Oct 18, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4945

Before submitting

  • Searched open and closed reports for pwntools cancellation/reason findings. Related: #4942 concerns core mapping authority, not this defect.
  • Evidence uses source-owned fixtures only.

Area

Native analysis or decompilation

Observed behavior

The shared pwntools decoder loses opaque cancellation reasons before admission, while queued, at owner-error translation and after final cleanup. Its outer catch also infers cancellation from AbortError names, equality with the current signal reason, or artifact cleanup metadata. A late signal can therefore replace an already observed physical failure. The optional pwndbg adapter repeats that heuristic.

Reproduction

At b33c0df02, added focused producer/adapter regressions and ran them: 15 failed, 7 controls passed. Actual public provider methods and real owned filesystem/process cleanup were used; only the Linux x64 availability gate was simulated on macOS.

  • Pre-aborted inspect / inspectAndClose, queued cancellation and final-root-cleanup cancellation return AnalysisCancelledError with cause === undefined instead of the selected object.
  • Cancelling immediately before the real Node snapshot write returns the Node AbortError envelope instead of its original reason.
  • Injected runtime acquisition failure named AbortError, or reused as the signal reason, is returned as cancellation rather than ProviderAdapterError.
  • Tagged command/artifact cancellation loses even explicit undefined/null/falsy reasons at the shared mapper.

Expected behavior

Consume tagged owner outcomes, retain exact opaque cancellation reasons, diagnostics, partial evidence and cleanup leases. Normalize Node filesystem cancellation at the API call that produced it. A physical failure must not change classification because an unrelated signal arrives.

Impact and scope

All providers sharing PwntoolsDecoder/PwntoolsFailures, including layout and recorded-crash context. Full native Python/pwndbg reproduction and external-client reason transport: NOT_ENOUGH_INFO; not run.

REA version

b33c0df02, source tests.

Runtime and platform

Pinned Node24.18.0, macOS arm64; existing isolated process-global host-gate simulation with real macOS process inspector prepared first.

Target and artifact context

Owned small ELF/core protocol fixtures and Node fixture processes; no external target execution.

Interface

Shared provider APIs and mapper; existing registered CLI/finalization controls.

Earliest failure stage

Admission, snapshot write, command/reader error projection and final cleanup.

Analysis

PwntoolsDecoder constructs reasonless cancellation errors and reinterprets caught failures using current signal/name/identity. PwntoolsFailures ignores existing OwnedCommandFailure.cancellation and ArtifactReaderFailure.cancellation facts. PwndbgCoreContext duplicates the outer heuristic. Pinned Node fs source and a real aborted write confirm its ABORT_ERR envelope carries the original reason in cause.

Originally created by @morluto on GitHub (Oct 18, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4945 ### Before submitting - [x] Searched open and closed reports for pwntools cancellation/reason findings. Related: #4942 concerns core mapping authority, not this defect. - [x] Evidence uses source-owned fixtures only. ### Area Native analysis or decompilation ### Observed behavior The shared pwntools decoder loses opaque cancellation reasons before admission, while queued, at owner-error translation and after final cleanup. Its outer catch also infers cancellation from `AbortError` names, equality with the current signal reason, or artifact cleanup metadata. A late signal can therefore replace an already observed physical failure. The optional pwndbg adapter repeats that heuristic. ### Reproduction At b33c0df02, added focused producer/adapter regressions and ran them: 15 failed, 7 controls passed. Actual public provider methods and real owned filesystem/process cleanup were used; only the Linux x64 availability gate was simulated on macOS. - Pre-aborted `inspect` / `inspectAndClose`, queued cancellation and final-root-cleanup cancellation return `AnalysisCancelledError` with `cause === undefined` instead of the selected object. - Cancelling immediately before the real Node snapshot write returns the Node AbortError envelope instead of its original reason. - Injected runtime acquisition failure named AbortError, or reused as the signal reason, is returned as cancellation rather than `ProviderAdapterError`. - Tagged command/artifact cancellation loses even explicit undefined/null/falsy reasons at the shared mapper. ### Expected behavior Consume tagged owner outcomes, retain exact opaque cancellation reasons, diagnostics, partial evidence and cleanup leases. Normalize Node filesystem cancellation at the API call that produced it. A physical failure must not change classification because an unrelated signal arrives. ### Impact and scope All providers sharing PwntoolsDecoder/PwntoolsFailures, including layout and recorded-crash context. Full native Python/pwndbg reproduction and external-client reason transport: NOT_ENOUGH_INFO; not run. ### REA version b33c0df02, source tests. ### Runtime and platform Pinned Node24.18.0, macOS arm64; existing isolated process-global host-gate simulation with real macOS process inspector prepared first. ### Target and artifact context Owned small ELF/core protocol fixtures and Node fixture processes; no external target execution. ### Interface Shared provider APIs and mapper; existing registered CLI/finalization controls. ### Earliest failure stage Admission, snapshot write, command/reader error projection and final cleanup. ### Analysis PwntoolsDecoder constructs reasonless cancellation errors and reinterprets caught failures using current signal/name/identity. PwntoolsFailures ignores existing `OwnedCommandFailure.cancellation` and `ArtifactReaderFailure.cancellation` facts. PwndbgCoreContext duplicates the outer heuristic. Pinned Node fs source and a real aborted write confirm its ABORT_ERR envelope carries the original reason in `cause`.
bsakaguchi 2026-10-31 00:35:51 +00:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@morluto commented on GitHub (Oct 18, 2026):

Fixed on main in 08fbeb8bd and 1f23e977b.

Root cause: shared adapters discarded producer-owned cancellation envelopes and inferred cancellation from late signals or exception names. Cleanup errors also outlived the exact resources they described.

The fixes preserve opaque cancellation reasons and physical failures, translate Node snapshot-write cancellation at its producing boundary, and bind retained process/root/file cleanup to their exact owners. Failed file cleanup retains the root; cancellation during failed final cleanup preserves decoded facts and the original reason through retry.

Validation: 68 focused tests across nine files passed again after rebasing; pre-push typecheck and lint passed. Earlier documentation checks passed (5 tests), with test discovery covering 1,577 files. Controlled fixtures exercise actual Node processes and filesystem cleanup; the Linux availability gate is simulated on macOS. This does not establish native pwntools/GDB behavior or performance measurements. The heavy CPU test and profiler were not restarted.

<!-- gh-comment-id:6244914646 --> @morluto commented on GitHub (Oct 18, 2026): Fixed on main in 08fbeb8bd and 1f23e977b. Root cause: shared adapters discarded producer-owned cancellation envelopes and inferred cancellation from late signals or exception names. Cleanup errors also outlived the exact resources they described. The fixes preserve opaque cancellation reasons and physical failures, translate Node snapshot-write cancellation at its producing boundary, and bind retained process/root/file cleanup to their exact owners. Failed file cleanup retains the root; cancellation during failed final cleanup preserves decoded facts and the original reason through retry. Validation: 68 focused tests across nine files passed again after rebasing; pre-push typecheck and lint passed. Earlier documentation checks passed (5 tests), with test discovery covering 1,577 files. Controlled fixtures exercise actual Node processes and filesystem cleanup; the Linux availability gate is simulated on macOS. This does not establish native pwntools/GDB behavior or performance measurements. The heavy CPU test and profiler were not restarted.
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#3069
No description provided.