Skip to main content
Vulnerability Database/CVE-2026-89928

CVE-2026-89928: Linux Kernel KVM Use-After-Free Vulnerability

CVE-2026-89928 is a use-after-free flaw in Linux kernel KVM that can lead to memory corruption during lockless rmap walks. This article covers the technical details, affected versions, security impact, and mitigation.

Published:

CVE-2026-89928 Overview

CVE-2026-89928 is a use-after-free vulnerability in the Linux kernel's Kernel-based Virtual Machine (KVM) x86 Memory Management Unit (MMU) subsystem. The flaw resides in the lockless reverse map (rmap) walk performed by kvm_rmap_age_gfn_range(). When __kvm_rmap_lock() elides the rmap lock on an empty rmap, the aging path ignores the returned value and re-reads rmap_head->val through rmap_get_first(). A concurrent writer holding mmu_lock can populate and then free the pte_list_desc chain via kmem_cache_free() while the walker traverses it, producing a slab use-after-free on hosts built with CONFIG_KVM_MMU_LOCKLESS_AGING=y.

Critical Impact

A local attacker with the ability to trigger KVM MMU aging on a system hosting virtual machines can induce a slab use-after-free, potentially leading to kernel memory corruption and privilege escalation.

Affected Products

  • Linux kernel builds enabling KVM x86 with CONFIG_KVM_MMU_LOCKLESS_AGING=y
  • Hypervisor hosts running KVM on x86 architectures
  • Distributions shipping affected upstream kernel revisions prior to the referenced fix commits

Discovery Timeline

  • 2026-09-16 - CVE-2026-89928 published to NVD
  • 2026-09-16 - Last updated in NVD database

Technical Details for CVE-2026-89928

Vulnerability Analysis

The vulnerability lives in KVM's x86 shadow paging code path used for tracking guest page accesses. __kvm_rmap_lock() deliberately skips taking the rmap lock when it observes an empty rmap. In that case kvm_rmap_lock_readonly() also re-enables preemption and returns zero, so the caller holds neither the rmap lock nor a preemption reference.

The elision documents an invariant: lockless readers cannot walk empty rmaps, and only writers holding mmu_lock for write manipulate them. However, kvm_rmap_age_gfn_range() discards the value returned by the lock helper and unconditionally invokes for_each_rmap_spte_lockless(). The iterator internally calls rmap_get_first(), which re-reads rmap_head->val a second time.

Between those two reads a writer can install a KVM_RMAP_MANY rmap containing a pte_list_desc chain. Because preemption was re-enabled, the window between the two reads can span an arbitrary scheduling delay, making the race practical to hit under load.

Root Cause

The root cause is a lock-elision invariant violation: the lockless walker re-reads shared state instead of consuming the value that the lock helper already sampled. This breaks the guarantee that empty-rmap fast paths remain mutually exclusive with writers holding mmu_lock.

Attack Vector

Exploitation requires local access and the ability to trigger KVM MMU aging on a host running guests. A malicious or compromised process capable of driving memory pressure and inducing page-aging callbacks can race a KVM writer that zaps rmaps through kvm_zap_all_rmap_sptes() or the recycle path. When the writer frees the pte_list_desc chain via kmem_cache_free() while the lockless walker follows it, the walker dereferences freed slab memory. See the upstream fix commit for the code path details.

Detection Methods for CVE-2026-89928

Indicators of Compromise

  • Kernel oops or panic messages referencing kvm_rmap_age_gfn_range, for_each_rmap_spte_lockless, or pte_list_desc in the call stack
  • KASAN slab-use-after-free reports naming the pte_list_desc slab cache on KVM hosts
  • Unexplained guest VM instability or host reboots on kernels with CONFIG_KVM_MMU_LOCKLESS_AGING=y

Detection Strategies

  • Enable Kernel Address Sanitizer (KASAN) in test kernels to surface the use-after-free before it reaches production
  • Audit running kernel versions and configuration options across the hypervisor fleet to identify hosts exposing the vulnerable code path
  • Correlate host crash dumps with KVM subsystem symbols to distinguish this issue from unrelated MMU faults

Monitoring Recommendations

  • Ship kernel ring buffer output and kdump crash artifacts from KVM hosts to a centralized logging pipeline for review
  • Alert on repeated KVM-related kernel warnings, especially on hosts running untrusted guest workloads
  • Track patch state for the upstream commits 41debfc9, 8edb3c09, and e428f977 across managed kernels

How to Mitigate CVE-2026-89928

Immediate Actions Required

  • Inventory hypervisor hosts running KVM on x86 and confirm whether kernels were built with CONFIG_KVM_MMU_LOCKLESS_AGING=y
  • Apply the stable kernel updates that include the fix once available from the Linux distribution vendor
  • Restrict local access to KVM hosts and limit which workloads can trigger aggressive memory aging on shared hypervisors

Patch Information

The fix splits rmap_get_first() into __rmap_get_first(), which starts iteration from an already-read rmap value. for_each_rmap_spte_lockless() now takes that value directly, and kvm_rmap_age_gfn_range() passes the value returned by kvm_rmap_lock_readonly(). When the lock was elided, the value is zero, __rmap_get_first() returns NULL, and the walk is skipped. Reference the following upstream commits: 41debfc9, 8edb3c09, and e428f977.

Workarounds

  • Rebuild affected kernels with CONFIG_KVM_MMU_LOCKLESS_AGING disabled where feasible to remove the racing code path until patches are deployed
  • Reduce host overcommit and memory pressure to lower the frequency of rmap zap operations that create the race window
  • Isolate untrusted tenants onto patched hosts and defer live migration of guests to unpatched hypervisors

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.