From: "Bogdan Codres (Wind River)" <bogdan.codres@windriver.com>
To: dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org,
vkoul@kernel.org, dave.jiang@intel.com, vinicius.gomes@intel.com
Cc: xueshuai@linux.alibaba.com, yi.sun@intel.com,
fenghuay@nvidia.com, dan.carpenter@linaro.org,
gregkh@linuxfoundation.org, stable@vger.kernel.org,
Bogdan Codres <bogdan.codres@windriver.com>
Subject: [PATCH v2] dmaengine: idxd: fix use-after-free in idxd_free() and idxd_alloc() error paths
Date: Thu, 18 Jun 2026 14:32:54 +0300 [thread overview]
Message-ID: <20260618113254.493582-1-bogdan.codres@windriver.com> (raw)
In-Reply-To: <ajMNBgdsvdLPCt7X@lizhi-Precision-Tower-5810>
From: Bogdan Codres <bogdan.codres@windriver.com>
[ 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.631474] CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 6.12.0-1-rt-amd64 #1
[ 18.631477] Hardware name: Dell Inc. PowerEdge XR8720t/0J91KV, BIOS 1.1.3 02/03/2026
[ 18.631478] Workqueue: events work_for_cpu_fn
[ 18.631480] RIP: 0010:ida_free+0xd3/0x130
[ 18.631492] Call Trace:
[ 18.631494] <TASK>
[ 18.631495] idxd_pci_probe+0x1b0/0x1860 [idxd]
[ 18.631506] local_pci_probe+0x43/0xa0
[ 18.631508] work_for_cpu_fn+0x13/0x20
[ 18.631510] process_one_work+0x179/0x390
[ 18.631512] worker_thread+0x237/0x340
[ 18.631517] kthread+0xc6/0x100
[ 18.631520] ret_from_fork+0x2d/0x50
[ 18.631524] ret_from_fork_asm+0x1a/0x30
[ 18.631526] </TASK>
idxd_free() calls put_device(idxd_confdev(idxd)) which drops the last
reference and synchronously invokes idxd_conf_device_release(). That
release callback already frees idxd->opcap_bmap, idxd->id (via
ida_free), and the idxd structure itself. The subsequent bitmap_free(),
ida_free(), and kfree() in idxd_free() therefore operate on freed
memory - a double-free that corrupts the slab allocator.
The same pattern exists in idxd_alloc() at the err_name label where
put_device() is followed by bitmap_free() fall-through.
Fix both by letting put_device() handle all resource cleanup via the
release callback, removing the duplicate frees.
Fixes: 90022b3a6981 ("dmaengine: idxd: fix memory leak in error handling path of idxd_pci_probe")
Fixes: 46a5cca76c76 ("dmaengine: idxd: fix memory leak in error handling path of idxd_alloc")
Cc: stable@vger.kernel.org
Signed-off-by: Bogdan Codres <bogdan.codres@windriver.com>
---
drivers/dma/idxd/init.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
index 18997f80bdc9..ce4d58740c88 100644
--- a/drivers/dma/idxd/init.c
+++ b/drivers/dma/idxd/init.c
@@ -585,15 +585,18 @@ static void idxd_read_caps(struct idxd_device *idxd)
idxd->hw.iaa_cap.bits = ioread64(idxd->reg_base + IDXD_IAACAP_OFFSET);
}
+/*
+ * Release an idxd device that was allocated (device_initialize() was called)
+ * but never successfully registered. put_device() drops the last reference and
+ * triggers idxd_conf_device_release() which frees all resources including the
+ * ida, opcap_bmap, and the idxd structure itself.
+ */
static void idxd_free(struct idxd_device *idxd)
{
if (!idxd)
return;
put_device(idxd_confdev(idxd));
- bitmap_free(idxd->opcap_bmap);
- ida_free(&idxd_ida, idxd->id);
- kfree(idxd);
}
static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data)
@@ -633,8 +636,12 @@ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_d
return idxd;
err_name:
+ /* device_initialize() was called, so put_device() will trigger
+ * idxd_conf_device_release() which frees ida, opcap_bmap, and idxd.
+ * Do not fall through to err_opcap/err_ida.
+ */
put_device(conf_dev);
- bitmap_free(idxd->opcap_bmap);
+ return NULL;
err_opcap:
ida_free(&idxd_ida, idxd->id);
err_ida:
--
2.51.0
next prev parent reply other threads:[~2026-06-18 11:34 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
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 10:39 ` Bogdan Codres (Wind River)
2026-06-15 11:02 ` sashiko-bot
2026-06-17 21:09 ` Frank Li
2026-06-18 11:32 ` Bogdan Codres (Wind River) [this message]
2026-06-18 13:55 ` [PATCH v2] " 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=20260618113254.493582-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.