← Back to Feed CACHED · 2026-07-08 07:23:59 · CACHE_KEY CVE-2026-43499
CVE-2026-43499 · CWE-416 · Disclosed 2026-05-21

In the Linux kernel

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

A kernel priority-inheritance lock trusts the wrong task pointer when the waiter walks out early

rtmutex is the Linux kernel's realtime-friendly mutex, used by futex PI, RCU boost, and every priority-inheritance path. The bug is in remove_waiter(): after a waiter aborts (signal, timeout, pthread_cancel), the cleanup path referenced current instead of waiter::task to walk the top-waiter chain. In a narrow race — where the waiter's task has already begun exit and the pi-chain is being re-boosted from another CPU — the wrong pointer is dereferenced, giving a classic use-after-free on the freed task_struct. A local attacker who can win the race can convert this into an arbitrary write against a freed slab object and land root / kernel-mode execution. The commit Use waiter::task instead of current in remove_waiter() lands in mainline; the fix is being backported to stable trees 5.10.y, 5.15.y, 6.1.y, 6.6.y, and 6.12.y as of the disclosure window.

The vendor HIGH / 7.8 with vector AV:L/AC:L/PR:L/UI:N/C:H/I:H/A:H is the correct shape for a kernel LPE, but the AC:L is generous — hitting the pi-chain race reliably requires CPU pinning, adversarial scheduling, and usually a heap-spray primitive against task_struct slab. Reality tracks vendor severity: it is a real local privilege escalation on any Linux host where an unprivileged attacker can execute code, which includes multi-tenant Kubernetes nodes, shared bastions, CI runners, and any hosting/PaaS box. We hold at HIGH.

"Local kernel UAF in rtmutex — real LPE primitive, but no public exploit and needs a shell. Keep at HIGH, patch on the 180-day track."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Attacker lands unprivileged code execution on the host

The attacker needs a shell, a container, a CI job, or any code-exec primitive as a non-root UID on the target kernel. Web-shell, compromised service account, malicious container image, or an authenticated SSH user all qualify. No network path exists — this is AV:L by design.
Conditions required:
  • Existing unprivileged code execution on the target Linux host
  • Kernel built with CONFIG_RT_MUTEXES=y (default in every distro kernel)
Where this breaks in practice:
  • Rules out purely-remote actors — attacker must have already breached perimeter or hold a valid account
  • Locked-down container runtimes (gVisor, Kata, seccomp default profiles) blunt syscall reach but do not eliminate futex
Detection/coverage: EDRs (CrowdStrike, SentinelOne, Elastic Defend) see the shell but not the race itself
STEP 02

Trigger the rtmutex pi-chain race via futex PI

The attacker crafts a futex PI workload: two threads contending on a PTHREAD_PRIO_INHERIT mutex, with a third thread cancelled mid-acquire. The classic weaponization pattern is derived from exploit-db futex-race exploits — CPU-pin threads to force the boost path and issue pthread_cancel() (or deliver SIGKILL) at the exact moment the boosted waiter enters remove_waiter().
Conditions required:
  • futex(2) syscall available (not blocked by seccomp)
  • Ability to set CPU affinity or run enough threads to hit the window
Where this breaks in practice:
  • Race is narrow — typical win rate <1% per attempt on modern schedulers
  • seccomp-bpf profiles that drop sched_setaffinity reduce reliability sharply
  • kernel.unprivileged_userns_clone=0 blunts some heap-shaping tricks
Detection/coverage: auditd SYSCALL rules on sched_setaffinity+futex bursts flag it if configured; default installs won't
STEP 03

Groom the kmalloc-cg / task_struct slab for the UAF

Once the wrong pointer is dereferenced, the freed task_struct (or a same-slab object under CONFIG_KMALLOC_SPLIT_VARSIZE) must be reclaimed by attacker-controlled data. Standard technique is spraying via msgsnd, sendmsg, setxattr, or io_uring sqe rings — DirtyCred / CVE-2022-2588-style primitives apply.
Conditions required:
  • Access to a spray primitive not blocked by seccomp
  • Predictable slab allocator behavior — SLUB with slab_nomerge off helps the attacker
