Check strftime(3) return value in all cases.
Old versions of strftime(3) didn't guarantee to NUL-terminate the buffer so we explicitly clear the last byte of the buffer and check it.
This commit is contained in:
@@ -427,7 +427,7 @@ send_mail(const struct eventlog *evlog, const char *fmt, ...)
|
||||
struct tm gmt;
|
||||
time_t now;
|
||||
FILE *mail;
|
||||
int fd, pfd[2], status;
|
||||
int fd, len, pfd[2], status;
|
||||
pid_t pid, rv;
|
||||
struct stat sb;
|
||||
va_list ap;
|
||||
@@ -568,7 +568,18 @@ 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, &gmt);
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
len = strftime(timebuf, sizeof(timebuf), timefmt, &gmt);
|
||||
if (len == 0 || timebuf[sizeof(timebuf) - 1] != '\0') {
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_ERROR,
|
||||
"strftime() failed to format time: %s", timefmt);
|
||||
/* Fall back to default time format string. */
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
len = strftime(timebuf, sizeof(timebuf), "%h %e %T", &gmt);
|
||||
if (len == 0 || timebuf[sizeof(timebuf) - 1] != '\0') {
|
||||
timebuf[0] = '\0'; /* give up */
|
||||
}
|
||||
}
|
||||
if (evlog != NULL) {
|
||||
(void) fprintf(mail, "\n\n%s : %s : %s : ", evlog->submithost, timebuf,
|
||||
evlog->submituser);
|
||||
@@ -599,6 +610,7 @@ json_add_timestamp(struct json_container *json, const char *name,
|
||||
const struct timespec *ts, bool format_timestamp)
|
||||
{
|
||||
struct json_value json_value;
|
||||
int len;
|
||||
debug_decl(json_add_timestamp, SUDO_DEBUG_PLUGIN);
|
||||
|
||||
if (!sudo_json_open_object(json, name))
|
||||
@@ -622,19 +634,25 @@ json_add_timestamp(struct json_container *json, const char *name,
|
||||
struct tm gmt;
|
||||
|
||||
if (gmtime_r(&secs, &gmt) != NULL) {
|
||||
strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt);
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
len = strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt);
|
||||
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0') {
|
||||
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, &gmt);
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
len = strftime(timebuf, sizeof(timebuf), timefmt, &gmt);
|
||||
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0') {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = timebuf; // -V507
|
||||
if (!sudo_json_add_value(json, "localtime", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!sudo_json_close_object(json))
|
||||
goto oom;
|
||||
|
@@ -128,11 +128,12 @@ static struct iolog_path_escape path_escapes[] = {
|
||||
static int
|
||||
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];
|
||||
char dir[PATH_MAX], dir_out[PATH_MAX] = "";
|
||||
char file[PATH_MAX], file_out[PATH_MAX] = "";
|
||||
int error = 0;
|
||||
struct tm tm;
|
||||
time_t now;
|
||||
int error = 0;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Expand any strftime(3) escapes
|
||||
@@ -141,8 +142,16 @@ do_check(char *dir_in, char *file_in, char *tdir_out, char *tfile_out)
|
||||
time(&now);
|
||||
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 (tdir_out[0] != '\0') {
|
||||
len = strftime(dir_out, sizeof(dir_out), tdir_out, &tm);
|
||||
if (len == 0 || dir_out[sizeof(dir_out) - 1] != '\0')
|
||||
sudo_fatalx("dir_out: strftime overflow");
|
||||
}
|
||||
if (tfile_out[0] != '\0') {
|
||||
len = strftime(file_out, sizeof(file_out), tfile_out, &tm);
|
||||
if (len == 0 || file_out[sizeof(file_out) - 1] != '\0')
|
||||
sudo_fatalx("file_out: strftime overflow");
|
||||
}
|
||||
|
||||
if (!expand_iolog_path(dir_in, dir, sizeof(dir), &path_escapes[1], NULL))
|
||||
sudo_fatalx("unable to expand I/O log dir");
|
||||
|
@@ -620,8 +620,9 @@ sudo_debug_write2_v1(int fd, const char *func, const char *file, int lineno,
|
||||
struct tm tm;
|
||||
size_t tlen;
|
||||
if (localtime_r(&now, &tm) != NULL) {
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
tlen = strftime(timebuf, sizeof(timebuf), "%b %e %H:%M:%S", &tm);
|
||||
if (tlen == 0) {
|
||||
if (tlen == 0 || timebuf[sizeof(timebuf) - 1] != '\0') {
|
||||
/* contents are undefined on error */
|
||||
timebuf[0] = '\0';
|
||||
} else {
|
||||
|
@@ -342,6 +342,7 @@ add_timestamp(struct json_container *json, struct timespec *ts)
|
||||
time_t secs = ts->tv_sec;
|
||||
char timebuf[1024];
|
||||
struct tm gmt;
|
||||
int len;
|
||||
debug_decl(add_timestamp, SUDO_DEBUG_PLUGIN);
|
||||
|
||||
if (gmtime_r(&secs, &gmt) == NULL)
|
||||
@@ -357,15 +358,21 @@ 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", &gmt);
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
len = strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt);
|
||||
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0'){
|
||||
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", &gmt);
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
len = strftime(timebuf, sizeof(timebuf), "%a %b %e %H:%M:%S %Z %Y", &gmt);
|
||||
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0'){
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = timebuf;
|
||||
sudo_json_add_value(json, "localtime", &json_value);
|
||||
}
|
||||
|
||||
sudo_json_close_object(json);
|
||||
|
||||
|
@@ -593,12 +593,13 @@ print_cmndspec_json(struct json_container *jsonc,
|
||||
struct sudoers_parse_tree *parse_tree, struct cmndspec *cs,
|
||||
struct cmndspec **nextp, struct defaults_list *options, bool expand_aliases)
|
||||
{
|
||||
char timebuf[sizeof("20120727121554Z")];
|
||||
struct cmndspec *next = *nextp;
|
||||
struct json_value value;
|
||||
struct defaults *def;
|
||||
struct member *m;
|
||||
struct tm gmt;
|
||||
char timebuf[sizeof("20120727121554Z")];
|
||||
int len;
|
||||
debug_decl(print_cmndspec_json, SUDOERS_DEBUG_UTIL);
|
||||
|
||||
/* Open Cmnd_Spec object. */
|
||||
@@ -650,7 +651,9 @@ print_cmndspec_json(struct json_container *jsonc,
|
||||
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", &gmt) == 0) {
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
len = strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt);
|
||||
if (len == 0 || timebuf[sizeof(timebuf) - 1] != '\0') {
|
||||
sudo_warnx("%s", U_("unable to format timestamp"));
|
||||
} else {
|
||||
value.type = JSON_STRING;
|
||||
@@ -663,7 +666,9 @@ print_cmndspec_json(struct json_container *jsonc,
|
||||
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", &gmt) == 0) {
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
len = strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt);
|
||||
if (len == 0 || timebuf[sizeof(timebuf) - 1] != '\0') {
|
||||
sudo_warnx("%s", U_("unable to format timestamp"));
|
||||
} else {
|
||||
value.type = JSON_STRING;
|
||||
|
@@ -316,12 +316,13 @@ static void
|
||||
print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||
struct cmndspec *cs, struct cmndspec **nextp, struct defaults_list *options)
|
||||
{
|
||||
char timebuf[sizeof("20120727121554Z")];
|
||||
struct cmndspec *next = *nextp;
|
||||
struct member *m;
|
||||
struct tm gmt;
|
||||
char *attr_val;
|
||||
bool last_one;
|
||||
char timebuf[sizeof("20120727121554Z")];
|
||||
int len;
|
||||
debug_decl(print_cmndspec_ldif, SUDOERS_DEBUG_UTIL);
|
||||
|
||||
/* Print runasuserlist as sudoRunAsUser attributes */
|
||||
@@ -345,7 +346,9 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||
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", &gmt) == 0) {
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
len = strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt);
|
||||
if (len == 0 || timebuf[sizeof(timebuf) - 1] != '\0') {
|
||||
sudo_warnx("%s", U_("unable to format timestamp"));
|
||||
} else {
|
||||
print_attribute_ldif(fp, "sudoNotBefore", timebuf);
|
||||
@@ -356,7 +359,9 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||
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", &gmt) == 0) {
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
len = strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt);
|
||||
if (len == 0 || timebuf[sizeof(timebuf) - 1] != '\0') {
|
||||
sudo_warnx("%s", U_("unable to format timestamp"));
|
||||
} else {
|
||||
print_attribute_ldif(fp, "sudoNotAfter", timebuf);
|
||||
|
@@ -240,18 +240,20 @@ sudoers_format_cmndspec(struct sudo_lbuf *lbuf,
|
||||
sudo_lbuf_append(lbuf, "TIMEOUT=%s ", numbuf);
|
||||
}
|
||||
if (cs->notbefore != UNSPEC && FIELD_CHANGED(prev_cs, cs, notbefore)) {
|
||||
char buf[sizeof("CCYYMMDDHHMMSSZ")];
|
||||
char buf[sizeof("CCYYMMDDHHMMSSZ")] = "";
|
||||
struct tm gmt;
|
||||
if (gmtime_r(&cs->notbefore, &gmt) != NULL) {
|
||||
if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &gmt) != 0)
|
||||
int len = strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &gmt);
|
||||
if (len != 0 && buf[sizeof(buf) - 1] == '\0')
|
||||
sudo_lbuf_append(lbuf, "NOTBEFORE=%s ", buf);
|
||||
}
|
||||
}
|
||||
if (cs->notafter != UNSPEC && FIELD_CHANGED(prev_cs, cs, notafter)) {
|
||||
char buf[sizeof("CCYYMMDDHHMMSSZ")];
|
||||
char buf[sizeof("CCYYMMDDHHMMSSZ")] = "";
|
||||
struct tm gmt;
|
||||
if (gmtime_r(&cs->notafter, &gmt) != NULL) {
|
||||
if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &gmt) != 0)
|
||||
int len = strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &gmt);
|
||||
if (len != 0 && buf[sizeof(buf) - 1] == '\0')
|
||||
sudo_lbuf_append(lbuf, "NOTAFTER=%s ", buf);
|
||||
}
|
||||
}
|
||||
|
@@ -491,10 +491,11 @@ done:
|
||||
static bool
|
||||
sudo_ldap_timefilter(char *buffer, size_t buffersize)
|
||||
{
|
||||
char timebuffer[sizeof("20120727121554.0Z")];
|
||||
bool ret = false;
|
||||
struct tm gmt;
|
||||
time_t now;
|
||||
char timebuffer[sizeof("20120727121554.0Z")];
|
||||
int len = -1;
|
||||
int len;
|
||||
debug_decl(sudo_ldap_timefilter, SUDOERS_DEBUG_LDAP);
|
||||
|
||||
/* Make sure we have a formatted timestamp for __now__. */
|
||||
@@ -505,7 +506,9 @@ sudo_ldap_timefilter(char *buffer, size_t buffersize)
|
||||
}
|
||||
|
||||
/* Format the timestamp according to the RFC. */
|
||||
if (strftime(timebuffer, sizeof(timebuffer), "%Y%m%d%H%M%S.0Z", &gmt) == 0) {
|
||||
timebuffer[sizeof(timebuffer) - 1] = '\0';
|
||||
len = strftime(timebuffer, sizeof(timebuffer), "%Y%m%d%H%M%S.0Z", &gmt);
|
||||
if (len == 0 || timebuffer[sizeof(timebuffer) - 1] != '\0') {
|
||||
sudo_warnx("%s", U_("unable to format timestamp"));
|
||||
goto done;
|
||||
}
|
||||
@@ -516,11 +519,13 @@ sudo_ldap_timefilter(char *buffer, size_t buffersize)
|
||||
if (len < 0 || (size_t)len >= buffersize) {
|
||||
sudo_warnx(U_("internal error, %s overflow"), __func__);
|
||||
errno = EOVERFLOW;
|
||||
len = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
done:
|
||||
debug_return_bool(len != -1);
|
||||
debug_return_bool(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -621,18 +621,22 @@ display_priv_long(struct sudoers_parse_tree *parse_tree, struct passwd *pw,
|
||||
sudo_lbuf_append(lbuf, " Timeout: %s\n", numbuf);
|
||||
}
|
||||
if (cs->notbefore != UNSPEC) {
|
||||
char buf[sizeof("CCYYMMDDHHMMSSZ")];
|
||||
char buf[sizeof("CCYYMMDDHHMMSSZ")] = "";
|
||||
struct tm gmt;
|
||||
int len;
|
||||
if (gmtime_r(&cs->notbefore, &gmt) != NULL) {
|
||||
if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &gmt) != 0)
|
||||
len = strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &gmt);
|
||||
if (len != 0 && buf[sizeof(buf) - 1] == '\0')
|
||||
sudo_lbuf_append(lbuf, " NotBefore: %s\n", buf);
|
||||
}
|
||||
}
|
||||
if (cs->notafter != UNSPEC) {
|
||||
char buf[sizeof("CCYYMMDDHHMMSSZ")];
|
||||
char buf[sizeof("CCYYMMDDHHMMSSZ")] = "";
|
||||
struct tm gmt;
|
||||
int len;
|
||||
if (gmtime_r(&cs->notafter, &gmt) != NULL) {
|
||||
if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &gmt) != 0)
|
||||
len = strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &gmt);
|
||||
if (len != 0 && buf[sizeof(buf) - 1] == '\0')
|
||||
sudo_lbuf_append(lbuf, " NotAfter: %s\n", buf);
|
||||
}
|
||||
}
|
||||
|
@@ -38,12 +38,14 @@ get_timestr(time_t tstamp, int log_year)
|
||||
{
|
||||
static char buf[128];
|
||||
struct tm tm;
|
||||
int len;
|
||||
|
||||
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",
|
||||
&tm) != 0 && buf[sizeof(buf) - 1] == '\0')
|
||||
len = strftime(buf, sizeof(buf), log_year ? "%h %e %T %Y" : "%h %e %T",
|
||||
&tm);
|
||||
if (len != 0 && buf[sizeof(buf) - 1] == '\0')
|
||||
return buf;
|
||||
}
|
||||
return NULL;
|
||||
|
Reference in New Issue
Block a user