[GH-ISSUE #6572] [Bug] Invalid managed signature type references are reported decoded with complete coverage #3963

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

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

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

The production member inspector reports signature.parse_status: "decoded", signature.issue: null, metadata.status: "complete", and coverage: {"state":"complete","issues":[]} for a field signature containing a reserved TypeDefOrRefOrSpec tag. A second fixture referencing a nonexistent TypeSpec row receives the same complete result. These are deliberately malformed signature operands inside otherwise admitted PE/CLI fixtures; this report does not claim rejection of valid assemblies.

The observed boundary was inspectManagedMembersBytes, the implementation selected by the public inspect_managed_members operation. Full CLI/MCP execution was not run.

Reproduction

One isolated source probe ran once with three fixture variants. It imported buildManagedPeFixture and managedPeFixtureTarget from src/dotnet/ManagedPe.fixture.ts and inspectManagedMembersBytes from src/dotnet/ManagedMemberInspector.ts, then executed the following operation for each signature:

const bytes = buildManagedPeFixture({ fieldSignature: Buffer.from(signature) });
const result = inspectManagedMembersBytes(bytes, managedPeFixtureTarget(bytes));
console.log(result.fields[0].signature, result.metadata.status, result.coverage);

The control signature was [0x06, 0x08] (FIELD I4); the reserved-tag case was [0x06, 0x12, 0x07] (FIELD CLASS, coded index 7, tag 3); the nonexistent-row case was [0x06, 0x12, 0x06] (TypeSpec row 1 in a fixture with no TypeSpec table). Both defective variants returned the incorrect complete result in this single probe; the primitive control returned decoded i4 with complete coverage. No repeat or minimization run was performed.

Proposed public-interface confirmation, not executed: save the reserved-tag fixture as reserved-tag.dll and run rea inspect-managed-members reserved-tag.dll --json.

Expected behavior

A reserved coded-index tag or a reference to an absent metadata row must remain an invalid signature fact, with a diagnostic and incomplete member coverage. Readable field names and raw signature hashes can remain available. Ordinary valid signatures such as the FIELD I4 control should remain decoded with complete coverage.

REA already defines the permitted signature operand tables as [TypeDef, TypeRef, TypeSpec] and has an explicit invalid-row failure for an invalid TypeDefOrRefOrSpec operand in ManagedMemberInspectorCore.ts, lines 483–508. The shared coded-index validator, lines 396–412 explicitly rejects undefined tags and nonexistent rows. This is inconsistent validation of existing signature forms, not a request to decode an additional form.

Impact and scope

The observed consequence is false complete member Evidence for malformed managed type references, with no diagnostic identifying the invalid signature. The raw bytes remain represented by their hashes, and resolved_sha256 correctly remains null; no false resolved name was observed. The probe establishes the field-signature cases above. NOT_ENOUGH_INFO: prevalence in real artifacts, effects on other signature positions, downstream comparison effects, and availability of a practical workaround were not tested.

REA version

Source commit 46111dd091f2ae01baab9eb119b53b9bd309a05b, package version 6.7.0. npm's current published release was also 6.7.0 at investigation start.

Runtime and platform

Node.js v24.22.1; Linux x64. The probe used the repository's locked dependencies. No CLR, Hopper, Ghidra, target loading, or target execution was involved.

Target and artifact context

Disposable PE32/CLI fixtures generated with the repository's existing buildManagedPeFixture helper. Only the requested field-signature bytes differed across the three fixture variants.

Interface

Other

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Observed output for the reserved-tag fixture, projected directly from the production inspector result:

{
  "signature_hex": "061207",
  "signature": {
    "kind": "field",
    "parse_status": "decoded",
    "field_type": "class:7",
    "issue": null,
    "resolved_sha256": null
  },
  "metadata_status": "complete",
  "coverage": {"state": "complete", "issues": []}
}

The nonexistent-TypeSpec case returned the same status and coverage with signature_hex: "061206" and field_type: "class:6". The control returned field_type: "i4", parse_status: "decoded", and complete coverage.

The public path is established by managed CLI registration, lines 78–95 and ManagedStaticProvider.ts, lines 211–218. The probe exercised the exact byte inspector selected by the latter; adapter behavior itself was not executed.

Typed outcome or recovery expected

Retain the field's readable facts and raw signature hash while identifying its invalid type reference and marking the affected signature/member coverage incomplete. Do not turn unsupported name resolution into successful validation of an invalid coded index.

Analysis or suspected cause

Source-derived cause: field/member signature decoding, lines 756–782 calls readTypeSignature without a metadata layout, so its operand validation guard is skipped. The name-digest resolver, lines 198–209 returns null for both the TypeSpec tag and the undefined fourth tag, without recording an invalid-row issue. Coverage construction, lines 325–345 consequently reports complete metadata and member coverage.

Additional context

Searched open and closed issues for TypeDefOrRef, TypeDefOrRefOrSpec, signature/reserved, signature/coded, signature/missing/row, and TypeSpec/invalid. Related #3877 concerns mismatched field/method signature kinds, #6558 concerns method-header locals tokens, and #5149 requests resolved type names; those reports do not cover invalid type-reference operands reported as decoded.

Evidence provenance: observed production-boundary probe, with source-derived public reachability and cause. Local verification: reproduced. Reproduction completeness: complete at the production byte-inspection boundary; NOT_ENOUGH_INFO for full CLI/MCP execution and a last-known-good release. No fix or restoration check was run. A restoration check should make the two malformed operands report their invalidity while preserving the complete primitive control.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: The isolated production inspector returned complete, diagnostic-free member Evidence for two deliberately invalid signature type references; the demonstrated consequence is bounded evidence-quality loss on malformed artifacts, not valid-input failure or target mutation.
  • Workaround status: unverified
  • Workaround basis: An independent metadata validator might identify the invalid signatures, but no alternate REA path or external validation workaround was exercised.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6572 ## Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ## Area Evidence, artifacts, or reconstruction ## Observed behavior The production member inspector reports `signature.parse_status: "decoded"`, `signature.issue: null`, `metadata.status: "complete"`, and `coverage: {"state":"complete","issues":[]}` for a field signature containing a reserved TypeDefOrRefOrSpec tag. A second fixture referencing a nonexistent TypeSpec row receives the same complete result. These are deliberately malformed signature operands inside otherwise admitted PE/CLI fixtures; this report does not claim rejection of valid assemblies. The observed boundary was `inspectManagedMembersBytes`, the implementation selected by the public `inspect_managed_members` operation. Full CLI/MCP execution was not run. ## Reproduction One isolated source probe ran once with three fixture variants. It imported `buildManagedPeFixture` and `managedPeFixtureTarget` from `src/dotnet/ManagedPe.fixture.ts` and `inspectManagedMembersBytes` from `src/dotnet/ManagedMemberInspector.ts`, then executed the following operation for each signature: ```ts const bytes = buildManagedPeFixture({ fieldSignature: Buffer.from(signature) }); const result = inspectManagedMembersBytes(bytes, managedPeFixtureTarget(bytes)); console.log(result.fields[0].signature, result.metadata.status, result.coverage); ``` The control signature was `[0x06, 0x08]` (`FIELD I4`); the reserved-tag case was `[0x06, 0x12, 0x07]` (`FIELD CLASS`, coded index 7, tag 3); the nonexistent-row case was `[0x06, 0x12, 0x06]` (TypeSpec row 1 in a fixture with no TypeSpec table). Both defective variants returned the incorrect complete result in this single probe; the primitive control returned decoded `i4` with complete coverage. No repeat or minimization run was performed. Proposed public-interface confirmation, not executed: save the reserved-tag fixture as `reserved-tag.dll` and run `rea inspect-managed-members reserved-tag.dll --json`. ## Expected behavior A reserved coded-index tag or a reference to an absent metadata row must remain an invalid signature fact, with a diagnostic and incomplete member coverage. Readable field names and raw signature hashes can remain available. Ordinary valid signatures such as the `FIELD I4` control should remain decoded with complete coverage. REA already defines the permitted signature operand tables as `[TypeDef, TypeRef, TypeSpec]` and has an explicit invalid-row failure for an invalid TypeDefOrRefOrSpec operand in [ManagedMemberInspectorCore.ts, lines 483–508](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/dotnet/ManagedMemberInspectorCore.ts#L483-L508). The shared [coded-index validator, lines 396–412](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/dotnet/ManagedMetadataHeaps.ts#L396-L412) explicitly rejects undefined tags and nonexistent rows. This is inconsistent validation of existing signature forms, not a request to decode an additional form. ## Impact and scope The observed consequence is false complete member Evidence for malformed managed type references, with no diagnostic identifying the invalid signature. The raw bytes remain represented by their hashes, and `resolved_sha256` correctly remains null; no false resolved name was observed. The probe establishes the field-signature cases above. NOT_ENOUGH_INFO: prevalence in real artifacts, effects on other signature positions, downstream comparison effects, and availability of a practical workaround were not tested. ## REA version Source commit `46111dd091f2ae01baab9eb119b53b9bd309a05b`, package version `6.7.0`. npm's current published release was also `6.7.0` at investigation start. ## Runtime and platform Node.js `v24.22.1`; Linux x64. The probe used the repository's locked dependencies. No CLR, Hopper, Ghidra, target loading, or target execution was involved. ## Target and artifact context Disposable PE32/CLI fixtures generated with the repository's existing `buildManagedPeFixture` helper. Only the requested field-signature bytes differed across the three fixture variants. ## Interface Other ## Earliest failure stage Native analysis or reconstruction ## Relevant output or evidence Observed output for the reserved-tag fixture, projected directly from the production inspector result: ```json { "signature_hex": "061207", "signature": { "kind": "field", "parse_status": "decoded", "field_type": "class:7", "issue": null, "resolved_sha256": null }, "metadata_status": "complete", "coverage": {"state": "complete", "issues": []} } ``` The nonexistent-TypeSpec case returned the same status and coverage with `signature_hex: "061206"` and `field_type: "class:6"`. The control returned `field_type: "i4"`, `parse_status: "decoded"`, and complete coverage. The public path is established by [managed CLI registration, lines 78–95](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/cli/managedCommands.ts#L78-L95) and [ManagedStaticProvider.ts, lines 211–218](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/dotnet/ManagedStaticProvider.ts#L211-L218). The probe exercised the exact byte inspector selected by the latter; adapter behavior itself was not executed. ## Typed outcome or recovery expected Retain the field's readable facts and raw signature hash while identifying its invalid type reference and marking the affected signature/member coverage incomplete. Do not turn unsupported name resolution into successful validation of an invalid coded index. ## Analysis or suspected cause Source-derived cause: [field/member signature decoding, lines 756–782](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/dotnet/ManagedMemberInspectorCore.ts#L756-L782) calls `readTypeSignature` without a metadata layout, so its operand validation guard is skipped. The [name-digest resolver, lines 198–209](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/dotnet/ManagedTypeNameDigests.ts#L198-L209) returns null for both the TypeSpec tag and the undefined fourth tag, without recording an invalid-row issue. [Coverage construction, lines 325–345](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/dotnet/ManagedMemberInspector.ts#L325-L345) consequently reports complete metadata and member coverage. ## Additional context Searched open and closed issues for `TypeDefOrRef`, `TypeDefOrRefOrSpec`, signature/reserved, signature/coded, signature/missing/row, and TypeSpec/invalid. Related #3877 concerns mismatched field/method signature kinds, #6558 concerns method-header locals tokens, and #5149 requests resolved type names; those reports do not cover invalid type-reference operands reported as decoded. Evidence provenance: observed production-boundary probe, with source-derived public reachability and cause. Local verification: reproduced. Reproduction completeness: complete at the production byte-inspection boundary; NOT_ENOUGH_INFO for full CLI/MCP execution and a last-known-good release. No fix or restoration check was run. A restoration check should make the two malformed operands report their invalidity while preserving the complete primitive control. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: The isolated production inspector returned complete, diagnostic-free member Evidence for two deliberately invalid signature type references; the demonstrated consequence is bounded evidence-quality loss on malformed artifacts, not valid-input failure or target mutation. - Workaround status: unverified - Workaround basis: An independent metadata validator might identify the invalid signatures, but no alternate REA path or external validation workaround was exercised.
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#3963
No description provided.