Skip to content

ProcessContainer (BaseContainer): GetFinalPathNameByHandleW(VOLUME_NAME_DOS) always fails — Mount Manager unreachable, breaks git's cwd and Node's realpath.native #1464

Description

@laurentftech

Relevant area(s)

Windows

Brief description of your issue

Under the tier 1 BaseContainer runner, a sandboxed process cannot translate an NT path back to a drive-letter path. GetFinalPathNameByHandleW fails with ERROR_ACCESS_DENIED (5) for every VOLUME_NAME_DOS request, on a handle the process just opened successfully, while the same call with VOLUME_NAME_NT succeeds. GetVolumeNameForVolumeMountPointW("C:\\") is refused too. So the Mount Manager seems to be out of reach from the container, and the NT→DOS translation needs it.

No filesystem policy changes this: it fails with the working directory inside readwritePaths, and also with C:\ itself in readonlyPaths.

Ordinary developer tools depend on this call:

  • Node.js: fs.realpathSync.native / fs.promises.realpath (libuv uv_fs_realpath) fail with EPERM on any path, the cwd included. npm and many CLIs resolve paths this way.
  • Git for Windows (native mingw64\bin\git.exe): mingw_getcwd calls GetFinalPathNameByHandleW, then falls back to GetLongPathNameW. That fallback has to list every ancestor folder by name, so every command that needs the work tree (init, status, rev-parse, ...) dies with fatal: unable to get current working directory: Permission denied unless the drive root is readable. Making C:\ readable means falling back to a deny list of everything beside the project, which defeats an allow-only policy.

git --version, cmd, PowerShell and NUL all work under tier 1, so this looks like the last thing between tier 1 and a usable git-based workflow.

Environment:

  • Windows 11 Home 24H2, build 26100.9457, x64
  • @microsoft/mxc-sdk 1.0.0, wxc-exec.exe (x64); --debug shows selected isolation tier: base-container, runner BaseContainer
  • Node 26.4.0, Git for Windows 2.45.1
  • Run from the interactive console session

Steps to reproduce

  1. Make a working folder, e.g. C:\mxc-lab\app.
  2. Config (ui.disable: false so that console tools start):
{
  "version": "1.0.0",
  "containment": "processcontainer",
  "process": {
    "commandLine": "node -e \"console.log(require('fs').realpathSync.native('.'))\"",
    "cwd": "C:\\mxc-lab\\app",
    "timeout": 30000
  },
  "filesystem": { "readwritePaths": ["C:\\mxc-lab\\app"] },
  "ui": { "disable": false }
}
  1. wxc-exec.exe config.json
  2. Same config with "commandLine": "git init -q repo".
  3. To isolate the call, a small probe that calls GetFinalPathNameByHandleW with each flag, GetLongPathNameW and GetVolumeNameForVolumeMountPointW on the cwd: https://github.com/laurentftech/pi-outpost/blob/feat/confined-terminal/scripts/probes/path-apis.cs (csc.exe from .NET Framework builds it; no SDK needed).

Expected behavior

realpathSync.native('.') prints C:\mxc-lab\app, git init creates the repository, and GetFinalPathNameByHandleW(h, ..., VOLUME_NAME_DOS) returns \\?\C:\mxc-lab\app, as it does outside the container. Resolving a path the process may already open should not need any extra grant.

Actual behavior

node realpath.native   EPERM: operation not permitted, realpath 'C:\mxc-lab\app'
git init               fatal: unable to get current working directory: Permission denied
                       (it leaves an empty `repo` folder behind)

path-apis.exe inside the container, cwd C:\mxc-lab\app:

GetVolumeNameForVolumeMountPointW(C:\)      ERROR 5
GetLongPathNameW                            ERROR 5   (OK once C:\ is in readonlyPaths)
CreateFileW(access=0, BACKUP_SEMANTICS)     OK
  GetFinalPathNameByHandleW(normalized, DOS) ERROR 5
  GetFinalPathNameByHandleW(opened, DOS)     ERROR 5
  GetFinalPathNameByHandleW(normalized, NT)  OK \Device\HarddiskVolume3\mxc-lab\app
  GetFinalPathNameByHandleW(opened, NT)      OK \Device\HarddiskVolume3\mxc-lab\app

Outside the container, every line succeeds. With C:\ added to readonlyPaths, the DOS variants still fail. Only git starts working, through its GetLongPathNameW fallback.

Related: #1061 (MSYS2 runtimes); this one affects native, non-MSYS tools.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-BugSomething is not working as intended.Needs-TriageHas not yet been reviewed, classified, and routed.OS-WindowsApplies specifically to Windows hosts or Windows behavior.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions