In sysfb_disable(), parent is obtained via sysfb_parent_dev(si), which
calls screen_info_pci_dev(si) and returns a pointer to &pdev->dev with
an acquired reference count. However, sysfb_disable() does not release
this reference before returning, leading to a device reference leak.

Fix this by checking if parent is not an ERR_PTR and calling
put_device(parent) before releasing the mutex.

Fixes: b49420d6a1ae ("video/aperture: optionally match the device in 
sysfb_disable()")
Cc: [email protected]
Signed-off-by: Wentao Liang <[email protected]>
---
 drivers/firmware/sysfb.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c
index 8833582c1883..11c5ce128a6c 100644
--- a/drivers/firmware/sysfb.c
+++ b/drivers/firmware/sysfb.c
@@ -71,9 +71,12 @@ void sysfb_disable(struct device *dev)
 
        mutex_lock(&disable_lock);
        parent = sysfb_parent_dev(si);
-       if (!dev || !parent || dev == parent) {
-               sysfb_unregister();
-               disabled = true;
+       if (!IS_ERR(parent)) {
+               if (!dev || !parent || dev == parent) {
+                       sysfb_unregister();
+                       disabled = true;
+               }
+               put_device(parent);
        }
        mutex_unlock(&disable_lock);
 }
-- 
2.34.1

Reply via email to