[GH-ISSUE #6558] [Bug] Invalid method locals-signature tokens receive complete managed coverage #3948

Closed
opened 2026-10-31 00:45:30 +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/6558

Before submitting

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

Area

Native analysis or decompilation

Observed behavior

An executed production-boundary probe of inspect_managed_members accepts a fat method header whose LocalVarSigTok names a MethodDef (0x06000001) or a nonexistent StandAloneSig row (0x11000001). Both return body.status: "present", body.issue: null, and coverage: {"state":"complete","issues":[]}. The fixture has no StandAloneSig table. The same result occurs in the published runtime and current main. A subsequent in-memory self-comparison reports an exact unchanged method with no limitations and complete coverage. CLI and MCP transports were not run.

Reproduction

Run this source-boundary program from the source checkout with its locked dependencies installed. It constructs inert PE/CLI byte fixtures and calls the production inspector; it does not build REA, load the assembly, invoke a provider, or execute CIL. This three-case inspector check was executed once per tested baseline. The saved evidence program additionally called the production comparison on each returned result.

node --import ./node_modules/tsx/dist/loader.mjs --input-type=module <<'JS'
import {buildManagedPeFixture,managedPeFixtureTarget} from './src/dotnet/ManagedPe.fixture.ts';
import {inspectManagedMembersBytes} from './src/dotnet/ManagedMemberInspector.ts';
for (const token of [0, 0x06000001, 0x11000001]) {
  const body = Buffer.alloc(13);
  body.writeUInt16LE(0x3013, 0); // fat, init-locals, 12-byte header
  body.writeUInt16LE(1, 2);      // max stack
  body.writeUInt32LE(1, 4);     // one byte of CIL
  body.writeUInt32LE(token, 8);
  body[12] = 0x2a;              // ret
  const bytes = buildManagedPeFixture({ilBody: body});
  const result = inspectManagedMembersBytes(bytes, managedPeFixtureTarget(bytes));
  console.log(JSON.stringify({token, tables: result.metadata.table_row_counts,
    body: result.methods[0].body, coverage: result.coverage}));
}
JS

The inline program preserves the executed fixture construction and inspector call. The retained run used an external .mts wrapper to import the source and published inspector modules and save each result; the inline command itself was not separately run. The public entry point rea inspect-managed-members fixture.dll --json reaches this same inspector through ManagedStaticProvider; that CLI command was not executed.

Expected behavior

A nonzero LocalVarSigTok must reference an existing StandAloneSig row describing local variables. A MethodDef token and a reference into an absent table cannot establish a valid locals declaration. Preserve the observed token and readable CIL, but report the malformed/unavailable locals fact in member/body coverage rather than unqualified complete coverage. Zero must remain the valid no-locals control. The format contract is ECMA-335 Partition II, fat method headers; REA also documents that missing or malformed member facts remain explicit in coverage and per-member status.

Impact and scope

Malformed PE/CLI inputs can appear fully inspected even though their retained method-header reference cannot name a locals signature. This also allows the malformed method into exact unchanged comparison output. Observed on two malformed fixtures and one valid no-locals control in each baseline; real-world frequency and CLR loading outcomes were not measured. The bounded defect concerns format validity and analysis coverage, not execution or a security boundary.

A consumer can detect the demonstrated wrong-table token from its prefix, but checking row existence additionally requires a metadata inventory. No existing end-to-end workaround was executed.

REA version

Main source 6c4d880f2dd9ca7d42593be916f90ec19b8a09d7 and installed npm rea-agents 6.7.0; both production inspector and comparison modules were executed.

Runtime and platform

Node.js v26.12.1, Linux x64. The source probe used the locked tsx loader with the ambient Node runtime rather than the repository-pinned Node toolchain. No CLR, Hopper, Ghidra, or target execution was used.

Target and artifact context

Synthetic managed PE fixture with one static void MethodDef, a fat method header, one ret CIL instruction, and no StandAloneSig table. The cases differ only in the four-byte LocalVarSigTok header field.

Interface

Other

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Observed for both baselines:

{"local_var_sig_token":null,"body_status":"present","body_issue":null,"coverage":{"state":"complete","issues":[]}}
{"local_var_sig_token":"0x06000001","body_status":"present","body_issue":null,"coverage":{"state":"complete","issues":[]}}
{"local_var_sig_token":"0x11000001","body_status":"present","body_issue":null,"coverage":{"state":"complete","issues":[]}}

The returned metadata.table_row_counts includes MethodDef: 1 and no StandAloneSig entry. Each malformed self-comparison returns method status: "unchanged", dimensions: [], match.basis: "exact-il-signature", match.confidence: "exact", limitations: [], and coverage.status: "complete-within-inputs". These are executed calls to the production comparison with the same inspection result on each side, not authenticated CLI Evidence round-trips.

Additional context

This is distinct from issue #6513, which compares a valid absent-versus-present locals-signature declaration. This report concerns failure to diagnose an invalid token during inspection and remains reproducible even if comparison starts noticing locals-signature presence. It is also independent of wrong-kind MethodDef/Field signature blobs: the MethodDef signature here is the normal decoded 00 00 01, and the defect is in a method-body header reference.

Restoration check (not executed): Both malformed tokens must retain a precise invalid locals-signature observation and partial/malformed coverage rather than an unqualified complete body. The zero-token fixture must continue reporting a complete no-locals method. A separate valid StandAloneSig fixture should remain readable; that positive case was not run in this investigation.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Both tested baselines directly report complete method/member coverage for two locally constructed invalid metadata references, and propagate those results into exact unchanged comparison output.
  • Workaround status: unverified
  • Workaround basis: The wrong token table is visible and a separate table inventory could identify missing rows, but no existing caller workflow that preserves valid coverage was executed.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6558 ### 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 Native analysis or decompilation ### Observed behavior An executed production-boundary probe of `inspect_managed_members` accepts a fat method header whose `LocalVarSigTok` names a MethodDef (`0x06000001`) or a nonexistent StandAloneSig row (`0x11000001`). Both return `body.status: "present"`, `body.issue: null`, and `coverage: {"state":"complete","issues":[]}`. The fixture has no StandAloneSig table. The same result occurs in the published runtime and current main. A subsequent in-memory self-comparison reports an exact unchanged method with no limitations and complete coverage. CLI and MCP transports were not run. ### Reproduction Run this source-boundary program from the source checkout with its locked dependencies installed. It constructs inert PE/CLI byte fixtures and calls the production inspector; it does not build REA, load the assembly, invoke a provider, or execute CIL. This three-case inspector check was executed once per tested baseline. The saved evidence program additionally called the production comparison on each returned result. ```sh node --import ./node_modules/tsx/dist/loader.mjs --input-type=module <<'JS' import {buildManagedPeFixture,managedPeFixtureTarget} from './src/dotnet/ManagedPe.fixture.ts'; import {inspectManagedMembersBytes} from './src/dotnet/ManagedMemberInspector.ts'; for (const token of [0, 0x06000001, 0x11000001]) { const body = Buffer.alloc(13); body.writeUInt16LE(0x3013, 0); // fat, init-locals, 12-byte header body.writeUInt16LE(1, 2); // max stack body.writeUInt32LE(1, 4); // one byte of CIL body.writeUInt32LE(token, 8); body[12] = 0x2a; // ret const bytes = buildManagedPeFixture({ilBody: body}); const result = inspectManagedMembersBytes(bytes, managedPeFixtureTarget(bytes)); console.log(JSON.stringify({token, tables: result.metadata.table_row_counts, body: result.methods[0].body, coverage: result.coverage})); } JS ``` The inline program preserves the executed fixture construction and inspector call. The retained run used an external `.mts` wrapper to import the source and published inspector modules and save each result; the inline command itself was not separately run. The public entry point `rea inspect-managed-members fixture.dll --json` reaches this same inspector through `ManagedStaticProvider`; that CLI command was not executed. ### Expected behavior A nonzero `LocalVarSigTok` must reference an existing StandAloneSig row describing local variables. A MethodDef token and a reference into an absent table cannot establish a valid locals declaration. Preserve the observed token and readable CIL, but report the malformed/unavailable locals fact in member/body coverage rather than unqualified complete coverage. Zero must remain the valid no-locals control. The format contract is ECMA-335 Partition II, fat method headers; REA also documents that missing or malformed member facts remain explicit in coverage and per-member status. ### Impact and scope Malformed PE/CLI inputs can appear fully inspected even though their retained method-header reference cannot name a locals signature. This also allows the malformed method into exact unchanged comparison output. Observed on two malformed fixtures and one valid no-locals control in each baseline; real-world frequency and CLR loading outcomes were not measured. The bounded defect concerns format validity and analysis coverage, not execution or a security boundary. A consumer can detect the demonstrated wrong-table token from its prefix, but checking row existence additionally requires a metadata inventory. No existing end-to-end workaround was executed. ### REA version Main source `6c4d880f2dd9ca7d42593be916f90ec19b8a09d7` and installed npm `rea-agents` 6.7.0; both production inspector and comparison modules were executed. ### Runtime and platform Node.js v26.12.1, Linux x64. The source probe used the locked `tsx` loader with the ambient Node runtime rather than the repository-pinned Node toolchain. No CLR, Hopper, Ghidra, or target execution was used. ### Target and artifact context Synthetic managed PE fixture with one static void MethodDef, a fat method header, one `ret` CIL instruction, and no StandAloneSig table. The cases differ only in the four-byte LocalVarSigTok header field. ### Interface Other ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence Observed for both baselines: ```json {"local_var_sig_token":null,"body_status":"present","body_issue":null,"coverage":{"state":"complete","issues":[]}} {"local_var_sig_token":"0x06000001","body_status":"present","body_issue":null,"coverage":{"state":"complete","issues":[]}} {"local_var_sig_token":"0x11000001","body_status":"present","body_issue":null,"coverage":{"state":"complete","issues":[]}} ``` The returned `metadata.table_row_counts` includes `MethodDef: 1` and no `StandAloneSig` entry. Each malformed self-comparison returns method `status: "unchanged"`, `dimensions: []`, `match.basis: "exact-il-signature"`, `match.confidence: "exact"`, `limitations: []`, and `coverage.status: "complete-within-inputs"`. These are executed calls to the production comparison with the same inspection result on each side, not authenticated CLI Evidence round-trips. - Expected source: [REA member coverage contract](https://github.com/morluto/rea/blob/6c4d880f2dd9ca7d42593be916f90ec19b8a09d7/docs/managed-code-analysis.md#L485-L488), and [ECMA-335 sixth edition, Partition II fat method headers](https://ecma-international.org/wp-content/uploads/ECMA-335_6th_edition_june_2012.pdf). - Failure source: Executed inspector outputs above; the [header reader reads LocalVarSigTok as a raw word](https://github.com/morluto/rea/blob/6c4d880f2dd9ca7d42593be916f90ec19b8a09d7/src/dotnet/ManagedMethodBodyReader.ts#L59-L66), [the body projects it without table/row validation](https://github.com/morluto/rea/blob/6c4d880f2dd9ca7d42593be916f90ec19b8a09d7/src/dotnet/ManagedMethodBodyReader.ts#L157-L176), and [the enclosing inspector returns complete coverage](https://github.com/morluto/rea/blob/6c4d880f2dd9ca7d42593be916f90ec19b8a09d7/src/dotnet/ManagedMemberInspector.ts#L304-L350). - Evidence provenance: observed, with the format requirement established from the specification and call-path explanation derived from source. - Local verification: reproduced at the production boundary; no CLI/MCP or CLR run. - Reproduction completeness: complete for the inspector coverage failure. ### Additional context This is distinct from issue #6513, which compares a valid absent-versus-present locals-signature declaration. This report concerns failure to diagnose an invalid token during inspection and remains reproducible even if comparison starts noticing locals-signature presence. It is also independent of wrong-kind MethodDef/Field signature blobs: the MethodDef signature here is the normal decoded `00 00 01`, and the defect is in a method-body header reference. Restoration check (not executed): Both malformed tokens must retain a precise invalid locals-signature observation and partial/malformed coverage rather than an unqualified complete body. The zero-token fixture must continue reporting a complete no-locals method. A separate valid StandAloneSig fixture should remain readable; that positive case was not run in this investigation. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Both tested baselines directly report complete method/member coverage for two locally constructed invalid metadata references, and propagate those results into exact unchanged comparison output. - Workaround status: unverified - Workaround basis: The wrong token table is visible and a separate table inventory could identify missing rows, but no existing caller workflow that preserves valid coverage was executed.
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#3948
No description provided.