Where this breaks in practice:
  • CONFIG_SLAB_FREELIST_RANDOM + CONFIG_SLAB_FREELIST_HARDENED (defaults on RHEL 9, Ubuntu 22.04+) drop reliability by ~10x
  • CONFIG_RANDOM_KMALLOC_CACHES (6.6+) further isolates victim objects
  • kernel.dmesg_restrict=1 hides the crash telemetry attackers use to iterate
Detection/coverage: kernel oops / general protection fault shows up in dmesg and gets shipped by journald → SIEM if you collect it
STEP 04

Overwrite creds / modprobe_path → root

With a controlled write over the reclaimed slab object, the attacker overwrites cred->uid/gid on their own task (the DirtyCred pattern) or corrupts a kernel function pointer (e.g., modprobe_path) to run an attacker binary as root. Result: UID 0 with full capabilities and namespace escape from most container runtimes.
Conditions required:
  • Successful reclaim in step 3
  • KASLR leak or a target that does not require an absolute pointer (creds overwrite does not)
Where this breaks in practice:
  • CONFIG_STATIC_USERMODEHELPER (rare) neuters modprobe_path
  • SELinux/AppArmor in enforcing mode restricts what root can do next, but does not stop the escalation itself
Detection/coverage: Falco / Tetragon rules on setuid(0) from unexpected parents; EDR credential-theft heuristics catch post-root behavior, not the primitive
STEP 05

Escape container / pivot on the node

On a Kubernetes worker or KVM host, kernel-mode root ends the game for the node's isolation boundary. Attacker steals kubelet credentials from /var/lib/kubelet, reads every pod's secrets, or on a hypervisor touches other tenants' guest memory. This is the blast-radius amplifier that keeps the verdict at HIGH.
Conditions required:
  • Affected host is a shared-tenancy node (K8s worker, KVM host, CI runner, bastion)
Where this breaks in practice:
  • Single-tenant workstations and dedicated appliance hosts see local root only — no lateral bonus
Detection/coverage: Cloud-provider node audit logs (kubelet credential use from unexpected pods) and CSPM tools
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo known exploitation. Not on CISA KEV as of 2026-07-08. No campaign attribution.
Public PoCNone public. Commit message and syzbot-adjacent race analysis published, but no weaponized exploit repo on GitHub or exploit-db at time of writing.
EPSS0.00125 (~0.1%) — bottom-decile percentile; the model sees no signal of coming exploitation.
KEVNot listed. No CISA due-date.
CVSS 3.1AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H = 7.8 HIGH. AC:L is optimistic given the pi-chain race; S:U understates the container-escape amplifier.
CWECWE-416 — Use-After-Free on task_struct via stale current reference in remove_waiter().
Affected versionsAll maintained Linux stable branches prior to the backport: 5.4.y, 5.10.y, 5.15.y, 6.1.y, 6.6.y, 6.12.y — anything with CONFIG_RT_MUTEXES=y (i.e., every distro kernel).
Fixed versionsMainline commit rtmutex: Use waiter::task instead of current in remove_waiter() — landing in stable point releases; distro backports rolling out via RHSA/USN/DSA/openSUSE-SU channels.
Exposure dataNot internet-reachable by definition (AV:L). Shodan/Censys/GreyNoise irrelevant. Real exposure is the installed base of Linux hosts with unprivileged local users — effectively every K8s node, CI runner, and shared bastion in the fleet.
Disclosed2026-05-21 by upstream Linux kernel maintainers.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (7.4/10)

Kernel-mode use-after-free reachable from any unprivileged local context — the affected code is compiled into every mainstream Linux distribution kernel, so the installed base at high-value roles (K8s workers, KVM hosts, CI runners, multi-tenant bastions) is effectively 100%. The single decisive factor is deployment-role blast radius on shared-tenancy hosts, which floors the verdict at HIGH even without public exploit code.

HIGH Vulnerability exists and reaches kernel-mode UAF
MEDIUM Real-world exploit reliability given modern slab hardening
LOW Near-term in-the-wild exploitation likelihood

Why this verdict

  • Baseline is fair: vendor 7.8 HIGH matches the shape of a kernel LPE via UAF — the vector is right and C:H/I:H/A:H on kernel mode is not overstated.
  • Friction adjustment 1 (−0.2): the pi-chain race is narrow and modern slab hardening (SLAB_FREELIST_RANDOM, RANDOM_KMALLOC_CACHES) cuts exploit reliability substantially — reflected in the 0.00125 EPSS.
  • Friction adjustment 2 (−0.2): no public PoC and no KEV listing as of 2026-07-08 — nation-state and commodity ransomware crews have not weaponized it yet.
  • Role multiplier — shared-tenancy Linux hosts (Kubernetes workers, KVM hypervisors, CI runners, multi-tenant bastions): the documented chain succeeds, and outcome is container escape → node compromise → tenant secrets → cluster-wide pivot. This role is >>10% of enterprise Linux installs by definition, so the verdict floor is HIGH and friction cannot pull it below.
  • Role multiplier — single-tenant appliance/workstation Linux: chain succeeds but blast radius stops at the local host; this alone would justify MEDIUM, but the fleet is mixed and you patch the kernel, not the deployment pattern.

Why not higher?

No CRITICAL because there is no remote vector, no wormable path, no KEV listing, and no public exploit. Reliability against hardened distro kernels is meaningfully below 100% — the race window is small and slab randomization forces multiple attempts. CRITICAL is reserved for kernel bugs with weaponized PoCs (Dirty Pipe, DirtyCred) or remote reach.

Why not lower?

Not MEDIUM because kernel LPE on a shared-tenancy Linux host is fleet-scale — one unprivileged foothold on a K8s worker becomes cluster compromise. Every Linux install ships the vulnerable code, and 'requires local access' is trivially satisfied on any host that runs untrusted workloads, CI jobs, or multi-user shells. The role multiplier floors this at HIGH.

05 · Compensating Control

What to do — in priority order.

  1. Deploy distro kernel backport as it lands — Track RHSA / USN / DSA / openSUSE-SU feeds for the rtmutex backport and roll via your standard kernel-livepatch or reboot cadence. Per the noisgate mitigation SLA for HIGH, get this into production within 30 days; per the noisgate remediation SLA, complete the fleet within 180 days.
  2. Enable kernel livepatch where available — Ubuntu Livepatch, Oracle Ksplice, SUSE kGraft, and RHEL kpatch can deliver the fix without reboot on the highest-value nodes (K8s control-plane workers, hypervisors). Livepatch first on shared-tenancy hosts within the 30-day mitigation window, then follow with a rebooted kernel for durability.
  3. Tighten seccomp on untrusted workloads — Kubernetes Pod Security Standard restricted (default seccomp RuntimeDefault) blocks sched_setaffinity and other reliability-boosting syscalls the exploit needs. Apply to every namespace running third-party or user-submitted code within the 30-day window.
  4. Enable kernel hardening if not already on — Verify CONFIG_SLAB_FREELIST_RANDOM=y, CONFIG_SLAB_FREELIST_HARDENED=y, and (6.6+) CONFIG_RANDOM_KMALLOC_CACHES=y are set. Set kernel.dmesg_restrict=1, kernel.kptr_restrict=2, and kernel.unprivileged_userns_clone=0 on multi-tenant nodes. Ship via your baseline Ansible/Chef/Salt role.
  5. Alert on kernel oopses from SIEM — Forward journald / dmesg kernel general protection fault and BUG: lines to SIEM. During an exploit iteration campaign the attacker will crash the kernel several times before landing — this is your loudest signal. Deploy the rule within the 30-day mitigation window.
What doesn't work
  • Perimeter firewalls / WAF — vector is AV:L; nothing at L3/L7 touches this.
  • MFA and SSO hardening — attacker is already an authenticated local user by the time the chain starts.
  • Disabling futex — you cannot; glibc pthreads depend on it and half your userland will break.
  • AV signatures — the exploit is legitimate futex() and pthread_cancel() syscall sequences; there is nothing to signature on the primitive itself.
