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

clocksource/drivers/arm_global_timer: Guard against division by zero

The result of the division of new_rate by gt_target_rate can be zero (if
new_rate is smaller than gt_target_rate). Using that result as divisor
without checking can result in a division by zero error. Guard against
this by checking for a zero value earlier.
While here, also change the psv variable to an unsigned long to make
sure we don't overflow the datatype as all other types involved are also
unsiged long.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20240225151336.2728533-3-martin.blumenstingl@googlemail.com

authored by

Martin Blumenstingl and committed by
Daniel Lezcano
e651f2fa f31c2048

+5 -6
+5 -6
drivers/clocksource/arm_global_timer.c
··· 291 291 switch (event) { 292 292 case PRE_RATE_CHANGE: 293 293 { 294 - int psv; 294 + unsigned long psv; 295 295 296 - psv = DIV_ROUND_CLOSEST(ndata->new_rate, 297 - gt_target_rate); 298 - 299 - if (abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR) 296 + psv = DIV_ROUND_CLOSEST(ndata->new_rate, gt_target_rate); 297 + if (!psv || 298 + abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR) 300 299 return NOTIFY_BAD; 301 300 302 301 psv--; 303 302 304 303 /* prescaler within legal range? */ 305 - if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX) 304 + if (psv > GT_CONTROL_PRESCALER_MAX) 306 305 return NOTIFY_BAD; 307 306 308 307 /*