← Back to Feed CACHED · 2026-09-18 16:31:14 · CACHE_KEY CVE-2025-39964
CVE-2025-39964 · CWE-362 · Disclosed 2025-10-13

In the Linux kernel

ASSESSED — NOISGATE
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

Leaving two people at the same typewriter and hoping the novel still makes sense

CVE-2025-39964 is a race condition (CWE-362) in the Linux kernel's af_alg_sendmsg function, which is the userspace-facing interface to the kernel cryptographic API via AF_ALG sockets. When two threads issue concurrent write() or sendmsg() calls on the same AF_ALG socket, data interleaves unpredictably and the internal socket state becomes inconsistent. The fix adds a ctx->write field enforcing exclusive write ownership. The vulnerability was introduced as far back as kernel 2.6.38 and affects virtually every stable branch up through 6.16.8, with fixes landing in 5.10.245, 5.15.194, 6.1.154, 6.6.108, 6.12.49, and 6.16.9.

The vendor's HIGH / 7.8 rating reflects the worst-case CVSS envelope: local access, low privileges, full CIA impact. That envelope is technically correct — a race-induced memory corruption in kernel space *can* theoretically escalate to root. However, the rating overweights theoretical ceiling and underweights practical friction. There is no public proof-of-concept, no observed exploitation, EPSS sits at the 0.3% mark, and race conditions in socket paths are notoriously difficult to weaponize reliably compared to straight-line logic bugs like the related Copy Fail (CVE-2026-31431) in the same AF_ALG subsystem. The vendor score deserves a downgrade to MEDIUM for real-world prioritization.

"Race condition in AF_ALG sockets is theoretical LPE with no known exploit — patch in cycle."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Obtain local shell

The attacker needs an unprivileged local shell on the target Linux host. This could come from compromised credentials, an SSH key, a webshell, or lateral movement from another compromised host. The vulnerability is not remotely exploitable.
Conditions required:
  • Local user account on target host
  • Shell or code execution capability
Where this breaks in practice:
  • Requires prior compromise or insider access — filters out the vast majority of internet-facing threat actors
STEP 02

Open AF_ALG socket pair

The attacker opens an AF_ALG socket using socket(AF_ALG, SOCK_SEQPACKET, 0), binds it to a crypto algorithm (e.g., skcipher or aead), and calls accept() to get the operation file descriptor. AF_ALG sockets are available to unprivileged users on most default kernel configurations.
Conditions required:
  • AF_ALG socket family enabled in kernel (CONFIG_CRYPTO_USER_API)
  • Algorithm modules loaded or auto-loadable
Where this breaks in practice:
  • Some hardened distributions or container runtimes restrict AF_ALG via seccomp profiles — Docker's default seccomp profile does NOT block AF_ALG, but custom profiles may
  • Kubernetes pod security standards at 'restricted' level may block raw socket creation
Detection/coverage: Auditd rules on socket() syscalls with AF_ALG family (family=38) can flag unusual crypto socket creation
STEP 03

Trigger concurrent writes

The attacker spawns two or more threads that simultaneously call sendmsg() or write() on the same AF_ALG operation socket. The goal is to corrupt internal ctx state — specifically the scatter-gather list management — by interleaving partial writes. This requires precise timing and repeated attempts.
Conditions required:
  • Multi-threaded execution capability
  • Ability to win the race window before kernel scheduling preempts
Where this breaks in practice:
  • Race conditions in socket paths are timing-sensitive and unreliable — success rates on production workloads with scheduling jitter are low
  • No known technique or tool automates reliable exploitation of this specific race
  • Unlike Copy Fail (CVE-2026-31431), this is not a straight-line logic flaw — it requires genuine concurrency exploitation
Detection/coverage: Kernel KASAN (if enabled) will detect the resulting out-of-bounds or use-after-free corruption
STEP 04

Achieve kernel memory corruption

If the race is won, the inconsistent socket state leads to corrupted scatter-gather lists or buffer metadata in kernel memory. The attacker must then shape this corruption into a useful primitive — e.g., a controlled out-of-bounds write or a use-after-free — to pivot toward privilege escalation.
Conditions required:
  • Successful race condition trigger
  • Heap layout favorable for exploitation (kernel heap feng shui)
Where this breaks in practice:
  • Modern kernels with SLAB_FREELIST_RANDOM, SLAB_FREELIST_HARDENED, CONFIG_INIT_ON_FREE_DEFAULT_ON significantly complicate heap shaping
  • KASLR adds another layer of uncertainty for any ROP/JOP chain
  • No public exploit demonstrates this pivot for CVE-2025-39964
