Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

hwmon: (gl520sm) Fix overflows and crash seen when writing into limit attributes

Writes into limit attributes can overflow due to multplications and
additions with unbound input values. Writing into fan limit attributes
can result in a crash with a division by zero if very large values are
written and the fan divider is larger than 1.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>

+16 -9
+16 -9
drivers/hwmon/gl520sm.c
··· 208 208 } 209 209 static DEVICE_ATTR_RO(cpu0_vid); 210 210 211 - #define VDD_FROM_REG(val) (((val) * 95 + 2) / 4) 212 - #define VDD_TO_REG(val) clamp_val((((val) * 4 + 47) / 95), 0, 255) 211 + #define VDD_FROM_REG(val) DIV_ROUND_CLOSEST((val) * 95, 4) 212 + #define VDD_CLAMP(val) clamp_val(val, 0, 255 * 95 / 4) 213 + #define VDD_TO_REG(val) DIV_ROUND_CLOSEST(VDD_CLAMP(val) * 4, 95) 213 214 214 - #define IN_FROM_REG(val) ((val) * 19) 215 - #define IN_TO_REG(val) clamp_val((((val) + 9) / 19), 0, 255) 215 + #define IN_FROM_REG(val) ((val) * 19) 216 + #define IN_CLAMP(val) clamp_val(val, 0, 255 * 19) 217 + #define IN_TO_REG(val) DIV_ROUND_CLOSEST(IN_CLAMP(val), 19) 216 218 217 219 static ssize_t get_in_input(struct device *dev, struct device_attribute *attr, 218 220 char *buf) ··· 351 349 352 350 #define DIV_FROM_REG(val) (1 << (val)) 353 351 #define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : (480000 / ((val) << (div)))) 354 - #define FAN_TO_REG(val, div) ((val) <= 0 ? 0 : \ 355 - clamp_val((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255)) 352 + 353 + #define FAN_BASE(div) (480000 >> (div)) 354 + #define FAN_CLAMP(val, div) clamp_val(val, FAN_BASE(div) / 255, \ 355 + FAN_BASE(div)) 356 + #define FAN_TO_REG(val, div) ((val) == 0 ? 0 : \ 357 + DIV_ROUND_CLOSEST(480000, \ 358 + FAN_CLAMP(val, div) << (div))) 356 359 357 360 static ssize_t get_fan_input(struct device *dev, struct device_attribute *attr, 358 361 char *buf) ··· 520 513 get_fan_div, set_fan_div, 1); 521 514 static DEVICE_ATTR_RW(fan1_off); 522 515 523 - #define TEMP_FROM_REG(val) (((val) - 130) * 1000) 524 - #define TEMP_TO_REG(val) clamp_val(((((val) < 0 ? \ 525 - (val) - 500 : (val) + 500) / 1000) + 130), 0, 255) 516 + #define TEMP_FROM_REG(val) (((val) - 130) * 1000) 517 + #define TEMP_CLAMP(val) clamp_val(val, -130000, 125000) 518 + #define TEMP_TO_REG(val) (DIV_ROUND_CLOSEST(TEMP_CLAMP(val), 1000) + 130) 526 519 527 520 static ssize_t get_temp_input(struct device *dev, struct device_attribute *attr, 528 521 char *buf)