mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
hwmon: (adt7470) Fix divide-by-zero TOCTOU crash in fan speed read
If the fan data becomes 0 between the FAN_DATA_VALID() check and the
FAN_PERIOD_TO_RPM() conversion, it will result in a divide-by-zero crash
due to a race with a concurrent update of the cached fan value.
Fix a TOCTOU issue by reading fan data once.
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/r/20260727034929.E29B71F000E9@smtp.kernel.org/
Fixes: fc958a61ff ("hwmon: (adt7470) Convert to devm_hwmon_device_register_with_info API")
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
Link: https://lore.kernel.org/r/20260727-adt7470_fixes-v2-7-598e38a46ba6@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
60677cd4c2
commit
1b46fe9dc8
|
|
@ -660,36 +660,33 @@ static ssize_t alarm_mask_store(struct device *dev,
|
|||
static int adt7470_fan_read(struct device *dev, u32 attr, int channel, long *val)
|
||||
{
|
||||
struct adt7470_data *data = adt7470_update_device(dev);
|
||||
u16 fan_data;
|
||||
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
switch (attr) {
|
||||
case hwmon_fan_input:
|
||||
if (FAN_DATA_VALID(data->fan[channel]))
|
||||
*val = FAN_PERIOD_TO_RPM(data->fan[channel]);
|
||||
else
|
||||
*val = 0;
|
||||
fan_data = READ_ONCE(data->fan[channel]);
|
||||
break;
|
||||
case hwmon_fan_min:
|
||||
if (FAN_DATA_VALID(data->fan_min[channel]))
|
||||
*val = FAN_PERIOD_TO_RPM(data->fan_min[channel]);
|
||||
else
|
||||
*val = 0;
|
||||
fan_data = READ_ONCE(data->fan_min[channel]);
|
||||
break;
|
||||
case hwmon_fan_max:
|
||||
if (FAN_DATA_VALID(data->fan_max[channel]))
|
||||
*val = FAN_PERIOD_TO_RPM(data->fan_max[channel]);
|
||||
else
|
||||
*val = 0;
|
||||
fan_data = READ_ONCE(data->fan_max[channel]);
|
||||
break;
|
||||
case hwmon_fan_alarm:
|
||||
*val = !!(data->alarm & FAN_ALARM_BIT(channel));
|
||||
break;
|
||||
return 0;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (FAN_DATA_VALID(fan_data))
|
||||
*val = FAN_PERIOD_TO_RPM(fan_data);
|
||||
else
|
||||
*val = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user