Module Name: src Committed By: riastradh Date: Sun May 15 16:20:10 UTC 2022
Modified Files: src/sys/kern: kern_time.c Log Message: adjtime(2): Handle negative tv_sec and tv_usec. Previously I clamped these to avoid dangerous arithmetic overflow. But I assumed sensible values should be nonnegative. For tv_sec, this assumption was just wrong -- the adjustment may be negative. For tv_usec, this assumption is...not wrong, but also not right. tv_usec is not _supposed_ to be negative (by POSIX, the type need only represent values in [-1, 1000000]; semantically the member is supposed to be a nonnegative number of microseconds below 1000000), but ntp abuses it to hold negative values, for reasons unclear -- the same effect could be had by subtracting one from tv_sec, and adding 1000000 to the negative tv_usec. However, let's not break existing ntp userlands... To generate a diff of this commit: cvs rdiff -u -r1.213 -r1.214 src/sys/kern/kern_time.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_time.c diff -u src/sys/kern/kern_time.c:1.213 src/sys/kern/kern_time.c:1.214 --- src/sys/kern/kern_time.c:1.213 Sun Mar 13 12:21:28 2022 +++ src/sys/kern/kern_time.c Sun May 15 16:20:10 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_time.c,v 1.213 2022/03/13 12:21:28 riastradh Exp $ */ +/* $NetBSD: kern_time.c,v 1.214 2022/05/15 16:20:10 riastradh Exp $ */ /*- * Copyright (c) 2000, 2004, 2005, 2007, 2008, 2009, 2020 @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.213 2022/03/13 12:21:28 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.214 2022/05/15 16:20:10 riastradh Exp $"); #include <sys/param.h> #include <sys/resourcevar.h> @@ -625,9 +625,11 @@ adjtime1(const struct timeval *delta, st */ if (delta->tv_sec > INT64_MAX/1000000 - 1) { time_adjtime = INT64_MAX; + } else if (delta->tv_sec < INT64_MIN/1000000 + 1) { + time_adjtime = INT64_MIN; } else { - time_adjtime = MAX(0, delta->tv_sec) * 1000000 - + MAX(0, MIN(999999, delta->tv_usec)); + time_adjtime = delta->tv_sec * 1000000 + + MAX(-999999, MIN(999999, delta->tv_usec)); } if (time_adjtime) {