per discussion with theo use LLONG_* since time_t is 64 bit on every
sane OS ;)
while we only send offsets and not absolute timestamps here that isn't
super important, but if I boot a machine after 2038 that comes up with
time=0 the settime call should still succeed imo. on legacy systems
with 32 bit time_t the bounds check shall be adjusted in portable, and
even if it is not the consequences aren't dramatic.
otto's isfinite() check added as well.
ok?
Index: ntpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntpd.c,v
diff -u -p -r1.142 ntpd.c
--- ntpd.c 21 Nov 2024 13:38:14 -0000 1.142
+++ ntpd.c 18 Aug 2025 12:05:47 -0000
@@ -410,6 +410,8 @@ dispatch_imsg(struct ntpd_conf *lconf, i
fatalx("invalid IMSG_ADJTIME received");
memcpy(&d, imsg.data, sizeof(d));
n = ntpd_adjtime(d);
+ if (n == -1)
+ fatalx("IMSG_ADJTIME with invalid value");
imsg_compose(ibuf, IMSG_ADJTIME, 0, 0, -1,
&n, sizeof(n));
break;
@@ -474,7 +476,8 @@ ntpd_adjtime(double d)
log_info("adjusting local clock by %fs", d);
else
log_debug("adjusting local clock by %fs", d);
- d_to_tv(d, &tv);
+ if (d_to_tv(d, &tv) == -1)
+ return (-1);
if (adjtime(&tv, &olddelta) == -1)
log_warn("adjtime failed");
else if (!firstadj && olddelta.tv_sec == 0 && olddelta.tv_usec == 0)
@@ -532,7 +535,10 @@ ntpd_settime(double d)
log_warn("gettimeofday");
return;
}
- d_to_tv(d, &tv);
+ if (d_to_tv(d, &tv) == -1) {
+ log_warn("ntpd_settime: invalid value");
+ return;
+ }
curtime.tv_usec += tv.tv_usec + 1000000;
curtime.tv_sec += tv.tv_sec - 1 + (curtime.tv_usec / 1000000);
curtime.tv_usec %= 1000000;
Index: ntpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntpd.h,v
diff -u -p -r1.154 ntpd.h
--- ntpd.h 21 May 2024 05:00:48 -0000 1.154
+++ ntpd.h 18 Aug 2025 12:05:47 -0000
@@ -399,7 +399,7 @@ double gettime_from_timeval(struct ti
double getoffset(void);
double gettime(void);
time_t getmonotime(void);
-void d_to_tv(double, struct timeval *);
+int d_to_tv(double, struct timeval *);
double lfp_to_d(struct l_fixedpt);
struct l_fixedpt d_to_lfp(double);
double sfp_to_d(struct s_fixedpt);
Index: util.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/util.c,v
diff -u -p -r1.28 util.c
--- util.c 20 Dec 2023 15:36:36 -0000 1.28
+++ util.c 18 Aug 2025 12:05:47 -0000
@@ -18,6 +18,7 @@
#include <fcntl.h>
#include <limits.h>
+#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -73,15 +74,21 @@ getmonotime(void)
}
-void
+int
d_to_tv(double d, struct timeval *tv)
{
+ /* this assumes a 64 bit time_t */
+ if (!isfinite(d) || d > (double)LLONG_MAX || d < (double)LLONG_MIN)
+ return (-1);
+
tv->tv_sec = d;
tv->tv_usec = (d - tv->tv_sec) * 1000000;
while (tv->tv_usec < 0) {
tv->tv_usec += 1000000;
tv->tv_sec -= 1;
}
+
+ return (0);
}
double
--
Henning Brauer, [email protected], [email protected]
BS Web Services GmbH, http://bsws.de, Full-Service ISP
Secure Hosting, Mail and DNS. Virtual & Dedicated Servers, Root to Fully Managed
Henning Brauer Consulting, http://henningbrauer.com/