From 63fe34e89028e01bdeeaf77c72f9360f74791a4f Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Wed, 20 Jun 2018 12:11:55 +0200 Subject: [PATCH] check values returned by gmtime() and localtime() While it is not expected to happen with any time that can be represented by the system clock, the functions are allowed to return NULL. Check the pointer before dereferencing. This issue was found in a Frama-C analysis. --- logging.c | 10 ++++++---- reference.c | 13 +++++++++---- rtc_linux.c | 14 ++++++++------ 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/logging.c b/logging.c index 7d9dbb8..aee6940 100644 --- a/logging.c +++ b/logging.c @@ -132,14 +132,16 @@ void LOG_Message(LOG_Severity severity, char buf[2048]; va_list other_args; time_t t; - struct tm stm; + struct tm *tm; if (!system_log && file_log) { /* Don't clutter up syslog with timestamps and internal debugging info */ time(&t); - stm = *gmtime(&t); - strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", &stm); - fprintf(file_log, "%s ", buf); + tm = gmtime(&t); + if (tm) { + strftime(buf, sizeof (buf), "%Y-%m-%dT%H:%M:%SZ", tm); + fprintf(file_log, "%s ", buf); + } #if DEBUG > 0 if (debug_level >= DEBUG_LEVEL_PRINT_FUNCTION) fprintf(file_log, "%s:%d:(%s) ", filename, line_number, function_name); diff --git a/reference.c b/reference.c index dff7ab9..dbc40e7 100644 --- a/reference.c +++ b/reference.c @@ -528,7 +528,7 @@ maybe_log_offset(double offset, time_t now) double abs_offset; FILE *p; char buffer[BUFLEN], host[BUFLEN]; - struct tm stm; + struct tm *tm; abs_offset = fabs(offset); @@ -547,9 +547,14 @@ maybe_log_offset(double offset, time_t now) } fprintf(p, "Subject: chronyd reports change to system clock on node [%s]\n", host); fputs("\n", p); - stm = *localtime(&now); - strftime(buffer, sizeof(buffer), "On %A, %d %B %Y\n with the system clock reading %H:%M:%S (%Z)", &stm); - fputs(buffer, p); + + tm = localtime(&now); + if (tm) { + strftime(buffer, sizeof (buffer), + "On %A, %d %B %Y\n with the system clock reading %H:%M:%S (%Z)", tm); + fputs(buffer, p); + } + /* If offset < 0 the local clock is slow, so we are applying a positive change to it to bring it into line, hence the negation of 'offset' in the next statement (and earlier) */ diff --git a/rtc_linux.c b/rtc_linux.c index 89855c2..d4d9bd0 100644 --- a/rtc_linux.c +++ b/rtc_linux.c @@ -352,7 +352,7 @@ rtc_from_t(const time_t *t) static time_t t_from_rtc(struct tm *stm) { - struct tm temp1, temp2; + struct tm temp1, temp2, *tm; long diff; time_t t1, t2; @@ -360,12 +360,14 @@ t_from_rtc(struct tm *stm) { temp1.tm_isdst = 0; t1 = mktime(&temp1); - if (rtc_on_utc) { - temp2 = *gmtime(&t1); - } else { - temp2 = *localtime(&t1); + + tm = rtc_on_utc ? gmtime(&t1) : localtime(&t1); + if (!tm) { + DEBUG_LOG("gmtime()/localtime() failed"); + return -1; } - + + temp2 = *tm; temp2.tm_isdst = 0; t2 = mktime(&temp2); diff = t2 - t1;