]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
hwmon: (adm1029) Add locking to avoid TOCTOU
authorGui-Dong Han <hanguidong02@gmail.com>
Wed, 26 Nov 2025 11:40:46 +0000 (19:40 +0800)
committerGuenter Roeck <linux@roeck-us.net>
Wed, 26 Nov 2025 15:48:31 +0000 (07:48 -0800)
The function fan_show checks shared data for zero or invalid values
before using 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.

Link: https://lore.kernel.org/all/CALbr=LYJ_ehtp53HXEVkSpYoub+XYSTU8Rg=o1xxMJ8=5z8B-g@mail.gmail.com/
Signed-off-by: Gui-Dong Han <hanguidong02@gmail.com>
Link: https://lore.kernel.org/r/20251126114047.10039-1-hanguidong02@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/adm1029.c

index 761c130924884965d926b8a451ac952c10513d00..71eea8ae51b95f5b30413edf8c65a51611178a14 100644 (file)
@@ -171,14 +171,17 @@ fan_show(struct device *dev, struct device_attribute *devattr, char *buf)
        struct adm1029_data *data = adm1029_update_device(dev);
        u16 val;
 
+       mutex_lock(&data->update_lock);
        if (data->fan[attr->index] == 0 ||
            (data->fan_div[attr->index] & 0xC0) == 0 ||
            data->fan[attr->index] == 255) {
+               mutex_unlock(&data->update_lock);
                return sprintf(buf, "0\n");
        }
 
        val = 1880 * 120 / DIV_FROM_REG(data->fan_div[attr->index])
            / data->fan[attr->index];
+       mutex_unlock(&data->update_lock);
        return sprintf(buf, "%d\n", val);
 }