[GH-ISSUE #3405] Real Ghidra source-admission verifier reuses an imported session between rejection cases #1268

Closed
opened 2026-10-16 21:03:34 +00:00 by bsakaguchi · 0 comments
Owner

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

The real Ghidra verifier currently fails a valid imported-snapshot read because its negative source-admission cases reuse the same target session.

Reproduced on Linux x64, ordinary uid1004, Ghidra12.1.4/JDK21, REA 8dde6370d0809ad04cda3342d4e6f290f48aa063. The relevant verifier and session files are unchanged on current main 322506d0c0d39d3cd1e2e1c285c2cc23cfa73ee7.

Both node scripts/verify-real-ghidra.mjs --aarch64-jump-table and --cross-format stop in scripts/lib/real-ghidra-target-admission.mjs:157:

AssertionError: analyze_function accepted {"procedure":"0x40155b"}
at verifySourceReadFailures (.../real-ghidra-target-admission.mjs:157)

The focused public MCP reproduction observes:

  1. Digest change is rejected with artifact_changed.
  2. Missing source is rejected with artifact_changed.
  3. The fixture restores the file, then reopens that same target without closing its instantiated client. Retained-client health can now import the restored bytes.
  4. Replacing the original path with a directory then permits analyze_function to read the already admitted private snapshot. The verifier incorrectly requires rejection.

Cold admission and reading an existing immutable snapshot are different states. The fix should isolate each negative scenario in a fresh session, preserving the positive assertion that admitted facts remain readable after the original source disappears. Do not force a new source read on valid imported-snapshot operations or weaken rejection assertions.

Counterfactual verification changes only the fixture to call close_binary before each negative case. On the unchanged pinned runtime, the complete public MCP source-admission proof passes: changed/missing/directory return artifact_changed, permission returns access_denied, failed runtime roots are removed, and imported facts remain readable after source deletion. Resource measurement:86.55s wall/83.08s waited-child CPU on a busy shared host; not a speedup comparison. Full normal package validation and pinned-main remote CI pass independently.

Originally created by @N0zoM1z0 on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3405 The real Ghidra verifier currently fails a valid imported-snapshot read because its negative source-admission cases reuse the same target session. Reproduced on Linux x64, ordinary uid1004, Ghidra12.1.4/JDK21, REA `8dde6370d0809ad04cda3342d4e6f290f48aa063`. The relevant verifier and session files are unchanged on current main `322506d0c0d39d3cd1e2e1c285c2cc23cfa73ee7`. Both `node scripts/verify-real-ghidra.mjs --aarch64-jump-table` and `--cross-format` stop in `scripts/lib/real-ghidra-target-admission.mjs:157`: ```text AssertionError: analyze_function accepted {"procedure":"0x40155b"} at verifySourceReadFailures (.../real-ghidra-target-admission.mjs:157) ``` The focused public MCP reproduction observes: 1. Digest change is rejected with `artifact_changed`. 2. Missing source is rejected with `artifact_changed`. 3. The fixture restores the file, then reopens that same target without closing its instantiated client. Retained-client health can now import the restored bytes. 4. Replacing the original path with a directory then permits `analyze_function` to read the already admitted private snapshot. The verifier incorrectly requires rejection. Cold admission and reading an existing immutable snapshot are different states. The fix should isolate each negative scenario in a fresh session, preserving the positive assertion that admitted facts remain readable after the original source disappears. Do not force a new source read on valid imported-snapshot operations or weaken rejection assertions. Counterfactual verification changes only the fixture to call `close_binary` before each negative case. On the unchanged pinned runtime, the complete public MCP source-admission proof passes: changed/missing/directory return `artifact_changed`, permission returns `access_denied`, failed runtime roots are removed, and imported facts remain readable after source deletion. Resource measurement:86.55s wall/83.08s waited-child CPU on a busy shared host; not a speedup comparison. Full normal package validation and pinned-main remote CI pass independently.
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#1268
No description provided.