You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Windows] Rscript/Python crash with 0xC0000142 / 0xC0000005 under read-only ACL sandbox
Environment
OS: Windows 11 Pro, build 26200
Node: v24.15.0
DSH: current main (4d2ce87), running from source via pnpm dsh web (tsx)
PowerShell: Windows PowerShell 5.1 (no PowerShell 7 installed)
R: R 4.6.0 (D:\Program Files\R\R-4.6.0\bin\x64\Rscript.exe)
Python: on PATH
Symptom
Invoking an external program through the DSH pwsh tool under the Windows ACL
sandbox pops up an interactive Windows error dialog:
The application was unable to start correctly (0xc0000142) — STATUS_DLL_INIT_FAILED, and/or
The instruction at 0x0000000000000000 referenced memory at 0x0000000000000000. The memory could not be written. — 0xC0000005 access violation with a NULL instruction pointer.
Key observation: Rscript --version works, but any invocation that fully
initializes the runtime (Rscript -e "1+1") crashes. Both error codes appear
to be two faces of the same underlying failure (see root cause).
Steps to reproduce
Call the windows-acl runner directly (no pwsh layer needed):
Actual (read-only): the process exits with -1073741819 (0xC0000005) and no output.
Expected: [1] 2 (or at minimum a clean, non-crash failure).
Same command with --mode workspace-write: works correctly.
Root cause
read-only confinement leaves the ambient TMP/TEMP untouched and grants no
temp write capability, so the child's write to %TEMP% is denied by the
WRITE_RESTRICTED pass-2 check. R creates its per-session temp directory
(%TEMP%\RtmpXXXX) during startup; when that write fails, R's startup error
path crashes instead of failing gracefully (0xC0000005 in this code path, and
the same denied-write-during-init surfaces as 0xC0000142 on other paths). workspace-write does not crash because the runner already redirects TMP/TEMP to a private granted temp directory there.
Evidence:
%TEMP% contains hundreds of RtmpXXXX directories — one per successful R
session, confirming R creates its session temp dir at startup.
read-only → crash; workspace-write → success, with the only relevant
difference being the private temp grant + TMP/TEMP redirection.
Adding Authenticated Users (S-1-5-11) to the restricting SID list was
tried first and did not fix the crash (the change was reverted) — the
failure is the temp-dir write, not an AU-gated system object.
This also matches the already-documented keep-alive behavior in packages/sandbox/sandbox-windows-acl/src/token.ts ("early DLL init dies with
0xC0000142 ... without them").
Proposed fix (implemented and verified locally)
Give every confined child a private writable scratch temp directory in both
modes, not just workspace-write:
src/runner.ts — in read-only, mkdtempSync a private scratch dir under --temp, derive its SID via tempWriteSid, and redirect TMP/TEMP to it
(reuses the existing workspace-write plumbing). Also call SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX) so a future
startup failure no longer blocks the session on an interactive WER dialog.
src/index.ts (AclSandbox) — allow read-only to accept a scratch tempDir + tempWriteSid (workspace SID still rejected); grant the scratch
in init() independently of the workspace grant.
src/token.ts — read-only restricting list becomes [logon SID, Everyone, ...writeSids] where writeSids is the optional
scratch-temp SID.
src/ffi.ts / src/win32-abi.ts — add the SetErrorMode binding and the SEM_FAILCRITICALERRORS / SEM_NOGPFAULTERRORBOX constants.
The scratch dir is per-invocation, removed on exit, and the ambient temp root
plus everything else stays denied — the write boundary is otherwise unchanged.
Behavior change to review
Because the scratch-temp capability lets PowerShell complete its startup
AppLocker probe, read-only pwsh now starts in FullLanguage instead of
ConstrainedLanguage (host-wide WDAC/AppLocker policy can still force it). The
pinned contract in runner.spec.ts and the model-facing tool-pwsh
description were updated accordingly. Flagging this explicitly since it is a
deliberate trade-off maintainers should confirm.
Verification
Rscript/python under --mode read-only: exit 0, tempdir() inside the
private scratch dir.
npx tsc --noEmit clean for sandbox-windows-acl, sandbox-local, tool-pwsh.
Test suites: runner.spec.ts 14/14 (updated read-only case pins the new
scratch/LANGMODE behavior), token-failure-paths + index-failure-paths
49/49, acl.spec.ts + tool-pwsh/tests/tools.spec.ts 70/70.
A full patch for the above is ready locally — happy to open a PR if maintainers
agree with the approach (especially the FullLanguage trade-off).
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
[Windows] Rscript/Python crash with 0xC0000142 / 0xC0000005 under read-only ACL sandbox
Environment
main(4d2ce87), running from source viapnpm dsh web(tsx)D:\Program Files\R\R-4.6.0\bin\x64\Rscript.exe)Symptom
Invoking an external program through the DSH
pwshtool under the Windows ACLsandbox pops up an interactive Windows error dialog:
The application was unable to start correctly (0xc0000142)—STATUS_DLL_INIT_FAILED, and/orThe instruction at 0x0000000000000000 referenced memory at 0x0000000000000000. The memory could not be written.—0xC0000005access violation with a NULL instruction pointer.Key observation:
Rscript --versionworks, but any invocation that fullyinitializes the runtime (
Rscript -e "1+1") crashes. Both error codes appearto be two faces of the same underlying failure (see root cause).
Steps to reproduce
Call the windows-acl runner directly (no pwsh layer needed):
-1073741819(0xC0000005) and no output.[1] 2(or at minimum a clean, non-crash failure).--mode workspace-write: works correctly.Root cause
read-onlyconfinement leaves the ambientTMP/TEMPuntouched and grants notemp write capability, so the child's write to
%TEMP%is denied by theWRITE_RESTRICTED pass-2 check. R creates its per-session temp directory
(
%TEMP%\RtmpXXXX) during startup; when that write fails, R's startup errorpath crashes instead of failing gracefully (0xC0000005 in this code path, and
the same denied-write-during-init surfaces as 0xC0000142 on other paths).
workspace-writedoes not crash because the runner already redirectsTMP/TEMPto a private granted temp directory there.Evidence:
%TEMP%contains hundreds ofRtmpXXXXdirectories — one per successful Rsession, confirming R creates its session temp dir at startup.
read-only→ crash;workspace-write→ success, with the only relevantdifference being the private temp grant +
TMP/TEMPredirection.Authenticated Users(S-1-5-11) to the restricting SID list wastried first and did not fix the crash (the change was reverted) — the
failure is the temp-dir write, not an AU-gated system object.
This also matches the already-documented keep-alive behavior in
packages/sandbox/sandbox-windows-acl/src/token.ts("early DLL init dies with0xC0000142 ... without them").
Proposed fix (implemented and verified locally)
Give every confined child a private writable scratch temp directory in both
modes, not just
workspace-write:src/runner.ts— inread-only,mkdtempSynca private scratch dir under--temp, derive its SID viatempWriteSid, and redirectTMP/TEMPto it(reuses the existing workspace-write plumbing). Also call
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX)so a futurestartup failure no longer blocks the session on an interactive WER dialog.
src/index.ts(AclSandbox) — allowread-onlyto accept a scratchtempDir+tempWriteSid(workspace SID still rejected); grant the scratchin
init()independently of the workspace grant.src/token.ts— read-only restricting list becomes[logon SID, Everyone, ...writeSids]wherewriteSidsis the optionalscratch-temp SID.
src/ffi.ts/src/win32-abi.ts— add theSetErrorModebinding and theSEM_FAILCRITICALERRORS/SEM_NOGPFAULTERRORBOXconstants.The scratch dir is per-invocation, removed on exit, and the ambient temp root
plus everything else stays denied — the write boundary is otherwise unchanged.
Behavior change to review
Because the scratch-temp capability lets PowerShell complete its startup
AppLocker probe,
read-onlypwsh now starts in FullLanguage instead ofConstrainedLanguage (host-wide WDAC/AppLocker policy can still force it). The
pinned contract in
runner.spec.tsand the model-facingtool-pwshdescription were updated accordingly. Flagging this explicitly since it is a
deliberate trade-off maintainers should confirm.
Verification
Rscript/pythonunder--mode read-only: exit 0,tempdir()inside theprivate scratch dir.
--temproot writeDENIED, scratch write OK, CIM still DENIED.
npx tsc --noEmitclean forsandbox-windows-acl,sandbox-local,tool-pwsh.runner.spec.ts14/14 (updated read-only case pins the newscratch/LANGMODE behavior),
token-failure-paths+index-failure-paths49/49,
acl.spec.ts+tool-pwsh/tests/tools.spec.ts70/70.A full patch for the above is ready locally — happy to open a PR if maintainers
agree with the approach (especially the FullLanguage trade-off).
All reactions