Replies: 1 comment 1 reply
|
Verified against rc.8 ( 1. The gap is real and visible at both call sites. In 2. The transactional-cleanup direction matches the family's ownership rules. My family tracking on this package (#3193 default-DACL/EPERM, #3460 console visibility) keeps hitting the same root pattern: native ownership is scattered across fallible Win32 calls with no single local invariant. Your "acquire-then-close-all-on-failure / transfer-with-finally" rule is the right shape, and keeping it private to 3. One check worth adding if not already covered: the 4. On the contribution-guide point: the guide's no-external-PR stance is exactly why these fork commits + discussion posts are the right channel right now. When PRs re-enable, this patch is a strong candidate — the fault-injection regression set (12 ownership checks) is exactly the kind of pin the package needs. I've noted it alongside the other Windows sandbox family items. Thanks for the thorough audit — this closes a real class of leaks in the most error-prone part of the sandbox. |
Uh oh!
There was an error while loading. Please reload this page.
Summary
I found a cluster of native resource-ownership gaps while auditing the Windows ACL sandbox launcher on master at
141eb6fef83422698aef7a981029e843e8161534.The launcher crosses several fallible Win32 calls while it owns only part of the final result: three anonymous pipe pairs, temporary inherit bits on caller-owned stdio handles, process and thread handles, a kill-on-close job, and handles transferred to pipe-drain and process-wait operations. Failures between acquisition and transfer can leak handles, leave stdio inheritable for a later spawn, strand a partial child, or replace the primary
GetLastError()value during cleanup.I searched the repository's public Discussions, issues, PRs, and indexed fork patches for the affected ownership paths and did not find an equivalent report or patch. The nearby Windows reports concern console visibility, ACL traversal latency, path encoding, wrappers, and attachment behavior rather than native handle cleanup.
Reproduction
I added fault-injection regressions through the package's real entry points before changing production code. In the pre-patch run, 12 of the new ownership checks failed. The cases cover:
CreatePipe()failure after earlier pairs were acquired;PROCESS_INFORMATIONresults containing only a process or thread handle;CreateProcessAsUserW(), job-assignment, and thread-resume failures after local ownership has accumulated;PeekNamedPipe(),ReadFile(), process-wait, and exit-code failures after ownership transfers to async drain/wait helpers.The observable failures were retained native handles, inherit bits not restored, partial children not terminated, and primary error codes overwritten by cleanup.
Root cause and patch
Ownership spans several native calls, but the original control flow cleaned up only selected fully assembled paths. There was no single local rule for when a handle remained owned, when it transferred, or which error had to survive cleanup.
I prepared a local transactional cleanup patch that:
finallyon success and failure; andsandbox-windows-acl, without a new public RAII abstraction.Fork commit:
1fde2cecce334bdc8f574452f444c323a688165bBranch:
codex/fix-windows-acl-spawn-failure-cleanupValidation
spawn.tsreached 100% statements, branches, functions, and lines.pnpm exec vitest run packages/sandbox/sandbox-windows-acl/tests— all 14 files and 166/166 tests passed.pnpm run build— passed.pnpm run lint— passed.pnpm run doc-sync— 27 of 28 checks passed; only the symlink verifier was blocked on this Windows checkout byEPERMwhile inspecting existing repository symlinks.Compatibility and limits
Successful spawn behavior, package exports, TypeScript interfaces, configuration, and child-process I/O contracts are unchanged. Cleanup calls remain best-effort: the patch guarantees that each owned cleanup is attempted and that cleanup cannot replace the primary failure, not that Windows must accept every cleanup call.
I left the implementation as a fork commit because the project's contribution guide currently does not accept external pull requests.
AI-assisted repository audit and implementation; I reviewed the source, reproduced the failures, and ran every validation listed above. The commit records
Codex <noreply@openai.com>as a co-author.All reactions