From fd599d8f540d25c542f9110395de42e144055a65 Mon Sep 17 00:00:00 2001 From: henning Date: Wed, 20 Aug 2025 10:40:21 +0000 Subject: [PATCH] give d_to_tv(), which converts an offset from double to a struct timeval, a return value, and make the callers in IMSG_ADJTIME and IMSG_SETTIME handlers use it to abort if it signals error. range-check the double value in d_to_tv. reported by Shibo, Shawn, Hugo Systopia Team / sai02 at student.ubc.ca discussed with and input from deraadt and otto, ok otto --- usr.sbin/ntpd/ntpd.c | 12 +++++++++--- usr.sbin/ntpd/ntpd.h | 4 ++-- usr.sbin/ntpd/util.c | 11 +++++++++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/usr.sbin/ntpd/ntpd.c b/usr.sbin/ntpd/ntpd.c index ed10c7f1806..8106e5fc43f 100644 --- a/usr.sbin/ntpd/ntpd.c +++ b/usr.sbin/ntpd/ntpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntpd.c,v 1.142 2024/11/21 13:38:14 claudio Exp $ */ +/* $OpenBSD: ntpd.c,v 1.143 2025/08/20 10:40:21 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -410,6 +410,8 @@ dispatch_imsg(struct ntpd_conf *lconf, int argc, char **argv) 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; diff --git a/usr.sbin/ntpd/ntpd.h b/usr.sbin/ntpd/ntpd.h index 872d028d0eb..b09fc030133 100644 --- a/usr.sbin/ntpd/ntpd.h +++ b/usr.sbin/ntpd/ntpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ntpd.h,v 1.154 2024/05/21 05:00:48 jsg Exp $ */ +/* $OpenBSD: ntpd.h,v 1.155 2025/08/20 10:40:21 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -399,7 +399,7 @@ double gettime_from_timeval(struct timeval *); 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); diff --git a/usr.sbin/ntpd/util.c b/usr.sbin/ntpd/util.c index d837a9e6796..3371a309847 100644 --- a/usr.sbin/ntpd/util.c +++ b/usr.sbin/ntpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.28 2023/12/20 15:36:36 otto Exp $ */ +/* $OpenBSD: util.c,v 1.29 2025/08/20 10:40:21 henning Exp $ */ /* * Copyright (c) 2004 Alexander Guy @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -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