If wq allocation fails during the initial iteration of the loop,
`conf_dev` is still NULL. However, the existing error handling via
`goto err` would attempt to call `put_device(conf_dev)`, leading to a
NULL pointer dereference.
This issue occurs because there's no dedicated error label for the WQ
allocation failure case, causing it to fall through to an incorrect
error path.
Fix this by introducing a new error label `err_wq`, ensuring that we
only invoke `put_device(conf_dev)` when `conf_dev` is valid.
Fixes: 3fd2f4bc010c ("dmaengine: idxd: fix memory leak in error handling path of idxd_setup_wqs")
Cc: stable@vger.kernel.org
Reported-by: Colin King <colin.i.king@gmail.com>
Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
---
drivers/dma/idxd/init.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
index 760b7d81fcd8..bf57ad30d613 100644
--- a/drivers/dma/idxd/init.c
+++ b/drivers/dma/idxd/init.c
@@ -196,7 +196,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
wq = kzalloc_node(sizeof(*wq), GFP_KERNEL, dev_to_node(dev));
if (!wq) {
rc = -ENOMEM;
- goto err;
+ goto err_wq;
}
idxd_dev_set_type(&wq->idxd_dev, IDXD_DEV_WQ);
@@ -246,6 +246,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
put_device(conf_dev);
kfree(wq);
+err_wq:
while (--i >= 0) {
wq = idxd->wqs[i];
if (idxd->hw.wq_cap.op_config)
--
2.43.5
On 5/21/25 11:33 PM, Shuai Xue wrote:
> If wq allocation fails during the initial iteration of the loop,
> `conf_dev` is still NULL. However, the existing error handling via
> `goto err` would attempt to call `put_device(conf_dev)`, leading to a
> NULL pointer dereference.
>
> This issue occurs because there's no dedicated error label for the WQ
> allocation failure case, causing it to fall through to an incorrect
> error path.
>
> Fix this by introducing a new error label `err_wq`, ensuring that we
> only invoke `put_device(conf_dev)` when `conf_dev` is valid.
>
> Fixes: 3fd2f4bc010c ("dmaengine: idxd: fix memory leak in error handling path of idxd_setup_wqs")
> Cc: stable@vger.kernel.org
> Reported-by: Colin King <colin.i.king@gmail.com>
> Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
> drivers/dma/idxd/init.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
> index 760b7d81fcd8..bf57ad30d613 100644
> --- a/drivers/dma/idxd/init.c
> +++ b/drivers/dma/idxd/init.c
> @@ -196,7 +196,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
> wq = kzalloc_node(sizeof(*wq), GFP_KERNEL, dev_to_node(dev));
> if (!wq) {
> rc = -ENOMEM;
> - goto err;
> + goto err_wq;
> }
>
> idxd_dev_set_type(&wq->idxd_dev, IDXD_DEV_WQ);
> @@ -246,6 +246,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
> put_device(conf_dev);
> kfree(wq);
>
> +err_wq:
> while (--i >= 0) {
> wq = idxd->wqs[i];
> if (idxd->hw.wq_cap.op_config)
© 2016 - 2025 Red Hat, Inc.