]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
dmaengine: idxd: fix device leaks on compat bind and unbind
authorJohan Hovold <johan@kernel.org>
Mon, 17 Nov 2025 16:12:48 +0000 (17:12 +0100)
committerVinod Koul <vkoul@kernel.org>
Sun, 14 Dec 2025 09:17:24 +0000 (14:47 +0530)
Make sure to drop the reference taken when looking up the idxd device as
part of the compat bind and unbind sysfs interface.

Fixes: 6e7f3ee97bbe ("dmaengine: idxd: move dsa_drv support to compatible mode")
Cc: stable@vger.kernel.org # 5.15
Cc: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20251117161258.10679-7-johan@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/dma/idxd/compat.c

index eff9943f1a42e2f7b1cc41fc1546b6973513bc62..95b8ef95863386cf7fb3a56aaae6530138398e70 100644 (file)
@@ -20,11 +20,16 @@ static ssize_t unbind_store(struct device_driver *drv, const char *buf, size_t c
        int rc = -ENODEV;
 
        dev = bus_find_device_by_name(bus, NULL, buf);
-       if (dev && dev->driver) {
+       if (!dev)
+               return -ENODEV;
+
+       if (dev->driver) {
                device_driver_detach(dev);
                rc = count;
        }
 
+       put_device(dev);
+
        return rc;
 }
 static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, 0200, NULL, unbind_store);
@@ -38,9 +43,12 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t cou
        struct idxd_dev *idxd_dev;
 
        dev = bus_find_device_by_name(bus, NULL, buf);
-       if (!dev || dev->driver || drv != &dsa_drv.drv)
+       if (!dev)
                return -ENODEV;
 
+       if (dev->driver || drv != &dsa_drv.drv)
+               goto err_put_dev;
+
        idxd_dev = confdev_to_idxd_dev(dev);
        if (is_idxd_dev(idxd_dev)) {
                alt_drv = driver_find("idxd", bus);
@@ -53,13 +61,20 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t cou
                        alt_drv = driver_find("user", bus);
        }
        if (!alt_drv)
-               return -ENODEV;
+               goto err_put_dev;
 
        rc = device_driver_attach(alt_drv, dev);
        if (rc < 0)
-               return rc;
+               goto err_put_dev;
+
+       put_device(dev);
 
        return count;
+
+err_put_dev:
+       put_device(dev);
+
+       return rc;
 }
 static DRIVER_ATTR_IGNORE_LOCKDEP(bind, 0200, NULL, bind_store);