The documentation for device_get_named_child_node() mentions this
important point:
"
The caller is responsible for calling fwnode_handle_put() on the
returned fwnode pointer.
"
Add fwnode_handle_put() to avoid leaked references.
Fixes: 1e264f9d2918 ("net: dsa: qca8k: add LEDs basic support")
Signed-off-by: Andy Shevchenko <[email protected]>
---
drivers/net/dsa/qca/qca8k-leds.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dsa/qca/qca8k-leds.c b/drivers/net/dsa/qca/qca8k-leds.c
index 811ebeeff4ed..ef529615237c 100644
--- a/drivers/net/dsa/qca/qca8k-leds.c
+++ b/drivers/net/dsa/qca/qca8k-leds.c
@@ -431,8 +431,10 @@ qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int p
init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d",
priv->internal_mdio_bus->id,
port_num);
- if (!init_data.devicename)
+ if (!init_data.devicename) {
+ fwnode_handle_put(leds);
return -ENOMEM;
+ }
ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data);
if (ret)
@@ -441,6 +443,7 @@ qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int p
kfree(init_data.devicename);
}
+ fwnode_handle_put(leds);
return 0;
}
@@ -471,9 +474,13 @@ qca8k_setup_led_ctrl(struct qca8k_priv *priv)
* the correct port for LED setup.
*/
ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num));
- if (ret)
+ if (ret) {
+ fwnode_handle_put(port);
+ fwnode_handle_put(ports);
return ret;
+ }
}
+ fwnode_handle_put(ports);
return 0;
}
--
2.43.0.rc1.1336.g36b5255a03ac
On Tue, Jun 04, 2024 at 07:15:51PM +0300, Andy Shevchenko wrote:
> The documentation for device_get_named_child_node() mentions this
> important point:
>
> "
> The caller is responsible for calling fwnode_handle_put() on the
> returned fwnode pointer.
> "
>
> Add fwnode_handle_put() to avoid leaked references.
>
> Fixes: 1e264f9d2918 ("net: dsa: qca8k: add LEDs basic support")
> Signed-off-by: Andy Shevchenko <[email protected]>
Reviewed-by: Simon Horman <[email protected]>
On Tue, 4 Jun 2024 19:15:51 +0300 Andy Shevchenko wrote:
> @@ -431,8 +431,10 @@ qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int p
> init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d",
> priv->internal_mdio_bus->id,
> port_num);
> - if (!init_data.devicename)
> + if (!init_data.devicename) {
> + fwnode_handle_put(leds);
> return -ENOMEM;
> + }
>
> ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data);
> if (ret)
I think there's more bugs in this here loop, if we break or return
during fwnode_for_each_child_node() - we need to put the iterator (led).