[PATCH] dmaengine: idxd: fix double free in idxd_setup_wqs() error path

Guangshuo Li posted 1 patch 5 hours ago
drivers/dma/idxd/init.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
[PATCH] dmaengine: idxd: fix double free in idxd_setup_wqs() error path
Posted by Guangshuo Li 5 hours ago
When an error happens after device_initialize(), idxd_setup_wqs()
calls put_device(conf_dev).

The device release callback idxd_conf_wq_release() frees wq,
wq->wqcfg, and wq->opcap_bmap, but the current error paths then free
them again directly, causing a double free.

Keep the cleanup in idxd_conf_wq_release() after put_device() and
avoid freeing those objects again in idxd_setup_wqs().

Fixes: 39aaa337449e7 ("dmaengine: idxd: Fix double free in idxd_setup_wqs()")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
 drivers/dma/idxd/init.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
index 2acc34b3daff..b782eb3c191d 100644
--- a/drivers/dma/idxd/init.c
+++ b/drivers/dma/idxd/init.c
@@ -212,7 +212,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
 		rc = dev_set_name(conf_dev, "wq%d.%d", idxd->id, wq->id);
 		if (rc < 0) {
 			put_device(conf_dev);
-			kfree(wq);
+
 			goto err_unwind;
 		}
 
@@ -226,7 +226,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
 		wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev));
 		if (!wq->wqcfg) {
 			put_device(conf_dev);
-			kfree(wq);
+
 			rc = -ENOMEM;
 			goto err_unwind;
 		}
@@ -234,9 +234,9 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
 		if (idxd->hw.wq_cap.op_config) {
 			wq->opcap_bmap = bitmap_zalloc(IDXD_MAX_OPCAP_BITS, GFP_KERNEL);
 			if (!wq->opcap_bmap) {
-				kfree(wq->wqcfg);
+
 				put_device(conf_dev);
-				kfree(wq);
+
 				rc = -ENOMEM;
 				goto err_unwind;
 			}
@@ -252,12 +252,10 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
 err_unwind:
 	while (--i >= 0) {
 		wq = idxd->wqs[i];
-		if (idxd->hw.wq_cap.op_config)
-			bitmap_free(wq->opcap_bmap);
-		kfree(wq->wqcfg);
+
 		conf_dev = wq_confdev(wq);
 		put_device(conf_dev);
-		kfree(wq);
+
 	}
 	bitmap_free(idxd->wq_enable_map);
 
-- 
2.43.0