← Back to Feed CACHED · 2026-10-02 15:13:35 · CACHE_KEY CVE-2026-46215
CVE-2026-46215 · CWE-416 · Disclosed 2026-05-28

Linux Kernel DRM GEM change_handle Use-After-Free Local Privilege Escalation

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

A brief window during a DRM handle swap lets a local attacker free an object out from under the kernel and ride it to root

CVE-2026-46215 is a use-after-free in the Linux kernel's Direct Rendering Manager (DRM) GEM subsystem, specifically in the change_handle ioctl path. When a GEM object is moved from one handle to another during a prime swap, the object briefly holds two IDR entries while its handle_count remains at 1. A concurrent DRM_IOCTL_GEM_CLOSE on the old handle drives the count to zero and frees the object, leaving the new handle dangling into freed slab memory. The bug was introduced in v6.18-rc1 and is fixed in 6.18.32, 7.0.9, and 7.1-rc3. Debian Bullseye, Bookworm, and Trixie are explicitly not affected because their kernels predate the vulnerable code. RHEL 8/9 and Ubuntu 22.04/24.04 LTS ship older kernel series and are likewise unaffected.

The vendor CVSS of 7.8 HIGH is mathematically correct — local, low-complexity, low-privilege, full CIA impact — but it significantly overstates the real-world risk. The affected kernel range (6.18+) is deployed almost exclusively on rolling-release desktops (Fedora 42+, Arch, Manjaro) and developer workstations. Enterprise infrastructure — hypervisors, Kubernetes nodes, database servers, CI runners — overwhelmingly runs LTS kernels well below 6.18. The EPSS of 0.0017 (bottom 15th percentile) confirms the market agrees: this is not an actively sought-after target. A public PoC exists and grants root, which prevents further downgrade, but the narrow blast radius justifies treating this as MEDIUM for fleet prioritization.

"Local LPE in bleeding-edge kernels only; most enterprise fleets are unaffected."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Obtain local shell on host running kernel 6.18–7.0.8

The attacker must already have interactive or scripted shell access to a Linux host running an affected kernel. This is the baseline prerequisite and represents a prior compromise or insider position. Remote exploitation is not possible.
Conditions required:
  • Local (or SSH) shell access to target host
  • Host runs Linux kernel ≥6.18, <6.18.32 or ≥7.0, <7.0.9 or 7.1-rc1/rc2
Where this breaks in practice:
  • Most enterprise hosts run RHEL/Ubuntu LTS/Debian stable with kernels far below 6.18
  • Gaining a local shell on a managed host implies the attacker has already bypassed endpoint controls
Detection/coverage: Kernel version is visible to any vulnerability scanner (Qualys, Nessus, Rapid7). Distro package managers track installed kernel versions.
STEP 02

Access DRM render node (/dev/dri/renderD*)

The exploit requires opening a DRM render node file descriptor. On desktop distributions with systemd-logind, render nodes are granted to the active console session automatically. On headless servers, DRM modules may be loaded for virtual consoles but render nodes may or may not be present. The attacker needs read-write access to at least one render node.
Conditions required:
  • DRM kernel modules loaded (e.g., i915, amdgpu, virtio-gpu, vgem)
  • Render node device file exists and is accessible to the attacker's user
Where this breaks in practice:
  • Minimal server installs may not load DRM modules at all
  • Container runtimes with default seccomp profiles block DRM ioctls
  • Hardened hosts may restrict /dev/dri access via udev rules
Detection/coverage: File-access auditing (auditd) on /dev/dri/renderD* can flag unexpected opens.
STEP 03

Race DRM_IOCTL_GEM_CHANGE_HANDLE against DRM_IOCTL_GEM_CLOSE

