Skip to content

ProcessContainer: MSYS2/Cygwin runtimes (git-bash) cannot initialize — NtCreateDirectoryObject(\BaseNamedObjects\...) denied #1061

Description

Relevant area(s)

Linux, Windows

Brief description of your issue

Summary

MSYS2/Cygwin-based executables (git-bash, and anything else linking msys-2.0.dll)
cannot run under the processcontainer backend. The process launches successfully,
but the MSYS runtime aborts during initialization when it tries to create its shared
state directory in the session-global object namespace, which AppContainer processes
cannot write.

This is not a policy or configuration problem — no filesystem, capability, or UI
setting can grant it.

Environment

  • MXC: main
  • Windows 11 25H2 (build 26200)
  • Selected tier: appcontainer-dacl (T3); --probe reports
    baseContainerApiPresent: true, bfsCompiledIn: false
  • git-bash / MSYS2 runtime 3.6.5 (x86_64-pc-msys)

Steps to reproduce

Repro

Config:

{
  "version": "0.8.0-alpha",
  "containment": "processcontainer",
  "process": {
    "commandLine": "\"C:\\tools\\git-bash\\bin\\bash.exe\" --version",
    "cwd": "C:\\tools\\git-bash",
    "timeout": 30000
  },
  "filesystem": {
    "readonlyPaths": ["C:\\tools\\git-bash", "C:\\Windows"],
    "readwritePaths": []
  },
  "fallback": { "allowDaclMutation": true },
  "ui": { "disable": false }
}
wxc-exec.exe config.json

Expected behavior

bash.exe --version
GNU bash, version 5.2.37(1)-release (x86_64-pc-msys)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Actual behavior

Observed

0 [main] bash (NNNN) C:\tools\git-bash\usr\bin\bash.exe: *** fatal error -
  NtCreateDirectoryObject(\BaseNamedObjects\msys-2.0S5-<hash>): 0xC0000022
Exit code: -1073741502 (0xC0000142)

0xC0000022 is STATUS_ACCESS_DENIED; 0xC0000142 is STATUS_DLL_INIT_FAILED.

Root cause

msys-2.0.dll passes an absolute NT path to NtCreateDirectoryObject.
AppContainer's named-object redirection lives in user-mode kernelbase
(BaseGetNamedObjectDirectory) and only covers the Win32 named-object APIs — it does
not rewrite absolute NT paths. The call therefore reaches the real global
\BaseNamedObjects and fails the DIRECTORY_CREATE_SUBDIRECTORY access check
(SeChangeNotifyPrivilege bypasses traverse, not create).

Verified by direct probe from inside the container, same container SID:

Path Result
\BaseNamedObjects\test 0xC0000022
\Sessions\1\AppContainerNamedObjects\<SID>\test STATUS_SUCCESS

The container's own namespace is writable; only the global one is denied.

An API trace of bash -c "echo hi | tr a-z A-Z" shows the full dependency is small —
exactly two absolute paths, with every child object created relative to the resulting
directory handle:

CreateDir     Root=0x0    "\BaseNamedObjects\msys-2.0S5-<hash>"
CreateDir     Root=0x0    "\Sessions\BNOLINKS\1\msys-2.0S5-<hash>"
CreateSection Root=0x124  "shared.5"
CreateSection Root=0x124  "cygpid.<pid>"        <- fork
CreateMutant  Root=0x124  "cygpipe.input.mutex.<pid>-0x1"   <- pipe
CreateMutant  Root=0x124  "sig_send.<pid>"      <- signals
CreateSymlink Root=0x124  "winpid.<winpid>"

Ruled out

  • Not Win32k. Identical failure with ui.disable: false.
  • Not filesystem policy. \BaseNamedObjects is an object-manager path; no
    readonlyPaths / readwritePaths entry reaches it. Granting read-write on the
    install directory changes nothing.
  • Not ACLs. The install tree already carries
    ALL APPLICATION PACKAGES:(OI)(CI)(RX).
  • Not tier-specific. Same result on appcontainer-dacl; the object namespace
    boundary is a property of AppContainer, not of the tier.

Impact

Any MSYS2/Cygwin-based tool is unusable under processcontainer. This includes
git-bash, which is a common developer shell on Windows.

docs/learning-mode/capabilities.md already classifies \BaseNamedObjects as
unsupportedObjectType ("outside the supported diagnostic model"), so even with
captureDenials enabled this denial is filtered out of the actionable output and
appears only in verbose logging.

