-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
Description Git Credential Manager (GCM) incorrectly identifies Docker containers running on WSL2 as WSL distributions. This is caused by /proc/version
in the container inheriting WSL-related strings (WSL2
, microsoft
) from the underlying WSL2 host kernel. As a result, GCM incorrectly applies WSL-specific logic and attempts to invoke Windows interop tools (e.g., powershell.exe
), which are not available in Linux-native Docker containers.This results in failed Git operations inside the Docker container, even when the container is a full Linux environment.
Steps to Reproduce
Prerequisites:
-
Docker Desktop is installed on Windows and configured to use WSL2 as the backend.
-
GCM for Linux is installed inside the Docker container.
Steps:
- Start a Full Desktop Environment Docker Container :
Run a desktop-enabled container likelinuxserver/rdesktop
:
docker run -it linuxserver/rdesktop
- Check Kernel Version Inside the Container :
Inside the container, run:
cat /proc/version
Output :
Linux version 5.15.167.4-microsoft-standard-WSL2 (root@f9c826d3017f) (gcc (GCC) 11.2.0, GNU ld (GNU Binutils) 2.37) #1 SMP Tue Nov 5 00:21:55 UTC 2024
This indicates the container inherits the WSL2 kernel from the host.
- Install Git and GCM :
Inside the container:
apt update && apt install -y git curl
curl -sSL https://github.com/GitCredentialManager/git-credential-manager/releases/download/v2.0.935/gcm-linux-x86_64.2.0.935.tar.gz | tar -xz
sudo ./install.sh
git config --global credential.helper /usr/local/bin/git-credential-manager
- Attempt to Clone a Repository :
Run:
git clone https://<username>@dev.azure.com/<project>/<repo>
Observe the Error :
fatal: An error occurred trying to start process '/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe' with working directory '/root/'. No such file or directory
Current Behavior
-
Detection Logic : GCM incorrectly detects the Docker container as a WSL distribution because
/proc/version
contains WSL2-related strings (WSL2
,microsoft
). -
Interop Issue : GCM tries to invoke Windows tools (e.g.,
powershell.exe
), which do not exist in the container. -
Result : Git operations relying on GCM fail inside the container.
Expected Behavior GCM should recognize the Docker container as a Linux-native environment and avoid invoking Windows interop tools. It should use Linux-native tools like pass
or other credential helpers configured for Linux.
Root Cause The problem lies in the current WSL detection logic in the WslUtils.GetWslVersion
method, which checks for WSL-related strings in /proc/version
but does not account for Docker containers that inherit these strings from the WSL2 host.
Current Logic:
const string procVersionPath = "/proc/version";
if (fs.FileExists(procVersionPath))
{
string procVersion = fs.ReadAllText(procVersionPath);
if (!Regex.IsMatch(procVersion, "[Mm]icrosoft"))
{
return 0; // Not WSL
}
if (Regex.IsMatch(procVersion, "wsl2", RegexOptions.IgnoreCase))
{
return 2; // WSL2
}
return 1; // WSL1
}
This does not differentiate between actual WSL distributions and Docker containers running on WSL2.
Proposed Fix
- Improve WSL Detection Logic :
- Add checks for container-specific environments using
/proc/1/cgroup
or/proc/self/cgroup
. If the environment is containerized (e.g.,docker
,containerd
), bypass WSL detection:
if (File.Exists("/proc/1/cgroup"))
{
string cgroup = File.ReadAllText("/proc/1/cgroup");
if (Regex.IsMatch(cgroup, "(docker|containerd|kubepods)"))
{
return 0; // Not WSL, it's a container
}
}
- Introduce
GCM_DISABLE_WSL_SUPPORT
:
Add an environment variable to explicitly disable WSL detection. This allows users to force Linux-native behavior in ambiguous environments. For example:
export GCM_DISABLE_WSL_SUPPORT=1
-
Default to Linux-Native Tools for Containers :
If/proc/version
contains WSL2-related strings but the environment is containerized, GCM should default to Linux-native behavior instead of invoking Windows tools. -
Proposed New Logic :
private static int GetWslVersion(IEnvironment env, IFileSystem fs)
{
// Check if WSL support is explicitly disabled
if (env.Variables.TryGetValue("GCM_DISABLE_WSL_SUPPORT", out _))
{
return 0; // Treat as non-WSL
}
// Detect containers and avoid misclassification as WSL
if (File.Exists("/proc/1/cgroup"))
{
string cgroup = File.ReadAllText("/proc/1/cgroup");
if (Regex.IsMatch(cgroup, "(docker|containerd|kubepods)"))
{
return 0; // Treat as non-WSL
}
}
// Standard WSL detection
const string procVersionPath = "/proc/version";
if (fs.FileExists(procVersionPath))
{
string procVersion = fs.ReadAllText(procVersionPath);
if (!Regex.IsMatch(procVersion, "[Mm]icrosoft"))
{
return 0; // Not WSL
}
if (Regex.IsMatch(procVersion, "wsl2", RegexOptions.IgnoreCase))
{
return 2; // WSL2
}
return 1; // WSL1
}
return 0;
}
Additional Context
This issue primarily affects:
-
Docker Containers running on WSL2 backends (e.g., Docker Desktop with WSL2 integration).
-
Linux-native workflows where users expect GCM to operate without invoking Windows interop tools.