Skip to content

War Stories: Interrupt and IRQ-Affinity Bugs

Four incidents in the machinery that decides which CPU handles an interrupt and cleans up after it moves — two CVEs, one two-year silent-failure gap, and one use-after-free in a rarely-exercised notifier path that took two separate fixes to fully close

Interrupt affinity is deceptively simple from the outside — "run this interrupt's handler on that CPU" — and genuinely intricate underneath, because changing it safely means coordinating in-flight interrupt delivery, per-CPU vector allocation, CPU hotplug, and (for drivers that want to know) an asynchronous notification callback, all without ever leaving a window where the same interrupt could be handled twice or a resource freed while something still points at it. Every incident below lives in that coordination layer, not in interrupt handling itself.

Incidents

Ordered reverse chronologically by when the fix landed in mainline — newest first.

The Vector Leak That Needed Two CPUs to Go Offline in the Wrong Order

Linux 6.10 (July 2024) · CVE-2024-31076 A deferred interrupt-affinity change and a CPU hot-unplug, interleaved in one specific rare order, meant one x86 interrupt vector was never returned to vector_matrix — a slow leak, one vector at a time, on systems that offline and re-online CPUs routinely.

The IPI Verifier That Trusted Its Own Caller

Linux 6.3 (April 2023) · CVE-2023-53332 ipi_send_verify() dereferenced its irq_data parameter before checking whether that parameter was NULL — an invalid IPI interrupt number turned a clean error return into a kernel oops.

The Warning That Vector Space Was Silently Breaking Affinity

Linux 5.4 (November 2019) · not a CVE When every CPU in a reserved affinity mask had exhausted its 202 assignable interrupt vectors, activating the interrupt silently widened the mask with no log message — for about two years, an administrator had no way to learn their affinity request had been quietly overruled.

The Affinity Notifier That Outlived Its Own Reference Count

Linux 5.2 (July 2019) · not a CVE Replacing an affinity-change notifier dropped the old one's reference count without checking whether its callback was still sitting in a workqueue — a use-after-free waiting for a very specific timing window to be hit.

Common threads

Pattern Vector leak (CPU offline) IPI verifier NULL deref Vector exhaustion warning Affinity-notifier UAF
Involves interrupt CPU-affinity machinery specifically Yes Yes (IPI targeting) Yes Yes
Root cause: two independently-correct code paths racing against each other Yes No No
Root cause: validation ordered after the operation it should have gated No Yes No
Root cause: a release not synchronized against a still-outstanding deferred use No No Yes
Is a security vulnerability (has a CVE) Yes Yes No No
Fix changed behavior, not just added a diagnostic Yes Yes No (diagnostic only) Yes
Years between introduction and fix 7 (2017 → 2024) ~7 (2015 → 2023) ~2 (2017 → 2019) ~8 (2011 → 2019)

Two of these four are architecturally related. The vector leak and the vector-exhaustion warning both live in the same x86 per-CPU vector allocator, separated by five years — one is about a resource silently falling back to a different CPU when space runs out, the other is about a resource silently not being reclaimed after a CPU goes away. Neither is a mistake in the other's fix; they're two different failure modes in the same limited-resource-management problem, discovered independently.

The IPI verifier bug and the affinity-notifier bug are both, in different ways, stories about validation and cleanup happening in the wrong order relative to the operation they were meant to guard. The IPI verifier read a value from an unchecked pointer before checking the pointer — fixed by reordering a small number of lines. The affinity-notifier bug released a reference before confirming a deferred user of that reference had actually finished — fixed by adding a synchronous cancellation, not by reordering existing code, and it took a second fix a year later to also account for the reference that cancellation itself was holding. In both cases, the hard part was recognizing that an ordering assumption, not a missing check, was the actual bug.

Only one of the four incidents here — the vector-exhaustion warning — isn't a "wrong behavior" bug at all. The silent CPU-set fallback it made visible was arguably correct behavior; the gap was purely that nothing told an administrator it had happened. It's the only incident on this page whose fix is a single diagnostic line rather than a change to what the kernel actually does.

See also

  • Interrupt Handling Overview — the top/bottom-half split and execution contexts these bugs assume
  • IRQ Affinity and CPU Isolation — the affinity-configuration interface three of the four incidents involve directly
  • Locking War Stories — a comparable set of kernel-internal bugs from priority-inheritance and rt_mutex bookkeeping, a different kind of cross-subsystem coordination problem