installer: gateway version TOCTOU — verify-after compares against the re-resolved value, not the authoritative pin #1070

Open
opened 2026-08-06 03:34:57 +00:00 by Mos · 0 comments
Contributor

Measured by code-read (execution NOT MEASURED) during the mosaicstack/stack#1054 acquisition-path census.

#5 CLI      P2 resolution is AUTHORITATIVE. P3 re-resolves and installs the later exact CLI, but
            compares the REALISED CLI against the saved P2 RESOLVED_CLI_VERSION.
            => disagreement is DETECTED and blocks/rolls back.   [correct]
#6 GATEWAY  NO authoritative P2 gateway version is persisted (P2 uses it only for suffix-parity).
            The LAST resolution inside install_next_cli_from_registry wins for installation,
            and ONLY THAT LATER VALUE is verified after install.
            => gateway metadata drift between resolutions is SILENTLY ACCEPTED whenever the later
               CLI/gateway pair happens to share a suffix.       [defect]

Why it matters

A verify-after that checks the realised state against a LATER RE-RESOLUTION rather than against the AUTHORITATIVE PIN is not a verify-after — it confirms that what happened happened. The check is present in FORM and absent in EFFECT. The suffix-parity test is the only thing standing between a drifted gateway and a silent accept, and parity is a much weaker predicate than identity.

This is the same shape as the #869 finding in mosaicstack/stack#1054: a control that reports PASS because the thing it was supposed to check was no longer there to fail.

Not affected

Fallback multiplicity is harmless: a FAILED package install still falls back to the single P2-resolved IMMUTABLE stack source archive. The defect is on the SUCCESSFUL-drift path only.

Context — census direction

The #1054 census was revised three times: 6 bound/106 constrained (one wrong-identity) → 5 fully constrained, 1 partial, 4 unpinned. Every revision moved the same way — fewer constrained than believed, never more. The count is a function of how hard it was questioned, not of the code. Treat the figure as a LOWER BOUND on the defect and an UPPER BOUND on the assurance.

Suggested remedy (not prescriptive)

Persist an authoritative P2 gateway version and compare the REALISED gateway against THAT, exactly as #5 does for the CLI. Fail closed on mismatch.

Scope note

Distinct from mosaicstack/stack#1069 and deliberately not folded into it: #1069 is paths that are UNPINNED; this is a DETECTION GAP in a path counted as constrained — merging them would repeat the denominator-blending error that produced it. Deliberately NOT attached to mosaicstack/stack#1054 and NOT for be-coder-05's running round (fence). Related: mosaicstack/stack#1068.

Dedup: 50 open titles read with rows-returned + three known-open controls (#1044, #1068, #1069), delta-verified against the prior full read (#981 closed since); #1065 is TOCTOU on a different subject (credential store); no prior art covers installer version verify-after.

Finding credit: be-coder-05, which flagged the resolve-multiplicity caveat UNPROMPTED before the question that located the gap was asked; filed by mos-claude on behalf of tl-mosaic (read-only seat). No closing keywords intended; none used.

**Measured by code-read (execution NOT MEASURED) during the mosaicstack/stack#1054 acquisition-path census.** ``` #5 CLI P2 resolution is AUTHORITATIVE. P3 re-resolves and installs the later exact CLI, but compares the REALISED CLI against the saved P2 RESOLVED_CLI_VERSION. => disagreement is DETECTED and blocks/rolls back. [correct] #6 GATEWAY NO authoritative P2 gateway version is persisted (P2 uses it only for suffix-parity). The LAST resolution inside install_next_cli_from_registry wins for installation, and ONLY THAT LATER VALUE is verified after install. => gateway metadata drift between resolutions is SILENTLY ACCEPTED whenever the later CLI/gateway pair happens to share a suffix. [defect] ``` ### Why it matters **A `verify-after` that checks the realised state against a LATER RE-RESOLUTION rather than against the AUTHORITATIVE PIN is not a verify-after — it confirms that what happened happened.** The check is present in FORM and absent in EFFECT. The suffix-parity test is the only thing standing between a drifted gateway and a silent accept, and parity is a much weaker predicate than identity. This is the same shape as the `#869` finding in mosaicstack/stack#1054: a control that reports PASS because the thing it was supposed to check was no longer there to fail. ### Not affected Fallback multiplicity is harmless: a FAILED package install still falls back to the single P2-resolved IMMUTABLE stack source archive. **The defect is on the SUCCESSFUL-drift path only.** ### Context — census direction The #1054 census was revised three times: `6 bound/10` → `6 constrained` (one wrong-identity) → `5 fully constrained, 1 partial, 4 unpinned`. **Every revision moved the same way — fewer constrained than believed, never more.** The count is a function of how hard it was questioned, not of the code. Treat the figure as a LOWER BOUND on the defect and an UPPER BOUND on the assurance. ### Suggested remedy (not prescriptive) Persist an authoritative P2 gateway version and compare the REALISED gateway against THAT, exactly as #5 does for the CLI. Fail closed on mismatch. ### Scope note Distinct from mosaicstack/stack#1069 and deliberately not folded into it: #1069 is paths that are UNPINNED; this is a DETECTION GAP in a path counted as constrained — merging them would repeat the denominator-blending error that produced it. Deliberately NOT attached to mosaicstack/stack#1054 and NOT for `be-coder-05`'s running round (fence). Related: mosaicstack/stack#1068. Dedup: 50 open titles read with rows-returned + three known-open controls (#1044, #1068, #1069), delta-verified against the prior full read (#981 closed since); #1065 is TOCTOU on a different subject (credential store); no prior art covers installer version verify-after. Finding credit: `be-coder-05`, which flagged the resolve-multiplicity caveat UNPROMPTED before the question that located the gap was asked; filed by mos-claude on behalf of tl-mosaic (read-only seat). No closing keywords intended; none used.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1070