Skip to content

[P2] Windows doctor: bind launched executable bytes and finish the hostile runtime corpus #333

Closed

Description

@wsdt

[P2] Windows doctor: bind launched executable bytes and finish the hostile runtime corpus

Scope and reviewed baseline

Remaining work from #299 (R24). Review date: 29 September 2026.
Branch: wavect/v070, PR #314, source commit 1ae35afe83f62f405b979f57ac90772cfec9daca.
Classification: Remaining executable-binding and confinement validation.

This ticket replaces only the unresolved portion of its predecessor. Migration of the old ticket is not a claim that its whole original scope was completed. A missing hosted CI receipt is not a blocker when the required implementation and substantive local execution are complete.

Already delivered: do not rebuild

There is real historical Windows Server 2025 runtime evidence, including ten selected tests for restricted launch, descendant termination, settlement and hostile-parent ACL handling. Do not reopen this as if the code had only cross-compiled.

Remaining gap

The last detailed implementation record leaves signed artifact/executable binding open: the spawn boundary reopens an executable pathname rather than consuming held request/bundle/image carriers. The full hostile/resource/handle-settlement scope is also not established.

Work to finish

  • Complete the exact signed artifact-to-launched-image binding at the Windows spawn boundary, using a reviewed held-image/carrier design or another explicitly justified race-resistant Windows mechanism. Refuse mismatches before process effects.
  • Extend the existing actual Windows selector with the remaining substitution/race, resource-limit and handle/descendant settlement cases; preserve the ten already passing cases.
  • Run the owning corpus on an authorized native Windows host. Keep production release-anchor provisioning/support promotion separate from deterministic test-key evidence.

Acceptance

  • Substituting the executable or request/bundle bytes between validation and launch cannot execute an unauthenticated image.
  • The claimed hostile corpus executes on real Windows with observable resource/handle cleanup; tests cannot pass by selecting zero cases.
  • Local native Windows evidence qualifies. No public Windows production-support or production signing claim is inferred from test fixtures.

Boundaries

Use the existing mechanisms and frozen profiles. Do not silently weaken resource, source-authority, ownership, oracle or refusal requirements. This ticket does not authorize paid model/training calls, credentials, external deployment, signing, publication or a support-policy change. Obtain those authorities only where the remaining work actually needs them. Do not reopen excluded deferred work.

Evidence and entry points

Review basis: source/document inspection plus retained repository/issue test reports, not a new execution of the Semaprax test suite. Evidence remains bound to the revision and host on which it was actually produced. Confidence: High.

