]> Git Repo - linux.git/commitdiff
ntp: Remove invalid cast in time offset math
authorMarcelo Dalmas <[email protected]>
Mon, 25 Nov 2024 12:16:09 +0000 (12:16 +0000)
committerThomas Gleixner <[email protected]>
Thu, 28 Nov 2024 11:02:38 +0000 (12:02 +0100)
Due to an unsigned cast, adjtimex() returns the wrong offest when using
ADJ_MICRO and the offset is negative. In this case a small negative offset
returns approximately 4.29 seconds (~ 2^32/1000 milliseconds) due to the
unsigned cast of the negative offset.

This cast was added when the kernel internal struct timex was changed to
use type long long for the time offset value to address the problem of a
64bit/32bit division on 32bit systems.

The correct cast would have been (s32), which is correct as time_offset can
only be in the range of [INT_MIN..INT_MAX] because the shift constant used
for calculating it is 32. But that's non-obvious.

Remove the cast and use div_s64() to cure the issue.

[ tglx: Fix white space damage, use div_s64() and amend the change log ]

Fixes: ead25417f82e ("timex: use __kernel_timex internally")
Signed-off-by: Marcelo Dalmas <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: [email protected]
Link: https://lore.kernel.org/all/SJ0P101MB03687BF7D5A10FD3C49C51E5F42E2@SJ0P101MB0368.NAMP101.PROD.OUTLOOK.COM
kernel/time/ntp.c

index b550ebe0f03b2205479f5343e11afe1fadd70185..163e7a2033b624f3f023c25968cd17e624ea831d 100644 (file)
@@ -798,7 +798,7 @@ int __do_adjtimex(struct __kernel_timex *txc, const struct timespec64 *ts,
 
                txc->offset = shift_right(ntpdata->time_offset * NTP_INTERVAL_FREQ, NTP_SCALE_SHIFT);
                if (!(ntpdata->time_status & STA_NANO))
-                       txc->offset = (u32)txc->offset / NSEC_PER_USEC;
+                       txc->offset = div_s64(txc->offset, NSEC_PER_USEC);
        }
 
        result = ntpdata->time_state;
This page took 0.058859 seconds and 4 git commands to generate.