The attacker spawns threads issuing DRM_IOCTL_GEM_CHANGE_HANDLE and DRM_IOCTL_GEM_CLOSE concurrently on the same GEM handle. When the close wins the race, the object is freed while the new handle still references it. The bluedragonsecurity PoC (adapted for kernel 7.0) demonstrates this reliably within seconds using a tight ioctl loop.
Conditions required:
  • Ability to issue DRM ioctls (open render node fd)
  • Sufficient CPU time to win the race (typically <10 seconds on multi-core)
Where this breaks in practice:
  • Race conditions may be less reliable on single-core VMs or under heavy load
  • Kernel hardening features (KASAN, SLUB debug) may detect the UAF and panic instead of allowing exploitation
Detection/coverage: Kernel KASAN (if enabled) will log a UAF report. Runtime anomaly detection (Falco, Tracee) can alert on rapid DRM ioctl patterns.
STEP 04

Heap spray via pipe pages to reclaim freed slab

After the GEM object is freed, the attacker sprays kernel heap via pipe() / splice() to reclaim the freed slab with attacker-controlled data. The dangling handle now points to attacker-controlled memory. The PoC uses this to overwrite credentials or function pointers to escalate to root.
Conditions required:
  • Standard unprivileged syscalls (pipe, splice) available
  • Slab allocator layout is predictable for the target kernel build
Where this breaks in practice:
  • CONFIG_SLAB_FREELIST_RANDOM and CONFIG_SLAB_FREELIST_HARDENED reduce spray reliability
  • Different distro kernel configs may change slab layout, requiring PoC adaptation
STEP 05

Achieve root shell

With kernel memory under attacker control, the PoC overwrites the current task's credentials to gain uid 0 or hijacks a function pointer to execute arbitrary kernel code. The bluedragonsecurity exploit writes a root entry and spawns a root shell via su. Full local privilege escalation is achieved.
Conditions required:
  • Successful heap reclaim from step 4
Where this breaks in practice:
  • Exploit is kernel-version-specific; the published PoC targets 7.0.x and may need adaptation for 6.18.x
  • SMEP/SMAP/KASLR add complexity but are routinely bypassed in modern kernel exploits
Detection/coverage: Process genealogy monitoring (EDR) should flag an unprivileged process suddenly spawning a root shell. Integrity monitoring on /etc/passwd or /etc/shadow detects the PoC's file-based persistence.
03 · Compensating Control

1
MEDIUM 5.5→LOW 3.0
SEVERITY REDUCED
Restrict access to DRM render nodes via udev rule — Create a udev rule (/etc/udev/rules.d/99-restrict-renderD.rules) setting SUBSYSTEM=="drm", KERNEL=="renderD*", MODE="0660", GROUP="render" and ensure only GPU-workload users are in the render group. This breaks step 2 of the attack path by denying the attacker the file descriptor needed to issue DRM ioctls. No mitigation SLA applies at MEDIUM — go straight to the 365-day remediation window, but this control is low-effort and can be deployed immediately.
2
MEDIUM 5.5→IGNORE 0.0
SEVERITY REDUCED
Unload DRM kernel modules on headless servers — On servers that do not require GPU acceleration, blacklist DRM modules (echo 'blacklist drm' > /etc/modprobe.d/no-drm.conf) and unload them (modprobe -r drm). This eliminates the attack surface entirely on affected servers. Requires a reboot or module unload. Apply within the 365-day remediation window.
3
MEDIUM 5.5→LOW 2.5
SEVERITY REDUCED
Block DRM ioctls in container seccomp profiles — If running containers on affected kernels, ensure the seccomp profile blocks ioctl calls to DRM device numbers, or do not mount /dev/dri into containers. Default Docker/containerd seccomp profiles already restrict most DRM ioctls; verify your runtime's policy. This prevents container-to-host escalation via this CVE.
4
MEDIUM 5.5→IGNORE 0.0
SEVERITY REDUCED
Upgrade kernel to fixed version — Update to kernel 6.18.32+, 7.0.9+, or 7.1-rc3+. This is the definitive remediation. Per noisgate remediation SLA for MEDIUM, complete within 365 days (by 2027-10-02). On rolling-release distros (Fedora, Arch), a standard dnf update or pacman -Syu pulls the fix.
What doesn't work
  • Network firewalls / WAF / IDS — This is a local privilege escalation; there is no network component to filter or inspect.
  • SELinux in default targeted policy — Default RHEL/Fedora SELinux policy permits confined users to access DRM render nodes. A custom policy restricting ioctl classes on renderD* would help but is non-trivial to write and test.
  • KASLR alone — Kernel address space layout randomization adds entropy to exploit development but is routinely bypassed in modern kernel exploits, including the published PoC. It slows but does not prevent exploitation.
