The 32-bit integer part of the NTP timestamp overflows in year 2036,
which starts the second NTP era.

Modify the timestamp conversion to shift values between 1900-1970 (in
the first era) to the second era to enable the client to measure its
offset correctly until year 2106 (assuming 64-bit time_t).

Also update the conversion from double used when stepping the clock to
work with 64-bit time_t after reaching the maximum 32-bit value in 2038
and the server conversion to work correctly in the next NTP era.

Signed-off-by: Miroslav Lichvar <[email protected]>
---
 networking/ntpd.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/networking/ntpd.c b/networking/ntpd.c
index 204e1d7c2..91faefcd8 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -554,7 +554,7 @@ gettime1900d(void)
 static void
 d_to_tv(struct timeval *tv, double d)
 {
-       tv->tv_sec = (long)d;
+       tv->tv_sec = (time_t)d;
        tv->tv_usec = (d - tv->tv_sec) * 1000000;
 }
 
@@ -565,6 +565,9 @@ lfp_to_d(l_fixedpt_t lfp)
        lfp.int_partl = ntohl(lfp.int_partl);
        lfp.fractionl = ntohl(lfp.fractionl);
        ret = (double)lfp.int_partl + ((double)lfp.fractionl / UINT_MAX);
+       /* Shift timestamps before 1970 to the second NTP era (2036-2106) */
+       if (lfp.int_partl < OFFSET_1900_1970)
+               ret += (double)UINT_MAX + 1.0;
        return ret;
 }
 static NOINLINE double
@@ -582,8 +585,8 @@ d_to_lfp(l_fixedpt_t *lfp, double d)
 {
        uint32_t intl;
        uint32_t frac;
-       intl = (uint32_t)d;
-       frac = (uint32_t)((d - intl) * UINT_MAX);
+       intl = (uint32_t)(time_t)d;
+       frac = (uint32_t)((d - (time_t)d) * UINT_MAX);
        lfp->int_partl = htonl(intl);
        lfp->fractionl = htonl(frac);
 }
-- 
2.37.3

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to