drivers/hwmon/max6620.c | 4 ++++ 1 file changed, 4 insertions(+)
The function max6620_read checks shared data (tach and target) for zero
before passing it to max6620_fan_tach_to_rpm, which uses it as a divisor.
These accesses are currently lockless. If the data changes to zero
between the check and the division, it causes a divide-by-zero error.
Explicitly acquire the update lock around these checks and calculations
to ensure the data remains stable, preventing Time-of-Check to
Time-of-Use (TOCTOU) race conditions.
This change also aligns the locking behavior with the hwmon_fan_alarm
case, which already uses the update lock.
Link: https://lore.kernel.org/all/CALbr=LYJ_ehtp53HXEVkSpYoub+XYSTU8Rg=o1xxMJ8=5z8B-g@mail.gmail.com/
Fixes: e8ac01e5db32 ("hwmon: Add Maxim MAX6620 hardware monitoring driver")
Cc: stable@vger.kernel.org
Signed-off-by: Gui-Dong Han <hanguidong02@gmail.com>
---
Based on the discussion in the link, I will submit a series of patches to
address TOCTOU issues in the hwmon subsystem by converting macros to
functions or adjusting locking where appropriate.
---
drivers/hwmon/max6620.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/hwmon/max6620.c b/drivers/hwmon/max6620.c
index 13201fb755c9..0dce2f5cb61b 100644
--- a/drivers/hwmon/max6620.c
+++ b/drivers/hwmon/max6620.c
@@ -290,20 +290,24 @@ max6620_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
*val = max6620_fan_div_from_reg(data->fandyn[channel]);
break;
case hwmon_fan_input:
+ mutex_lock(&data->update_lock);
if (data->tach[channel] == 0) {
*val = 0;
} else {
div = max6620_fan_div_from_reg(data->fandyn[channel]);
*val = max6620_fan_tach_to_rpm(div, data->tach[channel]);
}
+ mutex_unlock(&data->update_lock);
break;
case hwmon_fan_target:
+ mutex_lock(&data->update_lock);
if (data->target[channel] == 0) {
*val = 0;
} else {
div = max6620_fan_div_from_reg(data->fandyn[channel]);
*val = max6620_fan_tach_to_rpm(div, data->target[channel]);
}
+ mutex_unlock(&data->update_lock);
break;
default:
return -EOPNOTSUPP;
--
2.43.0
On Fri, Nov 28, 2025 at 08:43:51PM +0800, Gui-Dong Han wrote:
> The function max6620_read checks shared data (tach and target) for zero
> before passing it to max6620_fan_tach_to_rpm, which uses it as a divisor.
> These accesses are currently lockless. If the data changes to zero
> between the check and the division, it causes a divide-by-zero error.
>
> Explicitly acquire the update lock around these checks and calculations
> to ensure the data remains stable, preventing Time-of-Check to
> Time-of-Use (TOCTOU) race conditions.
>
> This change also aligns the locking behavior with the hwmon_fan_alarm
> case, which already uses the update lock.
>
> Link: https://lore.kernel.org/all/CALbr=LYJ_ehtp53HXEVkSpYoub+XYSTU8Rg=o1xxMJ8=5z8B-g@mail.gmail.com/
> Fixes: e8ac01e5db32 ("hwmon: Add Maxim MAX6620 hardware monitoring driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Gui-Dong Han <hanguidong02@gmail.com>
> ---
> Based on the discussion in the link, I will submit a series of patches to
> address TOCTOU issues in the hwmon subsystem by converting macros to
> functions or adjusting locking where appropriate.
This patch is not necessary. The driver registers with the hwmon subsystem
using devm_hwmon_device_register_with_info(). That means the hwmon subsystem
handles the necessary locking. On top of that, removing the existing driver
internal locking code is queued for v6.19.
Thanks,
Guenter
On Sat, Nov 29, 2025 at 12:34 AM Guenter Roeck <linux@roeck-us.net> wrote:
>
> On Fri, Nov 28, 2025 at 08:43:51PM +0800, Gui-Dong Han wrote:
> > The function max6620_read checks shared data (tach and target) for zero
> > before passing it to max6620_fan_tach_to_rpm, which uses it as a divisor.
> > These accesses are currently lockless. If the data changes to zero
> > between the check and the division, it causes a divide-by-zero error.
> >
> > Explicitly acquire the update lock around these checks and calculations
> > to ensure the data remains stable, preventing Time-of-Check to
> > Time-of-Use (TOCTOU) race conditions.
> >
> > This change also aligns the locking behavior with the hwmon_fan_alarm
> > case, which already uses the update lock.
> >
> > Link: https://lore.kernel.org/all/CALbr=LYJ_ehtp53HXEVkSpYoub+XYSTU8Rg=o1xxMJ8=5z8B-g@mail.gmail.com/
> > Fixes: e8ac01e5db32 ("hwmon: Add Maxim MAX6620 hardware monitoring driver")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Gui-Dong Han <hanguidong02@gmail.com>
> > ---
> > Based on the discussion in the link, I will submit a series of patches to
> > address TOCTOU issues in the hwmon subsystem by converting macros to
> > functions or adjusting locking where appropriate.
>
> This patch is not necessary. The driver registers with the hwmon subsystem
> using devm_hwmon_device_register_with_info(). That means the hwmon subsystem
> handles the necessary locking. On top of that, removing the existing driver
> internal locking code is queued for v6.19.
Hi Guenter,
Thanks for the information. I missed the new hwmon subsystem locking
implementation earlier as it wasn't present in v6.17.9. I have since
studied the code in v6.18-rc, and it looks like an excellent
improvement. I will focus exclusively on drivers not using
devm_hwmon_device_register_with_info() going forward.
In our previous discussion, you also suggested adding a note to
submitting-patches.rst about "avoiding calculations in macros" to
explicitly explain the risk of race conditions. Is this something you
would still like to see added? If so, I would be happy to prepare a
patch.
Best regards,
Gui-Dong Han
On Sat, 29 Nov 2025 01:59:51 +0800 Gui-Dong Han <hanguidong02@gmail.com> wrote: ... > In our previous discussion, you also suggested adding a note to > submitting-patches.rst about "avoiding calculations in macros" to > explicitly explain the risk of race conditions. Is this something you > would still like to see added? If so, I would be happy to prepare a > patch. The real problem with #defines evaluating their parameters more than once is just side effects of the expansion. Even if the current users just pass a simple variable, you never really know what is going to happen in the future. There is also a secondary issue of pre-processor output 'bloat'. This happens when large #define expansions get nested. With the current headers FIELD_PREP(GENMASK(8, 5), val) expands to about 18kB [1] (even though it is just (val >> 5) & 15). I think one of your #defines get passed one of those - and then expands it several times. As well as the massive line, the compiler may well generate the code multiple times. (CSE will normally stop foo->bar[x] being executed multiple times). [1] Nothing like the 30MB that triple nested min() generated for a while. David
On 11/28/25 09:59, Gui-Dong Han wrote:
> On Sat, Nov 29, 2025 at 12:34 AM Guenter Roeck <linux@roeck-us.net> wrote:
>>
>> On Fri, Nov 28, 2025 at 08:43:51PM +0800, Gui-Dong Han wrote:
>>> The function max6620_read checks shared data (tach and target) for zero
>>> before passing it to max6620_fan_tach_to_rpm, which uses it as a divisor.
>>> These accesses are currently lockless. If the data changes to zero
>>> between the check and the division, it causes a divide-by-zero error.
>>>
>>> Explicitly acquire the update lock around these checks and calculations
>>> to ensure the data remains stable, preventing Time-of-Check to
>>> Time-of-Use (TOCTOU) race conditions.
>>>
>>> This change also aligns the locking behavior with the hwmon_fan_alarm
>>> case, which already uses the update lock.
>>>
>>> Link: https://lore.kernel.org/all/CALbr=LYJ_ehtp53HXEVkSpYoub+XYSTU8Rg=o1xxMJ8=5z8B-g@mail.gmail.com/
>>> Fixes: e8ac01e5db32 ("hwmon: Add Maxim MAX6620 hardware monitoring driver")
>>> Cc: stable@vger.kernel.org
>>> Signed-off-by: Gui-Dong Han <hanguidong02@gmail.com>
>>> ---
>>> Based on the discussion in the link, I will submit a series of patches to
>>> address TOCTOU issues in the hwmon subsystem by converting macros to
>>> functions or adjusting locking where appropriate.
>>
>> This patch is not necessary. The driver registers with the hwmon subsystem
>> using devm_hwmon_device_register_with_info(). That means the hwmon subsystem
>> handles the necessary locking. On top of that, removing the existing driver
>> internal locking code is queued for v6.19.
>
> Hi Guenter,
>
> Thanks for the information. I missed the new hwmon subsystem locking
> implementation earlier as it wasn't present in v6.17.9. I have since
> studied the code in v6.18-rc, and it looks like an excellent
> improvement. I will focus exclusively on drivers not using
> devm_hwmon_device_register_with_info() going forward.
>
> In our previous discussion, you also suggested adding a note to
> submitting-patches.rst about "avoiding calculations in macros" to
> explicitly explain the risk of race conditions. Is this something you
> would still like to see added? If so, I would be happy to prepare a
> patch.
>
Yes, that would be great. Thanks!
Guenter
© 2016 - 2025 Red Hat, Inc.