From f0813cbf4f507462b5b9aa0e913483232e51bea5 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 6 Dec 2019 16:45:04 +0000 Subject: lib: harden full_timespec_to_nt_time() This protects against overflows when tv_sec is less then TIME_FIXUP_CONSTANT_INT. It also correctly limits the range of returned values to be [NTTIME_MIN, NTTIME_MAX]. Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- lib/util/time.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'lib/util/time.c') diff --git a/lib/util/time.c b/lib/util/time.c index 0875c9fbda9..d8f1daca901 100644 --- a/lib/util/time.c +++ b/lib/util/time.c @@ -1080,23 +1080,37 @@ struct timespec make_omit_timespec(void) * Like unix_timespec_to_nt_time() but without the special casing of tv_sec=0 * and -1. Also dealing with SAMBA_UTIME_OMIT. **/ -NTTIME full_timespec_to_nt_time(const struct timespec *ts) +NTTIME full_timespec_to_nt_time(const struct timespec *_ts) { + struct timespec ts = *_ts; uint64_t d; - if (ts->tv_sec == TIME_T_MAX) { - return 0x7fffffffffffffffLL; + if (is_omit_timespec(_ts)) { + return NTTIME_OMIT; } - if (is_omit_timespec(ts)) { - return 0; + /* Ensure tv_nsec is less than 1 sec. */ + while (ts.tv_nsec > 1000000000) { + if (ts.tv_sec > TIME_T_MAX) { + return NTTIME_MAX; + } + ts.tv_sec += 1; + ts.tv_nsec -= 1000000000; } - d = ts->tv_sec; - d += TIME_FIXUP_CONSTANT_INT; + if (ts.tv_sec >= TIME_T_MAX) { + return NTTIME_MAX; + } + if ((ts.tv_sec + TIME_FIXUP_CONSTANT_INT) <= 0) { + return NTTIME_MIN; + } + + d = TIME_FIXUP_CONSTANT_INT; + d += ts.tv_sec; + d *= 1000*1000*10; /* d is now in 100ns units. */ - d += (ts->tv_nsec / 100); + d += (ts.tv_nsec / 100); return d; } -- cgit v1.2.1