summaryrefslogtreecommitdiff
path: root/kernel/time
diff options
context:
space:
mode:
authorMarcelo Dalmas <marcelo.dalmas@ge.com>2024-11-25 12:16:09 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-12-14 19:54:26 +0100
commit6f24a5f8309438863e57d067d38ab5da7430a156 (patch)
treed4ae174349bed58d1e771754c43b6e3785d5251b /kernel/time
parent6c013fde1c7612b28caf3055710ec9d53d29bae2 (diff)
downloadlinux-6f24a5f8309438863e57d067d38ab5da7430a156.tar.gz
linux-6f24a5f8309438863e57d067d38ab5da7430a156.tar.bz2
linux-6f24a5f8309438863e57d067d38ab5da7430a156.zip
ntp: Remove invalid cast in time offset math
commit f5807b0606da7ac7c1b74a386b22134ec7702d05 upstream. 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 <marcelo.dalmas@ge.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/SJ0P101MB03687BF7D5A10FD3C49C51E5F42E2@SJ0P101MB0368.NAMP101.PROD.OUTLOOK.COM Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/ntp.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 8d2dd214ec68..b1ba80ce8496 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -796,7 +796,7 @@ int __do_adjtimex(struct __kernel_timex *txc, const struct timespec64 *ts,
txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ,
NTP_SCALE_SHIFT);
if (!(time_status & STA_NANO))
- txc->offset = (u32)txc->offset / NSEC_PER_USEC;
+ txc->offset = div_s64(txc->offset, NSEC_PER_USEC);
}
result = time_state; /* mostly `TIME_OK' */