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: 1d19h, last: 1d19h
✨ 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: ```c 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 (1)
ID Workflow Result Correct Bug Created Started Finished Revision
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.