From edf120d36aa2251839cfdeee74694feea3681b89 Mon Sep 17 00:00:00 2001 From: Krzysztof Chruscinski Date: Fri, 14 Jan 2022 09:25:37 +0100 Subject: [PATCH] lib: posix: clock: Prevent early overflows Algorithm was converting uptime to nanoseconds which can easily lead to overflows. Changed algorithm to use milliseconds and nanoseconds for remainder only. Signed-off-by: Krzysztof Chruscinski (cherry picked from commit 35593ce1e93107f9190587d28585e02bb28b3648) --- lib/posix/clock.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/posix/clock.c b/lib/posix/clock.c index c36f2401cc4c5..2bc8d052c1f5a 100644 --- a/lib/posix/clock.c +++ b/lib/posix/clock.c @@ -27,7 +27,6 @@ static struct k_spinlock rt_clock_base_lock; */ int z_impl_clock_gettime(clockid_t clock_id, struct timespec *ts) { - uint64_t elapsed_nsecs; struct timespec base; k_spinlock_key_t key; @@ -48,9 +47,13 @@ int z_impl_clock_gettime(clockid_t clock_id, struct timespec *ts) return -1; } - elapsed_nsecs = k_ticks_to_ns_floor64(k_uptime_ticks()); - ts->tv_sec = (int32_t) (elapsed_nsecs / NSEC_PER_SEC); - ts->tv_nsec = (int32_t) (elapsed_nsecs % NSEC_PER_SEC); + uint64_t ticks = k_uptime_ticks(); + uint64_t elapsed_secs = k_ticks_to_ms_floor64(ticks) / MSEC_PER_SEC; + uint64_t nremainder = ticks - k_ms_to_ticks_floor64(MSEC_PER_SEC * elapsed_secs); + + ts->tv_sec = (time_t) elapsed_secs; + /* For ns 32 bit conversion can be used since its smaller than 1sec. */ + ts->tv_nsec = (int32_t) k_ticks_to_ns_floor32(nremainder); ts->tv_sec += base.tv_sec; ts->tv_nsec += base.tv_nsec;