[PR #5754] [CLOSED] fix(native): keep recorded-core note types owner-qualified #7039

Closed
opened 2026-11-01 21:44:54 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/5754
Author: @saiprasanth-git
Created: 10/21/2026
Status: ❌ Closed

Base: main ← Head: fix/recorded-crash-note-owner


📝 Commits (1)

  • 020ed2f fix(native): keep recorded-core note types owner-qualified

📊 Changes

7 files changed (+132 additions, -12 deletions)

View changed files

📝 bridge/pwntools/recorded_crash_impl.py (+4 -1)
📝 docs/recorded-crashes.md (+4 -1)
📝 src/domain/native/recordedCrash.ts (+7 -1)
📝 src/native/pwndbg/CoreFileMappingAuthority.ts (+10 -2)
📝 src/native/pwntools/RecordedCrashStructureBindings.ts (+13 -2)
📝 tests/boundary/binaryDiagnostics/RecordedCrashStructureBindings.test.ts (+87 -0)
📝 tests/fixtures/binaryDiagnostics/recordedCrash.ts (+7 -5)

📄 Description

Summary

Fixes #5700. inspect-recorded-crash now keeps note types owner-qualified. Only exact Linux CORE\0 notes receive pyelftools' CORE names (NT_PRSTATUS, NT_FILE, …). Every other owner (GNU, LINUX, …) reports its original numeric n_type. As a result, GNU/3 is no longer labeled NT_PRPSINFO, and a GNU note whose number collides with NT_FILE no longer triggers Linux mapping-table validation and a false --debugger-context refusal.

Problem and expected behavior

pyelftools 0.33 picks its note enum from e_type alone (ENUM_CORE_NOTE_N_TYPE for every ET_CORE note), whatever the owner. recorded_crash_impl.py emitted that name before its CORE-owner guard. RecordedCrashStructureBindings accepted the same owner-independent names, and CoreFileMappingAuthority selected mapping validation by symbolic type alone. On main d0067ba, with the issue's synthetic cores:

Fixture main this PR readelf
GNU/3 build-id {"owner_display":"GNU","type":"NT_PRPSINFO"} {"owner_display":"GNU","type":3} NT_GNU_BUILD_ID
GNU/0x46494c45 --debugger-context capability_unavailable: "missing mapping table header" reaches debugger configuration (REA_PWNDBG_GDB is unavailable; GDB absent) Unknown note type: (0x46494c45)
LINUX/0x53494749 (extra case) "type":"NT_SIGINFO" "type":1397311305 —
GNU/0x12345678 control 305419896; reaches debugger configuration unchanged —
CORE/3 control NT_PRPSINFO unchanged —
CORE/0x46494c45 control --debugger-context "missing mapping table header" unchanged —

This matches the expected behavior in the issue: GNU/3 keeps numeric type 3, unfamiliar GNU types stay opaque, only genuine CORE mapping notes receive mapping validation, and CORE naming and confinement checks are unchanged.

Change and scope

  • bridge/pwntools/recorded_crash_impl.py: use pyelftools' name only when owner == b"CORE\0"; otherwise emit the raw little-endian n_type from the note header. The supported profile is ELF64 little-endian only.
  • src/domain/native/recordedCrash.ts: the schema rejects symbolic note types on any non-CORE\0 owner. LINUX_CORE_OWNER_BASE64 is exported for reuse.
  • src/native/pwntools/RecordedCrashStructureBindings.ts: note kinds are bound per owner. CORE notes use the CORE map; other owners must report the exact raw number.
  • src/native/pwndbg/CoreFileMappingAuthority.ts: confinement applies only to NT_FILE notes with exact CORE owner bytes (defense in depth).
  • docs/recorded-crashes.md: documents owner-qualified note types.
  • Not included: symbolic GNU names (for example NT_GNU_BUILD_ID). The issue accepts "a GNU build-id name or numeric type 3", and numeric keeps the existing "only Linux CORE notes are interpreted" contract. GNU naming can follow separately if wanted.

Contribution scope: ordinary fix within the existing recorded-crash boundary; maintainer scope decision not applicable.

Contract and boundary impact

  • Semantic owner and earliest changed stage: bridge/pwntools/recorded_crash_impl.py note identity, then TypeScript structure binding and debugger mapping authority.

  • Contribution scope fit and linked maintainer decision: not applicable (bug fix).

  • CLI and MCP/tool-catalog contract: notes[].type for non-CORE owners changes from a CORE symbolic name to the original number. The schema already allowed string | number. CORE notes are unchanged.

  • Provider, bridge, target-format, or platform compatibility: same pinned pwntools 4.15.0 / pyelftools 0.33 / Unicorn 2.1.2 profile; no dependency change.

  • Evidence, artifact, provenance, or reconstruction contract: more truthful note identity; raw bytes and ranges are unchanged.

  • Target selection, authority, upstream behavior, and cleanup details: no target execution; mapping confinement is narrowed to genuine CORE NT_FILE notes.

  • Generated metadata, package, or installation impact: none.

  • Documentation or usability only; no target interaction.

Evidence and regression coverage

  • Tests added or updated (tests/boundary/binaryDiagnostics/RecordedCrashStructureBindings.test.ts, with a fixture tweak so numeric note types write their raw value):
    • GNU-owned notes with raw types 3, 0x46494c45, 0x53494749, 0x12345678 are admitted by the schema and structure binding only with their numeric type.
    • GNU-owned notes reported as NT_PRPSINFO / NT_FILE / NT_SIGINFO are rejected by both.
    • Mapping confinement still refuses a CORE NT_FILE with no mapping header, and skips a GNU-owned 0x46494c45 note, including one mislabeled NT_FILE.
  • Base reproduction: with the three TypeScript sources reverted to main, 6 of the new structure/schema tests fail. With only CoreFileMappingAuthority.ts reverted, the mapping test fails.
  • Python bridge: there is no in-repo test lane that runs real pyelftools, so the Python change is covered by the end-to-end CLI reproduction above. I used the issue's fixture script plus one LINUX-owned case, with isolated HOME/XDG/TMPDIR and REA_PWNTOOLS_PYTHON on Python 3.12 + pwntools 4.15.0 / pyelftools 0.33 / Unicorn 2.1.2.
  • Remaining proof gaps: Linux x64 / Node 24.18.0 only; no real producer cores; AArch64 notes only through unit fixtures; GDB/pwndbg absent, so full debugger enrichment was not exercised; MCP covered only by the existing recordedCrashMcp test.

Validation performed

Based on main d0067ba; head 020ed2f. Linux x64, Node 24.18.0.

  • npm run test:prepare: passed
  • npx vitest run tests/boundary/binaryDiagnostics tests/boundary/native tests/boundary/mcp/recordedCrashMcp.test.ts src/domain/native src/native tests/acceptance/tools/localToolContracts.test.ts tests/conformance/providerCompletion.test.ts tests/process-global/pwntoolsCliRemediation.test.ts tests/process-global/binaryDiagnosticsCliCleanup.test.ts: 47 files passed; 687 tests passed, 1 skipped
  • npx tsc --noEmit -p tsconfig.json: passed
  • npm run lint: passed
  • npm run verify:test-discovery: all 1878 test files discovered exactly once
  • npx prettier --check on changed TS/MD files: passed
  • python -m py_compile bridge/pwntools/recorded_crash_impl.py: passed

Compatibility, safety, and release

  • Breaking changes or migration steps: consumers that matched CORE names on non-CORE owners will now see numeric types. Those names were incorrect.
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: mapping confinement still applies to every genuine CORE NT_FILE; no new file or host access.

Author readiness

Human owner: @saiprasanth-git

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/5754 **Author:** [@saiprasanth-git](https://github.com/saiprasanth-git) **Created:** 10/21/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/recorded-crash-note-owner` --- ### 📝 Commits (1) - [`020ed2f`](https://github.com/morluto/rea/commit/020ed2fcb0f6476aced2ab87eeaa7c751714311c) fix(native): keep recorded-core note types owner-qualified ### 📊 Changes **7 files changed** (+132 additions, -12 deletions) <details> <summary>View changed files</summary> 📝 `bridge/pwntools/recorded_crash_impl.py` (+4 -1) 📝 `docs/recorded-crashes.md` (+4 -1) 📝 `src/domain/native/recordedCrash.ts` (+7 -1) 📝 `src/native/pwndbg/CoreFileMappingAuthority.ts` (+10 -2) 📝 `src/native/pwntools/RecordedCrashStructureBindings.ts` (+13 -2) 📝 `tests/boundary/binaryDiagnostics/RecordedCrashStructureBindings.test.ts` (+87 -0) 📝 `tests/fixtures/binaryDiagnostics/recordedCrash.ts` (+7 -5) </details> ### 📄 Description ## Summary Fixes #5700. `inspect-recorded-crash` now keeps note types owner-qualified. Only exact Linux `CORE\0` notes receive pyelftools' CORE names (`NT_PRSTATUS`, `NT_FILE`, …). Every other owner (GNU, LINUX, …) reports its original numeric `n_type`. As a result, GNU/3 is no longer labeled `NT_PRPSINFO`, and a GNU note whose number collides with `NT_FILE` no longer triggers Linux mapping-table validation and a false `--debugger-context` refusal. ## Problem and expected behavior pyelftools 0.33 picks its note enum from `e_type` alone (`ENUM_CORE_NOTE_N_TYPE` for every ET_CORE note), whatever the owner. `recorded_crash_impl.py` emitted that name before its CORE-owner guard. `RecordedCrashStructureBindings` accepted the same owner-independent names, and `CoreFileMappingAuthority` selected mapping validation by symbolic type alone. On `main` d0067ba, with the issue's synthetic cores: | Fixture | main | this PR | readelf | |---|---|---|---| | GNU/3 build-id | `{"owner_display":"GNU","type":"NT_PRPSINFO"}` | `{"owner_display":"GNU","type":3}` | `NT_GNU_BUILD_ID` | | GNU/`0x46494c45` `--debugger-context` | `capability_unavailable`: "missing mapping table header" | reaches debugger configuration (`REA_PWNDBG_GDB is unavailable`; GDB absent) | `Unknown note type: (0x46494c45)` | | LINUX/`0x53494749` (extra case) | `"type":"NT_SIGINFO"` | `"type":1397311305` | — | | GNU/`0x12345678` control | `305419896`; reaches debugger configuration | unchanged | — | | CORE/3 control | `NT_PRPSINFO` | unchanged | — | | CORE/`0x46494c45` control `--debugger-context` | "missing mapping table header" | unchanged | — | This matches the expected behavior in the issue: GNU/3 keeps numeric type 3, unfamiliar GNU types stay opaque, only genuine CORE mapping notes receive mapping validation, and CORE naming and confinement checks are unchanged. ## Change and scope - `bridge/pwntools/recorded_crash_impl.py`: use pyelftools' name only when `owner == b"CORE\0"`; otherwise emit the raw little-endian `n_type` from the note header. The supported profile is ELF64 little-endian only. - `src/domain/native/recordedCrash.ts`: the schema rejects symbolic note types on any non-`CORE\0` owner. `LINUX_CORE_OWNER_BASE64` is exported for reuse. - `src/native/pwntools/RecordedCrashStructureBindings.ts`: note kinds are bound per owner. CORE notes use the CORE map; other owners must report the exact raw number. - `src/native/pwndbg/CoreFileMappingAuthority.ts`: confinement applies only to `NT_FILE` notes with exact CORE owner bytes (defense in depth). - `docs/recorded-crashes.md`: documents owner-qualified note types. - Not included: symbolic GNU names (for example `NT_GNU_BUILD_ID`). The issue accepts "a GNU build-id name or numeric type 3", and numeric keeps the existing "only Linux CORE notes are interpreted" contract. GNU naming can follow separately if wanted. Contribution scope: ordinary fix within the existing recorded-crash boundary; maintainer scope decision not applicable. ## Contract and boundary impact - Semantic owner and earliest changed stage: `bridge/pwntools/recorded_crash_impl.py` note identity, then TypeScript structure binding and debugger mapping authority. - Contribution scope fit and linked maintainer decision: not applicable (bug fix). - CLI and MCP/tool-catalog contract: `notes[].type` for non-CORE owners changes from a CORE symbolic name to the original number. The schema already allowed `string | number`. CORE notes are unchanged. - Provider, bridge, target-format, or platform compatibility: same pinned pwntools 4.15.0 / pyelftools 0.33 / Unicorn 2.1.2 profile; no dependency change. - Evidence, artifact, provenance, or reconstruction contract: more truthful note identity; raw bytes and ranges are unchanged. - Target selection, authority, upstream behavior, and cleanup details: no target execution; mapping confinement is narrowed to genuine CORE `NT_FILE` notes. - Generated metadata, package, or installation impact: none. - [x] Documentation or usability only; no target interaction. ## Evidence and regression coverage - Tests added or updated (`tests/boundary/binaryDiagnostics/RecordedCrashStructureBindings.test.ts`, with a fixture tweak so numeric note types write their raw value): - GNU-owned notes with raw types 3, `0x46494c45`, `0x53494749`, `0x12345678` are admitted by the schema and structure binding only with their numeric type. - GNU-owned notes reported as `NT_PRPSINFO` / `NT_FILE` / `NT_SIGINFO` are rejected by both. - Mapping confinement still refuses a CORE `NT_FILE` with no mapping header, and skips a GNU-owned `0x46494c45` note, including one mislabeled `NT_FILE`. - Base reproduction: with the three TypeScript sources reverted to `main`, 6 of the new structure/schema tests fail. With only `CoreFileMappingAuthority.ts` reverted, the mapping test fails. - Python bridge: there is no in-repo test lane that runs real pyelftools, so the Python change is covered by the end-to-end CLI reproduction above. I used the issue's fixture script plus one LINUX-owned case, with isolated HOME/XDG/TMPDIR and `REA_PWNTOOLS_PYTHON` on Python 3.12 + pwntools 4.15.0 / pyelftools 0.33 / Unicorn 2.1.2. - Remaining proof gaps: Linux x64 / Node 24.18.0 only; no real producer cores; AArch64 notes only through unit fixtures; GDB/pwndbg absent, so full debugger enrichment was not exercised; MCP covered only by the existing `recordedCrashMcp` test. ## Validation performed Based on `main` d0067ba; head 020ed2f. Linux x64, Node 24.18.0. - `npm run test:prepare`: passed - `npx vitest run tests/boundary/binaryDiagnostics tests/boundary/native tests/boundary/mcp/recordedCrashMcp.test.ts src/domain/native src/native tests/acceptance/tools/localToolContracts.test.ts tests/conformance/providerCompletion.test.ts tests/process-global/pwntoolsCliRemediation.test.ts tests/process-global/binaryDiagnosticsCliCleanup.test.ts`: 47 files passed; 687 tests passed, 1 skipped - `npx tsc --noEmit -p tsconfig.json`: passed - `npm run lint`: passed - `npm run verify:test-discovery`: all 1878 test files discovered exactly once - `npx prettier --check` on changed TS/MD files: passed - `python -m py_compile bridge/pwntools/recorded_crash_impl.py`: passed ## Compatibility, safety, and release - Breaking changes or migration steps: consumers that matched CORE names on non-CORE owners will now see numeric types. Those names were incorrect. - Real Hopper/Ghidra, browser, or OS coverage: not applicable. - Package or release metadata impact: none. - Security, privacy, process, or containment review: mapping confinement still applies to every genuine CORE `NT_FILE`; no new file or host access. ## Author readiness Human owner: @saiprasanth-git - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:44:54 +00:00
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#7039
No description provided.