[PATCH v7 1/3] hwmon: emc2305: Fix fan channel index handling

florin.leotescu
2026-04-29T06:45:17Z

From: Florin Leotescu <florin.leotescu@nxp.com>

The fan channel index is used to access per-channel data structures.
Validate the index against the number of available channels
before use to prevent out-of-bounds access if an invalid
value is provided.

The thermal registration path currently uses a sequential child index,
which may not match the validated channel from DT. Use the DT "reg"
property when registering cooling devices to ensure consistent
channel handling

Signed-off-by: Florin Leotescu <florin.leotescu@nxp.com>
---
drivers/hwmon/emc2305.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/hwmon/emc2305.c b/drivers/hwmon/emc2305.c
index 64b213e1451e..f71a0e265924 100644
--- a/drivers/hwmon/emc2305.c
+++ b/drivers/hwmon/emc2305.c
@@ -548,6 +548,12 @@ static int emc2305_of_parse_pwm_child(struct device *dev,
return ret;
}

+ if (ch >= data->pwm_num) {
+ dev_err(dev, "invalid reg %u for node %pOF (valid range 0-%u)\n", ch, child,
+ data->pwm_num - 1);
+ return -EINVAL;
+ }
+
ret = of_parse_phandle_with_args(child, "pwms", "#pwm-cells", 0, &args);

if (ret)
@@ -612,6 +618,7 @@ static int emc2305_probe(struct i2c_client *client)
int ret;
int i;
int pwm_childs;
+ u32 ch;

if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
return -ENODEV;
@@ -680,12 +687,18 @@ static int emc2305_probe(struct i2c_client *client)
if (IS_REACHABLE(CONFIG_THERMAL)) {
/* Parse and check for the available PWM child nodes */
if (pwm_childs > 0) {
- i = 0;
for_each_child_of_node_scoped(dev->of_node, child) {
- ret = emc2305_set_single_tz(dev, child, i);
+ ret = of_property_read_u32(child, "reg", &ch);
+ if (ret || ch >= data->pwm_num)
+ continue;
+
+ /*
+ * emc2305_set_single_tz() uses 0 for the common cooling
+ * device and 1..pwm_num for individual fan channels.
+ */
+ ret = emc2305_set_single_tz(dev, child, ch + 1);
if (ret != 0)
return ret;
- i++;
}
} else {
ret = emc2305_set_tz(dev);
--
2.34.1