[GH-ISSUE #5649] [Bug] inspect-macho treats dependencies as exhaustive when LC_LAZY_LOAD_DYLIB_INFO is present #3421

Closed
opened 2026-10-31 00:40:12 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @cursor[bot] on GitHub (Oct 20, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/5649

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

Source-derived, then checked with a synthetic otool -l fixture against inspectNativeMacho on current main before this report's fix. When otool -l prints LC_LAZY_LOAD_DYLIB_INFO (cmdsize 16, dataoff, datasize) and a normal LC_LOAD_DYLIB, inspect_macho keeps the raw load command but omits the lazy install name from dependencies while setting dependencies.exhaustive to true and limitations to empty. otool -l does not print that install name; it lives in the linkedit payload. This is the inspect-macho consumer of the same omission as #5551.

A macOS inspect-macho CLI replay of a -Wl,-lazy_library executable was not run in this environment.

Reproduction

On current main, parse this otool -h -l shape (header counts filled by the test helper) through inspectNativeMacho:

Load command 0
      cmd LC_LOAD_DYLIB
  cmdsize 56
         name /usr/lib/libSystem.B.dylib (offset 24)
   time stamp 2 Thu Jan  1 00:00:02 1970
      current version 1.0.0
compatibility version 1.0.0
Load command 1
      cmd LC_LAZY_LOAD_DYLIB_INFO
  cmdsize 16
    dataoff 49304
   datasize 56

Observed projection before the reader change: dependencies.items contained only libSystem, exhaustive was true, and total equaled that item count. The lazy command remained under load_commands.

Expected behavior

docs/tool-design.md requires missing coverage to stay unknown rather than become absence. dependencies.exhaustive must be false, with a limitation naming LC_LAZY_LOAD_DYLIB_INFO, unless the install name is actually read. The trace tool owns the payload parse (#5551). Classic LC_LOAD_DYLIB rows stay exhaustive when this command is absent.

Impact and scope

P2 for the tested command. A caller can treat the dependency list as complete and miss a first-use lazy load. No macOS CLI frequency was measured. No security-boundary crossing was established.

REA version

rea-agents 6.7.0, source commit b3aadaf474e59b33e5ff465236008a67eccefb87.

Runtime and platform

Node.js v24.18.0; Linux; no Apple clang, otool, or Hopper/Ghidra. The check used the in-process native inspection normalizer and a synthetic otool transcript.

Target and artifact context

Synthetic otool transcript for a thin arm64 Mach-O with one LC_LOAD_DYLIB and one LC_LAZY_LOAD_DYLIB_INFO. Not a captured Apple binary.

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

The normalizer is src/native/NativeMachoInspection.ts, which called covered(load.dependencies, true). src/native/parsers/otool.ts only copies commands in DYLIB_COMMANDS into dependencies. LC_LAZY_LOAD_DYLIB_INFO was stored as a raw command and dropped from that list. The regression now expects exhaustive: false and a limitation containing 1 LC_LAZY_LOAD_DYLIB_INFO.

Typed outcome or recovery expected

Keep the raw load command. Mark the dependency inventory non-exhaustive and name the omitted command. Do not invent an install name from otool text that does not contain one.

Analysis or suspected cause

Same producing omission as #5551 at the otool boundary: unrecognized dependency-bearing command text is treated as absence, and the inspection layer then marks the resulting list exhaustive.

Additional context

Related: #5551. The structural reader, not otool -l, can see the linkedit install name.

Originally created by @cursor[bot] on GitHub (Oct 20, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5649 ### 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 Source-derived, then checked with a synthetic `otool -l` fixture against `inspectNativeMacho` on current main before this report's fix. When `otool -l` prints `LC_LAZY_LOAD_DYLIB_INFO` (`cmdsize 16`, `dataoff`, `datasize`) and a normal `LC_LOAD_DYLIB`, `inspect_macho` keeps the raw load command but omits the lazy install name from `dependencies` while setting `dependencies.exhaustive` to true and `limitations` to empty. `otool -l` does not print that install name; it lives in the linkedit payload. This is the inspect-macho consumer of the same omission as #5551. A macOS `inspect-macho` CLI replay of a `-Wl,-lazy_library` executable was not run in this environment. ### Reproduction On current main, parse this `otool -h -l` shape (header counts filled by the test helper) through `inspectNativeMacho`: ```text Load command 0 cmd LC_LOAD_DYLIB cmdsize 56 name /usr/lib/libSystem.B.dylib (offset 24) time stamp 2 Thu Jan 1 00:00:02 1970 current version 1.0.0 compatibility version 1.0.0 Load command 1 cmd LC_LAZY_LOAD_DYLIB_INFO cmdsize 16 dataoff 49304 datasize 56 ``` Observed projection before the reader change: `dependencies.items` contained only libSystem, `exhaustive` was true, and `total` equaled that item count. The lazy command remained under `load_commands`. ### Expected behavior `docs/tool-design.md` requires missing coverage to stay unknown rather than become absence. `dependencies.exhaustive` must be false, with a limitation naming `LC_LAZY_LOAD_DYLIB_INFO`, unless the install name is actually read. The trace tool owns the payload parse (#5551). Classic `LC_LOAD_DYLIB` rows stay exhaustive when this command is absent. ### Impact and scope P2 for the tested command. A caller can treat the dependency list as complete and miss a first-use lazy load. No macOS CLI frequency was measured. No security-boundary crossing was established. ### REA version rea-agents 6.7.0, source commit `b3aadaf474e59b33e5ff465236008a67eccefb87`. ### Runtime and platform Node.js v24.18.0; Linux; no Apple clang, otool, or Hopper/Ghidra. The check used the in-process native inspection normalizer and a synthetic otool transcript. ### Target and artifact context Synthetic otool transcript for a thin arm64 Mach-O with one `LC_LOAD_DYLIB` and one `LC_LAZY_LOAD_DYLIB_INFO`. Not a captured Apple binary. ### Interface CLI ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence The normalizer is `src/native/NativeMachoInspection.ts`, which called `covered(load.dependencies, true)`. `src/native/parsers/otool.ts` only copies commands in `DYLIB_COMMANDS` into `dependencies`. `LC_LAZY_LOAD_DYLIB_INFO` was stored as a raw command and dropped from that list. The regression now expects `exhaustive: false` and a limitation containing `1 LC_LAZY_LOAD_DYLIB_INFO`. ### Typed outcome or recovery expected Keep the raw load command. Mark the dependency inventory non-exhaustive and name the omitted command. Do not invent an install name from otool text that does not contain one. ### Analysis or suspected cause Same producing omission as #5551 at the otool boundary: unrecognized dependency-bearing command text is treated as absence, and the inspection layer then marks the resulting list exhaustive. ### Additional context Related: #5551. The structural reader, not otool -l, can see the linkedit install name.
Author
Owner

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

Cross-referencing with canonical issue #5362 ([Bug] Dylib path expansion rejects line terminators in dependency names and rpaths) and siblings #5551, #5637. Addresses LC_LAZY_LOAD_DYLIB_INFO payload handling and exhaustive dependency claims in inspect-macho. Cataloged under Cluster BC in consolidation tracker #4330.

<!-- gh-comment-id:6298226427 --> @matbrgz commented on GitHub (Oct 20, 2026): Cross-referencing with canonical issue #5362 (`[Bug] Dylib path expansion rejects line terminators in dependency names and rpaths`) and siblings #5551, #5637. Addresses `LC_LAZY_LOAD_DYLIB_INFO` payload handling and exhaustive dependency claims in `inspect-macho`. Cataloged under Cluster BC in consolidation tracker #4330.
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#3421
No description provided.