[PATCH v2] firmware/sysfb: Fix device reference count leak in sysfb_disable()

From: Wentao Liang

Date: Sat Nov 07 2026 - 12:02:27 EST


sysfb_parent_dev() returns a pointer to &pdev->dev with an acquired
reference when it finds the PCI device that contains the system
framebuffer. sysfb_disable() never drops that reference, so a reference
to the PCI device is leaked on every call that resolves a parent.

Release the reference with put_device() before leaving the critical
section.

If the parent device cannot be determined, unregister the system
framebuffer unconditionally, as it might still belong to the calling
device. Leaving sysfb registered in that case can make it interfere
with the native driver.

Fixes: b49420d6a1ae ("video/aperture: optionally match the device in sysfb_disable()")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
Changes in v2:
- Sorry for the late reply.
- Unregister the system framebuffer when the parent device lookup fails,
as pointed out by Alex Deucher and Thomas Zimmermann.

Disclosure: the candidate was found with our static analysis tooling, and
the audit and the fix were assisted by DeepSeek and GPT 6.1 sol.
---
drivers/firmware/sysfb.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c
index 8833582c1883..4cd6e9f86962 100644
--- a/drivers/firmware/sysfb.c
+++ b/drivers/firmware/sysfb.c
@@ -71,10 +71,20 @@ void sysfb_disable(struct device *dev)

mutex_lock(&disable_lock);
parent = sysfb_parent_dev(si);
- if (!dev || !parent || dev == parent) {
+
+ /*
+ * If the parent device cannot be determined, unregister the system
+ * framebuffer unconditionally. It might belong to the calling device
+ * and would otherwise interfere with the native driver.
+ */
+ if (IS_ERR_OR_NULL(parent) || !dev || dev == parent) {
sysfb_unregister();
disabled = true;
}
+
+ if (!IS_ERR(parent))
+ put_device(parent);
+
mutex_unlock(&disable_lock);
}
EXPORT_SYMBOL_GPL(sysfb_disable);
--
2.34.1