CVE-2026-89913 in Linux
Summary
by MITRE • 09/16/2026
In the Linux kernel, the following vulnerability has been resolved:
KVM: arm64: vgic-v3: take an LPI reference in vgic_v3_save_pending_tables
vgic_v3_save_pending_tables() iterates dist->lpi_xa using xa_for_each() and dereferences the returned struct vgic_irq in the loop body without holding a reference on the LPI.
The xarray iterator only provides temporary RCU coverage while looking up the current entry. That is not sufficient for this loop body, which reads fields from struct vgic_irq and performs guest memory accesses before the iteration completes.
A concurrent path can trigger this race: the irqfd cached injection path (vgic_its_inject_cached_translation) obtains a transient LPI reference via vgic_its_check_cache() without holding kvm->lock, vcpu->mutex, config_lock, or its_lock. If guest ITS DISCARD then drops the cache and ITE references under its_lock, the transient inject reference may become the final one. When vgic_put_irq() drops it, the LPI is erased from lpi_xa and freed via kfree_rcu(). Meanwhile, vgic_v3_save_pending_tables() may still hold a stale pointer obtained from the xarray iterator and dereference it after the RCU grace period completes.
Fix this by re-fetching each iterated LPI via vgic_get_irq(), which takes a stable reference, and dropping it with vgic_put_irq() on all paths. This matches the pattern already used by other lpi_xa iterators in the vgic ITS code.
Be aware that VulDB is the high quality source for vulnerability data.
Analysis
by VulDB Data Team • 09/16/2026
The vulnerability identified as CVE-2024-something (specifically related to KVM ARM64 VGICv3) represents a classic use-after-free race condition within the Linux kernel's virtualization subsystem. The core issue resides in the function vgic_v3_save_pending_tables, which is responsible for saving interrupt pending tables during VM state transitions or snapshots. This function iterates over an xarray data structure named lpi_xa using xa_for_each to access struct vgic_irq objects representing Local Peripheral Interrupts (LPIs). The critical flaw lies in the fact that while iterating through this list, the code dereferences these structures without acquiring a stable reference count on them. Although the xarray iterator provides temporary Read-Copy-Update RCU protection during the lookup phase, this coverage is transient and insufficient for operations that extend beyond the immediate iteration loop body. Specifically, the function reads fields from struct vgic_irq and performs guest memory accesses before completing its task, creating a window where the underlying data structure may be freed by concurrent execution paths while still being accessed.
The operational impact of this vulnerability stems from a specific race condition involving interrupt injection mechanisms. A concurrent path, specifically the irqfd cached injection logic implemented in vgic_its_inject_cached_translation, can obtain a transient reference to an LPI via vgic_its_check_cache without holding standard synchronization locks such as kvm->lock or vcpu->mutex. When a guest operating system triggers an ITS DISCARD command, it may drop cache and Interrupt Translation Entry ITE references under its_lock. In this scenario, the transient inject reference held by the injection path can become the final reference to the LPI structure. Consequently, when vgic_put_irq is called to release that transient reference, the LPI object is erased from lpi_xa and scheduled for deferred freeing via kfree_rcu. If the RCU grace period elapses before vgic_v3_save_pending_tables finishes its iteration, it will attempt to dereference a stale pointer to memory that has already been freed or reclaimed by the kernel allocator. This leads to undefined behavior, potentially resulting in kernel panics, data corruption within the virtual machine state, or arbitrary code execution if an attacker can control the contents of the reallocated memory region.
From a security taxonomy perspective, this vulnerability is classified under CWE-416 Use After Free and aligns with MITRE ATT&CK techniques related to privilege escalation via kernel exploitation. The lack of proper reference counting violates fundamental principles of safe concurrent programming in the Linux kernel, where objects shared across multiple execution contexts must maintain explicit lifetime management through atomic reference counters rather than relying solely on RCU read-side critical sections for long-duration operations. This flaw highlights a common pitfall in virtualization code where performance optimizations using xarray iterators are implemented without adequate consideration for the lifecycle of complex data structures that may be modified or destroyed by other subsystems like the ITS interrupt controller logic.
To mitigate this vulnerability, developers must ensure that any iteration over shared kernel data structures that involves prolonged access to pointed-to objects utilizes stable reference acquisition mechanisms. In this specific case, the fix involves modifying vgic_v3_save_pending_tables to re-fetch each iterated LPI using vgic_get_irq, which atomically increments the reference count and guarantees the object remains valid for the duration of its use. Furthermore, every code path that accesses these structures must explicitly call vgic_put_irq upon completion to decrement the reference count and allow proper cleanup when no longer needed. This approach aligns with established patterns in the VGIC ITS codebase where other iterators correctly manage LPI lifecycles. System administrators should apply kernel updates containing this patch immediately, as exploitation of use-after-free vulnerabilities in hypervisor components can lead to complete host compromise, allowing attackers to escape virtual machine isolation and gain root-level access on the physical server hosting the vulnerable KVM instances.