ktime_t overflow from sys_nanosleep
PATCH 1/1 ktime_t overflow from sys_nanosleep
On systems where longs are 64 bits, nanosleep can pass a timespec with tv_sec larger than 18446744073 (approx 2^34), which is then multiplied by NSEC_PER_SEC and stuffed into a single s64 by ktime_set in hrtimer_nanosleep. This overflows of course, and causes the sleep to return early (instantly if you set the timespec to its maximum).
(this gets triggered by doing a "sleep inf" with the sleep from the gnu coreutils).
I can think of two solutions, either increase the size of ktime_t to something larger than 64 bits, which would probably bring along a host of issues and and lose the entire point of having a single scalar, or we can limit the range of sys_nanosleep, which is simple, but will have to be documented and sleep(1) will still need fixing.
I've put the check in timespec_valid in the attached patch. This will limit the range of timespecs in general, but since most of them seem to end up as ktime_t's anyway, it seems like a reasonable precaution.
include/linux/time.h +5 -3
@@ -68,11 +68,13 @@ extern unsigned long mktime(const unsignextern void set_normalized_timespec (struct timespec *ts,time_t sec,long nsec);/* -* Returns true if the timespec is norm, false if denorm: +* Returns true iff the timespec nanoseconds is less than one second +* ("normalised") and the seconds is in the range 0..2**31: */ #define timespec_valid (ts) \ - (((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC)) - + (((ts)->tv_sec >= 0) && (((ts)->tv_sec) <= (~(1<<31))) && \ + (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC)) +extern struct timespec xtime;extern struct timespec wall_to_monotonic;extern seqlock_t xtime_lock;
Signature · 3 lines
Frank v Waveren Key fingerprint: BDD7 D61E [email protected] 5D39 CF05 4BFC F57A Public key: hkp://wwwkeys.pgp.net/468D62C8 FA00 7D51 468D 62C8