Skip to content

feat(sandbox): Windows Job Object backend (process-tree isolation) - #149

Closed
raymondginger2018-sudo wants to merge 1 commit into
HKUDS:mainfrom
raymondginger2018-sudo:feat/win-job-object-sandbox
Closed

feat(sandbox): Windows Job Object backend (process-tree isolation)#149
raymondginger2018-sudo wants to merge 1 commit into
HKUDS:mainfrom
raymondginger2018-sudo:feat/win-job-object-sandbox

Conversation

@raymondginger2018-sudo

Copy link
Copy Markdown
Contributor

Native Windows previously reported sandbox backend none, so shell and code-mode commands ran with no isolation. This adds a real Windows isolation primitive — a Job Object with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.

What it provides

  • Process-tree isolation: when the wrapper exits (normal or killed), the entire child process tree is terminated — no orphaned shells/compilers survive.
  • Hierarchical: inner command spawned suspended (CreateProcessW), assigned to the job, resumed; all descendants join automatically.
  • Exit code forwarding so callers see the inner command's result.
  • Wiring mirrors seatbelt/bwrap: sandbox_backend() returns job on Windows; wrap_argv_command prefixes python -m core.harness.windows_sandbox --.
  • Pure ctypes, no third-party dependency; degrades to subprocess passthrough on Win32 failure.

Honest boundary

This provides process-tree isolation and lifetime guarantees, not a filesystem write-fence (which on Windows needs disk quotas or AppContainer/SILO privileges). Documented in the module.

Tests

Windows-only: exit-code forwarding, wrapper wiring via build_exec_command, and a KILL_ON_JOB_CLOSE descendant-kill smoke test. seatbelt profile tests are now correctly skipped off-Darwin.

Native Windows previously reported backend 'none', so shell and code-mode
commands ran without any isolation. This adds a real Windows isolation
primitive — a Job Object with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE:

- When the wrapper process exits (normally or killed), the entire child
  process tree is terminated: no orphaned shells/compilers survive.
- The inner command is spawned suspended (CreateProcessW), assigned to
  the job, then resumed; every descendant joins the same job
  automatically (Windows jobs are hierarchical).
- Exit code is forwarded so callers see the inner command's result.

Wiring mirrors the seatbelt/bwrap backends: sandbox_backend() returns
'job' on Windows and wrap_argv_command prefixes the inner argv with
'python -m core.harness.windows_sandbox --'. Pure ctypes, no third-party
dependency; degrades to a subprocess passthrough if any Win32 call fails.

Honest boundary documented in the module: this provides process-tree
isolation and lifetime guarantees, not a filesystem write-fence (which on
Windows requires disk quotas or AppContainer/SILO privileges).

Tests: exit-code forwarding, wrapper wiring via build_exec_command, and a
KILL_ON_JOB_CLOSE descendant-kill smoke test (Windows only). seatbelt
profile tests are now correctly skipped off-Darwin.
@Zongwei9888

Copy link
Copy Markdown
Collaborator

Merged as 9e4b2c8 (via #156).

This is now validated on real Windows: I extended the windows-2022 CI job to run tests/test_harness_sandbox.py, so the Job Object cases actually execute instead of being skipped everywhere. They pass.

Two things I appreciated in the review: the backend does not pretend to provide a write-fence, and the docstring says so plainly. I built on that — fences_writes() now derives the log line from the backend instead of hardcoding "writes fenced to workspace", which was previously a false claim on any non-seatbelt/bwrap platform.

@Zongwei9888 Zongwei9888 closed this Aug 6, 2026
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.

2 participants