Skip to content

Windows restricted_token: Hermes tools fail because MSYS2/git-bash cannot initialize (CreateFileMapping error 5) #29

Description

@0xReSan

Description

Under the restricted_token backend (the default for network: host), a Hermes agent running inside the sandbox cannot execute any of its file/tool operations (write_file, terminal, execute_code). All Hermes tools route through git-bash (MSYS2), and git-bash fails to initialize under the RestrictedToken sandbox with a fatal CreateFileMapping error.

This is not a sandbox file-permission failure — direct file writes via cmd.exe inside the same sandbox succeed. The failure is specific to MSYS2/Cygwin runtime initialization under a restricted token.

Test Environment

  • Windows 11 Pro, build 26200 (Insider Preview)
  • finsafe v0.9.30 (x86_64-pc-windows-msvc)
  • Hermes Agent v0.19.1 (git install, Python 3.11.15)
  • Git for Windows (MSYS2) — D:\Program Files\Git\bin\bash.exe (set as HERMES_GIT_BASH_PATH)
  • Backend: restricted_token, network: host

Policy Used

schema_version: 1
kind: local-wrapper
program_mode: short-lived
network: host
windows:
  backend: restricted_token
filesystem:
  read_only_paths: []
  read_write_paths:
    - 'D:\finclaw\workspace'
    - '${USERPROFILE}\AppData\Local\hermes'
    - '${USERPROFILE}\AppData\Local\Temp'

Steps to Reproduce

# 1. Run hermes inside the sandbox, asking it to write a file
finsafe --policy policy.yaml run cmd /c "hermes -z \"Write the text 'hello' to D:\finclaw\workspace\test.txt\"" chat

Hermes attempts write_file → fails → falls back to terminal (PowerShell Set-Content) → fails again with the same underlying error.

Actual Behavior

Hermes reports both tool attempts failed:

Attempt 1: write_file D:\finclaw\workspace\hermes-test-write.txt
  Result: FAILED, bytes_written: 0
  Error: bash.exe fatal - CreateFileMapping S-1-5-21-...-1001.1, Win32 error 5 (ACCESS DENIED)

Attempt 2: terminal -> native powershell.exe Set-Content (fallback)
  Result: FAILED, exit_code 256
  Error: same bash.exe fatal - CreateFileMapping ... Win32 error 5

The workspace file is NOT created. finsafe itself reports exit_code=Some(0) (the outer cmd wrapper exits 0 even though the inner hermes tool call failed).

Root Cause Evidence (Procmon Analysis)

Logfile-25 (bash.exe crash chain)

8 git-bash processes, each spawning the next (MSYS2 fork emulation), all exit with STATUS_DLL_INIT_FAILED (-1073741502):

bash.exe (login shell)
  → create Conhost.exe
  → create bash.exe (usr/bin)
    → create WerFault.exe   (Windows Error Reporting fired — process crashed)
    → exit -1073741502      (STATUS_DLL_INIT_FAILED)
  → exit -1073741502

Logfile-26 (bash.exe inside sandbox, 177k events)

  • 243 bash.exe processes spawned (fork chains)
  • 31 ACCESS DENIED events, all on:
    HKLM\System\CurrentControlSet\Services\WinSock2\Parameters (Desired Access: All Access)
  • No file-system ACCESS DENIED on the workspace / Temp paths — the sandbox DACLs are fine

Key: CreateFileMapping is a kernel-object operation

Procmon's default file/registry/network capture does not log CreateFileMapping failures, so the fatal error is only visible in bash's own stderr:

[main] bash (6004) ...bash.exe: *** fatal error - CreateFileMapping
S-1-5-21-2981251388-1693183809-1632240619-1001.1, Win32 error 5. Terminating.

S-1-5-21-...-1001.1 is the MSYS2 shared-memory mapping object named after the user SID (Cygwin/MSYS uses a named section for inter-process shared state). Creating it requires the SeCreateGlobalPrivilege (or an existing object whose DACL admits the restricted token). The RestrictedToken backend removes privileges, so the mapping cannot be created → MSYS runtime aborts → every Hermes tool that spawns bash dies before doing anything.

Comparison — Direct writes work fine

Same sandbox, no bash involved:

# cmd.exe direct write to Temp — SUCCESS
finsafe --policy policy.yaml self-confine -- cmd /c echo test > C:\Users\xuls2\AppData\Local\Temp\fs-test-1.txt   # file created

# Rust test program spawning a child that writes to workspace — SUCCESS
#   (parent spawns child exe; child writes D:\finclaw\workspace\child-write-test.txt)
finsafe --policy policy.yaml run D:\finclaw\child-write-test\target\release\child-write-test.exe
#   [child] wrote 57 bytes ... VERIFY: file exists — child write OK

So the sandbox itself correctly grants workspace/Temp write access and child-process creation. The breakage is confined to MSYS2/Cygwin runtime initialization under the restricted token.

Summary Table

Operation Inside sandbox Result
cmd /c echo > workspace\f.txt RestrictedToken ✅ write OK
cmd /c echo > %TEMP%\f.txt RestrictedToken ✅ write OK
Rust parent → child → write workspace RestrictedToken ✅ child spawn + write OK
Hermes write_file (via git-bash) RestrictedToken ❌ bash CreateFileMapping error 5
Hermes terminal → powershell Set-Content RestrictedToken ❌ same bash error
git-bash bash.exe init RestrictedToken ❌ STATUS_DLL_INIT_FAILED

Design Note (trade-off)

The Windows sandbox was originally designed for native Windows binaries — MSYS2/Cygwin runtimes (git-bash) are outside its intended compatibility scope. However, Hermes (and other agent toolchains that shell out through git-bash) requires MSYS2 to initialize for its write_file / terminal / execute_code tools. Supporting Hermes inside the sandbox therefore means either:

  1. Keeping SeCreateGlobalPrivilege (or otherwise permitting the user-SID named shared-memory object) in the RestrictedToken posture, or
  2. Having Hermes execute tools through a native Windows entry point (cmd.exe / PowerShell) instead of git-bash, or
  3. Documenting that RestrictedToken + MSYS2-dependent agents is unsupported.

This issue focuses on the problem report; the trade-off note is provided as context for maintainers.

Files Referenced

  • D:\finclaw\Logfile-25.CSV — bash fork chain, all STATUS_DLL_INIT_FAILED + WerFault
  • D:\finclaw\Logfile-26.CSV — 243 bash processes, 31 WinSock2 registry ACCESS DENIED
  • D:\finclaw\child-write-test\ — Rust repro: parent spawns child, child writes workspace (works under sandbox)

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bot:dispatchedbugSomething isn't workingdocumentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions