← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-8936 · CWE-674 · Disclosed 2026-06-02

Fixed a VM panic caused by unbounded recursion in the grpcfuse kernel module when a container created…

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a developer workstation self-own, not a wormable fire in the data center

CVE-2026-8936 is an uncontrolled recursion bug in Docker Desktop's grpcfuse kernel module. A container can trigger a Docker Desktop VM panic by creating very deep directory trees on a bind-mounted host folder and hitting a dentry invalidation path; the public CVE text says it is fixed in Docker Desktop 4.76.0, so the practical affected range is Docker Desktop versions before 4.76.0 on platforms where the grpcfuse file-sharing path is in play.

In real enterprise conditions this is not a top-tier emergency. The attacker already needs the ability to run a container on the target endpoint, then needs a bind mount into a shared host path, and the outcome is a local availability hit against that user's Docker Desktop VM rather than host compromise or broad lateral movement. That combination pushes this down from headline-grabbing CVE territory into a contained workstation/CI disruption problem.

"A local container can knock over one Docker Desktop VM, but it is post-initial-access and stops at availability."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Gain code execution in a Docker Desktop container

The attacker first needs the ability to start or influence a container on a host running Docker Desktop. In practice that means a malicious image, compromised developer account, poisoned local build workflow, or access to a shared CI/VDI endpoint where users can run Docker commands. The simplest weaponized tool is just docker run with a benign base image like alpine or busybox.
Conditions required:
  • Target host runs Docker Desktop
  • Attacker can execute docker run or influence a container workload
  • Linux containers mode is in use
Where this breaks in practice:
  • This is post-initial-access; the attacker is already on the box or already controlling a developer workflow
  • Many enterprise endpoints do not have Docker Desktop installed at all
  • Some orgs restrict Docker Desktop to a smaller developer population
Detection/coverage: No CVE-specific scanner logic is likely to catch this step. EDR and Docker audit telemetry can still show container launch activity and suspicious image provenance.
STEP 02

Obtain a writable bind mount into a shared host folder

The bug is triggered through the host-file-sharing path, so the container needs a bind mount such as -v $PWD:/mnt or --mount type=bind,src=<host-path>,dst=/mnt. A minimal PoC uses shell tooling like mkdir -p in a tight loop against the mounted path. Named volumes alone do not traverse the same host bind-mount path.
Conditions required:
  • A host directory is shared and bind-mounted into the container
  • The container can write into the mounted path
Where this breaks in practice:
  • No bind mount means no trigger path
  • Read-only mounts reduce the usable attack surface for directory creation
  • Workloads using named volumes or tmpfs instead of host binds are not on the hot path
Detection/coverage: Config scanners can usually see bind mounts in Compose files, docker inspect, or runtime policy engines, but they do not validate this specific recursion condition.
STEP 03

Trigger deep recursion in grpcfuse with nested directory creation

Inside the container, the attacker creates a deeply nested tree on the bind-mounted path until a dentry invalidation event reaches the vulnerable recursion path in grpcfuse. The public description does not reference a public exploit framework; ordinary shell utilities are sufficient. This is a reliability-focused DoS technique, not an exploit chain for privilege escalation.
Conditions required:
  • grpcfuse is the active file-sharing mechanism for the target workflow
  • The bind-mounted path can be mutated from inside the container
Where this breaks in practice:
  • If the deployment is using another file-sharing backend for that path, the trigger may not apply
  • The attacker must hit a fairly specific filesystem behavior, not just write any file
  • This is noisy from a filesystem-activity perspective
Detection/coverage: Host-side file activity can be visible through Docker Desktop backend processes, and abnormal bursts of nested directory creation are huntable, but there is no mainstream signature coverage yet.
STEP 04

Crash the Docker Desktop VM and disrupt local workloads

Successful exploitation causes a VM panic, taking down the Docker Desktop Linux VM and therefore the containers running inside it. The blast radius is typically the single endpoint or shared Desktop instance, with availability impact to local dev environments, demos, ephemeral labs, or Desktop-hosted CI jobs. There is no evidence in the published record of host escape, arbitrary code execution on the host, or data theft.
Conditions required:
  • The vulnerable recursion path is reached successfully
  • Docker Desktop is currently hosting active containers or services worth disrupting
Where this breaks in practice:
  • Impact stops at availability based on current public information
  • Blast radius is usually one user workstation or one shared Desktop node
  • Enterprise servers and Kubernetes worker fleets are generally not using Docker Desktop as the runtime
