Skip to content

fix(network): scope Windows egress by socket owner - #3491

Open
prekshivyas wants to merge 5 commits into
NVIDIA:windowsfrom
prekshivyas:fix/windows-process-identity
Open

prekshivyas wants to merge 5 commits into
NVIDIA:windowsfrom
prekshivyas:fix/windows-process-identity

Conversation

@prekshivyas

Copy link
Copy Markdown
Contributor

Summary

Fixes a Windows MXC authorization defect by authorizing each proxied TCP connection as the process that actually owns the workload-side socket.

The Windows host proxy previously evaluated every connection with one static identity: command[0], captured when the sandbox started. As a result, a child process could inherit the entry command's allow grant, while a policy explicitly granting the child binary did not authorize it.

Change

  • resolve the exact accepted IPv4/IPv6 TCP tuple through GetExtendedTcpTable(OWNER_PID_ALL)
  • require one unique owning PID, then obtain its executable with QueryFullProcessImageNameW
  • evaluate path/hash policy using that socket owner's identity and the existing TOFU hash cache
  • fail closed on missing/ambiguous ownership, process lookup, hashing, or policy evaluation errors
  • preserve per-sandbox proxy authentication and remove the obsolete static entry-command identity from the MXC driver contract
  • add a real-MXC regression covering both the declared child and undeclared child cases

Before / after evidence

Environment: Yukon Windows ARM64; Rust 1.95; MXC wxc-exec.exe 0.8.0+7dac1a9 (ARM64).

Pre-fix reproduction on unmodified windows tip fb2980e077288b61ef03a2e6187e162d158526aa, using cmd.exe /c curl.exe https://example.com/:

  • policy grants curl.exe: denied with HTTP 403 / curl exit 22 / ExecFailed; test exit 101; scenario 0.63 s
  • policy grants only parent cmd.exe: child curl succeeds; test exit 0; scenario 0.70 s

That inversion proves the proxy was using the static parent identity rather than the socket owner.

Post-fix commit 3a902900ed7d0d995b3e58ace3f5e0fe9bd32e80, rebased onto current windows base 4f06e23cc8e4bfb48f78f43645771683f674fe2d:

  • policy grants curl.exe: HTTPS succeeds and produces a non-empty response
  • policy grants only parent cmd.exe: child curl is denied with HTTP 403 / ExecFailed
  • combined real-MXC regression: pass, 1.04 s

Verification

  • cargo test -p openshell-supervisor-network --lib --target aarch64-pc-windows-msvc windows_process::tests -- --nocapture — 2 passed
  • cargo test -p openshell-supervisor-network --lib --target aarch64-pc-windows-msvc per_sandbox_credentials_reject_missing_wrong_cross_and_duplicate_auth -- --nocapture — 1 passed
  • cargo test -p openshell-driver-mxc --test wxc_exec_real --target aarch64-pc-windows-msvc pc_proxy_scopes_network_policy_to_socket_owner -- --ignored --test-threads=1 --nocapture — 1 passed, 1.04 s
  • full supervisor-network suite — 1,232 passed, 2 ignored
  • focused MXC surface — 93 unit, 3 OpenClaw, 10 example, and 44 matrix tests passed
  • mise run --jobs 1 pre-commit on the rebased tree — exit 0, 219.975 s
  • post-CI portability fix: cargo fmt --all -- --check and focused Windows ARM64 Clippy — pass
  • git diff --check — pass

The full Windows gate used the installed x64 Biome binary because Biome's native ARM64 executable crashes on this host, plus the official Z3 4.16.0 ARM64 release because the unauthenticated prebuilt download endpoint returned HTTP 403.

Security impact

This removes an authorization-broadening path: an allowed Windows entry process no longer lends its binary-scoped network permissions to arbitrary descendants. Identity failures deny the request; they do not fall back to entry-command or endpoint-only authorization.

Scope and residual risk

This is intentionally limited to Windows proxy process-identity binding. It does not normalize Windows path spelling or case; that separate behavior remains tracked separately. The latest base already contains the independent governed-proxy lifecycle fix.

Validation was performed on native Windows ARM64 with real ARM64 MXC. x64 compilation/CI remains expected coverage. A process that exits before its image can be queried is denied, which is the intended fail-closed behavior.

NVBug 6783086

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Resolve each accepted Windows proxy connection to its unique owning PID and executable before evaluating binary-scoped network policy. Fail closed when ownership or process identity cannot be established, and cover allowed and undeclared child processes with a real MXC regression.
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
(cherry picked from commit 32ea316deb6c83c157fdf2de4a2cdc3a7d2da1e3)
@copy-pr-bot

copy-pr-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@prekshivyas

Copy link
Copy Markdown
Contributor Author

Combined Windows-NVBug qualification exposed and fixed a cross-PR compatibility regression with #3434.

#3434 attaches immutable per-sandbox OCSF context to the former static Windows proxy identity; this PR replaces that identity with per-socket Windows process ownership. When both heads were merged, the audit-context methods still matched the removed Static variant, so the combined ARM64 build failed.

Pushed:

  • 3d72cda43 stacks fix(ocsf): attribute MXC proxy events to sandboxes #3434's audit-attribution head into this branch and resolves the host constructor to use socket-owner identity plus sandbox context.
  • 61afbad9b stores the per-sandbox event context on the new Windows identity, updates the combined tests for the removed binary-path parameter, and adds a focused attribution regression.

Validation on native Windows ARM64:

  • combined release build for openshell.exe, openshell-gateway.exe, and openshell-supervisor-relay.exe: PASS
  • cargo test -p openshell-supervisor-network --lib --target aarch64-pc-windows-msvc -- --test-threads=1: 1,236 passed, 0 failed, 2 ignored
  • focused windows_socket_owner_identity_keeps_per_proxy_sandbox_attribution: PASS
  • cargo fmt --all -- --check: PASS

This PR is now intentionally stacked on #3434. Once #3434 merges into windows, its overlapping commits will disappear from this PR's effective diff.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant