[PATCH] drm/vc4: Fix firmware reference leak in vc4_hvs_bind()
From: Wentao Liang
Date: Fri Nov 06 2026 - 04:23:46 EST
The firmware reference taken via rpi_firmware_get() is leaked when
either of the devm_clk_get() calls for the core or display clocks
fails, as both error paths return without releasing it.
Fix it by moving the firmware lookup below the clock lookups, so that
the reference is taken right before the firmware property is read and
released immediately afterwards. The rpi_firmware_find_node() call
moves with it: the device node reference it returns would otherwise be
leaked by those same error paths.
The candidate was found by our static analysis tooling, and this change
was prepared with assistance from DeepSeek-V4.1-Flash and GPT-6.1-Sol.
Fixes: 2a001ca00ad5 ("drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection code")
Cc: stable@xxxxxxxxxxxxxxx
Suggested-by: Maíra Canal <mcanal@xxxxxxxxxx>
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
Changes in v2:
- Sorry for the very late reply, and thanks for the review.
- Move the firmware and device node lookups below the clock lookups
instead of adding rpi_firmware_put() to the two error paths, as
suggested by Maíra.
- Link to v1: https://lore.kernel.org/all/20260916154137.2058618-1-vulab@xxxxxxxxxxx/
---
drivers/gpu/drm/vc4/vc4_hvs.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index b1fb096858cc..537aaa992129 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -1677,15 +1677,6 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
struct device_node *node;
unsigned int max_rate;
- node = rpi_firmware_find_node();
- if (!node)
- return -EINVAL;
-
- firmware = rpi_firmware_get(node);
- of_node_put(node);
- if (!firmware)
- return -EPROBE_DEFER;
-
hvs->core_clk = devm_clk_get(&pdev->dev,
(vc4->gen >= VC4_GEN_6_C) ? "core" : NULL);
if (IS_ERR(hvs->core_clk)) {
@@ -1700,6 +1691,15 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
return PTR_ERR(hvs->disp_clk);
}
+ node = rpi_firmware_find_node();
+ if (!node)
+ return -EINVAL;
+
+ firmware = rpi_firmware_get(node);
+ of_node_put(node);
+ if (!firmware)
+ return -EPROBE_DEFER;
+
max_rate = rpi_firmware_clk_get_max_rate(firmware,
RPI_FIRMWARE_CORE_CLK_ID);
rpi_firmware_put(firmware);
--
2.34.1