syzbot
memory leak in iommu_fwspec_init
Status:
upstream: reported syz repro on 2026/10/30 02:36
Subsystems:
iommu
Labels:
prio:low
[Documentation on labels]
Reported-by: syzbot+fe84fc6a684e0beb86e2@syzkaller.appspotmail.com
First crash: 2d16h, last: 2d16h
✨ AI-generated root cause summary:
A memory leak of struct dev_iommu occurs when iommu_fwspec_init() allocates dev->iommu via dev_iommu_get(), but subsequently fails on allocating the iommu_fwspec structure (e.g. via fault injection) and returns -ENOMEM without releasing dev->iommu. Furthermore, callers such as iommu_mock_device_add() do not invoke dev_iommu_free() on error from iommu_fwspec_init(). When device initialization fails and the device is released, dev->iommu remains allocated, causing an unreferenced object memory leak.
▶
▼
✨ Full AI root cause analysis
Root Cause Analysis
1. Functions, Structs, Fields, and Files Involved
- Source File:
drivers/iommu/iommu.c (with caller context in drivers/iommu/iommufd/selftest.c)
- Functions:
dev_iommu_get(), iommu_fwspec_init(), iommu_mock_device_add(), mock_dev_create()
- Data Structures and Fields:
struct dev_iommu (size 64 bytes) assigned to dev->iommu.
struct iommu_fwspec referenced by dev->iommu->fwspec.
struct mock_dev and struct device (mdev->dev).
2. Trigger and Invariant Violation
During mock device registration (mock_dev_create() via iommufd_test_mock_domain() triggered through /dev/iommu ioctl IOMMU_TEST_OP_MOCK_DOMAIN), iommu_mock_device_add() calls iommu_fwspec_init(&mdev->dev, mock_iommu.fwnode):
iommu_fwspec_init() checks if dev->iommu is initialized; if not, it invokes dev_iommu_get(dev) (drivers/iommu/iommu.c:3086).
dev_iommu_get() dynamically allocates struct dev_iommu (64 bytes) via kzalloc_obj() and assigns it to dev->iommu.
- Next,
iommu_fwspec_init() attempts to allocate the fwspec structure:
fwspec = kzalloc_flex(*fwspec, ids, 1);
if (!fwspec)
return -ENOMEM;
- If this allocation fails (as stimulated by fault injection in the reproducer via
/proc/thread-self/fail-nth), iommu_fwspec_init() returns -ENOMEM without unwinding or freeing the newly allocated dev->iommu.
- Callers such as
iommu_mock_device_add() immediately exit on error from iommu_fwspec_init() (drivers/iommu/iommu.c:388-389), without calling dev_iommu_free(dev) (in contrast to failure in device_add(), where dev_iommu_free() is properly called).
- As a result, when
mock_dev_create() cleans up via put_device(&mdev->dev), mock_dev_release() frees mdev without freeing dev->iommu, leaving the 64-byte struct dev_iommu completely unreferenced on the slab heap.
3. Runtime Consequences in a Production Kernel
- Memory Corruption: False. The defect is an omission in error-path cleanup leading to a leak; no corrupted pointers, double frees, or out-of-bounds accesses take place.
- Info Leak: "none". No kernel memory is exposed to user space.
- Raw Denial of Service: True. Systematic failure to reclaim allocated kernel memory on error paths leads to kernel heap memory leaks. If hit repeatedly under low-memory or fault-injection conditions, this causes kernel resource exhaustion.
- Virtualization / KVM Candidate: True. The bug is reached via the
iommufd userspace subsystem (/dev/iommu), which provides IOMMU controls for VM device passthrough and virtual IOMMUs (vIOMMU).
- Networking Candidate: False. The defect is strictly within the IOMMU core framework and IOMMUFD selftest driver.
Sample crash report:
* Struck through repros no longer work on HEAD.