Repository navigation
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);--probereports
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.
\BaseNamedObjectsis an object-manager path; no
readonlyPaths/readwritePathsentry 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
github-actions commentedon Aug 28, 2026
Triage summary
Container-Process— this is aprocesscontainer/ AppContainer backend issue on Windows.@jsidewhiteand@bbonaby(AppContainer / process isolation area).Needs-Triagehas 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.dllcallsNtCreateDirectoryObjectwith an absolute\BaseNamedObjects\...path, which bypasses the redirection and hits the global namespace access check.Maintainers: Comment
/investigateto 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.jsidewhite commentedon Sep 14, 2026
For Tier 1 to support,
get_session_parent_dir()to use a non-global namespaceSalah Khan (@SalahKhan-MSFT)
jsidewhite commentedon Sep 14, 2026
I tried to workaround it by ACL'ing the global object, but it didn't pan out.
metacpp commentedon Sep 22, 2026
Hi Jeff Whiteside (@jsidewhite),
Checking in on this one. Are there any updates, and is there an ETA for this issue ? Thanks!
Studio: name the Git Bash MXC incompatibility and stop re-probing it (#…
Studio: name the Git Bash MXC incompatibility and stop re-probing it (u…
docs(investigations): MXC tier 1 on Windows 11 - NUL works, git needs…
laurentftech commentedon Oct 10, 2026
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-sdk1.0.0.--debugreportsselected 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:\inreadonlyPaths, see #1464 for why that matters), it reports:With a narrower policy, the process just exits with
0xC0000142. MXC's diagnostic then suggestsui.disable: false, which is already set.usr\bin\true.exefails the same way, andmsys-2.0.dllimports nouser32, 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):NtOpenDirectoryObject(\BaseNamedObjects),(\Sessions\1\BaseNamedObjects)0xC0000022NtCreateDirectoryObjectunder either0xC0000022CreateMutexW("Local\x")\Sessions\1\AppContainerNamedObjects\S-1-15-2-…\xCreateMutexW("Global\x"),CreateFileMappingW("Global\x")\Sessions\1\AppContainerNamedObjects\S-1-15-2-…\Global\xNtCreateDirectoryObjectunder\Sessions\1\AppContainerNamedObjects\S-1-15-2-…\So if
get_shared_parent_dir()/get_session_parent_dir()built their path underAppContainerNamedObjects\<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.