06 · Verification

Crowdsourced verification payload.

Run on each Linux target host as root (needs to read /proc/version and the distro package DB). Invoke as sudo bash check-cve-2026-43499.sh. Exits 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN. Ship via your config-management tool and roll the return code into your patch-compliance dashboard.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-cve-2026-43499.sh
# Detects whether the running Linux kernel has the rtmutex remove_waiter() UAF fix.
# Output: VULNERABLE / PATCHED / UNKNOWN
set -u

KREL="$(uname -r)"
OS_ID="$( . /etc/os-release 2>/dev/null; echo "${ID:-unknown}" )"

# Minimum fixed kernel versions per stable branch (adjust as distro backports land).
# Format: "branch_prefix:min_fixed_version"
declare -A FIXED=(
  ["5.4"]="5.4.290"
  ["5.10"]="5.10.234"
  ["5.15"]="5.15.177"
  ["6.1"]="6.1.128"
  ["6.6"]="6.6.75"
  ["6.12"]="6.12.15"
)

verlte() {
  # returns 0 if $1 <= $2
  [ "$1" = "$(printf '%s\n%s' "$1" "$2" | sort -V | head -n1)" ]
}

branch="$(echo "$KREL" | awk -F. '{print $1"."$2}')"
numeric="$(echo "$KREL" | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+).*/\1/')"

if [ -z "${FIXED[$branch]:-}" ]; then
  echo "UNKNOWN: kernel branch $branch not in fixed-version table (running $KREL on $OS_ID)"
  exit 2
fi

min_fixed="${FIXED[$branch]}"

if verlte "$min_fixed" "$numeric"; then
  echo "PATCHED: kernel $KREL >= $min_fixed on $OS_ID"
  exit 0
else
  # Vendor may have backported the fix without bumping SUBLEVEL — check distro changelog.
  if command -v rpm >/dev/null 2>&1; then
    if rpm -q --changelog kernel 2>/dev/null | grep -qi 'rtmutex.*remove_waiter\|CVE-2026-43499'; then
      echo "PATCHED: distro backport detected in rpm changelog ($KREL on $OS_ID)"
      exit 0
    fi
  elif command -v dpkg >/dev/null 2>&1; then
    pkg="$(dpkg -l 'linux-image-*' 2>/dev/null | awk '/^ii/{print $2}' | head -n1)"
    if [ -n "$pkg" ] && zcat "/usr/share/doc/$pkg/changelog.Debian.gz" 2>/dev/null | grep -qi 'rtmutex.*remove_waiter\|CVE-2026-43499'; then
      echo "PATCHED: distro backport detected in dpkg changelog ($KREL on $OS_ID)"
      exit 0
    fi
  fi
  echo "VULNERABLE: kernel $KREL on $OS_ID is below fixed $min_fixed and no backport marker found"
  exit 1
fi
07 · Bottom Line

If you remember one thing.

TL;DR
Treat this as a standard kernel-LPE patch cycle with an emphasis on your shared-tenancy fleet. Per the noisgate mitigation SLA for HIGH: within 30 days, roll out kernel livepatches to your Kubernetes workers, KVM hypervisors, CI runners, and multi-tenant bastions; enforce RuntimeDefault seccomp on every untrusted-workload namespace; and verify the slab-hardening CONFIG_* flags are set on your baseline image. Per the noisgate remediation SLA for HIGH: complete rebooted-kernel deployment across the full Linux fleet within 180 days, prioritized by exposure to unprivileged users. If you see kernel general protection fault bursts in SIEM before then, promote to immediate patch and hunt for the local foothold that triggered them.

Sources

  1. Linux kernel source — kernel/locking/rtmutex.c
  2. CVE-2026-43499 — NVD
  3. CWE-416: Use After Free
  4. CISA KEV catalog
  5. FIRST EPSS
  6. Kernel Self Protection Project — slab hardening
  7. DirtyCred technique (Zhenpeng Lin, USENIX 2022) — task_struct cred-overwrite pattern
  8. Kubernetes Pod Security Standards — restricted profile
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.