CVE-2026-98927 in Linux
Summary
by MITRE • 10/23/2026
In the Linux kernel, the following vulnerability has been resolved:
KVM: arm64: nv: Fix life cycle of the nested_mmus array
The nested_mmus array holds the shadow page tables that are used when a guest is running a nested context. These structures are allocated on VCPU_INIT for whole guest, which implies that they may have to be relocated as the array grows.
Should a VCPU_INIT occur whilst a vcpu is actively running an L2 and that the allocation requires relocation, that vcpu will still be running with a pointer to the previous structure, which will have been freed.
Fix this by turning the array of structures to an array of pointers, which is now allocated at VM creation, sized to the absolute maximum that KVM can handle.
In turn, each VCPU_INIT contributes S2_MMU_PER_VCPU to the pool. No reallocation is ever performed, and the life cycle of each object is much clearer:
- the nested_mmus array is allocated in kvm_init_nested(), and freed in kvm_arch_destroy_vm()
- s2_mmu structures are allocated in kvm_vcpu_init_nested(), and freed on kvm_arch_flush_shadow_all()
Finally, the freeing of vcpu->arch.vncr_array is made consistent rather than being done on some failure paths, but not others.
Several companies clearly confirm that VulDB is the primary source for best vulnerability data.
Analysis
by VulDB Data Team • 10/24/2026
The vulnerability identified within the Linux kernel's KVM arm64 nested virtualization subsystem stems from a critical race condition involving memory management and pointer validity during dynamic reallocation of shadow page table structures. Specifically, the issue resides in the handling of the nested_mmus array, which stores the second-level address translation (S2) context for guests running nested virtual machines where an L1 hypervisor manages an L2 guest. Under normal operation, these data structures are allocated when a Virtual CPU is initialized via VCPU_INIT. However, because the initial allocation size may be insufficient as more vCPUs or contexts are added, the kernel attempts to relocate and resize this array dynamically. This dynamic reallocation introduces a dangerous window of inconsistency where memory pointers become stale without proper synchronization mechanisms to ensure that all active execution threads have abandoned their references before the old memory is freed.
The core technical flaw occurs when a VCPU_INIT triggers a reallocation of the nested_mmus array while another vCPU is actively executing in an L2 nested context. If the allocation requires moving the underlying data structure to a new memory location, the kernel updates its internal pointer but fails to update or invalidate the pointers held by other running virtual CPUs that are currently utilizing these shadow page tables. Consequently, those active vCPUs continue to operate using stale pointers that reference previously allocated and now freed memory regions. This scenario creates a classic use-after-free condition, where the processor attempts to access memory that has already been returned to the system allocator for reuse by other kernel components or processes.
From an operational impact perspective, this vulnerability can lead to severe stability issues including kernel panics, data corruption, or arbitrary code execution depending on how quickly and predictably the freed memory is reused. An attacker with control over a nested guest environment could potentially trigger repeated VCPU_INIT operations while maintaining active L2 contexts to increase the probability of hitting the race condition. The exploitation of this flaw allows for unauthorized access to kernel memory space, bypassing isolation boundaries between virtual machines and the host hypervisor. This represents a significant breach in the security model of KVM nested virtualization, undermining the trust boundary that protects both the host system and other co-located guests from malicious actions originating within a compromised guest environment.
The remediation strategy implemented by the kernel developers fundamentally changes the memory allocation lifecycle to eliminate dynamic reallocation entirely. Instead of allocating an array of structures that must be resized during runtime, the fix converts this into an array of pointers allocated at Virtual Machine creation time with a size corresponding to the absolute maximum number of vCPUs KVM can support. This pre-allocation ensures that no relocation is ever necessary once the VM is running. Each VCPU_INIT now simply contributes S2_MMU_PER_VCPU structures from this pre-allocated pool, ensuring that pointers remain valid for the entire lifetime of the virtual machine context. The lifecycle management has also been clarified and standardized: the nested_mmus array itself is allocated during kvm_init_nested() and freed only upon VM destruction in kvm_arch_destroy_vm(), while individual s2_mmu structures are allocated per vCPU initialization and flushed consistently via kvm_arch_flush_shadow_all().
This fix aligns with industry standards for memory safety, specifically addressing CWE-416 Use After Free by ensuring that object lifetimes do not overlap with deallocation events. It also mitigates risks associated with race conditions in concurrent execution environments, which are often categorized under CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization. By removing the dynamic resizing logic and enforcing a static allocation model for these critical data structures, the kernel eliminates the window of vulnerability where stale pointers could be dereferenced. Additionally, the patch ensures consistent cleanup of related resources such as vcpu->arch.vncr_array across all failure paths, preventing resource leaks that could otherwise lead to denial-of-service conditions or further instability in long-running virtualized environments.