data built 2026-10-19T13:16:53Z

Look up another CVE · open CVE-2026-90244 in the interactive tracker

CVE-2026-90244

iommu/dma: Restore locking around msi_page_list

7.8 EPSS 0.2% AV:L

Published 2026-09-17 (31 days ago) by the Linux kernel CNA. Subsystem drivers/iommu. Debian urgency: unimportant.

What to do, per Debian release

Debian's own status for CVE-2026-90244 in every release this site tracks, and what each one means in practice. Every status below is the one the Debian Security Team publishes for this CVE. source

ReleaseStatus VersionWhat this means
Debian 12bookwormnot affected6.1.190-1Nothing to do. bookworm never shipped the vulnerable code.
Debian 13trixienot affected6.12.113-1Nothing to do. trixie never shipped the vulnerable code.
Debian 14forkyfixed7.2.6-1Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts.
Debian unstablesidfixed7.2.6-1Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts.

The vulnerability

What the bug is

Unlike a group's default domain, which is always freshly allocated and privately owned (iommu_group_alloc_default_domain()), VFIO type1's legacy container merges any newly attached group into an existing domain whenever their iommu_ops and cache-coherency enforcement match. iommu_dma_get_msi_page() only asserts the caller's own group mutex is held (iommu_group_mutex_assert()). On an IOMMU that publishes IOMMU_RESV_SW_MSI, e.g. ARM SMMU, a VM with two such devices assigned through the legacy container can have their guest drivers probe and allocate MSIs in parallel; each host-side VFIO_DEVICE_SET_IRQS lands on a different device fd and group mutex, but both devices' domains are the same merged domain, so both can enter iommu_dma_get_msi_page() concurrently and corrupt msi_page_list. commit 288683c92b1a ("iommu: Make iommu_dma_prepare_msi() into a generic operation") dropped the prior msi_prepare_lock on the reasoning that "each iommu_domain is unique to a group," which holds for default domains but not this VFIO type1 case. Restore the static lock, since it's only guarding a corner case and will likely never be contended. iommufd avoids the equivalent problem by having its own callers (iommufd_sw_map_msi()) take a ctx-wide sw_msi_lock before ever reaching the shared list. VFIO type1 can't mirror that since it dispatches to iommu_dma_sw_msi() which is outside VFIO's jurisdiction.

Where it lives

The fix touches these files. If the subsystem is one you do not use, the practical exposure is lower, though the package is still the vulnerable one.

drivers/iommu/dma-iommu.c

What this is
IOMMU DMA-API LAYERMAINTAINERS section matched on drivers/iommu/dma-iommu.c · iommu@lists.linux.dev · Maintained

Check it on the machine

grep -w CONFIG_IOMMU_DMA /boot/config-$(uname -r)

Reads the booted kernel's own configuration, on the machine and nowhere else. =y is built in, =m is a module, and an is not set line means the code is not there.

Show whether Debian builds this, per release

Debian builds this, but not on every flavour. At least one release below builds the code on some of its kernel flavours and not on others, so the answer depends on the architecture and flavour installed.

  • bookwormYnot built on armhf/armmp, armhf/armmp-lpae, armhf/rt/armmp, ppc64el/powerpc64le
  • trixieYnot built on armel/rpi, armhf/armmp, armhf/armmp-lpae, armhf/rt/armmp, ppc64el/powerpc64le, ppc64el/powerpc64le-64k, riscv64/riscv64
  • forky, sidYnot built on armhf/armmp, armhf/armmp-lpae, loong64/loong64, ppc64el/powerpc64le, ppc64el/powerpc64le-64k, riscv64/riscv64
Y
built in where it is built at all; some flavours do not build it
Build switch
CONFIG_IOMMU_DMA

From the configuration Debian publishes for every kernel flavour it builds. It covers only the architectures Debian ships a linux-config package for, and nothing about a kernel you built yourself. Debian's own status above stays authoritative about the source package.MAINTAINERS kbuild Makefiles Debian linux-config packages

Signals

Published
2026-09-17 (31 days ago)source
CVSS
7.8 high
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:Hsource recompute it
Attack vector
local (AV:L)source
EPSS
0.17%, higher than 6.3% of all CVEssource
CISA KEV
not listedthe KEV catalogue
Debian urgency
unimportantsource
Subsystem
drivers/iommu

Upstream fixes

The versions the CNA records as introducing and fixing this, and the commit for each. source

IntroducedFixed inCommit
6.156.18.52e3c53e9173a4
6.157.2.62af1e99ec14d
6.157.35a9e89ea34e0

Why the CNA scored it this way

Quoted from the kernel CNA's own scoring file, word for word. A highlighted metric carries the most severe value CVSS v3.1 defines for it, which is what pushes the score up. source

AV:LAttack vector, local
The race is entered only via ioctl(VFIO_DEVICE_SET_IRQS) on a local vfio-pci fd: vfio_pci_core_ioctl → vfio_pci_ioctl_set_irqs → vfio_pci_set_msi_trigger → vfio_msi_enable → pci_alloc_irq_vectors → its_irq_domain_alloc → iommu_dma_prepare_msi → iommu_dma_get_msi_page. No received packet or protocol message carries the trigger.
AC:LAttack complexity, low
The attacker issues concurrent VFIO_DEVICE_SET_IRQS on two device fds whose groups vfio_iommu_type1_attach_group already merged onto one domain; iommu_dma_prepare_msi takes only each device's own group->mutex, so both threads run iommu_dma_get_msi_page() on the shared msi_page_list. The attacker owns both sides of the race.
PR:LPrivileges required, low
vfio_pci_ioctl_set_irqs() and vfio_group_fops_open() have no capable() check on the IOMMU-backed path; CAP_SYS_RAWIO gates only VFIO_NO_IOMMU. An unprivileged qemu/kvm-group or DPDK user with two assigned /dev/vfio nodes can attach them to a type1 container and call SET_IRQS.
UI:NUser interaction, none
The attacker attaches its own groups with vfio_iommu_type1_attach_group and fires the concurrent SET_IRQS ioctls on fds it already holds; no other user must mount, open, or otherwise act.
S:UScope, unchanged
The race corrupts the host kernel's msi_page_list of iommu_dma_msi_page objects. iommu_map() still maps only the irqchip doorbell from its->get_msi_base() into the IOMMU_RESV_SW_MSI window vfio_iommu_has_sw_msi() reserved; that does not install extra host-RAM translations or bypass the DMA/VM isolation boundary.
C:HConfidentiality impact, high
Concurrent list_for_each_entry() versus unlocked list_add() on msi_page_list can follow a torn next pointer into a freed iommu_dma_msi_page, a use-after-free read of phys/iova and neighboring slab.
I:HIntegrity impact, high
Unlocked list_add() of iommu_dma_msi_page nodes overwrites kernel list next/prev, and the unlocked msi_cookie->msi_iova bump in iommu_dma_alloc_iova() can alias IOVAs; a sprayable UAF of that object is an arbitrary-write and control-flow primitive.
A:HAvailability impact, high
A corrupted msi_page_list walk or list_add in iommu_dma_get_msi_page() dereferences invalid list pointers and oopses or panics the host kernel even if the UAF is not fully weaponized.