A janitor shredding a shared office directory while people are still looking up phone numbers
CVE-2026-43074 is a use-after-free in the Linux kernel's fs/eventpoll.c. The function ep_free() can kfree the struct eventpoll object while another concurrent thread is still reading from it. The race was introduced by a 2023 commit family that reworked epoll's reference counting. Affected kernels include mainline 6.6+ through 7.x; older LTS branches like 6.1 and 5.10 are not affected because the vulnerable refactoring was never backported to them. The upstream fix (commit 07712db80857) replaces kfree(ep) with kfree_rcu(ep, rcu), deferring reclamation until all concurrent RCU readers have exited their critical sections. Distro fixes are available: RHEL 9.4+/10, Debian Trixie (6.12.85-1+), and Forky (7.1.7-1+).
The vendor CVSS of 7.8 HIGH is defensible. This is a local privilege escalation with low attack complexity and low privileges required — the textbook profile for a kernel UAF. Notably, Red Hat's own Bugzilla rates the *priority* as Medium, which is a pragmatic nod to the local-access prerequisite. However, a public kernelCTF exploit by Jaeyoung Chung (Seoul National University) demonstrates 80%+ success rates on 6.6.118/AArch64, and a closely related sibling bug (CVE-2026-46242, "Bad Epoll") achieves 98–99% on LTS and Container-Optimized OS. The exploit reliability and the ubiquity of the affected component keep this firmly in the HIGH bucket.
4 steps from start to impact.
Obtain local code execution
PR:L means any uid can reach the vulnerable syscall path.- Local shell or code execution on target host
- Kernel version in vulnerable range (6.6 – 7.1.x unpatched)
- Requires prior initial access — not remotely exploitable
- Older LTS kernels (5.10, 5.15, 6.1) are unaffected, shrinking the vulnerable population
kernel package version checks all cover this CVE. Runtime detection is weak — standard EDR does not flag epoll syscall abuse patterns.Trigger the epoll UAF race
close() to trigger ep_free() → kfree(ep), while the other concurrently accesses the freed struct eventpoll via an epoll_wait or similar path. The race window is narrow but reliably hittable with tight CPU pinning. Jaeyoung Chung's kernelCTF PoC achieves 80%+ success on AArch64 and 98%+ on x86_64 LTS.- Ability to create epoll file descriptors (unprivileged)
- Two or more CPU cores available to the attacker's process
- Single-core VMs or heavily cgroup-throttled containers may reduce race reliability
- Kernel ASLR (KASLR) and SMAP/SMEP raise exploitation complexity but do not prevent the UAF trigger
Reclaim freed slab object
struct eventpoll is freed, the attacker performs a heap spray — allocating same-sized kernel objects (e.g., struct msg_msg, struct pipe_buffer) to reclaim the slab slot. The dangling pointer in the concurrent reader thread now points to attacker-controlled data. This is a standard kernel heap exploitation primitive documented in the kernelCTF PoC.- Knowledge of target kernel's slab allocator layout (SLUB/SLAB)
- Exploit tuned for target kernel version and architecture
- CONFIG_SLAB_FREELIST_HARDENED and CONFIG_SLAB_FREELIST_RANDOM complicate but don't block reclamation
- GKE/COS hardened kernels have additional slab mitigations
Achieve root via arbitrary read/write
task_struct->cred or modifying modprobe_path to escalate to uid 0. On success the attacker has full root on the host, including access to all containers on a shared Kubernetes node or all data on a database server.- Successful heap reclamation from step 3
- Bypass of CFI/BTI if enabled (kernel 6.12+ with ARM BTI)
- Lockdown LSM in integrity/confidentiality mode blocks some post-exploitation paths
- SELinux confined domains limit what root can do (but kernel-level root can disable SELinux)
The supporting signals.
| In-the-Wild Exploitation | No confirmed in-the-wild campaigns. Not on CISA KEV. The sibling CVE-2026-46242 ("Bad Epoll") also has no KEV listing as of 2026-08-14. |
|---|---|
| Proof-of-Concept | Public. Jaeyoung Chung (Seoul National University) submitted a working LPE exploit via Google's kernelCTF program. The PoC targets Android 17 / Linux 6.6.118 (AArch64, Pixel 10 Pro) with 80%+ reliability. The related CVE-2026-46242 PoC achieves 98–99% on LTS x86_64. |
| EPSS Score | 0.00482 (≈ top 30th percentile) — low predicted exploitation probability, consistent with local-only attack vector. |
| KEV Status | Not listed as of 2026-08-14. |
| CVSS Vector | CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H — 7.8 HIGH. Local vector, low complexity, low privilege, full CIA impact. Scope is Unchanged (no cross-boundary impact in CVSS terms, though container escape is real-world cross-boundary). |
| Affected Versions | Mainline kernels 6.6 through 7.1.x (unpatched). Older LTS branches (5.10, 5.15, 6.1) are not affected — the vulnerable 2023 refactoring was not backported. The race exists in fs/eventpoll.c across all architectures. |
| Fixed Versions | Upstream: commit 07712db80857 (kernel 7.0+). Debian Trixie: 6.12.85-1. Debian Forky: 7.1.7-1. RHEL 9.4 EUS / RHEL 10: via RHSA-2026:36186 and RHSA-2026:37729. Ubuntu patches pending for Noble (6.8) and Oracular (6.11). |
| Scanning / Exposure | All Linux hosts running kernel 6.6+ are potentially affected. Per Shodan/Censys, the kernel version itself is not externally fingerprinted, but the population of 6.6+ hosts in enterprise is substantial given RHEL 9.4+ and Ubuntu 24.04+ defaults. Exposure is gated by local access, not network reachability. |
| Disclosure Date | 2026-05-06 (upstream advisory and NVD publication). |
| Researcher | Jaeyoung Chung, Computer Security Lab, Seoul National University. Reported via Google kernelCTF zero-day track. |
noisgate verdict.
The single most decisive factor sustaining this at HIGH is the public, high-reliability exploit combined with the role multiplier on shared-kernel infrastructure (Kubernetes nodes, CI runners, KVM hypervisors). The local-access prerequisite prevents escalation to CRITICAL, but it does not override the fleet-scale blast radius when the chain lands on container orchestration hosts.
Why this verdict
- Public exploit with high reliability: Jaeyoung Chung's kernelCTF PoC achieves 80%+ success on AArch64 and the sibling Bad Epoll PoC hits 98–99% on x86_64 LTS. This is not a theoretical bug — it is a proven, weaponized LPE.
- Role multiplier: The Linux kernel is the canonical high-value component. On Kubernetes nodes (≥15–20% of enterprise Linux installs), this UAF is a container escape to root on the host, compromising every pod on that node — blast radius is tenant → fleet. On KVM hypervisors, root equals access to all guest VMs. On CI runners, root equals exfiltration of all build secrets and supply-chain pivot. The component is definitionally high-value-role (≥10% of installs), setting a verdict floor of HIGH.
- Local access prerequisite provides meaningful friction: AV:L means the attacker must already have code execution on the target. This is not remotely exploitable. Every exploitation scenario requires a prior compromise stage (phished user, compromised app, malicious container image). This friction prevents escalation to CRITICAL.
- Narrow affected version range: Only kernels 6.6+ are vulnerable. The large installed base of RHEL 8 (4.18), RHEL 9.0–9.2 (5.14), Debian Bullseye (5.10), and Bookworm (6.1) are unaffected, materially reducing the exposed population compared to a kernel bug that hits all branches.
Why not higher?
CRITICAL would require either remote exploitability or an active KEV listing / confirmed in-the-wild campaign. This bug requires local access — every attack chain must first solve the initial-access problem independently. The EPSS of 0.48% and absence from KEV corroborate that mass exploitation is not imminent. The affected version range (6.6+) also excludes a large share of enterprise kernels still on older LTS branches.
Why not lower?
A public exploit with 80%+ reliability against a universally-deployed component (the kernel) prevents any downgrade below HIGH. On Kubernetes nodes, CI runners, and KVM hypervisors — which collectively represent well over 10% of 6.6+ kernel deployments — successful exploitation yields host-level root from an unprivileged container, with blast radius extending to all co-located workloads. The role-multiplier floor holds this at HIGH regardless of the local-access friction.
What to do — in priority order.
- Restrict unprivileged user namespaces — Set
kernel.unprivileged_userns_clone=0(Debian) or use the RHEL 9.4+ user-namespace restrictions. Many kernel exploits — including UAF heap sprays — rely on unprivileged user namespaces for capability escalation primitives. Deploy within the noisgate mitigation SLA of 30 days. - Enable seccomp-bpf profiles blocking epoll_create/epoll_ctl where unnecessary — Containers and CI workloads that do not need epoll can run under a strict seccomp profile that blocks
epoll_create1,epoll_ctl, andepoll_wait. This directly eliminates the attack surface. Kubernetes PodSecurityAdmission or OPA/Gatekeeper can enforce this. Deploy within 30 days. - Enforce read-only root filesystems and drop all capabilities in container security contexts — Setting
readOnlyRootFilesystem: true,allowPrivilegeEscalation: false, and droppingALLcapabilities in Kubernetes SecurityContext limits post-exploitation options even if the UAF fires. Deploy within 30 days. - Prioritize kernel patching on Kubernetes nodes, CI runners, and KVM hypervisors — These are the high-blast-radius hosts. Patch these first, within the 30-day mitigation window, even if general fleet patching takes longer. Use node cordoning and rolling replacement to minimize downtime.
- Deploy Falco or Tetragon for container escape detection — Runtime security tools monitoring for unexpected capability acquisition, namespace escape, or
setuid(0)from container contexts provide detective control. Not preventive, but reduces dwell time. Deploy within 30 days.
- Container image updates alone — This is a kernel bug, not a userspace bug. Updating container images does not change the host kernel. You must patch and reboot the host.
- AppArmor/SELinux in default profiles — Default container profiles (docker-default, container-selinux) do not restrict epoll syscalls. A custom policy would be needed, which is operationally expensive at scale.
- KASLR alone — Kernel ASLR raises the bar but the kernelCTF PoC demonstrates reliable bypasses. Do not rely on KASLR as a compensating control.
Crowdsourced verification payload.
Run this script on each target Linux host as any user (no root required for the version check). Invoke with: bash check_cve_2026_43074.sh. The script checks the running kernel version against known-fixed versions for major distributions and outputs VULNERABLE, PATCHED, or UNKNOWN.
#!/usr/bin/env bash
# check_cve_2026_43074.sh — CVE-2026-43074 eventpoll UAF version check
# Run on target host. No root required.
# Exit codes: 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN
set -euo pipefail
KERNEL=$(uname -r)
echo "[*] Running kernel: $KERNEL"
# Extract major.minor.patch
MAJOR=$(echo "$KERNEL" | cut -d. -f1)
MINOR=$(echo "$KERNEL" | cut -d. -f2)
PATCH=$(echo "$KERNEL" | cut -d. -f3 | cut -d- -f1)
# Kernels before 6.6 are NOT AFFECTED (vulnerable commit not present)
if [ "$MAJOR" -lt 6 ] || { [ "$MAJOR" -eq 6 ] && [ "$MINOR" -lt 6 ]; }; then
echo "[+] PATCHED — Kernel $KERNEL predates the vulnerable code (introduced in 6.6+)."
exit 0
fi
# Check for distro-specific fixed versions
VULNERABLE=false
if [ -f /etc/os-release ]; then
. /etc/os-release
case "${ID:-unknown}" in
rhel|centos|rocky|alma|ol)
echo "[*] Detected RHEL-family: $PRETTY_NAME"
# RHSA-2026:36186 and RHSA-2026:37729 provide fixes
# Check if kernel RPM includes the fix
if rpm -q --quiet kernel 2>/dev/null; then
INSTALLED=$(rpm -q kernel --qf '%{VERSION}-%{RELEASE}\n' | sort -V | tail -1)
echo "[*] Installed kernel RPM: $INSTALLED"
echo "[!] Verify against RHSA-2026:36186 / RHSA-2026:37729 advisory fixed versions."
fi
VULNERABLE=true
;;
debian)
echo "[*] Detected Debian: $PRETTY_NAME"
# Trixie fixed in 6.12.85-1, Forky in 7.1.7-1
if dpkg --compare-versions "$KERNEL" ge "6.12.85" 2>/dev/null; then
echo "[+] PATCHED — Kernel $KERNEL is at or above Debian fix (6.12.85-1)."
exit 0
fi
VULNERABLE=true
;;
ubuntu)
echo "[*] Detected Ubuntu: $PRETTY_NAME"
# Check for ubuntu-specific patched kernel
echo "[!] Check Ubuntu security tracker for linux package fix status."
VULNERABLE=true
;;
*)
echo "[*] Detected: ${PRETTY_NAME:-unknown}"
VULNERABLE=true
;;
esac
else
VULNERABLE=true
fi
# Mainline check: upstream fix is in 7.0+ stable
if [ "$MAJOR" -ge 7 ] && [ "$MINOR" -ge 0 ]; then
# Check if running a post-fix 7.x kernel
if [ "$MAJOR" -eq 7 ] && [ "$MINOR" -eq 1 ] && [ "${PATCH:-0}" -ge 7 ]; then
echo "[+] PATCHED — Kernel $KERNEL is at or above upstream fix (7.1.7+)."
exit 0
elif [ "$MAJOR" -gt 7 ] || { [ "$MAJOR" -eq 7 ] && [ "$MINOR" -gt 1 ]; }; then
echo "[+] PATCHED — Kernel $KERNEL is above known vulnerable range."
exit 0
fi
fi
if $VULNERABLE; then
echo "[-] VULNERABLE — Kernel $KERNEL is in the affected range (6.6+) and no distro fix was confirmed."
echo " Fix: update kernel and REBOOT. A patched package on disk does NOT protect until reboot."
exit 1
fi
echo "[?] UNKNOWN — Could not determine patch status for kernel $KERNEL. Manual review required."
exit 2If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.