Activity

  1. wsdt commented on Sep 30, 2026

    @wsdt
    MemberAuthor

    Progress on wavect/v070 at 1ee9ed0: Windows doctor spawn now retains a held signed-image/ancestor guard and read oplock through suspended process creation, with bounded hashing and additional substitution/settlement cases. Cross-target Windows cargo check --tests passed locally; selector self-tests passed 16/16 and Linux selector tests 137/137. Native Windows hostile runtime execution and exact binding across the writable mapped-section race remain open; no production support claim is made.

  2. wsdt commented on Sep 30, 2026

    @wsdt
    MemberAuthor

    #333 investigation on wavect/v080: a private executable carrier can eliminate source-file mapping mutations only if the verified carrier remains continuously protected through CreateProcessAsUserW. A copy, hash, close, and reopen sequence leaves a same-user write/substitution race in the current scratch ACL. Keeping the carrier writer handle open with FILE_SHARE_READ closes that gap in the candidate design, but Windows symmetric-share rules may prevent the loader from opening it; this requires the native selector before integration. The experiment was kept out of wavect/v080 because this macOS host has neither the Windows target nor a native Windows run. The existing #333 code and documented unresolved binding status are unchanged; no exact binding or hostile-corpus success is claimed.

  3. wsdt commented on Oct 1, 2026

    @wsdt
    MemberAuthor

    Pushed 85d08d4f0 on wavect/v080: the Windows doctor confined launcher now supplies CreateProcessAsUserW an explicit three-handle STARTUPINFOEXW allowlist. A new provisioned Windows child probe holds an unrelated inheritable delete-on-close sentinel and checks it is absent from the child; the exact native selector grows from 16 to 17 cases. Local source formatting and the gate's --self-test/--plan passed on macOS. No native Windows execution was available, so this is not runtime acceptance. Exact launched-byte binding, request/bundle carriers, resource-exhaustion corpus, and the full Windows gate remain open.

  4. wsdt commented on Oct 1, 2026

    @wsdt
    MemberAuthor

    v080 source progress at 92f021d: the existing selected Windows held-image launch case now also attempts post-binding hard-link creation and a PAGE_READWRITE section from a fresh read handle, requiring both to refuse before the authenticated child launches. Scoped rustfmt and diff checks passed on macOS. The native 17-case Windows gate was not run at this revision; this probe does not model a retained writable section or solve exact request/bundle/image-to-launch binding. #333 remains open.

  5. wsdt commented on Oct 1, 2026

    @wsdt
    MemberAuthor

    v080 source-only experiment pushed at 7bf5b49: authenticated request/bundle artifact bytes can be copied into unnamed paging mappings and retained only through read-only inheritable handles. Added a native hostile-write and handle-settlement case to the 18-case Windows gate; gate self-test and plan passed on macOS, rustfmt/diff checks passed. No native Windows execution at this revision, child role/transport, or exact launched-image binding is claimed. #333 remains open.

  6. wsdt commented on Oct 1, 2026

    @wsdt
    MemberAuthor

    Provisioned Windows runtime evidence now exists for the exact source checkout 06c0090: run https://github.com/wavect/semaprax/actions/runs/36911767583 passed the fail-closed gate self-test and all 18 selected native cases (0 failed, 0 ignored), including post-binding hostile probes and the read-only request/bundle carrier. Contract/changelog reconciliation pushed at 4530b5f. This is selected runtime evidence only: the retained writable-section/loader binding invariant, child carrier role/transport, broader hostile corpus, and production WP-05 promotion remain open. #333 stays open.

  7. wsdt commented on Oct 1, 2026

    @wsdt
    MemberAuthor

    The v080 branch now includes the expanded native Windows hostile/settlement selector at e15c16202 (22 named cases, including retained writable-section refusal and read-only carrier handle cleanup). The provisioned Windows Server 2025 run 36919771375 checked out that exact head and reported 22 passed, 0 failed, 0 ignored, 115 filtered out; the gate confirmed all 22 explicitly selected cases ran.

    This is real Windows runtime evidence for the added corpus. The retained writable-section case proves refusal and handle/scratch settlement while that section exists. It does not prove atomic exclusion of later mutation through a retained writable section, and the anonymous request/bundle carriers are not yet connected to child transport or the launched image. Exact signed artifact-to-executed-image binding and the broader WP-05 support boundary therefore remain open; I am leaving #333 open.

  8. wsdt commented on Oct 2, 2026

    @wsdt
    MemberAuthor

    Progress on wavect/v080:

    • Native provisioned Windows run 36982984686 passed all 24 explicitly selected confinement cases at ea9b98a751418b5a1ebafd9a592daeea3e218b20, including retained writable-section refusal and launch-boundary checkpoints.
    • A fresh-image OWNER RIGHTS experiment at f9ddd4fddbeaaa19a1d97f2927f63bedc59c7f96 failed in native run 36983893062: SetSecurityInfo returned ERROR_ACCESS_DENIED at the creator-to-reader ACL transition. The exploratory test then contaminated the shared fixture, so its other failures are not evidence of production regressions. The invalid experiment was retired at 16e14488ed5c8bfcaa1ba6a300989df319ab7db6; the Windows source and 24-case selector are byte-identical to the green ea9b98a75 run.

    The exact signed-bytes-to-launched-image guarantee remains open. The current held-path/oplock checks do not prove exclusion of a pre-existing writable section through image creation. Native validation and a race-resistant mechanism are still required before closing #333; no production support/signing claim is made.

  9. wsdt commented on Oct 2, 2026

    @wsdt
    MemberAuthor

    Pushed d0b42ce3d on wavect/v080. The Windows image path now records FileOpened immediately after the first handle opens, before pinning and oplock acquisition. The retained writable-section and surviving-view fixtures require refusal before that checkpoint; the positive launch control requires the full checkpoint sequence.

    The provisioned Windows gate passed on this exact commit: https://github.com/wavect/semaprax/actions/runs/36988402356 (24/24 selected native tests, 0 failed, 0 ignored). This establishes initial-open exclusion for those hostile retained-section shapes on that NTFS runner, not merely a later oplock refusal. The guard remains held through child lifetime. Request/bundle substitution and resource-limit acceptance remain open, so #333 is not closed.

  10. wsdt commented on Oct 2, 2026

    @wsdt
    MemberAuthor

    Pushed request/bundle carrier binding on wavect/v080 through 2c9695f5d. Exact signed request and bundle bytes are copied into paired inherited section carriers with a protected DACL; the child receives only the fixed standard-I/O and carrier inventory, and native hostile cases require same-length substitution refusal and reject DuplicateHandle attempts to regain write/DACL/owner access. The first hosted run exposed a handle-count test's one-time Windows descriptor initialization, which was isolated before its per-carrier accounting assertion.

    The provisioned Windows gate now passed on the exact pushed commit: https://github.com/wavect/semaprax/actions/runs/36991582065 — 26/26 named native cases, 0 failed, 0 ignored. This is a provisioned primitive and child-transport receipt. CPU/memory/output resource-limit corpus and ordinary Windows provisioner integration/support remain open; #333 stays open.

  11. wsdt commented on Oct 2, 2026

    @wsdt
    MemberAuthor

    Completed on wavect/v080 at 2b0a984. The standalone Windows confinement primitive binds the authenticated signed image at launch; the native hostile corpus covers retained writable sections, image substitution and mutation windows, protected request/bundle carriers, CPU and committed-memory limits, combined stdout+stderr output cap, job/handle settlement, and scratch cleanup. The provisioned native Windows selector passed 31/31 with 0 failures and 0 ignored on the exact commit: https://github.com/wavect/semaprax/actions/runs/36994574610 . This closes the bounded issue acceptance; ordinary Windows CLI/provisioner support and production release authority remain separate per the owning specification. The locally requested full profile was not run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions