Cloudanix VulnDB

CVE-2025-38062

None

CVSS

—

EPSS

0.2%

Published

Jun 18, 2025

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A bug in the Linux kernel's handling of certain hardware interrupts for virtual devices could let an attacker corrupt memory and take over the system.

Exploitation
Local Privilege
Attacker needs
Low Privilege
Complexity
Moderate
Impact
Privilege Gain
Component
OS kernel
Class
Use After Free
Remediation
Patch
Effort
Medium
Patch risk
Low

What it actually does

Use-after-free on an IOMMU cookie pointer stored in msi_desc during a race between iommu_attach_group and iommu_dma_compose_msi_msg when an iommufd-backed VFIO domain is changed concurrently with MSI programming; a secondary unlocked iommu_get_domain_for_dev call is also affected.

Why it matters to the business

Attackers with access to a VFIO-managed device can trigger kernel memory corruption on affected Linux systems, leading to denial of service, privilege escalation, or arbitrary code execution; the bug affects virtualized and containerized workloads using iommufd, increasing operational risk for cloud and enterprise hosts until patched.

How an attack unfolds

An attacker controlling a userspace VFIO client races VFIO_DEVICE_ATTACH_IOMMUFD_PT against VFIO_DEVICE_SET_IRQS while an MSI interrupt is being programmed; the freed cookie pointer and domain reference are dereferenced without locking, resulting in use-after-free. Named threat actors and related Linux kernel privilege-escalation campaigns have demonstrated similar patterns against unpatched kernels.

How to fix it

Upgrade the Linux kernel to commit e4d3763223c7b72ded53425207075e7453b4e3d5 or later; apply the companion fix in "iommu: Make iommu_dma_prepare_msi() into a generic operation"; rebuild and reboot all affected hosts. Where immediate patching is impossible, restrict VFIO/iommufd usage to trusted workloads and monitor for domain-change operations.

How to confirm the fix worked

Verify the running kernel contains commit e4d3763223c7b72ded53425207075e7453b4e3d5; confirm iommu_dma_prepare_msi no longer stores a cookie pointer; exercise VFIO attach/set-irqs concurrently under stress and ensure no UAF reports appear in dmesg or KASAN logs.

Typical attack path

  1. Obtain a VFIO device file descriptor for a device backed by iommufd
  2. Prepare an MSI interrupt allocation via VFIO_DEVICE_SET_IRQS
  3. Concurrently issue VFIO_DEVICE_ATTACH_IOMMUFD_PT to change the IOMMU domain
  4. Trigger the race window so that the stale cookie pointer and unlocked domain lookup are dereferenced
  5. Exploit the resulting use-after-free for memory corruption or code execution

How to detect it

Search kernel logs and audit trails for concurrent VFIO attach and IRQ programming events; inspect for KASAN or slab UAF reports mentioning msi_desc or iommu_dma_compose_msi_msg; correlate with process activity using VFIO_DEVICE_ATTACH_IOMMUFD_PT or VFIO_DEVICE_SET_IRQS ioctls.

What your security team should do

  • Prioritize kernel upgrades on all systems exposing VFIO or iommufd to untrusted guests
  • Add the fixed commit to internal kernel build pipelines and CI regression tests
  • Restrict VFIO device access via SELinux/AppArmor or device-allow lists until patches are deployed
  • Monitor EPSS trend and threat-actor activity for any increase in targeting of similar IOMMU races

The record

In the Linux kernel, the following vulnerability has been resolved: genirq/msi: Store the IOMMU IOVA directly in msi_desc instead of iommu_cookie The IOMMU translation for MSI message addresses has been a 2-step process, separated in time: 1) iommu_dma_prepare_msi(): A cookie pointer containing the IOVA address is stored in the MSI descriptor when an MSI interrupt is allocated. 2) iommu_dma_compose_msi_msg(): this cookie pointer is used to compute a translated message address. This has an inherent lifetime problem for the pointer stored in the cookie that must remain valid between the two steps. However, there is no locking at the irq layer that helps protect the lifetime. Today, this works under the assumption that the iommu domain is not changed while MSI interrupts being programmed. This is true for normal DMA API users within the kernel, as the iommu domain is attached before the driver is probed and cannot be changed while a driver is attached. Classic VFIO type1 also prevented changing the iommu domain while VFIO was running as it does not support changing the "container" after starting up. However, iommufd has improved this so that the iommu domain can be changed during VFIO operation. This potentially allows userspace to directly race VFIO_DEVICE_ATTACH_IOMMUFD_PT (which calls iommu_attach_group()) and VFIO_DEVICE_SET_IRQS (which calls into iommu_dma_compose_msi_msg()). This potentially causes both the cookie pointer and the unlocked call to iommu_get_domain_for_dev() on the MSI translation path to become UAFs. Fix the MSI cookie UAF by removing the cookie pointer. The translated IOVA address is already known during iommu_dma_prepare_msi() and cannot change. Thus, it can simply be stored as an integer in the MSI descriptor. The other UAF related to iommu_get_domain_for_dev() will be addressed in patch "iommu: Make iommu_dma_prepare_msi() into a generic operation" by using the IOMMU group mutex.

Affected packages

Ecosystem Package Introduced Fixed
Debian:11 linux 0 No fix
Debian:12 linux 0 No fix
Debian:13 linux 0 6.12.32-1
Debian:14 linux 0 6.12.32-1
Linux Kernel 5.2.0 6.1.141
SUSE:Linux Enterprise High Availability Extension 15 SP6 kernel-default 0 6.4.0-150600.23.65.1
SUSE:Linux Enterprise Live Patching 15 SP6 kernel-default 0 6.4.0-150600.23.65.1
SUSE:Linux Enterprise Live Patching 15 SP6 kernel-livepatch-SLE15-SP6-RT_Update_14 0 1-150600.1.5.1
SUSE:Linux Enterprise Live Patching 15 SP6 kernel-livepatch-SLE15-SP6_Update_14 0 1-150600.13.3.4
SUSE:Linux Enterprise Live Patching 15 SP7 kernel-livepatch-SLE15-SP7-RT_Update_3 0 1-150700.1.5.1
SUSE:Linux Enterprise Module for Basesystem 15 SP6 kernel-64kb 0 6.4.0-150600.23.65.1
SUSE:Linux Enterprise Module for Basesystem 15 SP6 kernel-default 0 6.4.0-150600.23.65.1
SUSE:Linux Enterprise Module for Basesystem 15 SP6 kernel-default-base 0 6.4.0-150600.23.65.1.150600.12.28.4
SUSE:Linux Enterprise Module for Basesystem 15 SP6 kernel-source 0 6.4.0-150600.23.65.1
SUSE:Linux Enterprise Module for Basesystem 15 SP6 kernel-zfcpdump 0 6.4.0-150600.23.65.1
SUSE:Linux Enterprise Module for Confidential Computing Technical Preview 15 SP6 kernel-coco 0 6.4.0-15061.28.coco15sp6.1
SUSE:Linux Enterprise Module for Confidential Computing Technical Preview 15 SP6 kernel-coco_debug 0 6.4.0-15061.28.coco15sp6.1
SUSE:Linux Enterprise Module for Confidential Computing Technical Preview 15 SP6 kernel-source-coco 0 6.4.0-15061.28.coco15sp6.1
SUSE:Linux Enterprise Module for Confidential Computing Technical Preview 15 SP6 kernel-syms-coco 0 6.4.0-15061.28.coco15sp6.1
SUSE:Linux Enterprise Module for Development Tools 15 SP6 kernel-docs 0 6.4.0-150600.23.65.1
SUSE:Linux Enterprise Module for Development Tools 15 SP6 kernel-obs-build 0 6.4.0-150600.23.65.1
SUSE:Linux Enterprise Module for Development Tools 15 SP6 kernel-source 0 6.4.0-150600.23.65.1
SUSE:Linux Enterprise Module for Development Tools 15 SP6 kernel-syms 0 6.4.0-150600.23.65.1
SUSE:Linux Enterprise Module for Legacy 15 SP6 kernel-default 0 6.4.0-150600.23.65.1
SUSE:Linux Enterprise Module for Public Cloud 15 SP6 kernel-azure 0 6.4.0-150600.8.48.1
SUSE:Linux Enterprise Module for Public Cloud 15 SP6 kernel-source-azure 0 6.4.0-150600.8.48.1
SUSE:Linux Enterprise Module for Public Cloud 15 SP6 kernel-syms-azure 0 6.4.0-150600.8.48.1
SUSE:Linux Enterprise Workstation Extension 15 SP6 kernel-default 0 6.4.0-150600.23.65.1
SUSE:Real Time Module 15 SP6 kernel-rt 0 6.4.0-150600.10.49.1
SUSE:Real Time Module 15 SP6 kernel-rt_debug 0 6.4.0-150600.10.49.1
SUSE:Real Time Module 15 SP6 kernel-source-rt 0 6.4.0-150600.10.49.1
SUSE:Real Time Module 15 SP6 kernel-syms-rt 0 6.4.0-150600.10.49.1
SUSE:Real Time Module 15 SP7 kernel-rt 0 6.4.0-150700.7.13.1
SUSE:Real Time Module 15 SP7 kernel-source-rt 0 6.4.0-150700.7.13.1
SUSE:Real Time Module 15 SP7 kernel-syms-rt 0 6.4.0-150700.7.13.1
openSUSE:Leap 15.6 dtb-aarch64 0 6.4.0-150600.23.65.1
openSUSE:Leap 15.6 kernel-64kb 0 6.4.0-150600.23.65.1
openSUSE:Leap 15.6 kernel-azure 0 6.4.0-150600.8.48.1
openSUSE:Leap 15.6 kernel-debug 0 6.4.0-150600.23.65.1
openSUSE:Leap 15.6 kernel-default 0 6.4.0-150600.23.65.1
openSUSE:Leap 15.6 kernel-default-base 0 6.4.0-150600.23.65.1.150600.12.28.4
openSUSE:Leap 15.6 kernel-docs 0 6.4.0-150600.23.65.1
openSUSE:Leap 15.6 kernel-kvmsmall 0 6.4.0-150600.23.65.1
openSUSE:Leap 15.6 kernel-obs-build 0 6.4.0-150600.23.65.1
openSUSE:Leap 15.6 kernel-obs-qa 0 6.4.0-150600.23.65.1
openSUSE:Leap 15.6 kernel-rt 0 6.4.0-150600.10.49.1
openSUSE:Leap 15.6 kernel-rt_debug 0 6.4.0-150600.10.49.1
openSUSE:Leap 15.6 kernel-source 0 6.4.0-150600.23.65.1
openSUSE:Leap 15.6 kernel-source-azure 0 6.4.0-150600.8.48.1
openSUSE:Leap 15.6 kernel-source-rt 0 6.4.0-150600.10.49.1
openSUSE:Leap 15.6 kernel-syms 0 6.4.0-150600.23.65.1
openSUSE:Leap 15.6 kernel-syms-azure 0 6.4.0-150600.8.48.1
openSUSE:Leap 15.6 kernel-syms-rt 0 6.4.0-150600.10.49.1
openSUSE:Leap 15.6 kernel-zfcpdump 0 6.4.0-150600.23.65.1
openSUSE:Leap 16.0 dtb-aarch64 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-64kb 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-default 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-default-base 0 6.12.0-160000.6.1.160000.2.4
openSUSE:Leap 16.0 kernel-docs 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-kvmsmall 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-obs-build 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-obs-qa 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-rt 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-source 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-syms 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-zfcpdump 0 6.12.0-160000.6.1

Related vulnerabilities