04 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNone observed. Not on CISA KEV. No GreyNoise or Shadowserver sightings. No campaign attribution.
Proof of ConceptPublic PoC available. bluedragonsecurity/CVE-2026-46215-EXPLOIT (C, Makefile; July 11 2026) by Antonius (ev1lut10n/sw0rdm4n), adapted for kernel 7.0. Also 0xCyberstan/CVE-2026-46215-POC. Races DRM ioctls, pipe-sprays slab, spawns root shell.
EPSS0.0017 (0.17%) — bottom ~15th percentile. Market consensus: low exploitation probability.
CISA KEVNot listed as of 2026-10-02.
CVSS VectorCVSS: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, no user interaction. Scope unchanged limits blast radius to the exploited host.
Affected VersionsIntroduced in v6.18-rc1. Affected: 6.18.0–6.18.31, 7.0.0–7.0.8, 7.1-rc1/rc2. Debian Bullseye/Bookworm/Trixie explicitly *not affected* (vulnerable code not present). RHEL 8/9, Ubuntu 22.04/24.04 LTS ship older kernel series and are unaffected.
Fixed Versions6.18.32, 7.0.9, 7.1-rc3. Debian unstable/sid fixed in kernel package 7.0.9-1. Upstream commits: 5e28b7b94408, 61bd96d3e547, 672464dd5323.
Scanning / ExposureLocal-only vulnerability — no network exposure surface. Standard vulnerability scanners (Qualys, Nessus, Rapid7) detect via kernel package version. No Shodan/Censys/FOFA relevance (not remotely exploitable).
Disclosure Date2026-05-28 (linux-cve-announce). Patch commits landed in stable trees the same week.
Researcher / ReporterReported via linux-cve-announce. PoC authored by Antonius (ev1lut10n/sw0rdm4n) of bluedragonsecurity.

Sources.

  1. NVD - CVE-2026-46215
  2. Debian Security Tracker - CVE-2026-46215
  3. SentinelOne Vulnerability Database
  4. bluedragonsecurity PoC Exploit (GitHub)
  5. 0xCyberstan PoC (GitHub)
  6. OpenCVE - CVE-2026-46215
  7. linux-cve-announce Disclosure
05 · The Call

Final Verdict
↓ DOWNGRADED to MEDIUM (5.5/10)

Why this verdict

  • Local-only attack vector: Requires an existing shell on the target host, meaning the attacker has already cleared initial access — this is purely a post-compromise escalation primitive, not a remotely exploitable entry point.
  • Extremely narrow affected kernel range: Only kernels 6.18.0–6.18.31, 7.0.0–7.0.8, and 7.1-rc1/rc2 are vulnerable. RHEL 8/9 (kernel 4.18/5.14), Ubuntu 22.04 LTS (5.15/6.5), Ubuntu 24.04 LTS (6.8), Debian Bullseye/Bookworm/Trixie (5.10/6.1/6.12) are all explicitly unaffected. In a typical 10,000-host enterprise fleet, estimated <3% of Linux hosts run an affected kernel.
  • Public PoC prevents further downgrade: The bluedragonsecurity exploit is functional, well-documented, and grants root. This keeps the rating at MEDIUM rather than LOW — on any host where the conditions are met, exploitation is straightforward.
  • EPSS confirms low real-world risk: At 0.0017, the exploit prediction model places this in the bottom ~15th percentile. No KEV listing, no in-the-wild campaigns, no threat-actor tooling integration observed.
  • Role multiplier: The Linux kernel is canonically a high-value-role component (hypervisors, k8s nodes, CI runners). However, enterprise high-value Linux hosts overwhelmingly run LTS kernels (RHEL 5.14, Ubuntu 5.15/6.5/6.8, Debian 6.1) that are *far below* the 6.18 introduction point. Estimated <2% of enterprise hypervisors and <1% of production k8s nodes run an affected kernel. This breaks the HIGH floor per the installed-base evidence requirement. On the rare high-value host running 6.18+ (e.g., a Fedora-based dev k8s cluster), the chain would succeed and yield host-level root — but this represents an edge case, not a fleet-wide concern.

Why not higher?

The vendor's 7.8 HIGH accurately reflects the CVSS math for a local LPE with full CIA impact. However, CVSS does not account for installed-base narrowness. The 6.18+ kernel requirement eliminates the vast majority of enterprise Linux deployments — all current RHEL, Ubuntu LTS, Debian stable, and SLES releases ship kernels well below the introduction point. Upgrading to HIGH would overstate urgency for fleets that are simply not running affected code.

Why not lower?

A public, functional PoC exists that reliably escalates to root in seconds. On any host where the kernel version and DRM access conditions are met, exploitation is trivial. The DRM render node is auto-granted on desktop distros, requiring no special privileges beyond a local session. Dropping to LOW would understate the risk for organizations running Fedora, Arch, or custom mainline kernels in any capacity.

06 · Verification

Crowdsourced verification payload.

Run this script on each target Linux host as any user. No root privileges required. Usage: bash check_cve_2026_46215.sh. It checks the running kernel version against affected ranges and reports DRM render node availability.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# CVE-2026-46215 checker - Linux kernel DRM GEM change_handle UAF
# Outputs: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN

set -euo pipefail

KVER=$(uname -r)
echo "[*] Running kernel: $KVER"

# Extract major.minor.patch
MAJOR=$(echo "$KVER" | cut -d. -f1)
MINOR=$(echo "$KVER" | cut -d. -f2)
PATCH=$(echo "$KVER" | cut -d. -f3 | grep -oE '^[0-9]+' || echo 0)

# Count DRM render nodes
RENDER_NODES=$(ls /dev/dri/renderD* 2>/dev/null | wc -l || echo 0)
echo "[*] DRM render nodes found: $RENDER_NODES"

vulnerable=0

if [ "$MAJOR" -eq 6 ] && [ "$MINOR" -eq 18 ]; then
  if [ "$PATCH" -lt 32 ]; then
    vulnerable=1
    echo "[!] Kernel 6.18.x detected, patch level $PATCH < 32"
  fi
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -eq 0 ]; then
  if [ "$PATCH" -lt 9 ]; then
    vulnerable=1
    echo "[!] Kernel 7.0.x detected, patch level $PATCH < 9"
  fi
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -eq 1 ]; then
  if echo "$KVER" | grep -qE 'rc[12]([^0-9]|$)'; then
    vulnerable=1
    echo "[!] Kernel 7.1-rc1 or rc2 detected"
  fi
fi

if [ "$vulnerable" -eq 1 ]; then
  if [ "$RENDER_NODES" -gt 0 ]; then
    echo "VULNERABLE - kernel $KVER is affected and $RENDER_NODES DRM render node(s) are accessible"
    exit 1
  else
    echo "VULNERABLE (reduced risk) - kernel $KVER is affected but no DRM render nodes found"
    exit 1
  fi
else
  if [ "$MAJOR" -lt 6 ] || { [ "$MAJOR" -eq 6 ] && [ "$MINOR" -lt 18 ]; }; then
    echo "PATCHED - kernel $KVER predates vulnerable code (introduced in 6.18-rc1)"
    exit 0
  fi
  echo "PATCHED - kernel $KVER is at or above the fixed version"
  exit 0
fi