Detection/coverage: Kernel crash logs (panic, BUG, WARNING in crypto/af_alg.c) are strong indicators of exploitation attempts
STEP 05

Escalate to root

With a kernel write primitive, the attacker overwrites credential structures (e.g., cred->uid) or hijacks control flow to disable SELinux/AppArmor and gain root. From root on the host, lateral movement to other hosts or container escape becomes possible.
Conditions required:
  • Successful memory corruption primitive from step 4
  • Bypass of kernel exploit mitigations (KASLR, SMEP, SMAP, CFI)
Where this breaks in practice:
  • Clang CFI and ARM64 PAC (on applicable architectures) make control-flow hijacking extremely difficult
  • No demonstrated end-to-end chain exists for this CVE
Detection/coverage: EDR agents monitoring for unexpected privilege transitions (uid 1000→0) or credential structure modifications
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNone observed. Not listed in CISA KEV. No reports from threat intelligence vendors or incident response teams.
Proof-of-ConceptNo public PoC exists. No exploit code on GitHub, Exploit-DB, or researcher blogs. The fix commit describes the theoretical impact but no reproduction steps beyond the bug description.
EPSS Score0.00323 — approximately 0.3rd percentile. Indicates the statistical model sees very low probability of exploitation in the next 30 days.
KEV StatusNot listed. No CISA KEV entry as of 2026-09-19.
CVSS VectorCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H — Local attack vector, low complexity (debatable for a race condition), low privileges required, no user interaction, unchanged scope, full CIA impact.
Affected VersionsLinux kernel 2.6.38 through 5.10.244, 5.11–5.15.193, 5.16–6.1.153, 6.2–6.6.107, 6.7–6.12.48, 6.13–6.16.8. Extremely wide range — virtually every supported kernel branch.
Fixed Versions5.10.245, 5.15.194, 6.1.154, 6.6.108, 6.12.49, 6.16.9. Distro backports: RHEL, Debian, Ubuntu, SUSE, Oracle Linux, Amazon Linux have all issued fixes.
Scanning/ExposureLocal-only vulnerability — not detectable via network scanning. Nessus plugin and Qualys QID available for authenticated local scans. 100% of unpatched Linux hosts are theoretically exposed but exploitation requires local access.
Disclosure Date2025-10-13 — publicly disclosed via kernel stable tree commits.
ReporterLinux kernel developers via internal code review. No specific external researcher credited.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.5/10)

The single most decisive factor is the absence of any demonstrated exploit chain — this is a race condition with no public PoC, no in-the-wild exploitation, and a 0.3% EPSS score, making weaponization speculative rather than proven. While the kernel is a high-value component, the unproven exploitability of this specific race breaks the HIGH floor that would otherwise apply to a demonstrated kernel LPE.

HIGH Vulnerability existence and affected version ranges
MEDIUM Exploitability assessment (race conditions are inherently uncertain)
HIGH Absence of public exploit or in-the-wild activity

Why this verdict

  • No exploit exists: Zero public PoCs, no researcher demonstrations, no weaponized tooling. For a race condition disclosed 11 months ago, this silence is meaningful — compare to Copy Fail (CVE-2026-31431) in the same AF_ALG subsystem which had a 732-byte Python exploit within days.
  • Race condition friction: Unlike straight-line logic bugs, this requires winning a timing race in kernel socket handling. Modern kernel scheduling, CPU frequency scaling, and workload jitter make reliable exploitation on production systems significantly harder than CVSS AC:L suggests.
  • Local-only attack surface: AV:L means the attacker must already have a local shell. This prerequisite implies a prior compromise stage — the vulnerability is an escalation tool, not an entry point. The population of attackers who have local access but lack root is a subset of an already-compromised scenario.
  • Role multiplier: The Linux kernel is canonically deployed in high-value roles (KVM hypervisors, container hosts, CI/CD runners, production database servers). An LPE on these targets has fleet-scale blast radius. However, because no exploit chain has been demonstrated for *this specific race condition*, the theoretical high-value-role outcome does not trigger the HIGH floor. If a PoC emerges, this verdict should be immediately re-evaluated to HIGH or CRITICAL.
  • Kernel hardening mitigations: KASLR, SMEP/SMAP, SLAB_FREELIST_HARDENED, Clang CFI (on 6.x kernels), and CONFIG_INIT_ON_FREE all add friction layers that a theoretical exploit must bypass. These are active on most enterprise kernels.

