Skip to content
This repository was archived by the owner on Sep 13, 2026. It is now read-only.
This repository was archived by the owner on Sep 13, 2026. It is now read-only.

M2: wire up --elevate -- the attached-read-only compaction path #114

Description

@zcsizmadia

The spike (#6, PR #113) settled the
shape and answered the security questions. None of it is in src/. This issue is
the real thing: compact --elevate, the attached-read-only "full" mode that D10
left as an opt-in, and whatever later needs an elevated token.

What the spike already decided

Do not re-litigate these; they are measured in
docs/RESEARCH.md.

  • One-way pipe (PIPE_ACCESS_INBOUND, worker → parent) for progress, plus a
    separate manual-reset event for cancellation. A duplex pipe deadlocks: I/O on a
    synchronous file object is serialized, so a pending ReadFile blocks the
    concurrent WriteFile.
  • DACL D:P(A;;GA;;;<user sid>) -- the launching user and nobody else, not
    even SYSTEM. The elevated child is the same user one integrity level up, so it
    opens without weakening anything.
  • 128-bit random pipe name created with FILE_FLAG_FIRST_PIPE_INSTANCE; abort
    if the name is taken.
  • The worker verifies its server (pid, image path, token SID) before it
    streams anything.
  • Declining is ERROR_CANCELLEDErrorCode::NeedsElevation → exit 4.
  • Ctrl+C does not reach the elevated child. Cancellation is explicit, via the
    event, and the worker must unwind rather than die.
  • D11: the elevated half is one verb, re-validates its path against the
    caller's own Lxss hive, and reads nothing from the pipe.

Work

  • IElevation interface + Win32Elevation behind it, with a fake, so the
    operation logic stays unit-testable (CheckTokenMembership,
    ShellExecuteEx, pipe, event -- all through the Win32Api table so the
    error branches are injectable).
  • The worker verb: attach read-only (ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY | NO_DRIVE_LETTER | NO_LOCAL_HOST), compact, detach. Path re-validated
    against the registry before anything is opened.
  • Progress records into the existing ProgressSink so an elevated run renders
    identically to an unelevated one.
  • --elevate on compact, and the interactive prompt when full mode is what
    the user needs. Never implied by a bare compact.
  • Rollback: a detach that has to happen even when the compaction fails or the
    worker is cancelled mid-operation.
  • Exit-code propagation: the parent exits with the worker's code, and the
    worker's failures carry a remedy like every other error.

Over-the-shoulder elevation

The one thing the spike could not measure. The user-only DACL works because a
split-token administrator's filtered and elevated tokens share a user SID. A
standard user who elevates by entering another account's credentials gets a
worker with a different SID, which that DACL denies.

Decide and implement one of:

  1. Detect it (compare the client SID after ImpersonateNamedPipeClient) and fail
    with a message that says what happened, or
  2. Grant the elevated identity explicitly in the DACL -- which means knowing it
    before the pipe is created, and is not obviously possible.

Needs a second account on a test machine to verify either way.

Done when

compact <distro> --elevate runs the attached-read-only path end to end on a
machine where the unattached path leaves space behind, streams one progress bar,
propagates one exit code, detaches the disk even when interrupted, and declining
the prompt costs the user nothing but exit 4. Unit tests cover every failure
branch with injected errors; the integration test is gated like the rest.

Activity

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

    area:platformsrc/lib/platform - Win32, registry, WSL hostenhancementNew feature or requestroadmapTracked item from ROADMAP.mdsecuritySecurity-relevant

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions