]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
intel_th: Fix error handling in intel_th_output_open
authorMa Ke <make24@iscas.ac.cn>
Wed, 12 Nov 2025 09:17:23 +0000 (17:17 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 Jan 2026 11:57:14 +0000 (12:57 +0100)
commit 6d5925b667e4ed9e77c8278cc215191d29454a3f upstream.

intel_th_output_open() calls bus_find_device_by_devt() which
internally increments the device reference count via get_device(), but
this reference is not properly released in several error paths. When
device driver is unavailable, file operations cannot be obtained, or
the driver's open method fails, the function returns without calling
put_device(), leading to a permanent device reference count leak. This
prevents the device from being properly released and could cause
resource exhaustion over time.

Found by code review.

Cc: stable <stable@kernel.org>
Fixes: 39f4034693b7 ("intel_th: Add driver infrastructure for Intel(R) Trace Hub devices")
Signed-off-by: Ma Ke <make24@iscas.ac.cn>
Link: https://patch.msgid.link/20251112091723.35963-1-make24@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/hwtracing/intel_th/core.c

index 47d9e6c3bac0415336d3293494e58307ef9a27a7..fdb9d022d8753faf7fc7b005187ee9aec34a65ef 100644 (file)
@@ -810,13 +810,17 @@ static int intel_th_output_open(struct inode *inode, struct file *file)
        int err;
 
        dev = bus_find_device_by_devt(&intel_th_bus, inode->i_rdev);
-       if (!dev || !dev->driver)
-               return -ENODEV;
+       if (!dev || !dev->driver) {
+               err = -ENODEV;
+               goto out_no_device;
+       }
 
        thdrv = to_intel_th_driver(dev->driver);
        fops = fops_get(thdrv->fops);
-       if (!fops)
-               return -ENODEV;
+       if (!fops) {
+               err = -ENODEV;
+               goto out_put_device;
+       }
 
        replace_fops(file, fops);
 
@@ -824,10 +828,16 @@ static int intel_th_output_open(struct inode *inode, struct file *file)
 
        if (file->f_op->open) {
                err = file->f_op->open(inode, file);
-               return err;
+               if (err)
+                       goto out_put_device;
        }
 
        return 0;
+
+out_put_device:
+       put_device(dev);
+out_no_device:
+       return err;
 }
 
 static const struct file_operations intel_th_output_fops = {