[PR #1100] [MERGED] fix(apple): validate dylib candidates and preserve search uncertainty #2648

Closed
opened 2026-10-17 21:08:36 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1100
Author: @morluto
Created: 10/8/2026
Status: ✅ Merged
Merged: 10/8/2026
Merged by: @N0zoM1z0

Base: main ← Head: codex/dyld-boundary-backport


📝 Commits (5)

  • 67e9eab fix(apple): validate dylib candidates and preserve search uncertainty
  • 1ac0cb6 chore: merge main into dyld boundary backport
  • c7b6de3 fix(apple): scope embedded dyld uncertainty by search phase
  • 88b5687 fix(apple): scope dyld prefixes to eligible paths and platforms
  • ea44976 fix(apple): ignore embedded process settings on library roots

📊 Changes

9 files changed (+819 additions, -20 deletions)

View changed files

📝 docs/apple-application-analysis.md (+8 -4)
📝 src/artifacts/apple/MachoLoadCommandReader.test.ts (+12 -0)
📝 src/artifacts/apple/MachoLoadCommandReader.ts (+5 -0)
➕ src/domain/apple/dyldEnvironment.ts (+103 -0)
📝 src/domain/apple/dylibResolution.test.ts (+392 -3)
📝 src/domain/apple/dylibResolution.ts (+56 -6)
📝 src/domain/apple/dylibResolutionFindings.ts (+12 -7)
📝 tests/boundary/cli/dylibResolutionCli.test.ts (+112 -0)
📝 tests/boundary/mcp/dylibResolutionMcp.test.ts (+119 -0)

📄 Description

trace_dylib_resolution could report a dependency as resolved with complete coverage even when the root supplied unmodeled LC_DYLD_ENVIRONMENT path overrides. It also accepted executable or bundle slices as dylib candidates, and the Mach-O reader could silently ignore declared load-command bytes after ncmds.

Require the parsed command count to consume sizeofcmds, reject non-dylib candidates using the existing not-loadable outcome, and apply embedded image-selection uncertainty by search phase and dependency kind, including missing, lazy, and descendant dependencies. Fallback paths cannot preempt an ordinary-search hit; framework search paths apply only to framework install names. Root and overlay prefixes cannot affect @loader_path, @executable_path, or @rpath install names; root paths are ignored on known non-simulator platforms, with missing/future platform metadata retained as unknown. Empty prefixes are no-ops. Only executable roots supply embedded process settings; library, bundle, and other non-executable roots retain the commands as observations without changing resolution, coverage, or unresolved-load findings. Explanations distinguish inactive library metadata from executable settings and describe required dependency load failure without assuming the root can be launched. Preserve diagnostic-only environment settings as observations without changing resolution. Qualify rpath findings and mark affected coverage partial. Settings are classified once per root slice and reused during resolution; coverage records only applicable unmodeled inputs, avoiding a second metadata scan.

This backports existing-boundary fixes identified while reviewing closed #947. Shared-cache inventory and system-path resolution remain outside this change; caller-visible schemas are unchanged.

Validation:

  • npm run check and npm run check:fast

  • npm run docs:check

  • npm run test:focused -- src/domain/apple/dylibResolution.test.ts src/artifacts/apple/MachoLoadCommandReader.test.ts tests/boundary/cli/dylibResolutionCli.test.ts tests/boundary/mcp/dylibResolutionMcp.test.ts — 100 tests passed, including known simulator and non-simulator platforms, absent/future platform metadata, prefix path forms, preserved environment observations, non-executable roots, process isolation, and explicit CLI/MCP library-root selection.

  • Real macOS arm64 bundle fixture using the existing buildMacosBundleFixture and verifyDylibResolution helpers: CLI/MCP agreement, 11 slices compared against otool, and two executable roots compared against actual dyld load order.

  • Real macOS arm64 binaries with embedded DYLD_FALLBACK_LIBRARY_PATH, DYLD_FRAMEWORK_PATH, DYLD_LIBRARY_PATH, DYLD_ROOT_PATH, and DYLD_OVERLAY_PATH: the ordinary dylib hit remains resolved for fallback/framework/root/overlay settings and conditional for library overrides; CLI/MCP results agree. Absolute system dependencies retain their separate uncertainty; known macOS root settings do not add uncertainty. Simulator behavior is covered by domain fixtures, not a real simulator runtime.

  • Real macOS arm64 source-built dylib with both DYLD_LIBRARY_PATH and DYLD_INSERT_LIBRARIES commands injected into reserved header padding before re-signing: actual dyld ignores the library settings; CLI/MCP retain the observations and return the resolved child with complete coverage.

Hopper/Ghidra verification was not performed; these artifact boundaries do not use either provider.


🔄 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/1100 **Author:** [@morluto](https://github.com/morluto) **Created:** 10/8/2026 **Status:** ✅ Merged **Merged:** 10/8/2026 **Merged by:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Base:** `main` ← **Head:** `codex/dyld-boundary-backport` --- ### 📝 Commits (5) - [`67e9eab`](https://github.com/morluto/rea/commit/67e9eab8b7b8c2d9e764f06dd9825c265c645999) fix(apple): validate dylib candidates and preserve search uncertainty - [`1ac0cb6`](https://github.com/morluto/rea/commit/1ac0cb6a75d46d5b6ab5e3c6c27916dfce388e5b) chore: merge main into dyld boundary backport - [`c7b6de3`](https://github.com/morluto/rea/commit/c7b6de35dfd7c2adb5d4d3db059f833ea92701d8) fix(apple): scope embedded dyld uncertainty by search phase - [`88b5687`](https://github.com/morluto/rea/commit/88b5687e6803b64db16292fd9da8a96abe894c3d) fix(apple): scope dyld prefixes to eligible paths and platforms - [`ea44976`](https://github.com/morluto/rea/commit/ea44976b6248f1333fc56412cf87de5afb41a107) fix(apple): ignore embedded process settings on library roots ### 📊 Changes **9 files changed** (+819 additions, -20 deletions) <details> <summary>View changed files</summary> 📝 `docs/apple-application-analysis.md` (+8 -4) 📝 `src/artifacts/apple/MachoLoadCommandReader.test.ts` (+12 -0) 📝 `src/artifacts/apple/MachoLoadCommandReader.ts` (+5 -0) ➕ `src/domain/apple/dyldEnvironment.ts` (+103 -0) 📝 `src/domain/apple/dylibResolution.test.ts` (+392 -3) 📝 `src/domain/apple/dylibResolution.ts` (+56 -6) 📝 `src/domain/apple/dylibResolutionFindings.ts` (+12 -7) 📝 `tests/boundary/cli/dylibResolutionCli.test.ts` (+112 -0) 📝 `tests/boundary/mcp/dylibResolutionMcp.test.ts` (+119 -0) </details> ### 📄 Description `trace_dylib_resolution` could report a dependency as resolved with complete coverage even when the root supplied unmodeled `LC_DYLD_ENVIRONMENT` path overrides. It also accepted executable or bundle slices as dylib candidates, and the Mach-O reader could silently ignore declared load-command bytes after `ncmds`. Require the parsed command count to consume `sizeofcmds`, reject non-dylib candidates using the existing not-loadable outcome, and apply embedded image-selection uncertainty by search phase and dependency kind, including missing, lazy, and descendant dependencies. Fallback paths cannot preempt an ordinary-search hit; framework search paths apply only to framework install names. Root and overlay prefixes cannot affect `@loader_path`, `@executable_path`, or `@rpath` install names; root paths are ignored on known non-simulator platforms, with missing/future platform metadata retained as unknown. Empty prefixes are no-ops. Only executable roots supply embedded process settings; library, bundle, and other non-executable roots retain the commands as observations without changing resolution, coverage, or unresolved-load findings. Explanations distinguish inactive library metadata from executable settings and describe required dependency load failure without assuming the root can be launched. Preserve diagnostic-only environment settings as observations without changing resolution. Qualify rpath findings and mark affected coverage partial. Settings are classified once per root slice and reused during resolution; coverage records only applicable unmodeled inputs, avoiding a second metadata scan. This backports existing-boundary fixes identified while reviewing closed #947. Shared-cache inventory and system-path resolution remain outside this change; caller-visible schemas are unchanged. Validation: - `npm run check` and `npm run check:fast` - `npm run docs:check` - `npm run test:focused -- src/domain/apple/dylibResolution.test.ts src/artifacts/apple/MachoLoadCommandReader.test.ts tests/boundary/cli/dylibResolutionCli.test.ts tests/boundary/mcp/dylibResolutionMcp.test.ts` — 100 tests passed, including known simulator and non-simulator platforms, absent/future platform metadata, prefix path forms, preserved environment observations, non-executable roots, process isolation, and explicit CLI/MCP library-root selection. - Real macOS arm64 bundle fixture using the existing `buildMacosBundleFixture` and `verifyDylibResolution` helpers: CLI/MCP agreement, 11 slices compared against `otool`, and two executable roots compared against actual dyld load order. - Real macOS arm64 binaries with embedded `DYLD_FALLBACK_LIBRARY_PATH`, `DYLD_FRAMEWORK_PATH`, `DYLD_LIBRARY_PATH`, `DYLD_ROOT_PATH`, and `DYLD_OVERLAY_PATH`: the ordinary dylib hit remains resolved for fallback/framework/root/overlay settings and conditional for library overrides; CLI/MCP results agree. Absolute system dependencies retain their separate uncertainty; known macOS root settings do not add uncertainty. Simulator behavior is covered by domain fixtures, not a real simulator runtime. - Real macOS arm64 source-built dylib with both `DYLD_LIBRARY_PATH` and `DYLD_INSERT_LIBRARIES` commands injected into reserved header padding before re-signing: actual dyld ignores the library settings; CLI/MCP retain the observations and return the resolved child with complete coverage. Hopper/Ghidra verification was not performed; these artifact boundaries do not use either provider. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:08:36 +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#2648
No description provided.