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: 2d15h, last: 2d15h
✨ 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
Based on kernel commit 65ba8f34ec88:

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):

  1. iommu_fwspec_init() checks if dev->iommu is initialized; if not, it invokes dev_iommu_get(dev) (drivers/iommu/iommu.c:3086).
  2. dev_iommu_get() dynamically allocates struct dev_iommu (64 bytes) via kzalloc_obj() and assigns it to dev->iommu.
  3. Next, iommu_fwspec_init() attempts to allocate the fwspec structure:
    fwspec = kzalloc_flex(*fwspec, ids, 1);
    if (!fwspec)
        return -ENOMEM;
    
  4. 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.
  5. 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).
  6. 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.
▶ ▼ ✨ AI Jobs (2)
ID Workflow Result Correct Bug Created Started Finished Revision
fc375e76 repro-c 💥 memory leak in iommu_fwspec_init 2026/10/31 00:00 2026/10/31 00:01 2026/10/31 06:00 0ec395f8
fb46e4e2 assessment-security DenialOfService: ✅ Exploitable: ❌ FilesystemTrigger: ❌ FuzzingArtifact: ❌ MemoryCorruption: ❌ NetworkNeedsSetup: ❌ NetworkTrigger: ❌ PeripheralTrigger: ❌ RemoteTrigger: ❌ Unprivileged: ❌ UserNamespace: ❌ VMGuestTrigger: ❌ VMHostTrigger: ❌ ❓ memory leak in iommu_fwspec_init 2026/10/28 20:29 2026/10/28 20:29 2026/10/28 21:17 b1d00f76
▶ ▼ Discussions (1)
Title Replies (including bot) Last reply
[syzbot] [iommu?] memory leak in iommu_fwspec_init 0 (1) 2026/10/30 02:36

Sample crash report:
BUG: memory leak
unreferenced object 0xffff88812bad6bc0 (size 64):
  comm "syz.0.26", pid 5965, jiffies 4294941985
  hex dump (first 32 bytes):
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace (crc 0):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4733 [inline]
    slab_alloc_node mm/slub.c:5033 [inline]
    __kmalloc_cache_noprof+0x35f/0x3f0 mm/slub.c:5676
    _kmalloc_noprof include/linux/slab.h:991 [inline]
    _kzalloc_noprof include/linux/slab.h:1312 [inline]
    dev_iommu_get drivers/iommu/iommu.c:408 [inline]
    dev_iommu_get drivers/iommu/iommu.c:399 [inline]
    iommu_fwspec_init+0x20d/0x240 drivers/iommu/iommu.c:3086
    iommu_mock_device_add+0x29/0x90 drivers/iommu/iommu.c:385
    mock_dev_create drivers/iommu/iommufd/selftest.c:1026 [inline]
    iommufd_test_mock_domain drivers/iommu/iommufd/selftest.c:1068 [inline]
    iommufd_test+0x1a97/0x2ec0 drivers/iommu/iommufd/selftest.c:2104
    iommufd_fops_ioctl+0x1ed/0x370 drivers/iommu/iommufd/main.c:556
    vfs_ioctl fs/ioctl.c:51 [inline]
    __do_sys_ioctl fs/ioctl.c:597 [inline]
    __se_sys_ioctl fs/ioctl.c:583 [inline]
    __x64_sys_ioctl+0xf4/0x140 fs/ioctl.c:583
    do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
    do_syscall_64+0xe9/0x530 arch/x86/entry/syscall_64.c:84
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

connection error: failed to recv *flatrpc.ExecutorMessageRawT: EOF

Crashes (1):
Time Kernel Commit Syzkaller Config Log Report Syz repro C repro VM info Assets (help?) Manager Title
2026/10/28 20:29 upstream 65ba8f34ec88 858db2ec .config console log report syz / log [disk image] [vmlinux] [kernel image] ci-upstream-gce-leak memory leak in iommu_fwspec_init
* Struck through repros no longer work on HEAD.