Detection/coverage: Monitoring should catch Docker Desktop VM crashes, abrupt container termination, and backend restart events. Vulnerability scanners will lag because this is a Desktop-specific local DoS with limited remote observables.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo public evidence of active exploitation found in the sources reviewed, and not listed in CISA KEV.
Proof-of-concept availabilityNo named public exploit repo or researcher PoC surfaced. Based on the CVE text, a bare-bones PoC likely needs only docker run, a writable bind mount, and recursive mkdir activity.
EPSSNo CVE-specific public EPSS value was confirmed from FIRST during this assessment; treat EPSS as unavailable/too new to rely on rather than as a risk reducer.
KEV statusNo in CISA's Known Exploited Vulnerabilities catalog.
CVSS / vector interpretationThe user-supplied brief says there is no vendor/authority baseline severity to compare against, so this is scored here as a fresh operational assessment. The attack is effectively local, low-complexity, low-privilege, availability-only.
Affected versionsPublic CVE text says the fix lands in Docker Desktop 4.76.0; practical read: Docker Desktop < 4.76.0 where the vulnerable grpcfuse file-sharing path is used.
Fixed versionsUpgrade to Docker Desktop 4.76.0 or later. No distro backport guidance was found because this is a Docker Desktop product issue, not a typical Linux distro package advisory.
Exposure populationReachable population is naturally capped: this affects developer desktops and shared Desktop-style build hosts, not generic internet-facing services. Shodan/Censys-style exposure data is largely irrelevant because exploitation requires local container execution.
Disclosure date2026-06-02.
Reporter / creditCredited in the public CVE mirror to Nitesh Surana of TrendAI Research / Trend Micro.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to MEDIUM (5.4/10)

The decisive downgrading factor is attacker position: this is a post-initial-access local container issue, not something an unauthenticated remote attacker can reach across your fleet. Impact is real but narrow—an endpoint-scale Docker Desktop VM crash with availability loss, not host takeover or broad tenant escape based on current public evidence.

HIGH Availability impact is the primary consequence
HIGH Attacker must already be able to run a container on the target
MEDIUM Prevalence of `grpcfuse` usage across all Docker Desktop deployments

Why this verdict

  • Post-initial-access requirement: exploitation starts only after the attacker can run or influence a container on the endpoint, which implies a prior compromise stage or trusted-user abuse.
  • Reachability is narrowed by bind mounts: the vulnerable path depends on a writable host bind mount into the container, so named-volume-only workflows are not in the main blast zone.
  • Impact is availability, not takeover: the public record describes a VM panic and Docker Desktop disruption, with no current evidence of host code execution, container escape, or confidentiality compromise.

Why not higher?

A higher rating would need one of three things that are missing here: unauthenticated remote reachability, host compromise, or active exploitation evidence. Instead, the chain stacks multiple prerequisites—local container execution, bind-mount presence, and the vulnerable file-sharing path—before it produces a one-node DoS.

Why not lower?

This is still more than cosmetic. On developer laptops, demo machines, or shared Desktop-backed build endpoints, a reliable Docker Desktop VM panic can kill active containers and disrupt work immediately. If you support many developers, the aggregate operational pain is real enough to keep it out of LOW.

05 · Compensating Control

What to do — in priority order.

  1. Prefer named volumes or tmpfs for untrusted workloads — Move disposable or semi-trusted containers off writable host bind mounts where feasible, because the vulnerable path is tied to host file sharing. For a MEDIUM finding there is no mitigation SLA, but this is the cleanest exposure reduction to fold into normal engineering work before the remediation window closes.
  2. Restrict who can run Docker Desktop containers — Treat Docker Desktop like a privileged developer tool, not a general-purpose endpoint app. Tightening local group membership, image trust, and shared workstation use reduces the chance that a compromised user session can weaponize the bug; for MEDIUM, there is no mitigation SLA — go straight to planned control hardening inside the 365-day patch window.
  3. Monitor for abnormal bind-mounted directory churn — Hunt for containers hammering bind-mounted paths with extreme nested directory creation or causing repeated Docker Desktop backend/VM restarts. This will not prevent exploitation, but it gives you an early signal on shared build hosts and power-user laptops while you schedule patching.
What doesn't work
  • Turning on MFA does nothing for the exploit path once an attacker is already running local containers.
  • A WAF or external network IDS is irrelevant; this is not an internet-reachable request/response flaw.
  • Enhanced Container Isolation alone is not a fix; Docker documents that normal host directory mounts still work under ECI, and the bug lives in the Desktop file-sharing path rather than in a missing auth check.
