Skip to content

fix(spawn): start detached Windows runtimes in jobs that forbid breakaway - #12

Open
olebhansen wants to merge 1 commit into
main-digdirfrom
fix/windows-job-breakaway-fallback
Open

olebhansen wants to merge 1 commit into
main-digdirfrom
fix/windows-job-breakaway-fallback

Conversation

@olebhansen

Copy link
Copy Markdown

The SDK starts detached runtimes on Windows with CREATE_BREAKAWAY_FROM_JOB. When the launcher sits in a job object that does not allow breakaway, CreateProcess refuses with ERROR_ACCESS_DENIED. The SDK then reported a bare PermissionDenied (os error 5) that looked like a file problem. This affects cargo test, whose kill-on-close job breaks create_detached() and modify().restart(), and agentd when it is started from sandboxed tool shells.

The SDK now retries without breakaway and logs a warning. If the retry also fails, the error names the process start and both causes.

This was the third commit of #10. It moved here because Windows nested virtualization will come from upstream in the next fork sync. Upstream still spawns with breakaway and has no fallback, so this fix stays in the patch queue.

Compatibility

A runtime started inside a job that forbids breakaway stays in that job. It ends when the job is terminated, or when its last handle closes with kill-on-close, such as when the test run or the shell exits. Before this change it did not start at all. Launchers in no job, or in a job that allows breakaway, behave as before. Launch arguments, JSON, handles and runtime state are unchanged. COMPATIBILITY.md records the lifecycle change.

Tests

On Windows 11 Enterprise 26200, Intel:

  • New test: windows_detached_spawn_stays_in_job_without_breakaway puts the test in a kill-on-close job without breakaway. It checks that the detached process starts and runs inside that job.
  • Spawn tests: the existing runtime::spawn::tests::windows_ tests pass.
  • Clippy: cargo clippy -p microsandbox -- -D warnings is clean.
  • Integration tests: on the earlier feat(runtime): support nested virtualization on Windows x86_64 hosts #10 branch, both nested virtualization integration tests passed under plain cargo test with this fix. Before it, nested_virt_can_be_modified_on_an_existing_sandbox failed with os error 5.

🤖 Generated with Claude Code

…away

The SDK starts a detached runtime with CREATE_BREAKAWAY_FROM_JOB so that
it outlives the launcher's job object. When the launcher is in a job
without JOB_OBJECT_LIMIT_BREAKAWAY_OK, CreateProcess refuses with
ERROR_ACCESS_DENIED and the SDK reported a bare permission error that
looked like a file problem. This hits `cargo test`, whose kill-on-close
job breaks create_detached() and modify().restart(), and agentd started
from sandboxed tool shells.

Retry without the breakaway flag when the first attempt is refused, and
log a warning. If the retry also fails, the error names the process
start and both causes.

Trade-off: a runtime started this way stays in the launcher's job, so it
ends when that job is terminated or closed with kill-on-close, for
example when the test run or the shell exits. The alternative is not
starting at all, since such a job lets no child escape. Launchers in no
job, or in a job that allows breakaway, behave as before. The launch
contract is unchanged; COMPATIBILITY.md records the lifecycle change.

The new test reproduces the refusal in a kill-on-close job without
breakaway and checks that the detached process starts inside that job.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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