Why not higher?

Upgrading to HIGH would require either a demonstrated exploit chain, active exploitation, or KEV listing. None of these exist. The 0.3% EPSS score and 11 months without a PoC for a publicly disclosed kernel race condition strongly suggest this is not practically exploitable with current techniques. If a PoC surfaces, upgrade immediately.

Why not lower?

Downgrading to LOW or IGNORE would undervalue the fact that this is a kernel-level memory corruption bug with full CIA impact *in theory*, affecting an enormous installed base across every major Linux distribution. The wide version range (2.6.38+) and the AF_ALG socket's default availability to unprivileged users mean the attack surface exists on nearly every Linux host. A future breakthrough in race condition exploitation could change the calculus overnight.

05 · Compensating Control

What to do — in priority order.

  1. Block AF_ALG sockets via seccomp — Apply a seccomp profile that denies socket() calls with AF_ALG (family 38) to workloads that do not need userspace crypto API access. This eliminates the attack surface entirely for containerized and sandboxed workloads. Most applications use OpenSSL/libgcrypt in userspace and never touch AF_ALG. No mitigation SLA applies at MEDIUM — go straight to the 365-day remediation window.
  2. Unload unused crypto API modules — If algif_hash, algif_skcipher, algif_aead, and algif_rng are not needed, blacklist them via /etc/modprobe.d/. This prevents the AF_ALG socket family from being usable even if the syscall is permitted. Verify with lsmod | grep algif.
  3. Enable KASAN on staging/canary hosts — Kernel Address Sanitizer will detect the memory corruption caused by this race condition and panic the kernel before exploitation completes. Not suitable for production due to performance overhead, but useful for detection in pre-production environments.
  4. Audit AF_ALG socket creation with auditd — Add an audit rule: auditctl -a always,exit -F arch=b64 -S socket -F a0=38 -k af_alg_access. This logs any process opening AF_ALG sockets, giving your SOC visibility into unexpected usage patterns.
What doesn't work
  • Network firewalls / WAF — This is a local-only vulnerability. No network-layer control can prevent exploitation since the attack never crosses a network boundary.
  • SELinux / AppArmor in default policy — Default policies on RHEL and Ubuntu do not restrict AF_ALG socket creation for confined processes. Custom policy would be needed to block socket(AF_ALG) specifically.
  • Container isolation alone — Docker's default seccomp profile does NOT block AF_ALG sockets. The kernel is shared between host and containers, so an exploit in a container compromises the host kernel.
06 · Verification

Crowdsourced verification payload.

