CVE-2026-46316
This is a double-decrement vulnerability in the ARM GICv4 ITS (Interrupt Translation Service) code. The bug: when iterating over the xarray with `xa_for_each()` and then erasing entries with `xa_erase()`, the code incorrectly drops a reference using the pointer obtained from iteration instead of the value returned by `xa_erase()`. These are the same object, but the API semantics differ—`xa_for_each()` gives you a pointer to the stored value, while `xa_erase()` returns the value directly. Using both results in double-decrementing the refcount, triggering use-after-free and potential hypervisor state corruption. CVSS 9.3 reflects the severity: this is kernel-level code controlling interrupt routing for PCIe devices, and the corruption occurs in a code path (EnableLPIs) that lacks the locking protecting the other two call sites. Check your kernel versions: this affects the vgic-its driver in kernels using xarray for interrupt translation table management. The three affected call sites are ITS command handlers (protected by its_lock), GITS_CTLR writes (protected by cmd_lock), and the EnableLPIs path (unprotected)—the latter is the concerning one. Do this now: audit any code in your kernel tree that combines `xa_for_each()` or similar iteration with `xa_erase()` or `xa_store()` on the same xarray. The correct pattern is to use the return value from the erase/store call, never the pointer from iteration. If you find this pattern, check whether the code path has explicit locking; the EnableLPIs path's lack of locking is the red flag that allowed this bug to persist. The fix is three lines—change `vgic_put_irq(irq)` to use `xa_erase()`'s return value—but the deeper issue is that the xarray API provides no compiler warning, no runtime assertion, and no documentation flagging this as dangerous. This is the third double-decrement-via-iterator/destructor mismatch in kernel xarray users this year. The xarray header explicitly warns that iteration and modification are incompatible—but that warning lives in a comment developers grep past, not in the type system. Consider this a canary: if you maintain code using xarray, audit for this pattern now, because the same semantic trap is likely hiding elsewhere in your codebase.
Reviewed through automated stages and approved by a human before publication.