• David Engraf's avatar
    hrtimer: Fix ktime_add_ns() overflow on 32bit architectures · f931d5e4
    David Engraf authored
    commit 51fd36f3 upstream.
    
    One can trigger an overflow when using ktime_add_ns() on a 32bit
    architecture not supporting CONFIG_KTIME_SCALAR.
    
    When passing a very high value for u64 nsec, e.g. 7881299347898368000
    the do_div() function converts this value to seconds (7881299347) which
    is still to high to pass to the ktime_set() function as long. The result
    in is a negative value.
    
    The problem on my system occurs in the tick-sched.c,
    tick_nohz_stop_sched_tick() when time_delta is set to
    timekeeping_max_deferment(). The check for time_delta < KTIME_MAX is
    valid, thus ktime_add_ns() is called with a too large value resulting in
    a negative expire value. This leads to an endless loop in the ticker code:
    
    time_delta: 7881299347898368000
    expires = ktime_add_ns(last_update, time_delta)
    expires: negative value
    
    This fix caps the value to KTIME_MAX.
    
    This error doesn't occurs on 64bit or architectures supporting
    CONFIG_KTIME_SCALAR (e.g. ARM, x86-32).
    Signed-off-by: default avatarDavid Engraf <david.engraf@sysgo.com>
    [jstultz: Minor tweaks to commit message & header]
    Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    f931d5e4
hrtimer.c 47.2 KB