Activity

  1. added
    OS-LinuxApplies specifically to Linux hosts or Linux behavior.
    OS-WindowsApplies specifically to Windows hosts or Windows behavior.
    on Aug 28, 2026
  2. added
    Backend-ProcessContainerWindows ProcessContainer behavior, including BaseContainer and AppContainer isolation tiers.
    on Aug 28, 2026
  3. github-actions commented on Aug 28, 2026

    @github-actions

    Triage summary

    • Label added: Container-Process — this is a processcontainer / AppContainer backend issue on Windows.
    • Assigned: @jsidewhite and @bbonaby (AppContainer / process isolation area).
    • Needs-Triage has been removed.

    The root cause is well-documented in the issue: AppContainer's named-object redirection (via BaseGetNamedObjectDirectory) only covers Win32 APIs and does not rewrite absolute NT paths. msys-2.0.dll calls NtCreateDirectoryObject with an absolute \BaseNamedObjects\... path, which bypasses the redirection and hits the global namespace access check.

    Maintainers: Comment /investigate to check whether this issue or bug is valid against the most current code. Copilot will also produce a report with the changes that will be needed. For a small, unambiguous documentation or test fix, it may also create one draft PR.

    Generated by 🏷️ Issue Triage for #1061 · sonnet46 · 27.6 AIC · ⌖ 7.84 AIC · ⊞ 7.7K · ◷

  4. jsidewhite commented on Sep 14, 2026

    @jsidewhite
    Member

    For Tier 1 to support,

    1. Tools should be fixed in MSYS's get_session_parent_dir() to use a non-global namespace
    2. In OS, we will need true namespace virtualization support for BNO
      Salah Khan (@SalahKhan-MSFT)
  5. added
    Issue-FeatureA request for new or expanded product functionality.
    and removed
    Issue-BugSomething is not working as intended.
    on Sep 14, 2026
  6. jsidewhite commented on Sep 14, 2026

    @jsidewhite
    Member

    I tried to workaround it by ACL'ing the global object, but it didn't pan out.

    param(
        [Parameter(Mandatory)]
        [scriptblock]$Command,
    
        [string]$MsysDirectoryName = "msys-2.0S5-1888ae32e00d56aa"
    )
    
    $ErrorActionPreference = "Stop"
    Import-Module NtObjectManager
    
    $sessionId = (Get-Process -Id $PID).SessionId
    
    # AC = ALL APPLICATION PACKAGES (S-1-15-2-1).
    # The Low mandatory label permits writes from Low-IL AppContainer processes.
    $securityDescriptor = New-NtSecurityDescriptor `
        "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;AC)S:(ML;;NW;;;LW)"
    
    $globalDirectory = $null
    $sessionDirectory = $null
    
    try {
        $globalDirectory = New-NtDirectory `
            "\BaseNamedObjects\$MsysDirectoryName" `
            -SecurityDescriptor $securityDescriptor
    
        $sessionDirectory = New-NtDirectory `
            "\Sessions\BNOLINKS\$sessionId\$MsysDirectoryName" `
            -SecurityDescriptor $securityDescriptor
    
        & $Command
        $exitCode = $LASTEXITCODE
    }
    finally {
        if ($null -ne $sessionDirectory) {
            $sessionDirectory.Dispose()
        }
    
        if ($null -ne $globalDirectory) {
            $globalDirectory.Dispose()
        }
    }
  7. metacpp commented on Sep 22, 2026

    @metacpp

    Hi Jeff Whiteside (@jsidewhite),

    Checking in on this one. Are there any updates, and is there an ETA for this issue ? Thanks!

  8. laurentftech commented on Oct 10, 2026

    @laurentftech

    Additional data from tier 1 (BaseContainer), in case it helps whoever picks up the MSYS side.

    Environment: Windows 11 Home 24H2, build 26100.9457, x64, @microsoft/mxc-sdk 1.0.0. --debug reports selected isolation tier: base-container. Git for Windows 2.45.1 (MSYS2 runtime 3.4.10). The original report was on T3, so this confirms that tier 1 fails the same way.

    The runtime's own message. Once the policy lets MSYS initialise far enough (C:\ in readonlyPaths, see #1464 for why that matters), it reports:

    bash.exe: *** fatal error - NtCreateDirectoryObject(\BaseNamedObjects\msys-2.0S5-1888ae32e00d56aa): 0xC0000022
    

    With a narrower policy, the process just exits with 0xC0000142. MXC's diagnostic then suggests ui.disable: false, which is already set. usr\bin\true.exe fails the same way, and msys-2.0.dll imports no user32, so the Win32k hint is misleading for this case.

    Where kernel32 redirects names under tier 1, measured from inside the container with a small probe (named-objects.cs, calls NtQueryObject(ObjectNameInformation) on the handles):

    Attempt Result
    NtOpenDirectoryObject(\BaseNamedObjects), (\Sessions\1\BaseNamedObjects) 0xC0000022
    NtCreateDirectoryObject under either 0xC0000022
    CreateMutexW("Local\x") OK, lands in \Sessions\1\AppContainerNamedObjects\S-1-15-2-…\x
    CreateMutexW("Global\x"), CreateFileMappingW("Global\x") OK, lands in \Sessions\1\AppContainerNamedObjects\S-1-15-2-…\Global\x
    NtCreateDirectoryObject under \Sessions\1\AppContainerNamedObjects\S-1-15-2-…\ OK

    So if get_shared_parent_dir() / get_session_parent_dir() built their path under AppContainerNamedObjects\<package SID> when the token is an AppContainer (TokenIsAppContainer, TokenAppContainerSid), the directory creation itself would succeed under tier 1, without any OS change. MSYS processes inside the same container would share that state. They would not share it with MSYS processes outside the container, which seems acceptable for a sandbox.

    The next wall, probably. A project confining Git Bash with a restricted token (not MXC) got past the named objects and then hit MSYS's signal pipe: couldn't create signal pipe, Win32 error 5. The pipe's explicit DACL (user, Administrators, SYSTEM) has no entry the restricted client matches: buhuikongpan/dsh-win-gitbash#10. Under an AppContainer the same DACL would lack the package SID, so a runtime fix likely needs to cover that pipe too.

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

    Backend-ProcessContainerWindows ProcessContainer behavior, including BaseContainer and AppContainer isolation tiers.Issue-FeatureA request for new or expanded product functionality.OS-WindowsApplies specifically to Windows hosts or Windows behavior.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions