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

CVE-2026-89908: Linux Kernel KVM Privilege Escalation Flaw

CVE-2026-89908 is a privilege escalation vulnerability in the Linux Kernel KVM that affects memory slot handling, potentially allowing unauthorized access to host memory pages. This article covers technical details, impact analysis, and mitigation strategies.

Published:

CVE-2026-89908 Overview

CVE-2026-89908 is a Linux kernel vulnerability in the LoongArch Kernel-based Virtual Machine (KVM) subsystem. The flaw stems from kvm_arch_prepare_memory_region() failing to preserve memslot architecture flags during KVM_MR_FLAGS_ONLY updates. When guests toggle KVM_MEM_LOG_DIRTY_PAGES, such as during live migration, the active memslot loses its KVM_MEM_HUGEPAGE_INCAPABLE marker. This allows PMD-level huge page mappings on memslots with mismatched Guest Physical Address (GPA) and Host Virtual Address (HVA) offsets, causing the guest to access the wrong host pages.

Critical Impact

A local guest operator triggering a memslot flag update can cause guest memory to alias to incorrect host pages, resulting in data corruption and confidentiality loss across VM boundaries on LoongArch hosts.

Affected Products

  • Linux kernel LoongArch KVM subsystem
  • Kernel builds prior to the fix commits 27a9bfee, 4e4dbc34, 7c6df65b, and bc7a6849
  • Virtualization hosts running LoongArch processors with KVM enabled

Discovery Timeline

  • 2026-09-16 - CVE-2026-89908 published to the National Vulnerability Database (NVD)
  • 2026-09-16 - Last updated in NVD database

Technical Details for CVE-2026-89908

Vulnerability Analysis

The vulnerability resides in the LoongArch KVM memory region management path. The function kvm_arch_prepare_memory_region() computes new->arch.flags, specifically KVM_MEM_HUGEPAGE_CAPABLE or KVM_MEM_HUGEPAGE_INCAPABLE, only for KVM_MR_CREATE and KVM_MR_MOVE operations. For all other memslot change types, the function returns early without setting these flags.

Generic KVM code allocates a zeroed memslot on every change and never copies old->arch into the new structure. Consequently, after a KVM_MR_FLAGS_ONLY operation, the active memslot has arch.flags == 0. This state clears both hugepage capability indicators.

With both flags cleared, fault_supports_huge_mapping() falls through to an alignment check on the HVA range alone. The check no longer verifies that the GPA and HVA share the same offset within a Page Middle Directory (PMD) entry. This is a state-tracking flaw closely related to memory management logic errors in kernel virtualization code.

Root Cause

The root cause is missing state preservation across memslot lifecycle transitions. The LoongArch KVM implementation assumes arch.flags will only need computation during creation and movement. However, the generic memslot allocator wipes the destination structure for every operation, including flag-only updates, breaking that assumption.

Attack Vector

Exploitation requires local access with permission to control a KVM guest on a LoongArch host. An attacker with guest-management privileges toggles a memslot flag such as KVM_MEM_LOG_DIRTY_PAGES, commonly issued during live migration. On a memslot originally marked KVM_MEM_HUGEPAGE_INCAPABLE due to a GPA/HVA offset mismatch, the flag update strips the incapability marker. Subsequent read faults may install PMD entries. Because kvm_map_page() aligns the Guest Frame Number (GFN) and Page Frame Number (PFN) independently, the guest reads or writes host pages outside its intended mapping. This produces the "d -> f, e -> g" mismapping documented in the source comment.

No verified public exploitation code is available. The vulnerability mechanism is described in prose based on the upstream commit messages.

Detection Methods for CVE-2026-89908

Indicators of Compromise

  • Unexpected guest memory contents or kernel oops messages inside LoongArch guests after live migration or dirty-page logging activation
  • Host-side KVM tracepoints showing PMD-level mappings on memslots previously classified as hugepage-incapable
  • Guest filesystem or memory integrity checks failing shortly after KVM_SET_USER_MEMORY_REGION ioctl activity

Detection Strategies

  • Audit the running kernel version against the fix commits 27a9bfee3bbc, 4e4dbc341b15, 7c6df65b5384, and bc7a6849b439 published on git.kernel.org
  • Enable KVM tracepoints (kvm_mmu_get_page, kvm_set_memory_region) on LoongArch hosts and correlate memslot flag transitions with subsequent huge page installations
  • Inspect qemu or libvirt logs for KVM_MR_FLAGS_ONLY operations preceding guest instability

Monitoring Recommendations

  • Track kernel package versions across LoongArch virtualization hosts and alert on unpatched systems
  • Monitor guest crash rates and correlate spikes with live migration events
  • Collect and centralize hypervisor host logs for post-incident analysis of KVM state transitions

How to Mitigate CVE-2026-89908

Immediate Actions Required

  • Apply the upstream fix that carries arch.flags over from the old memslot on KVM_MR_FLAGS_ONLY updates, delivered in commits 27a9bfee, 4e4dbc34, 7c6df65b, and bc7a6849
  • Update all LoongArch KVM hosts to a stable kernel containing the backport
  • Restrict guest management operations to trusted operators until patched kernels are deployed

Patch Information

The fix preserves architecture-specific memslot flags when the operation type is KVM_MR_FLAGS_ONLY, since the GPA, HVA, and size are guaranteed to be unchanged. Reference the upstream commits: Kernel Git Commit 27a9bfe, Kernel Git Commit 4e4dbc3, Kernel Git Commit 7c6df65, and Kernel Git Commit bc7a684.

Workarounds

  • Avoid enabling KVM_MEM_LOG_DIRTY_PAGES and defer live migrations on affected LoongArch hosts until the patch is applied
  • Recreate guests rather than issuing flag-only memslot updates on hosts that must remain temporarily unpatched
  • Limit which users can invoke KVM_SET_USER_MEMORY_REGION through host access controls and hypervisor management policies
bash
# Verify installed kernel contains the fix commits on a LoongArch host
uname -r
git -C /usr/src/linux log --oneline | grep -E "27a9bfee|4e4dbc34|7c6df65b|bc7a6849"

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.