06 · Verification

Crowdsourced verification payload.

Run this on the target Docker Desktop host as the logged-in user who can invoke Docker Desktop. Save it as check_cve_2026_8936.py and run python3 check_cve_2026_8936.py; no admin rights are usually required, but the script needs the docker CLI and access to docker desktop version if available.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# Check exposure to CVE-2026-8936 on Docker Desktop hosts.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

import json
import os
import re
import subprocess
import sys
from pathlib import Path

FIXED_VERSION = (4, 76, 0)

def run(cmd):
    try:
        p = subprocess.run(cmd, capture_output=True, text=True, check=False)
        return p.returncode, (p.stdout or '').strip(), (p.stderr or '').strip()
    except Exception as e:
        return 127, '', str(e)


def parse_semver(text):
    m = re.search(r'(\d+)\.(\d+)\.(\d+)', text)
    if not m:
        return None
    return tuple(int(x) for x in m.groups())


def get_desktop_version():
    candidates = [
        ['docker', 'desktop', 'version'],
        ['docker', 'desktop', 'version', '--format', 'json'],
    ]

    for cmd in candidates:
        rc, out, err = run(cmd)
        if rc == 0 and out:
            # Try JSON first
            try:
                data = json.loads(out)
                for key in ('Version', 'version', 'desktopVersion'):
                    if key in data:
                        v = parse_semver(str(data[key]))
                        if v:
                            return v, 'docker desktop version'
            except Exception:
                pass

            v = parse_semver(out)
            if v:
                return v, 'docker desktop version'

    # Fallback: try local settings files that sometimes include Desktop metadata.
    paths = []
    home = Path.home()
    if sys.platform.startswith('darwin'):
        paths.append(home / 'Library' / 'Group Containers' / 'group.com.docker' / 'settings-store.json')
        paths.append(home / 'Library' / 'Group Containers' / 'group.com.docker' / 'settings.json')
    elif os.name == 'nt':
        appdata = os.environ.get('APPDATA')
        localapp = os.environ.get('LOCALAPPDATA')
        if appdata:
            paths.append(Path(appdata) / 'Docker' / 'settings-store.json')
            paths.append(Path(appdata) / 'Docker' / 'settings.json')
        if localapp:
            paths.append(Path(localapp) / 'Docker' / 'settings-store.json')
    else:
        paths.append(home / '.docker' / 'desktop' / 'settings-store.json')
        paths.append(home / '.docker' / 'desktop' / 'settings.json')

    for p in paths:
        try:
            if p.exists():
                text = p.read_text(encoding='utf-8', errors='ignore')
                v = parse_semver(text)
                if v:
                    return v, str(p)
        except Exception:
            continue

    return None, None


def cmp_ver(a, b):
    return (a > b) - (a < b)


def main():
    version, source = get_desktop_version()
    if not version:
        print('UNKNOWN - Could not determine Docker Desktop version from CLI or local settings')
        sys.exit(2)

    version_str = '.'.join(map(str, version))
    fixed_str = '.'.join(map(str, FIXED_VERSION))

    if cmp_ver(version, FIXED_VERSION) < 0:
        print(f'VULNERABLE - Docker Desktop {version_str} detected via {source}; fixed in {fixed_str}. Assumes this host may use the affected grpcfuse file-sharing path.')
        sys.exit(1)
    else:
        print(f'PATCHED - Docker Desktop {version_str} detected via {source}; fixed threshold is {fixed_str}.')
        sys.exit(0)

if __name__ == '__main__':
    main()
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, pull an inventory of developer endpoints and shared build workstations running Docker Desktop, then identify anything below 4.76.0 and any teams that routinely use writable host bind mounts. For this MEDIUM assessment there is no noisgate mitigation SLA — go straight to the 365-day remediation window and complete the Docker Desktop upgrade under the noisgate remediation SLA; in the meantime, reserve immediate workaround effort for shared or higher-risk developer hosts by steering untrusted workloads away from writable host bind mounts.

Sources

  1. Docker CVE mirror entry for CVE-2026-8936
  2. Docker Desktop release notes
  3. Docker Desktop networking and file I/O architecture
  4. Docker bind mounts documentation
  5. Docker container security FAQ
  6. Docker Enhanced Container Isolation
  7. CISA Known Exploited Vulnerabilities catalog
  8. FIRST EPSS documentation / API reference
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.