CVE-2026-23198

Source
https://cve.org/CVERecord?id=CVE-2026-23198
Import Source
https://storage.googleapis.com/osv-test-cve-osv-conversion/osv-output/CVE-2026-23198.json
JSON Data
https://api.test.osv.dev/v1/vulns/CVE-2026-23198
Downstream
Related
Published
2026-02-14T16:27:23.621Z
Modified
2026-03-20T17:44:15.671600Z
Summary
KVM: Don't clobber irqfd routing type when deassigning irqfd
Details

In the Linux kernel, the following vulnerability has been resolved:

KVM: Don't clobber irqfd routing type when deassigning irqfd

When deassigning a KVMIRQFD, don't clobber the irqfd's copy of the IRQ's routing entry as doing so breaks kvmarchirqbypassdelproducer() on x86 and arm64, which explicitly look for KVMIRQROUTINGMSI. Instead, to handle a concurrent routing update, verify that the irqfd is still active before consuming the routing information. As evidenced by the x86 and arm64 bugs, and another bug in kvmarchupdateirqfd_routing() (see below), clobbering the entry type without notifying arch code is surprising and error prone.

As a bonus, checking that the irqfd is active provides a convenient location for documenting why KVM must not consume the routing entry for an irqfd that is in the process of being deassigned: once the irqfd is deleted from the list (which happens before the eventfd is detached), it will no longer receive updates via kvmirqroutingupdate(), and so KVM could deliver an event using stale routing information (relative to KVMSETGSIROUTING returning to userspace).

As an even better bonus, explicitly checking for the irqfd being active fixes a similar bug to the one the clobbering is trying to prevent: if an irqfd is deactivated, and then its routing is changed, kvmirqroutingupdate() won't invoke kvmarchupdateirqfd_routing() (because the irqfd isn't in the list). And so if the irqfd is in bypass mode, IRQs will continue to be posted using the old routing information.

As for kvmarchirqbypassdel_producer(), clobbering the routing type results in KVM incorrectly keeping the IRQ in bypass mode, which is especially problematic on AMD as KVM tracks IRQs that are being posted to a vCPU in a list whose lifetime is tied to the irqfd.

Without the help of KASAN to detect use-after-free, the most common sympton on AMD is a NULL pointer deref in amdiommuupdatega() due to the memory for irqfd structure being re-allocated and zeroed, resulting in irqfd->irqbypassdata being NULL when read by avicupdateiommuvcpu_affinity():

BUG: kernel NULL pointer dereference, address: 0000000000000018 #PF: supervisor read access in kernel mode #PF: errorcode(0x0000) - not-present page PGD 40cf2b9067 P4D 40cf2b9067 PUD 408362a067 PMD 0 Oops: Oops: 0000 [#1] SMP CPU: 6 UID: 0 PID: 40383 Comm: vfioirqtest Tainted: G U W O 6.19.0-smp--5dddc257e6b2-irqfd #31 NONE Tainted: [U]=USER, [W]=WARN, [O]=OOTMODULE Hardware name: Google, Inc. ArcadiaIT80/ArcadiaIT80, BIOS 34.78.2-0 09/05/2025 RIP: 0010:amdiommuupdatega+0x19/0xe0 Call Trace: <TASK> avicupdateiommuvcpuaffinity+0x3d/0x90 [kvmamd] __avicvcpuload+0xf4/0x130 [kvm_amd] kvmarchvcpuload+0x89/0x210 [kvm] vcpuload+0x30/0x40 [kvm] kvmarchvcpuioctlrun+0x45/0x620 [kvm] kvmvcpuioctl+0x571/0x6a0 [kvm] __sesysioctl+0x6d/0xb0 dosyscall64+0x6f/0x9d0 entrySYSCALL64afterhwframe+0x4b/0x53 RIP: 0033:0x46893b </TASK> ---[ end trace 0000000000000000 ]---

If AVIC is inhibited when the irfd is deassigned, the bug will manifest as list corruption, e.g. on the next irqfd assignment.

listadd corruption. next->prev should be prev (ffff8d474d5cd588), but was 0000000000000000. (next=ffff8d8658f86530). ------------[ cut here ]------------ kernel BUG at lib/listdebug.c:31! Oops: invalid opcode: 0000 [#1] SMP CPU: 128 UID: 0 PID: 80818 Comm: vfioirqtest Tainted: G U W O 6.19.0-smp--f19dc4d680ba-irqfd #28 NONE Tainted: [U]=USER, [W]=WARN, [O]=OOTMODULE Hardware name: Google, Inc. ArcadiaIT80/ArcadiaIT80, BIOS 34.78.2-0 09/05/2025 RIP: 0010:listaddvalidorreport+0x97/0xc0 Call Trace: <TASK> avicpiupdateirte+0x28e/0x2b0 [kvmamd] kvmpiupdateirte+0xbf/0x190 [kvm] kvmarchirqbypassaddproducer+0x72/0x90 [kvm] irqbypassregisterconsumer+0xcd/0x170 [irqbypa ---truncated---

Database specific
{
    "cna_assigner": "Linux",
    "osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/23xxx/CVE-2026-23198.json"
}
References

Affected packages

Git / git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

Affected ranges

Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
f70c20aaf141adb715a2d750c55154073b02a9c3
Fixed
959a063e7f12524bc1871ad1f519787967bbcd45
Fixed
2284bc168b148a17b5ca3b37b3d95c411f18a08d
Fixed
6d14ba1e144e796b5fc81044f08cfba9024ca195
Fixed
b61f9b2fcf181451d0a319889478cc53c001123e
Fixed
ff48c9312d042bfbe826ca675e98acc6c623211c
Fixed
4385b2f2843549bfb932e0dcf76bf4b065543a3c
Fixed
b4d37cdb77a0015f51fee083598fa227cc07aaf1

Database specific

source
"https://storage.googleapis.com/osv-test-cve-osv-conversion/osv-output/CVE-2026-23198.json"

Linux / Kernel

Package

Name
Kernel

Affected ranges

Type
ECOSYSTEM
Events
Introduced
4.4.0
Fixed
5.10.250
Type
ECOSYSTEM
Events
Introduced
5.11.0
Fixed
5.15.200
Type
ECOSYSTEM
Events
Introduced
5.16.0
Fixed
6.1.163
Type
ECOSYSTEM
Events
Introduced
6.2.0
Fixed
6.6.124
Type
ECOSYSTEM
Events
Introduced
6.7.0
Fixed
6.12.70
Type
ECOSYSTEM
Events
Introduced
6.13.0
Fixed
6.18.10

Database specific

source
"https://storage.googleapis.com/osv-test-cve-osv-conversion/osv-output/CVE-2026-23198.json"