From: "Bogdan Codres (Wind River)" <bogdan.codres@windriver.com>
To: dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: vkoul@kernel.org, dave.jiang@intel.com, vinicius.gomes@intel.com,
xueshuai@linux.alibaba.com, yi.sun@intel.com,
fenghuay@nvidia.com, dan.carpenter@linaro.org,
gregkh@linuxfoundation.org, stable@vger.kernel.org
Subject: [PATCH] dmaengine: idxd: fix use-after-free in idxd_free() and idxd_alloc() error paths
Date: Mon, 15 Jun 2026 13:39:31 +0300 [thread overview]
Message-ID: <20260615103932.61828-1-bogdan.codres@windriver.com> (raw)
To: dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Vinod Koul <vkoul@kernel.org>,
Dave Jiang <dave.jiang@intel.com>,
Vinicius Costa Gomes <vinicius.gomes@intel.com>,
Shuai Xue <xueshuai@linux.alibaba.com>,
Yi Sun <yi.sun@intel.com>,
Fenghua Yu <fenghuay@nvidia.com>,
Dan Carpenter <dan.carpenter@linaro.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org
Hi,
This patch fixes a double-free / use-after-free bug in the IDXD driver's
probe error path that corrupts the slab allocator and crashes the kernel.
The bug was introduced by commit 90022b3a6981 ("dmaengine: idxd: fix memory
leak in error handling path of idxd_pci_probe") which added the idxd_free()
helper.
Root Cause
----------
idxd_free() performs:
static void idxd_free(struct idxd_device *idxd)
{
if (!idxd)
return;
put_device(idxd_confdev(idxd)); // (1) triggers release callback
bitmap_free(idxd->opcap_bmap); // (2) USE AFTER FREE
ida_free(&idxd_ida, idxd->id); // (3) DOUBLE ida_free
kfree(idxd); // (4) DOUBLE kfree
}
Since device_initialize() was called in idxd_alloc(), conf_dev has
refcount=1. Step (1) drops it to 0 and synchronously triggers:
put_device() -> kobject_put() -> kobject_release() -> kobject_cleanup()
-> device_release() -> dev->type->release -> idxd_conf_device_release()
idxd_conf_device_release() (in sysfs.c) already does:
static void idxd_conf_device_release(struct device *dev)
{
struct idxd_device *idxd = confdev_to_idxd(dev);
kfree(idxd->groups);
bitmap_free(idxd->wq_enable_map);
kfree(idxd->wqs);
kfree(idxd->engines);
kfree(idxd->evl);
kmem_cache_destroy(idxd->evl_cache);
ida_free(&idxd_ida, idxd->id); // <- FIRST ida_free
bitmap_free(idxd->opcap_bmap); // <- FIRST bitmap_free
kfree(idxd); // <- FIRST kfree
}
So after put_device() returns in idxd_free():
- idxd pointer is dangling (memory freed)
- idxd->opcap_bmap is dangling
- idxd->id has already been freed from the IDA
Steps 2-4 then operate on freed memory, corrupting the slab allocator.
The same pattern exists in idxd_alloc() at the err_name label.
How to Reproduce
----------------
This occurs during kdump (crash dump collection) on systems with
Intel IDXD hardware:
1. System has Intel IDXD (DSA/IAX) -- e.g., Granite Rapids / Sapphire
Rapids platforms
2. Original kernel panics (any reason)
3. Kdump kernel boots with: reset_devices nr_cpus=1
4. IDXD device is in HALTED state due to reset_devices
5. IDXD driver probes the device -> probe fails -> idxd_free() ->
double-free -> slab corruption
6. systemd-udevd loads next module -> module signature verification
allocates memory -> hits corrupted slab -> kernel oops
Console Output (kdump kernel)
-----------------------------
[ 18.628791] idxd 0000:00:01.0: Device is HALTED!
[ 18.631447] idxd 0000:00:01.0: Intel(R) IDXD DMA Engine init failed
[ 18.631450] ------------[ cut here ]------------
[ 18.631451] ida_free called for id=0 which is not allocated.
[ 18.631462] WARNING: CPU: 0 PID: 11 at lib/idr.c:525 ida_free+0xd3/0x130
[ 18.631502] idxd_pci_probe+0x1b0/0x1860 [idxd]
...
[ 18.898798] BUG: unable to handle page fault for address: ff2c9dd300000010
[ 18.931865] RIP: 0010:___slab_alloc+0x168/0xa10
...
[ 19.097220] __kmalloc_cache_noprof+0x82/0x230
[ 19.102683] mpi_alloc+0x20/0x80
[ 19.106676] rsa_enc+0x2f/0x120
[ 19.110549] pkcs1pad_verify+0x13b/0x1a0
...
[ 19.161968] module_sig_check+0x87/0xe0
[ 19.166709] load_module+0x3c/0x1e80
Affected Versions
-----------------
- Mainline: present at HEAD (introduced Apr 2025)
- Stable: v6.12.30+ (backport commit 017d4012dc05)
- Also present in other stable branches that received the backport
Test Platform
-------------
- Dell PowerEdge XR8720t
- Intel Xeon 6716P-B (Granite Rapids)
- Kernel: 6.12.0-1-rt-amd64 (StarlingX 6.12.40-1.stx.140)
- RT: PREEMPT_RT
Why This Was Not Caught Earlier
-------------------------------
1. The error path only triggers when IDXD device is HALTED -- this
only happens with reset_devices (kdump) or hardware error
2. On normal boot, IDXD probe always succeeds
3. Most kdump configurations blacklist IDXD via module_blacklist=
4. Systems without IDXD hardware are unaffected
5. The ida_free WARNING alone doesn't crash -- it's the subsequent
slab corruption that causes the fatal oops, which may appear as
an unrelated bug
Workaround
----------
Add idxd to module_blacklist in the kdump kernel command line:
module_blacklist=idxd,idxd_bus
Fix
---
Remove the duplicate bitmap_free/ida_free/kfree from idxd_free()
since idxd_conf_device_release() (triggered by put_device()) already
handles all resource deallocation. Similarly fix idxd_alloc() err_name
path.
Related Commits
---------------
- 90022b3a6981 ("dmaengine: idxd: fix memory leak in error handling
path of idxd_pci_probe") -- introduces the bug
- 46a5cca76c76 ("dmaengine: idxd: fix memory leak in error handling
path of idxd_alloc") -- same pattern in idxd_alloc
- f41c538881ee ("dmaengine: idxd: Remove improper idxd_free") -- fixes
the same function but only in idxd_remove(), not probe error path
- c311f5e9248471 ("dmaengine: idxd: Fix freeing the allocated ida too
late") -- establishes the correct pattern for cdev (ida_free before
put_device, not in .release())
Thanks,
Bogdan
Bogdan Codres (1):
dmaengine: idxd: fix use-after-free in idxd_free() and idxd_alloc()
error paths
drivers/dma/idxd/init.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
--
2.43.0
next reply other threads:[~2026-06-15 10:40 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-15 10:39 Bogdan Codres (Wind River) [this message]
2026-06-15 10:39 ` [PATCH] dmaengine: idxd: fix use-after-free in idxd_free() and idxd_alloc() error paths Bogdan Codres (Wind River)
2026-06-15 11:02 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260615103932.61828-1-bogdan.codres@windriver.com \
--to=bogdan.codres@windriver.com \
--cc=dan.carpenter@linaro.org \
--cc=dave.jiang@intel.com \
--cc=dmaengine@vger.kernel.org \
--cc=fenghuay@nvidia.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=vinicius.gomes@intel.com \
--cc=vkoul@kernel.org \
--cc=xueshuai@linux.alibaba.com \
--cc=yi.sun@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.