[GH-ISSUE #5076] [Bug] Go inspection reports successful Evidence for a 64-bit Mach-O with a misaligned load command #3113

Closed
opened 2026-10-31 00:36:47 +00:00 by bsakaguchi · 2 comments
Owner

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

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

The real GoBinaryService and GoBinaryProvider return successful inspect_go_binary Evidence for a 44-byte synthetic 64-bit thin Mach-O whose sole load command has cmdsize = 12. The Evidence says confidence: "observed", format: "macho", bits: 64, and build_info: null. The built-in Apple reader rejects the same bytes as malformed: load command 0 at offset 0 has invalid cmdsize 12.

This is an executed shared-workflow/provider-boundary reproduction without mocks. The packaged CLI and MCP transport were not executed.

Reproduction

From the source checkout at the revision below, with its locked dependencies already installed, run this reduced probe. It creates only inert fixtures and invokes the production service and readers; it never executes the fixtures.

WORK=$(mktemp -d)
mkdir -p "$WORK/home" "$WORK/config"
env -i PATH="$PATH" HOME="$WORK/home" XDG_CONFIG_HOME="$WORK/config" WORK="$WORK" node --import tsx --input-type=module <<'JS'
import { writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { GoBinaryProvider } from './src/go/GoBinaryProvider.ts';
import { GoBinaryService } from './src/application/go/GoBinaryService.ts';
import { readMachoImage } from './src/artifacts/apple/MachoLoadCommandReader.ts';
const service = new GoBinaryService(new GoBinaryProvider());
try {
  for (const [bits, size] of [[64,12], [64,16], [64,10], [32,12]]) {
    const header = bits === 64 ? 32 : 28;
    const bytes = Buffer.alloc(header + size);
    [bits === 64 ? 0xfeedfacf : 0xfeedface,
     bits === 64 ? 0x0100000c : 7, bits === 64 ? 0 : 3,
     2, 1, size, 0, ...(bits === 64 ? [0] : [])]
      .forEach((v,i) => bytes.writeUInt32LE(v,i*4));
    bytes.writeUInt32LE(0x7f000001,header);
    bytes.writeUInt32LE(size,header+4);
    const path = join(process.env.WORK, `fixture-${bits}-${size}.bin`);
    await writeFile(path,bytes);
    const go = await service.inspect({path});
    const apple = await readMachoImage(
      async (offset,length) => bytes.subarray(offset,offset+length), bytes.length);
    console.log(JSON.stringify({bits,cmdsize:size,go_ok:go.ok,
      apple_status:apple.status,reason:apple.reason ?? null}));
  }
} finally { await service.close(); }
JS

Expected behavior

Reject the 64-bit size-12 command with an input-format failure, preserving 32-bit size-12 acceptance. The Go contract promises an input-format failure for malformed supported containers. The Apple reader's width-dependent alignment and existing alignment test establish this exact distinction.

Impact and scope

Malformed-container bytes become successful observed Evidence instead of an input-format failure. The size-12 case reproduced twice through the real shared service/provider; the 64-bit size-16 and 32-bit size-12 controls succeed, while 64-bit size 10 fails as expected. This establishes bounded incorrect classification, not a crash or incorrect populated Go metadata. NOT_ENOUGH_INFO: real-world frequency, downstream consequences, Rust runtime behavior, and a same-artifact workaround were not established.

REA version

Source package version 6.7.0, tested main SHA 3537e58c1ab29309f06eabf50bc52adba9817a0c.

Runtime and platform

Node.js v26.12.0; macOS 27.0.1 (26A434), darwin arm64. No native analysis engine was used.

Target and artifact context

Synthetic thin little-endian Mach-O: ARM64 64-bit failing fixture, one unknown non-required load command, ncmds=1, sizeofcmds=12, cmdsize=12, 44 total bytes. Controls use the same construction with command size 16 or 10, or an i386 32-bit header with size 12.

Interface

Other

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Observed production-boundary comparison:

bits cmdsize Go service                  Apple reader
64   12      success, build_info null     malformed: invalid cmdsize 12
64   16      success                      parsed
64   10      failure: invalid_format      malformed: invalid cmdsize 10
32   12      success                      parsed

The public CLI command delegates to this service. The real provider reads stable file bytes then calls readGoBinaryImage, which dispatches thin Mach-O to readGoMachoImage. That reader accepts any command size divisible by four.

Typed outcome or recovery expected

An input failure with issue reason invalid_format, consistent with the size-10 control and the provider's existing malformed-format mapping. Do not emit successful inspection Evidence from the malformed 64-bit command stream.

Analysis or suspected cause

Source-derived and consistent with execution: readGoMachoImage knows the header width but hardcodes % 4 for every load command. The Apple reader derives alignment as 8 for 64-bit images and 4 for 32-bit images.

Additional context

Relevant Go reader, service, CLI adapter, Apple reader/test and Go documentation sources are identical between tested main and stable tag rea-agents-6.7.0 (stable SHA 27dc42d10249f0410904a75c0997842eb03b931c). This is source equality only; the published stable package was not executed. No last known good version is established.

Originally created by @coygeek on GitHub (Oct 18, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5076 ## 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 The real `GoBinaryService` and `GoBinaryProvider` return successful `inspect_go_binary` Evidence for a 44-byte synthetic 64-bit thin Mach-O whose sole load command has `cmdsize = 12`. The Evidence says `confidence: "observed"`, `format: "macho"`, `bits: 64`, and `build_info: null`. The built-in Apple reader rejects the same bytes as malformed: `load command 0 at offset 0 has invalid cmdsize 12`. This is an executed shared-workflow/provider-boundary reproduction without mocks. The packaged CLI and MCP transport were not executed. ## Reproduction From the source checkout at the revision below, with its locked dependencies already installed, run this reduced probe. It creates only inert fixtures and invokes the production service and readers; it never executes the fixtures. ```sh WORK=$(mktemp -d) mkdir -p "$WORK/home" "$WORK/config" env -i PATH="$PATH" HOME="$WORK/home" XDG_CONFIG_HOME="$WORK/config" WORK="$WORK" node --import tsx --input-type=module <<'JS' import { writeFile } from 'node:fs/promises'; import { join } from 'node:path'; import { GoBinaryProvider } from './src/go/GoBinaryProvider.ts'; import { GoBinaryService } from './src/application/go/GoBinaryService.ts'; import { readMachoImage } from './src/artifacts/apple/MachoLoadCommandReader.ts'; const service = new GoBinaryService(new GoBinaryProvider()); try { for (const [bits, size] of [[64,12], [64,16], [64,10], [32,12]]) { const header = bits === 64 ? 32 : 28; const bytes = Buffer.alloc(header + size); [bits === 64 ? 0xfeedfacf : 0xfeedface, bits === 64 ? 0x0100000c : 7, bits === 64 ? 0 : 3, 2, 1, size, 0, ...(bits === 64 ? [0] : [])] .forEach((v,i) => bytes.writeUInt32LE(v,i*4)); bytes.writeUInt32LE(0x7f000001,header); bytes.writeUInt32LE(size,header+4); const path = join(process.env.WORK, `fixture-${bits}-${size}.bin`); await writeFile(path,bytes); const go = await service.inspect({path}); const apple = await readMachoImage( async (offset,length) => bytes.subarray(offset,offset+length), bytes.length); console.log(JSON.stringify({bits,cmdsize:size,go_ok:go.ok, apple_status:apple.status,reason:apple.reason ?? null})); } } finally { await service.close(); } JS ``` ## Expected behavior Reject the 64-bit size-12 command with an input-format failure, preserving 32-bit size-12 acceptance. The [Go contract](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/docs/go-binaries.md#L82-L86) promises an input-format failure for malformed supported containers. The [Apple reader's width-dependent alignment](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/src/artifacts/apple/MachoLoadCommandReader.ts#L325-L326) and [existing alignment test](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/src/artifacts/apple/MachoLoadCommandReader.test.ts#L549-L571) establish this exact distinction. ## Impact and scope Malformed-container bytes become successful observed Evidence instead of an input-format failure. The size-12 case reproduced twice through the real shared service/provider; the 64-bit size-16 and 32-bit size-12 controls succeed, while 64-bit size 10 fails as expected. This establishes bounded incorrect classification, not a crash or incorrect populated Go metadata. NOT_ENOUGH_INFO: real-world frequency, downstream consequences, Rust runtime behavior, and a same-artifact workaround were not established. ## REA version Source package version 6.7.0, tested main SHA `3537e58c1ab29309f06eabf50bc52adba9817a0c`. ## Runtime and platform Node.js v26.12.0; macOS 27.0.1 (26A434), darwin arm64. No native analysis engine was used. ## Target and artifact context Synthetic thin little-endian Mach-O: ARM64 64-bit failing fixture, one unknown non-required load command, `ncmds=1`, `sizeofcmds=12`, `cmdsize=12`, 44 total bytes. Controls use the same construction with command size 16 or 10, or an i386 32-bit header with size 12. ## Interface Other ## Earliest failure stage Native analysis or reconstruction ## Relevant output or evidence Observed production-boundary comparison: ```text bits cmdsize Go service Apple reader 64 12 success, build_info null malformed: invalid cmdsize 12 64 16 success parsed 64 10 failure: invalid_format malformed: invalid cmdsize 10 32 12 success parsed ``` [The public CLI command delegates to this service](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/src/cli/goCommands.ts#L26-L35). [The real provider reads stable file bytes then calls readGoBinaryImage](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/src/go/GoBinaryProvider.ts#L218-L227), which [dispatches thin Mach-O to readGoMachoImage](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/src/go/GoBinaryImage.ts#L238-L239). That reader [accepts any command size divisible by four](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/src/go/GoMachoImage.ts#L40-L47). ## Typed outcome or recovery expected An input failure with issue reason `invalid_format`, consistent with the size-10 control and the provider's existing malformed-format mapping. Do not emit successful inspection Evidence from the malformed 64-bit command stream. ## Analysis or suspected cause Source-derived and consistent with execution: `readGoMachoImage` knows the header width but hardcodes `% 4` for every load command. The Apple reader derives alignment as 8 for 64-bit images and 4 for 32-bit images. ## Additional context Relevant Go reader, service, CLI adapter, Apple reader/test and Go documentation sources are identical between tested main and stable tag `rea-agents-6.7.0` (stable SHA `27dc42d10249f0410904a75c0997842eb03b931c`). This is source equality only; the published stable package was not executed. No last known good version is established.
Author
Owner

@x1mm4nu3l commented on GitHub (Oct 20, 2026):

Confirmed on main 2538214e2, Linux/Node 24.18.0, through CLI and stdio MCP. This also affects inspect_rust_binary, which shares the container reader: both inspectors accept the 44-byte 64-bit/cmdsize-12 fixture while the Apple reader rejects it. The 64-bit/16 and 32-bit/12 controls succeed; 64-bit/10 is rejected. These are static malformed-input checks, not loader tests.

<!-- gh-comment-id:6286502610 --> @x1mm4nu3l commented on GitHub (Oct 20, 2026): Confirmed on main 2538214e2, Linux/Node 24.18.0, through CLI and stdio MCP. This also affects `inspect_rust_binary`, which shares the container reader: both inspectors accept the 44-byte 64-bit/cmdsize-12 fixture while the Apple reader rejects it. The 64-bit/16 and 32-bit/12 controls succeed; 64-bit/10 is rejected. These are static malformed-input checks, not loader tests.
Author
Owner

@coygeek commented on GitHub (Oct 24, 2026):

Checked the reported fix on main at d87e73f2db.

Go binary inspection now uses the common readBinaryContainer native reader instead of the previous separate Go Mach-O reader. The common Mach-O reader passes the known width into MachoLoadCommandCursor, which applies 8-byte alignment for 64-bit commands and 4-byte alignment for 32-bit. cmdsize 12 for the reported 44-byte 64-bit fixture thus produces BinaryFormatFailure(malformed), and the Go provider maps that to an AnalysisInputError issue invalid_format.

Implementation: GoBinaryImage.ts, readBinaryContainer.ts.

The relevant regression checks in GoMachoImage.alignment.test.ts passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.

<!-- gh-comment-id:6380728594 --> @coygeek commented on GitHub (Oct 24, 2026): Checked the reported fix on `main` at d87e73f2db50be72d33a4b3c7199af35518b441c. Go binary inspection now uses the common readBinaryContainer native reader instead of the previous separate Go Mach-O reader. The common Mach-O reader passes the known width into MachoLoadCommandCursor, which applies 8-byte alignment for 64-bit commands and 4-byte alignment for 32-bit. cmdsize 12 for the reported 44-byte 64-bit fixture thus produces BinaryFormatFailure(malformed), and the Go provider maps that to an AnalysisInputError issue invalid_format. Implementation: [GoBinaryImage.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/go/GoBinaryImage.ts#L57), [readBinaryContainer.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/native/metadata/readBinaryContainer.ts#L41). The relevant regression checks in [GoMachoImage.alignment.test.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/go/GoMachoImage.alignment.test.ts) passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.
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#3113
No description provided.