Use gmtime_r() and localtime_r() instead of gmtime() and localtime().

This commit is contained in:
Todd C. Miller
2021-09-17 10:55:06 -06:00
parent fa71679b5a
commit 18f1884ddc
15 changed files with 135 additions and 166 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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: ");

View File

@@ -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;

View File

@@ -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;

View File

@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
* Copyright (c) 2017, 2021 Todd C. Miller <Todd.Miller@sudo.ws>
*
* 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;

View File

@@ -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;
}

View File

@@ -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"));
}

View File

@@ -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;