Skip to content

Bug: GCM Misidentifies Docker Containers Running on WSL2 Due to /proc/version #1813

@vinitsiriya

Description

@vinitsiriya

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:

  1. Docker Desktop is installed on Windows and configured to use WSL2 as the backend.

  2. GCM for Linux is installed inside the Docker container.

Steps:

  1. Start a Full Desktop Environment Docker Container :
    Run a desktop-enabled container like linuxserver/rdesktop:
docker run -it linuxserver/rdesktop
  1. 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.

  1. 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
  1. 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

  1. 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
    }
}
  1. 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
  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.

  2. 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:

  1. Docker Containers running on WSL2 backends (e.g., Docker Desktop with WSL2 integration).

  2. Linux-native workflows where users expect GCM to operate without invoking Windows interop tools.


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions