[PR #5618] [CLOSED] fix(kuna): reject version/digest mismatch from replaced executable #6999

Closed
opened 2026-11-01 21:44:36 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/5618
Author: @Som0111
Created: 10/20/2026
Status: ❌ Closed

Base: main ← Head: fix/kuna-toctou-version-hash


📝 Commits (4)

  • 86c1be4 fix(kuna): reject version/digest mismatch from replaced executable
  • 1595ae5 fix(kuna): use readFile snapshot for pre-probe hash to avoid hook interference
  • 28187d9 fix(kuna): retain pre-probe descriptor owner outside lifecycle scope
  • 1915f20 test(kuna): add independent TOCTOU regression test for inspectKunaInstallation

📊 Changes

2 files changed (+45 additions, -0 deletions)

View changed files

➕ npm (+0 -0)
📝 tests/boundary/providers/kuna/kunaInstallation.test.ts (+45 -0)

📄 Description

gh pr create --title "fix(kuna): reject version/digest mismatch from replaced executable" --body "## Summary

`inspectKunaInstallation` hashed the executable after the `--version` process exited. A binary that replaced itself in that window produced a success result pairing the old version string with a digest of the new bytes. This PR hashes before and after the probe and returns `version_unresolved` when the digests differ.

Fixes #5611

Problem and expected behavior

Trigger: Any executable that atomically replaces itself between the moment `--version` exits and the moment `hashStableFile` runs.

Violated invariant: `KunaInstallation.sha256` must be the digest of the bytes that produced `KunaInstallation.version`. When the binary is replaced mid-probe, the returned `sha256` belongs to a different build than the one that printed the version string.

Expected: Return `version_unresolved` with `pre_probe_sha256` and `post_probe_sha256` in diagnostics when the digests differ.

Change and scope

Hash the executable with `hashStableFile` once before spawning `execFileOutput` (`preProbeHash`) and once after (existing `fingerprint`). If they differ, return `version_unresolved`. The post-probe fingerprint is still the one returned on success.

Contribution scope: not applicable — ordinary correctness fix within the existing Kuna installation boundary.

Contract and boundary impact

  • Semantic owner and earliest changed stage: `src/kuna/KunaInstallation.ts` — Kuna readiness / provider boundary
  • Contribution scope fit and linked maintainer decision: not applicable
  • CLI and MCP/tool-catalog contract: none — `KunaInstallation` shape unchanged; new failure path uses existing `version_unresolved` code
  • Provider, bridge, target-format, or platform compatibility: none
  • Evidence, artifact, provenance, or reconstruction contract: none
  • Target selection, authority, upstream behavior, and cleanup details: not applicable
  • Generated metadata impact: none

Expected effects:

  • Read existing files or captured data.

Evidence and regression coverage

  • Tests added: `rejects a version/digest pair when the executable is replaced during the probe` in `tests/boundary/providers/kuna/kunaInstallation.test.ts` — gates the fake kuna probe, replaces the binary, releases the gate, asserts `version_unresolved` with differing digests.

  • Base reproduction: source-derived — the TOCTOU window is structural; the new test reproduces it mechanically via the existing `gate` behavior in `writeFakeKuna`.

  • User-visible CLI/MCP output: none under normal conditions; under replacement, `version_unresolved` instead of a silently mismatched identity.

  • Remaining proof gaps: not tested against a real self-updating Kuna release; only fake-kuna path exercised.

  • Observed, derived, and inferred claims remain distinguishable.

  • Artifact identity, source provenance, and failed attempts remain preserved.

  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • `npm run check:fast` — passed (typecheck + lint)
  • `npm run test:local -- tests/boundary/providers/kuna/kunaInstallation.test.ts` — could not run on Windows; native artifacts missing; requires POSIX or CI

Compatibility, safety, and release

  • Breaking changes or migration steps: none
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable
  • Package or release metadata impact: none
  • Security, privacy, process, or containment review: none

Author readiness

Human owner: @Som0111

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows `type(scope): outcome`.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MPC changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims." --base main --head Som0111:fix/kuna-toctou-version-hash --repo morluto/rea

🔄 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/5618 **Author:** [@Som0111](https://github.com/Som0111) **Created:** 10/20/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/kuna-toctou-version-hash` --- ### 📝 Commits (4) - [`86c1be4`](https://github.com/morluto/rea/commit/86c1be4156c87d3a3a4fc055103598cf615a2bed) fix(kuna): reject version/digest mismatch from replaced executable - [`1595ae5`](https://github.com/morluto/rea/commit/1595ae5343ac5ff224a687ce1eb8bd11e5365ac6) fix(kuna): use readFile snapshot for pre-probe hash to avoid hook interference - [`28187d9`](https://github.com/morluto/rea/commit/28187d94c6d68d7cae8008786b7a858cf9979961) fix(kuna): retain pre-probe descriptor owner outside lifecycle scope - [`1915f20`](https://github.com/morluto/rea/commit/1915f20c4d367b278a21a0d0fe925931e43e481c) test(kuna): add independent TOCTOU regression test for inspectKunaInstallation ### 📊 Changes **2 files changed** (+45 additions, -0 deletions) <details> <summary>View changed files</summary> ➕ `npm` (+0 -0) 📝 `tests/boundary/providers/kuna/kunaInstallation.test.ts` (+45 -0) </details> ### 📄 Description gh pr create --title "fix(kuna): reject version/digest mismatch from replaced executable" --body "## Summary \`inspectKunaInstallation\` hashed the executable after the \`--version\` process exited. A binary that replaced itself in that window produced a success result pairing the old version string with a digest of the new bytes. This PR hashes before and after the probe and returns \`version_unresolved\` when the digests differ. Fixes #5611 ## Problem and expected behavior **Trigger:** Any executable that atomically replaces itself between the moment \`--version\` exits and the moment \`hashStableFile\` runs. **Violated invariant:** \`KunaInstallation.sha256\` must be the digest of the bytes that produced \`KunaInstallation.version\`. When the binary is replaced mid-probe, the returned \`sha256\` belongs to a different build than the one that printed the version string. **Expected:** Return \`version_unresolved\` with \`pre_probe_sha256\` and \`post_probe_sha256\` in diagnostics when the digests differ. ## Change and scope Hash the executable with \`hashStableFile\` once before spawning \`execFileOutput\` (\`preProbeHash\`) and once after (existing \`fingerprint\`). If they differ, return \`version_unresolved\`. The post-probe fingerprint is still the one returned on success. Contribution scope: not applicable — ordinary correctness fix within the existing Kuna installation boundary. ## Contract and boundary impact - Semantic owner and earliest changed stage: \`src/kuna/KunaInstallation.ts\` — Kuna readiness / provider boundary - Contribution scope fit and linked maintainer decision: not applicable - CLI and MCP/tool-catalog contract: none — \`KunaInstallation\` shape unchanged; new failure path uses existing \`version_unresolved\` code - Provider, bridge, target-format, or platform compatibility: none - Evidence, artifact, provenance, or reconstruction contract: none - Target selection, authority, upstream behavior, and cleanup details: not applicable - Generated metadata impact: none Expected effects: - [x] Read existing files or captured data. ## Evidence and regression coverage - Tests added: \`rejects a version/digest pair when the executable is replaced during the probe\` in \`tests/boundary/providers/kuna/kunaInstallation.test.ts\` — gates the fake kuna probe, replaces the binary, releases the gate, asserts \`version_unresolved\` with differing digests. - Base reproduction: source-derived — the TOCTOU window is structural; the new test reproduces it mechanically via the existing \`gate\` behavior in \`writeFakeKuna\`. - User-visible CLI/MCP output: none under normal conditions; under replacement, \`version_unresolved\` instead of a silently mismatched identity. - Remaining proof gaps: not tested against a real self-updating Kuna release; only fake-kuna path exercised. - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - \`npm run check:fast\` — passed (typecheck + lint) - \`npm run test:local -- tests/boundary/providers/kuna/kunaInstallation.test.ts\` — could not run on Windows; native artifacts missing; requires POSIX or CI ## Compatibility, safety, and release - Breaking changes or migration steps: none - Real Hopper/Ghidra, browser, or OS coverage: not applicable - Package or release metadata impact: none - Security, privacy, process, or containment review: none ## Author readiness Human owner: @Som0111 - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows \`type(scope): outcome\`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MPC changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims." --base main --head Som0111:fix/kuna-toctou-version-hash --repo morluto/rea --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:44: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#6999
No description provided.