diff --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c index 314140c10..fa007cb31 100644 --- a/lib/eventlog/eventlog.c +++ b/lib/eventlog/eventlog.c @@ -424,7 +424,7 @@ send_mail(const struct eventlog *evlog, const char *fmt, ...) const struct eventlog_config *evl_conf = eventlog_getconf(); const char *cp, *timefmt = evl_conf->time_fmt; char timebuf[1024]; - struct tm *tm; + struct tm gmt; time_t now; FILE *mail; int fd, pfd[2], status; @@ -445,7 +445,7 @@ send_mail(const struct eventlog *evlog, const char *fmt, ...) debug_return_bool(false); time(&now); - if ((tm = gmtime(&now)) == NULL) + if (gmtime_r(&now, &gmt) == NULL) debug_return_bool(false); /* Fork and return, child will daemonize. */ @@ -568,7 +568,7 @@ send_mail(const struct eventlog *evlog, const char *fmt, ...) (void) fprintf(mail, "\nContent-Type: text/plain; charset=\"%s\"\nContent-Transfer-Encoding: 8bit", nl_langinfo(CODESET)); #endif /* HAVE_NL_LANGINFO && CODESET */ - strftime(timebuf, sizeof(timebuf), timefmt, tm); + strftime(timebuf, sizeof(timebuf), timefmt, &gmt); if (evlog != NULL) { (void) fprintf(mail, "\n\n%s : %s : %s : ", evlog->submithost, timebuf, evlog->submituser); @@ -619,16 +619,16 @@ json_add_timestamp(struct json_container *json, const char *name, const char *timefmt = evl_conf->time_fmt; time_t secs = ts->tv_sec; char timebuf[1024]; - struct tm *tm; + struct tm gmt; - if ((tm = gmtime(&secs)) != NULL) { - strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tm); + if (gmtime_r(&secs, &gmt) != NULL) { + strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt); json_value.type = JSON_STRING; json_value.u.string = timebuf; // -V507 if (!sudo_json_add_value(json, "iso8601", &json_value)) goto oom; - strftime(timebuf, sizeof(timebuf), timefmt, tm); + strftime(timebuf, sizeof(timebuf), timefmt, &gmt); json_value.type = JSON_STRING; json_value.u.string = timebuf; // -V507 if (!sudo_json_add_value(json, "localtime", &json_value)) @@ -1117,7 +1117,7 @@ do_logfile_sudo(const char *logline, const struct eventlog *evlog, const char *timefmt = evl_conf->time_fmt; const char *logfile = evl_conf->logpath; time_t tv_sec = event_time->tv_sec; - struct tm *timeptr; + struct tm tm; bool ret = false; FILE *fp; int len; @@ -1132,10 +1132,10 @@ do_logfile_sudo(const char *logline, const struct eventlog *evlog, goto done; } - if ((timeptr = localtime(&tv_sec)) != NULL) { + if (localtime_r(&tv_sec, &tm) != NULL) { /* strftime() does not guarantee to NUL-terminate so we must check. */ timebuf[sizeof(timebuf) - 1] = '\0'; - if (strftime(timebuf, sizeof(timebuf), timefmt, timeptr) != 0 && + if (strftime(timebuf, sizeof(timebuf), timefmt, &tm) != 0 && timebuf[sizeof(timebuf) - 1] == '\0') { timestr = timebuf; } diff --git a/lib/iolog/iolog_path.c b/lib/iolog/iolog_path.c index 1f34c0b10..16f228c51 100644 --- a/lib/iolog/iolog_path.c +++ b/lib/iolog/iolog_path.c @@ -103,16 +103,16 @@ expand_iolog_path(const char *inpath, char *path, size_t pathlen, /* Expand strftime escapes as needed. */ if (strfit) { + struct tm tm; time_t now; - struct tm *timeptr; time(&now); - if ((timeptr = localtime(&now)) == NULL) + if (localtime_r(&now, &tm) == NULL) goto bad; /* We only call strftime() on the current part of the buffer. */ tmpbuf[sizeof(tmpbuf) - 1] = '\0'; - len = strftime(tmpbuf, sizeof(tmpbuf), path, timeptr); + len = strftime(tmpbuf, sizeof(tmpbuf), path, &tm); if (len == 0 || tmpbuf[sizeof(tmpbuf) - 1] != '\0') goto bad; /* strftime() failed, buf too small? */ diff --git a/lib/iolog/regress/iolog_path/check_iolog_path.c b/lib/iolog/regress/iolog_path/check_iolog_path.c index 8598384b4..7e690b8f8 100644 --- a/lib/iolog/regress/iolog_path/check_iolog_path.c +++ b/lib/iolog/regress/iolog_path/check_iolog_path.c @@ -130,20 +130,19 @@ do_check(char *dir_in, char *file_in, char *tdir_out, char *tfile_out) { char dir[PATH_MAX], dir_out[PATH_MAX]; char file[PATH_MAX], file_out[PATH_MAX]; - struct tm *timeptr; + struct tm tm; time_t now; int error = 0; /* * Expand any strftime(3) escapes - * XXX - want to pass timeptr to expand_iolog_path + * XXX - want to pass tm to expand_iolog_path */ time(&now); - timeptr = localtime(&now); - if (timeptr == NULL) - sudo_fatalx("localtime returned NULL"); - strftime(dir_out, sizeof(dir_out), tdir_out, timeptr); - strftime(file_out, sizeof(file_out), tfile_out, timeptr); + if (localtime_r(&now, &tm) == NULL) + sudo_fatal("localtime_r"); + strftime(dir_out, sizeof(dir_out), tdir_out, &tm); + strftime(file_out, sizeof(file_out), tfile_out, &tm); if (!expand_iolog_path(dir_in, dir, sizeof(dir), &path_escapes[1], NULL)) sudo_fatalx("unable to expand I/O log dir"); diff --git a/lib/util/sudo_debug.c b/lib/util/sudo_debug.c index 8625e9d18..236749d38 100644 --- a/lib/util/sudo_debug.c +++ b/lib/util/sudo_debug.c @@ -617,9 +617,10 @@ sudo_debug_write2_v1(int fd, const char *func, const char *file, int lineno, timebuf[0] = '\0'; if (gettimeofday(&tv, NULL) != -1) { time_t now = tv.tv_sec; - struct tm *tm = localtime(&now); - if (tm != NULL) { - size_t tlen = strftime(timebuf, sizeof(timebuf), "%b %e %H:%M:%S", tm); + struct tm tm; + size_t tlen; + if (localtime_r(&now, &tm) != NULL) { + tlen = strftime(timebuf, sizeof(timebuf), "%b %e %H:%M:%S", &tm); if (tlen == 0) { /* contents are undefined on error */ timebuf[0] = '\0'; diff --git a/plugins/audit_json/audit_json.c b/plugins/audit_json/audit_json.c index 74a2eb926..9e57a562c 100644 --- a/plugins/audit_json/audit_json.c +++ b/plugins/audit_json/audit_json.c @@ -341,10 +341,10 @@ add_timestamp(struct json_container *json, struct timespec *ts) struct json_value json_value; time_t secs = ts->tv_sec; char timebuf[1024]; - struct tm *tm; + struct tm gmt; debug_decl(add_timestamp, SUDO_DEBUG_PLUGIN); - if ((tm = gmtime(&secs)) == NULL) + if (gmtime_r(&secs, &gmt) == NULL) debug_return_bool(false); sudo_json_open_object(json, "timestamp"); @@ -357,12 +357,12 @@ add_timestamp(struct json_container *json, struct timespec *ts) json_value.u.number = ts->tv_nsec; sudo_json_add_value(json, "nanoseconds", &json_value); - strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tm); + strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt); json_value.type = JSON_STRING; json_value.u.string = timebuf; sudo_json_add_value(json, "iso8601", &json_value); - strftime(timebuf, sizeof(timebuf), "%a %b %e %H:%M:%S %Z %Y", tm); + strftime(timebuf, sizeof(timebuf), "%a %b %e %H:%M:%S %Z %Y", &gmt); json_value.type = JSON_STRING; json_value.u.string = timebuf; sudo_json_add_value(json, "localtime", &json_value); diff --git a/plugins/sample_approval/sample_approval.c b/plugins/sample_approval/sample_approval.c index cd1a8b268..505f32c39 100644 --- a/plugins/sample_approval/sample_approval.c +++ b/plugins/sample_approval/sample_approval.c @@ -117,7 +117,7 @@ static int sample_approval_check(char * const command_info[], char * const run_argv[], char * const run_envp[], const char **errstr) { - struct tm *tm; + struct tm tm; time_t now; int ret = 0; debug_decl(sample_approval_check, SUDO_DEBUG_PLUGIN); @@ -126,14 +126,14 @@ sample_approval_check(char * const command_info[], char * const run_argv[], * Only approve requests that are within business hours, * which are 9am - 5pm local time. Does not check holidays. */ - if (time(&now) == -1 || (tm = localtime(&now)) == NULL) + if (time(&now) == -1 || localtime_r(&now, &tm) == NULL) goto done; - if (tm->tm_wday < 1 || tm->tm_wday > 5) { + if (tm.tm_wday < 1 || tm.tm_wday > 5) { /* bad weekday */ goto done; } - if (tm->tm_hour < 9 || tm->tm_hour > 17 || - (tm->tm_hour == 17 && tm->tm_min > 0)) { + if (tm.tm_hour < 9 || tm.tm_hour > 17 || + (tm.tm_hour == 17 && tm.tm_min > 0)) { /* bad hour */ goto done; } diff --git a/plugins/sudoers/cvtsudoers_json.c b/plugins/sudoers/cvtsudoers_json.c index bb481a667..bcd3d8bdb 100644 --- a/plugins/sudoers/cvtsudoers_json.c +++ b/plugins/sudoers/cvtsudoers_json.c @@ -597,7 +597,7 @@ print_cmndspec_json(struct json_container *jsonc, struct json_value value; struct defaults *def; struct member *m; - struct tm *tp; + struct tm gmt; char timebuf[sizeof("20120727121554Z")]; debug_decl(print_cmndspec_json, SUDOERS_DEBUG_UTIL); @@ -647,10 +647,10 @@ print_cmndspec_json(struct json_container *jsonc, sudo_json_add_value_as_object(jsonc, "command_timeout", &value); } if (cs->notbefore != UNSPEC) { - if ((tp = gmtime(&cs->notbefore)) == NULL) { + if (gmtime_r(&cs->notbefore, &gmt) == NULL) { sudo_warn("%s", U_("unable to get GMT time")); } else { - if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tp) == 0) { + if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt) == 0) { sudo_warnx("%s", U_("unable to format timestamp")); } else { value.type = JSON_STRING; @@ -660,10 +660,10 @@ print_cmndspec_json(struct json_container *jsonc, } } if (cs->notafter != UNSPEC) { - if ((tp = gmtime(&cs->notafter)) == NULL) { + if (gmtime_r(&cs->notafter, &gmt) == NULL) { sudo_warn("%s", U_("unable to get GMT time")); } else { - if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tp) == 0) { + if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt) == 0) { sudo_warnx("%s", U_("unable to format timestamp")); } else { value.type = JSON_STRING; diff --git a/plugins/sudoers/cvtsudoers_ldif.c b/plugins/sudoers/cvtsudoers_ldif.c index f13b13762..c62360297 100644 --- a/plugins/sudoers/cvtsudoers_ldif.c +++ b/plugins/sudoers/cvtsudoers_ldif.c @@ -318,7 +318,7 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree, { struct cmndspec *next = *nextp; struct member *m; - struct tm *tp; + struct tm gmt; char *attr_val; bool last_one; char timebuf[sizeof("20120727121554Z")]; @@ -342,10 +342,10 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree, /* Print sudoNotBefore and sudoNotAfter attributes */ if (cs->notbefore != UNSPEC) { - if ((tp = gmtime(&cs->notbefore)) == NULL) { + if (gmtime_r(&cs->notbefore, &gmt) == NULL) { sudo_warn("%s", U_("unable to get GMT time")); } else { - if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tp) == 0) { + if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt) == 0) { sudo_warnx("%s", U_("unable to format timestamp")); } else { print_attribute_ldif(fp, "sudoNotBefore", timebuf); @@ -353,10 +353,10 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree, } } if (cs->notafter != UNSPEC) { - if ((tp = gmtime(&cs->notafter)) == NULL) { + if (gmtime_r(&cs->notafter, &gmt) == NULL) { sudo_warn("%s", U_("unable to get GMT time")); } else { - if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tp) == 0) { + if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt) == 0) { sudo_warnx("%s", U_("unable to format timestamp")); } else { print_attribute_ldif(fp, "sudoNotAfter", timebuf); diff --git a/plugins/sudoers/fmtsudoers.c b/plugins/sudoers/fmtsudoers.c index a58071e5d..8b1b292d5 100644 --- a/plugins/sudoers/fmtsudoers.c +++ b/plugins/sudoers/fmtsudoers.c @@ -241,15 +241,19 @@ sudoers_format_cmndspec(struct sudo_lbuf *lbuf, } if (cs->notbefore != UNSPEC && FIELD_CHANGED(prev_cs, cs, notbefore)) { char buf[sizeof("CCYYMMDDHHMMSSZ")]; - struct tm *tm = gmtime(&cs->notbefore); - if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", tm) != 0) - sudo_lbuf_append(lbuf, "NOTBEFORE=%s ", buf); + struct tm gmt; + if (gmtime_r(&cs->notbefore, &gmt) != NULL) { + if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &gmt) != 0) + sudo_lbuf_append(lbuf, "NOTBEFORE=%s ", buf); + } } if (cs->notafter != UNSPEC && FIELD_CHANGED(prev_cs, cs, notafter)) { char buf[sizeof("CCYYMMDDHHMMSSZ")]; - struct tm *tm = gmtime(&cs->notafter); - if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", tm) != 0) - sudo_lbuf_append(lbuf, "NOTAFTER=%s ", buf); + struct tm gmt; + if (gmtime_r(&cs->notafter, &gmt) != NULL) { + if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &gmt) != 0) + sudo_lbuf_append(lbuf, "NOTAFTER=%s ", buf); + } } if (TAG_CHANGED(prev_cs, cs, tags, setenv)) sudo_lbuf_append(lbuf, tags.setenv ? "SETENV: " : "NOSETENV: "); diff --git a/plugins/sudoers/getdate.c b/plugins/sudoers/getdate.c index dd3d4f6f5..5559ece5c 100644 --- a/plugins/sudoers/getdate.c +++ b/plugins/sudoers/getdate.c @@ -577,7 +577,7 @@ Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes, static int DaysInMonth[12] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - struct tm *tm; + struct tm tm; time_t tod; time_t Julian; int i; @@ -610,7 +610,7 @@ Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes, return -1; Julian += tod; if (DSTmode == DSTon - || (DSTmode == DSTmaybe && (tm = localtime(&Julian)) && tm->tm_isdst)) + || (DSTmode == DSTmaybe && localtime_r(&Julian, &tm) && tm.tm_isdst)) Julian -= 60 * 60; return Julian; } @@ -619,18 +619,16 @@ Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes, static time_t DSTcorrect(time_t Start, time_t Future) { - struct tm *start_tm; - struct tm *future_tm; + struct tm start_tm; + struct tm future_tm; time_t StartDay; time_t FutureDay; - start_tm = localtime(&Start); - future_tm = localtime(&Future); - if (!start_tm || !future_tm) + if (!localtime_r(&Start, &start_tm) || !localtime_r(&Future, &future_tm)) return -1; - StartDay = (start_tm->tm_hour + 1) % 24; - FutureDay = (future_tm->tm_hour + 1) % 24; + StartDay = (start_tm.tm_hour + 1) % 24; + FutureDay = (future_tm.tm_hour + 1) % 24; return (Future - Start) + (StartDay - FutureDay) * 60L * 60L; } @@ -638,13 +636,13 @@ DSTcorrect(time_t Start, time_t Future) static time_t RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber) { - struct tm *tm; + struct tm tm; time_t now; now = Start; - if (!(tm = localtime(&now))) + if (!localtime_r(&now, &tm)) return -1; - now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7); + now += SECSPERDAY * ((DayNumber - tm.tm_wday + 7) % 7); now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1); return DSTcorrect(Start, now); } @@ -653,20 +651,20 @@ RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber) static time_t RelativeMonth(time_t Start, time_t RelMonth) { - struct tm *tm; + struct tm tm; time_t Month; time_t Year; if (RelMonth == 0) return 0; - if (!(tm = localtime(&Start))) + if (!localtime_r(&Start, &tm)) return -1; - Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth; + Month = 12 * (tm.tm_year + 1900) + tm.tm_mon + RelMonth; Year = Month / 12; Month = Month % 12 + 1; return DSTcorrect(Start, - Convert(Month, (time_t)tm->tm_mday, Year, - (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, + Convert(Month, (time_t)tm.tm_mday, Year, + (time_t)tm.tm_hour, (time_t)tm.tm_min, (time_t)tm.tm_sec, MER24, DSTmaybe)); } @@ -855,7 +853,7 @@ difftm(struct tm *a, struct tm *b) time_t get_date(char *p) { - struct tm *tm, *gmt, gmtbuf; + struct tm tm, gmt; time_t Start; time_t tod; time_t now; @@ -864,36 +862,19 @@ get_date(char *p) yyInput = p; (void)time (&now); - gmt = gmtime (&now); - if (gmt != NULL) - { - /* Make a copy, in case localtime modifies *tm (I think - that comment now applies to *gmt, but I am too - lazy to dig into how gmtime and locatime allocate the - structures they return pointers to). */ - gmtbuf = *gmt; - gmt = &gmtbuf; - } - - if (! (tm = localtime (&now))) + if (gmtime_r (&now, &gmt) == NULL) return -1; - if (gmt != NULL) - tz = difftm (gmt, tm) / 60; - else - /* We are on a system like VMS, where the system clock is - in local time and the system has no concept of timezones. - Hopefully we can fake this out (for the case in which the - user specifies no timezone) by just saying the timezone - is zero. */ - tz = 0; + if (localtime_r (&now, &tm) == NULL) + return -1; - if(tm->tm_isdst) + tz = difftm (&gmt, &tm) / 60; + if (tm.tm_isdst) tz += 60; - yyYear = tm->tm_year + 1900; - yyMonth = tm->tm_mon + 1; - yyDay = tm->tm_mday; + yyYear = tm.tm_year + 1900; + yyMonth = tm.tm_mon + 1; + yyDay = tm.tm_mday; yyTimezone = tz; yyDSTmode = DSTmaybe; yyHour = 0; @@ -921,7 +902,7 @@ get_date(char *p) else { Start = now; if (!yyHaveRel) - Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec; + Start -= ((tm.tm_hour * 60L + tm.tm_min) * 60L) + tm.tm_sec; } Start += yyRelSeconds; @@ -962,7 +943,7 @@ main(int argc, char *argv[]) /* NOTREACHED */ } #endif /* TEST */ -#line 952 "getdate.c" +#line 933 "getdate.c" /* allocate initial stack or double stack size, up to YYMAXDEPTH */ static int yygrowstack(void) { @@ -1442,7 +1423,7 @@ case 41: yyval.Meridian = yyvsp[0].Meridian; } break; -#line 1432 "getdate.c" +#line 1413 "getdate.c" } yyssp -= yym; yystate = *yyssp; diff --git a/plugins/sudoers/getdate.y b/plugins/sudoers/getdate.y index 38cde8e74..33cf240dc 100644 --- a/plugins/sudoers/getdate.y +++ b/plugins/sudoers/getdate.y @@ -549,7 +549,7 @@ Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes, static int DaysInMonth[12] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - struct tm *tm; + struct tm tm; time_t tod; time_t Julian; int i; @@ -582,7 +582,7 @@ Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes, return -1; Julian += tod; if (DSTmode == DSTon - || (DSTmode == DSTmaybe && (tm = localtime(&Julian)) && tm->tm_isdst)) + || (DSTmode == DSTmaybe && localtime_r(&Julian, &tm) && tm.tm_isdst)) Julian -= 60 * 60; return Julian; } @@ -591,18 +591,16 @@ Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes, static time_t DSTcorrect(time_t Start, time_t Future) { - struct tm *start_tm; - struct tm *future_tm; + struct tm start_tm; + struct tm future_tm; time_t StartDay; time_t FutureDay; - start_tm = localtime(&Start); - future_tm = localtime(&Future); - if (!start_tm || !future_tm) + if (!localtime_r(&Start, &start_tm) || !localtime_r(&Future, &future_tm)) return -1; - StartDay = (start_tm->tm_hour + 1) % 24; - FutureDay = (future_tm->tm_hour + 1) % 24; + StartDay = (start_tm.tm_hour + 1) % 24; + FutureDay = (future_tm.tm_hour + 1) % 24; return (Future - Start) + (StartDay - FutureDay) * 60L * 60L; } @@ -610,13 +608,13 @@ DSTcorrect(time_t Start, time_t Future) static time_t RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber) { - struct tm *tm; + struct tm tm; time_t now; now = Start; - if (!(tm = localtime(&now))) + if (!localtime_r(&now, &tm)) return -1; - now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7); + now += SECSPERDAY * ((DayNumber - tm.tm_wday + 7) % 7); now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1); return DSTcorrect(Start, now); } @@ -625,20 +623,20 @@ RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber) static time_t RelativeMonth(time_t Start, time_t RelMonth) { - struct tm *tm; + struct tm tm; time_t Month; time_t Year; if (RelMonth == 0) return 0; - if (!(tm = localtime(&Start))) + if (!localtime_r(&Start, &tm)) return -1; - Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth; + Month = 12 * (tm.tm_year + 1900) + tm.tm_mon + RelMonth; Year = Month / 12; Month = Month % 12 + 1; return DSTcorrect(Start, - Convert(Month, (time_t)tm->tm_mday, Year, - (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, + Convert(Month, (time_t)tm.tm_mday, Year, + (time_t)tm.tm_hour, (time_t)tm.tm_min, (time_t)tm.tm_sec, MER24, DSTmaybe)); } @@ -827,7 +825,7 @@ difftm(struct tm *a, struct tm *b) time_t get_date(char *p) { - struct tm *tm, *gmt, gmtbuf; + struct tm tm, gmt; time_t Start; time_t tod; time_t now; @@ -836,36 +834,19 @@ get_date(char *p) yyInput = p; (void)time (&now); - gmt = gmtime (&now); - if (gmt != NULL) - { - /* Make a copy, in case localtime modifies *tm (I think - that comment now applies to *gmt, but I am too - lazy to dig into how gmtime and locatime allocate the - structures they return pointers to). */ - gmtbuf = *gmt; - gmt = &gmtbuf; - } - - if (! (tm = localtime (&now))) + if (gmtime_r (&now, &gmt) == NULL) return -1; - if (gmt != NULL) - tz = difftm (gmt, tm) / 60; - else - /* We are on a system like VMS, where the system clock is - in local time and the system has no concept of timezones. - Hopefully we can fake this out (for the case in which the - user specifies no timezone) by just saying the timezone - is zero. */ - tz = 0; + if (localtime_r (&now, &tm) == NULL) + return -1; - if(tm->tm_isdst) + tz = difftm (&gmt, &tm) / 60; + if (tm.tm_isdst) tz += 60; - yyYear = tm->tm_year + 1900; - yyMonth = tm->tm_mon + 1; - yyDay = tm->tm_mday; + yyYear = tm.tm_year + 1900; + yyMonth = tm.tm_mon + 1; + yyDay = tm.tm_mday; yyTimezone = tz; yyDSTmode = DSTmaybe; yyHour = 0; @@ -893,7 +874,7 @@ get_date(char *p) else { Start = now; if (!yyHaveRel) - Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec; + Start -= ((tm.tm_hour * 60L + tm.tm_min) * 60L) + tm.tm_sec; } Start += yyRelSeconds; diff --git a/plugins/sudoers/gmtoff.c b/plugins/sudoers/gmtoff.c index dcf448984..51cdb7c75 100644 --- a/plugins/sudoers/gmtoff.c +++ b/plugins/sudoers/gmtoff.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: ISC * - * Copyright (c) 2017 Todd C. Miller + * Copyright (c) 2017, 2021 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -32,42 +32,41 @@ /* * Returns the offset from GMT in seconds (algorithm taken from sendmail). - * Warning: clobbers the static storage used by localtime() and gmtime(). */ #ifdef HAVE_STRUCT_TM_TM_GMTOFF long get_gmtoff(time_t *when) { - struct tm *local; + struct tm local; - local = localtime(when); - return local->tm_gmtoff; + if (localtime_r(when, &local) == NULL) + return 0; + return local.tm_gmtoff; } #else long get_gmtoff(time_t *when) { - struct tm *gm, gmt, *local; + struct tm gmt, local; long offset; - if ((gm = gmtime(when)) == NULL) + if (gmtime_r(when, &gmt) == NULL) return 0; - gmt = *gm; - if ((local = localtime(when)) == NULL) + if (localtime_r(when, &local) == NULL) return 0; - offset = (local->tm_sec - gmt.tm_sec) + - ((local->tm_min - gmt.tm_min) * 60) + - ((local->tm_hour - gmt.tm_hour) * 3600); + offset = (local.tm_sec - gmt.tm_sec) + + ((local.tm_min - gmt.tm_min) * 60) + + ((local.tm_hour - gmt.tm_hour) * 3600); /* Timezone may cause year rollover to happen on a different day. */ - if (local->tm_year < gmt.tm_year) + if (local.tm_year < gmt.tm_year) offset -= 24 * 3600; - else if (local->tm_year > gmt.tm_year) + else if (local.tm_year > gmt.tm_year) offset -= 24 * 3600; - else if (local->tm_yday < gmt.tm_yday) + else if (local.tm_yday < gmt.tm_yday) offset -= 24 * 3600; - else if (local->tm_yday > gmt.tm_yday) + else if (local.tm_yday > gmt.tm_yday) offset += 24 * 3600; return offset; diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c index ef65db555..3bff17972 100644 --- a/plugins/sudoers/ldap.c +++ b/plugins/sudoers/ldap.c @@ -491,7 +491,7 @@ done: static bool sudo_ldap_timefilter(char *buffer, size_t buffersize) { - struct tm *tp; + struct tm gmt; time_t now; char timebuffer[sizeof("20120727121554.0Z")]; int len = -1; @@ -499,13 +499,13 @@ sudo_ldap_timefilter(char *buffer, size_t buffersize) /* Make sure we have a formatted timestamp for __now__. */ time(&now); - if ((tp = gmtime(&now)) == NULL) { + if (gmtime_r(&now, &gmt) == NULL) { sudo_warn("%s", U_("unable to get GMT time")); goto done; } /* Format the timestamp according to the RFC. */ - if (strftime(timebuffer, sizeof(timebuffer), "%Y%m%d%H%M%S.0Z", tp) == 0) { + if (strftime(timebuffer, sizeof(timebuffer), "%Y%m%d%H%M%S.0Z", &gmt) == 0) { sudo_warnx("%s", U_("unable to format timestamp")); goto done; } diff --git a/plugins/sudoers/parse.c b/plugins/sudoers/parse.c index d3bf8a556..5370b15a9 100644 --- a/plugins/sudoers/parse.c +++ b/plugins/sudoers/parse.c @@ -622,15 +622,19 @@ display_priv_long(struct sudoers_parse_tree *parse_tree, struct passwd *pw, } if (cs->notbefore != UNSPEC) { char buf[sizeof("CCYYMMDDHHMMSSZ")]; - struct tm *tm = gmtime(&cs->notbefore); - if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", tm) != 0) - sudo_lbuf_append(lbuf, " NotBefore: %s\n", buf); + struct tm gmt; + if (gmtime_r(&cs->notbefore, &gmt) != NULL) { + if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &gmt) != 0) + sudo_lbuf_append(lbuf, " NotBefore: %s\n", buf); + } } if (cs->notafter != UNSPEC) { char buf[sizeof("CCYYMMDDHHMMSSZ")]; - struct tm *tm = gmtime(&cs->notafter); - if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", tm) != 0) - sudo_lbuf_append(lbuf, " NotAfter: %s\n", buf); + struct tm gmt; + if (gmtime_r(&cs->notafter, &gmt) != NULL) { + if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &gmt) != 0) + sudo_lbuf_append(lbuf, " NotAfter: %s\n", buf); + } } sudo_lbuf_append(lbuf, "%s", _(" Commands:\n")); } diff --git a/plugins/sudoers/timestr.c b/plugins/sudoers/timestr.c index 339840559..57fd56708 100644 --- a/plugins/sudoers/timestr.c +++ b/plugins/sudoers/timestr.c @@ -37,13 +37,13 @@ char * get_timestr(time_t tstamp, int log_year) { static char buf[128]; - struct tm *timeptr; + struct tm tm; - if ((timeptr = localtime(&tstamp)) != NULL) { + if (localtime_r(&tstamp, &tm) != NULL) { /* strftime() does not guarantee to NUL-terminate so we must check. */ buf[sizeof(buf) - 1] = '\0'; if (strftime(buf, sizeof(buf), log_year ? "%h %e %T %Y" : "%h %e %T", - timeptr) != 0 && buf[sizeof(buf) - 1] == '\0') + &tm) != 0 && buf[sizeof(buf) - 1] == '\0') return buf; } return NULL;