Run this script on each target Linux host as any user (no root required). Invoke with: bash check_cve_2025_39964.sh. It checks the running kernel version against known-fixed versions and reports VULNERABLE, PATCHED, or UNKNOWN.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/bin/bash\n# CVE-2025-39964 checker — af_alg concurrent write race condition\n# Run on target Linux host as any user\n\nKERNEL=$(uname -r)\nVERSION=$(echo \"$KERNEL\" | grep -oP '^[0-9]+\\.[0-9]+\\.[0-9]+')\nMAJOR=$(echo \"$VERSION\" | cut -d. -f1)\nMINOR=$(echo \"$VERSION\" | cut -d. -f2)\nPATCH=$(echo \"$VERSION\" | cut -d. -f3)\n\necho \"[*] Checking CVE-2025-39964 (af_alg race condition)\"\necho \"[*] Running kernel: $KERNEL\"\necho \"[*] Parsed version: $MAJOR.$MINOR.$PATCH\"\n\n# Fixed versions per stable branch:\n# 5.10.245, 5.15.194, 6.1.154, 6.6.108, 6.12.49, 6.16.9\n\nresult=\"UNKNOWN\"\n\nif [ \"$MAJOR\" -lt 2 ]; then\n  result=\"PATCHED\"  # Pre-2.6.38 not affected\nelif [ \"$MAJOR\" -eq 5 ] && [ \"$MINOR\" -eq 10 ]; then\n  [ \"$PATCH\" -ge 245 ] && result=\"PATCHED\" || result=\"VULNERABLE\"\nelif [ \"$MAJOR\" -eq 5 ] && [ \"$MINOR\" -eq 15 ]; then\n  [ \"$PATCH\" -ge 194 ] && result=\"PATCHED\" || result=\"VULNERABLE\"\nelif [ \"$MAJOR\" -eq 6 ] && [ \"$MINOR\" -eq 1 ]; then\n  [ \"$PATCH\" -ge 154 ] && result=\"PATCHED\" || result=\"VULNERABLE\"\nelif [ \"$MAJOR\" -eq 6 ] && [ \"$MINOR\" -eq 6 ]; then\n  [ \"$PATCH\" -ge 108 ] && result=\"PATCHED\" || result=\"VULNERABLE\"\nelif [ \"$MAJOR\" -eq 6 ] && [ \"$MINOR\" -eq 12 ]; then\n  [ \"$PATCH\" -ge 49 ] && result=\"PATCHED\" || result=\"VULNERABLE\"\nelif [ \"$MAJOR\" -eq 6 ] && [ \"$MINOR\" -eq 16 ]; then\n  [ \"$PATCH\" -ge 9 ] && result=\"PATCHED\" || result=\"VULNERABLE\"\nelif [ \"$MAJOR\" -ge 7 ]; then\n  result=\"PATCHED\"  # Future mainline includes fix\nelif [ \"$MAJOR\" -eq 5 ] && [ \"$MINOR\" -lt 10 ]; then\n  result=\"VULNERABLE\"  # 5.x before 5.10 stable branch\nelif [ \"$MAJOR\" -eq 5 ] && [ \"$MINOR\" -gt 10 ] && [ \"$MINOR\" -lt 15 ]; then\n  result=\"VULNERABLE\"  # 5.11-5.14 no stable fix\nelif [ \"$MAJOR\" -eq 6 ] && [ \"$MINOR\" -lt 1 ]; then\n  result=\"VULNERABLE\"\nelif [ \"$MAJOR\" -eq 6 ] && [ \"$MINOR\" -gt 1 ] && [ \"$MINOR\" -lt 6 ]; then\n  result=\"VULNERABLE\"  # 6.2-6.5 no stable fix\nelif [ \"$MAJOR\" -eq 6 ] && [ \"$MINOR\" -gt 6 ] && [ \"$MINOR\" -lt 12 ]; then\n  result=\"VULNERABLE\"  # 6.7-6.11 no stable fix\nelif [ \"$MAJOR\" -eq 6 ] && [ \"$MINOR\" -gt 12 ] && [ \"$MINOR\" -lt 16 ]; then\n  result=\"VULNERABLE\"  # 6.13-6.15 no stable fix\nelse\n  result=\"UNKNOWN\"\nfi\n\n# Check if AF_ALG is available (additional context)\nif [ -f /proc/config.gz ]; then\n  if zcat /proc/config.gz 2>/dev/null | grep -q 'CONFIG_CRYPTO_USER_API=y'; then\n    echo \"[*] AF_ALG: enabled (compiled in)\"\n  elif zcat /proc/config.gz 2>/dev/null | grep -q 'CONFIG_CRYPTO_USER_API=m'; then\n    echo \"[*] AF_ALG: module (may be loadable)\"\n  else\n    echo \"[*] AF_ALG: not configured (not exploitable)\"\n    result=\"PATCHED\"\n  fi\nelse\n  echo \"[*] AF_ALG: config not available, assuming enabled\"\nfi\n\necho \"\"\necho \"=== RESULT: $result ===\"\n\nif [ \"$result\" = \"VULNERABLE\" ]; then\n  exit 1\nelif [ \"$result\" = \"PATCHED\" ]; then\n  exit 0\nelse\n  exit 2\nfi
07 · Bottom Line

If you remember one thing.

TL;DR
At MEDIUM reassessed severity, CVE-2025-39964 does not warrant emergency action. There is no mitigation SLA at this tier — go straight to the noisgate remediation SLA of 365 days to apply kernel patches through your normal patching cadence. Prioritize patching high-value Linux hosts first (hypervisors, container hosts, CI/CD runners, database servers) within your next quarterly kernel update cycle. For immediate risk reduction on sensitive hosts, deploy a seccomp profile blocking AF_ALG sockets (family 38) or blacklist the algif_* kernel modules. Monitor for PoC emergence — if a working exploit drops, this verdict escalates to HIGH or CRITICAL immediately given the kernel's role as a high-value component, and the noisgate mitigation SLA would compress to 30 days (or hours if exploitation is confirmed in the wild).

Sources

  1. NVD - CVE-2025-39964
  2. OSV - CVE-2025-39964
  3. OpenCVE - CVE-2025-39964
  4. CVE Security - CVE-2025-39964
  5. Stack.watch - CVE-2025-39964
  6. CyberStrike - CVE-2025-39964
  7. Copy Fail (related AF_ALG vuln) - ExtraHop
  8. Debian Security Tracker - CVE-2025-39964
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.