mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
timekeeping: Force upper bound for setting CLOCK_REALTIME
Several people reported testing failures after setting CLOCK_REALTIME close to the limits of the kernel internal representation in nanoseconds, i.e. year 2262. The failures are exposed in subsequent operations, i.e. when arming timers or when the advancing CLOCK_MONOTONIC makes the calculation of CLOCK_REALTIME overflow into negative space. Now people start to paper over the underlying problem by clamping calculations to the valid range, but that's just wrong because such workarounds will prevent detection of real issues as well. It is reasonable to force an upper bound for the various methods of setting CLOCK_REALTIME. Year 2262 is the absolute upper bound. Assume a maximum uptime of 30 years which is plenty enough even for esoteric embedded systems. That results in an upper bound of year 2232 for setting the time. Once that limit is reached in reality this limit is only a small part of the problem space. But until then this stops people from trying to paper over the problem at the wrong places. Reported-by: Xiongfeng Wang <[email protected]> Reported-by: Hongbo Yao <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: John Stultz <[email protected]> Cc: Stephen Boyd <[email protected]> Cc: Miroslav Lichvar <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Richard Cochran <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
This commit is contained in:
parent
f28d3d5346
commit
7a8e61f847
3 changed files with 25 additions and 4 deletions
|
|
@ -171,7 +171,7 @@ int do_sys_settimeofday64(const struct timespec64 *tv, const struct timezone *tz
|
|||
static int firsttime = 1;
|
||||
int error = 0;
|
||||
|
||||
if (tv && !timespec64_valid(tv))
|
||||
if (tv && !timespec64_valid_settod(tv))
|
||||
return -EINVAL;
|
||||
|
||||
error = security_settime64(tv, tz);
|
||||
|
|
|
|||
|
|
@ -1221,7 +1221,7 @@ int do_settimeofday64(const struct timespec64 *ts)
|
|||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (!timespec64_valid_strict(ts))
|
||||
if (!timespec64_valid_settod(ts))
|
||||
return -EINVAL;
|
||||
|
||||
raw_spin_lock_irqsave(&timekeeper_lock, flags);
|
||||
|
|
@ -1278,7 +1278,7 @@ static int timekeeping_inject_offset(const struct timespec64 *ts)
|
|||
/* Make sure the proposed value is valid */
|
||||
tmp = timespec64_add(tk_xtime(tk), *ts);
|
||||
if (timespec64_compare(&tk->wall_to_monotonic, ts) > 0 ||
|
||||
!timespec64_valid_strict(&tmp)) {
|
||||
!timespec64_valid_settod(&tmp)) {
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -1527,7 +1527,7 @@ void __init timekeeping_init(void)
|
|||
unsigned long flags;
|
||||
|
||||
read_persistent_wall_and_boot_offset(&wall_time, &boot_offset);
|
||||
if (timespec64_valid_strict(&wall_time) &&
|
||||
if (timespec64_valid_settod(&wall_time) &&
|
||||
timespec64_to_ns(&wall_time) > 0) {
|
||||
persistent_clock_exists = true;
|
||||
} else if (timespec64_to_ns(&wall_time) != 0) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue