From b205d946bc4d92a63918093e4dac726834be3d03 Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 28 Apr 2024 16:43:42 +0000 Subject: [PATCH] gmtime(3) / locatime(3) can fail when timestamps are way off. Add missing error checks to all calls under sbin/ Input & OK millert --- sbin/dhclient/dhclient.c | 15 +++++++++++---- sbin/isakmpd/log.c | 8 ++++++-- sbin/isakmpd/policy.c | 16 +++++++++++++--- sbin/isakmpd/x509.c | 22 ++++++++++++++++++---- sbin/newfs_msdos/newfs_msdos.c | 6 ++++-- sbin/route/route.c | 7 +++++-- sbin/shutdown/shutdown.c | 27 +++++++++++++++++++++------ sbin/unwind/libunbound/util/log.c | 4 ++-- 8 files changed, 80 insertions(+), 25 deletions(-) diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index 97fc9b5b2fe..e96dae1f5d9 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.727 2022/07/02 17:21:32 deraadt Exp $ */ +/* $OpenBSD: dhclient.c,v 1.728 2024/04/28 16:43:42 florian Exp $ */ /* * Copyright 2004 Henning Brauer @@ -2079,6 +2079,7 @@ lease_as_string(char *type, struct client_lease *lease) static char string[8192]; char timebuf[27]; /* 6 2017/04/08 05:47:50 UTC; */ struct option_data *opt; + struct tm *tm; char *buf, *name; time_t t; size_t rslt; @@ -2138,19 +2139,25 @@ lease_as_string(char *type, struct client_lease *lease) free(buf); t = lease->epoch + lease_renewal(lease); - rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT, gmtime(&t)); + if ((tm = gmtime(&t)) == NULL) + return NULL; + rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT, tm); if (rslt == 0) return NULL; append_statement(string, sizeof(string), " renew ", timebuf); t = lease->epoch + lease_rebind(lease); - rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT, gmtime(&t)); + if ((tm = gmtime(&t)) == NULL) + return NULL; + rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT, tm); if (rslt == 0) return NULL; append_statement(string, sizeof(string), " rebind ", timebuf); t = lease->epoch + lease_expiry(lease); - rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT, gmtime(&t)); + if ((tm = gmtime(&t)) == NULL) + return NULL; + rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT, tm); if (rslt == 0) return NULL; append_statement(string, sizeof(string), " expire ", timebuf); diff --git a/sbin/isakmpd/log.c b/sbin/isakmpd/log.c index 5a0df1df5e9..4ba58bc5f1f 100644 --- a/sbin/isakmpd/log.c +++ b/sbin/isakmpd/log.c @@ -1,4 +1,4 @@ -/* $OpenBSD: log.c,v 1.64 2018/01/15 09:54:48 mpi Exp $ */ +/* $OpenBSD: log.c,v 1.65 2024/04/28 16:43:42 florian Exp $ */ /* $EOM: log.c,v 1.30 2000/09/29 08:19:23 niklas Exp $ */ /* @@ -182,7 +182,11 @@ _log_print(int error, int syslog_level, const char *fmt, va_list ap, if (log_output) { gettimeofday(&now, 0); t = now.tv_sec; - tm = localtime(&t); + if ((tm = localtime(&t)) == NULL) { + /* Invalid time, use the epoch. */ + t = 0; + tm = localtime(&t); + } if (class >= 0) snprintf(nbuf, sizeof nbuf, "%02d%02d%02d.%06ld %s %02d ", diff --git a/sbin/isakmpd/policy.c b/sbin/isakmpd/policy.c index 9dbf339c0db..d76f39099c8 100644 --- a/sbin/isakmpd/policy.c +++ b/sbin/isakmpd/policy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: policy.c,v 1.102 2021/10/22 12:30:54 bluhm Exp $ */ +/* $OpenBSD: policy.c,v 1.103 2024/04/28 16:43:42 florian Exp $ */ /* $EOM: policy.c,v 1.49 2000/10/24 13:33:39 niklas Exp $ */ /* @@ -1728,13 +1728,23 @@ policy_callback(char *name) return phase_1; if (strcmp(name, "GMTTimeOfDay") == 0) { + struct tm *tm; tt = time(NULL); - strftime(mytimeofday, 14, "%Y%m%d%H%M%S", gmtime(&tt)); + if ((tm = gmtime(&tt)) == NULL) { + log_error("policy_callback: invalid time %lld", tt); + goto bad; + } + strftime(mytimeofday, 14, "%Y%m%d%H%M%S", tm); return mytimeofday; } if (strcmp(name, "LocalTimeOfDay") == 0) { + struct tm *tm; tt = time(NULL); - strftime(mytimeofday, 14, "%Y%m%d%H%M%S", localtime(&tt)); + if ((tm = localtime(&tt)) == NULL) { + log_error("policy_callback: invalid time %lld", tt); + goto bad; + } + strftime(mytimeofday, 14, "%Y%m%d%H%M%S", tm); return mytimeofday; } if (strcmp(name, "initiator") == 0) diff --git a/sbin/isakmpd/x509.c b/sbin/isakmpd/x509.c index 989553897e2..fae735d423b 100644 --- a/sbin/isakmpd/x509.c +++ b/sbin/isakmpd/x509.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509.c,v 1.125 2022/01/16 14:30:11 naddy Exp $ */ +/* $OpenBSD: x509.c,v 1.126 2024/04/28 16:43:42 florian Exp $ */ /* $EOM: x509.c,v 1.54 2001/01/16 18:42:16 ho Exp $ */ /* @@ -222,8 +222,15 @@ x509_generate_kn(int id, X509 *cert) if (((tm = X509_get_notBefore(cert)) == NULL) || (tm->type != V_ASN1_UTCTIME && tm->type != V_ASN1_GENERALIZEDTIME)) { - tt = time(0); - strftime(before, 14, "%Y%m%d%H%M%S", localtime(&tt)); + struct tm *ltm; + + tt = time(NULL); + if ((ltm = localtime(&tt)) == NULL) { + LOG_DBG((LOG_POLICY, 30, + "x509_generate_kn: invalid local time")); + goto fail; + } + strftime(before, 14, "%Y%m%d%H%M%S", ltm); timecomp = "LocalTimeOfDay"; } else { if (tm->data[tm->length - 1] == 'Z') { @@ -312,8 +319,15 @@ x509_generate_kn(int id, X509 *cert) if (tm == NULL || (tm->type != V_ASN1_UTCTIME && tm->type != V_ASN1_GENERALIZEDTIME)) { + struct tm *ltm; + tt = time(0); - strftime(after, 14, "%Y%m%d%H%M%S", localtime(&tt)); + if ((ltm = localtime(&tt)) == NULL) { + LOG_DBG((LOG_POLICY, 30, + "x509_generate_kn: invalid local time")); + goto fail; + } + strftime(after, 14, "%Y%m%d%H%M%S", ltm); timecomp2 = "LocalTimeOfDay"; } else { if (tm->data[tm->length - 1] == 'Z') { diff --git a/sbin/newfs_msdos/newfs_msdos.c b/sbin/newfs_msdos/newfs_msdos.c index dae0a704daa..0cc837778d8 100644 --- a/sbin/newfs_msdos/newfs_msdos.c +++ b/sbin/newfs_msdos/newfs_msdos.c @@ -1,4 +1,4 @@ -/* $OpenBSD: newfs_msdos.c,v 1.28 2021/07/11 15:39:58 kettenis Exp $ */ +/* $OpenBSD: newfs_msdos.c,v 1.29 2024/04/28 16:43:42 florian Exp $ */ /* * Copyright (c) 1998 Robert Nordier @@ -550,7 +550,9 @@ main(int argc, char *argv[]) if (!opt_N) { gettimeofday(&tv, NULL); now = tv.tv_sec; - tm = localtime(&now); + if ((tm = localtime(&now)) == NULL) + errx(1, "Invalid time"); + if (!(img = malloc(bpb.bps))) err(1, NULL); dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft; diff --git a/sbin/route/route.c b/sbin/route/route.c index 755e548e9cc..4228114edc7 100644 --- a/sbin/route/route.c +++ b/sbin/route/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.265 2023/03/17 16:11:09 claudio Exp $ */ +/* $OpenBSD: route.c,v 1.266 2024/04/28 16:43:42 florian Exp $ */ /* $NetBSD: route.c,v 1.16 1996/04/15 18:27:05 cgd Exp $ */ /* @@ -1878,7 +1878,10 @@ bfd_calc_uptime(time_t time) fmt = "%Ss"; tp = localtime(&time); - (void)strftime(buf, sizeof(buf), fmt, tp); + if (tp) + (void)strftime(buf, sizeof(buf), fmt, tp); + else + buf[0] = '\0'; return (buf); } diff --git a/sbin/shutdown/shutdown.c b/sbin/shutdown/shutdown.c index 2c74ae3d25a..adbf4cad54a 100644 --- a/sbin/shutdown/shutdown.c +++ b/sbin/shutdown/shutdown.c @@ -1,4 +1,4 @@ -/* $OpenBSD: shutdown.c,v 1.55 2023/04/19 12:58:15 jsg Exp $ */ +/* $OpenBSD: shutdown.c,v 1.56 2024/04/28 16:43:42 florian Exp $ */ /* $NetBSD: shutdown.c,v 1.9 1995/03/18 15:01:09 cgd Exp $ */ /* @@ -345,8 +345,13 @@ timewarn(time_t timeleft) if (timeleft > 10 * 60) { shuttime = time(NULL) + timeleft; lt = localtime(&shuttime); - strftime(when, sizeof(when), "%H:%M %Z", lt); - dprintf(fd[1], "System going down at %s\n\n", when); + if (lt != NULL) { + strftime(when, sizeof(when), "%H:%M %Z", lt); + dprintf(fd[1], "System going down at %s\n\n", when); + } else + dprintf(fd[1], "System going down in %lld minute%s\n\n", + (long long)(timeleft / 60), + (timeleft > 60) ? "s" : ""); } else if (timeleft > 59) { dprintf(fd[1], "System going down in %lld minute%s\n\n", (long long)(timeleft / 60), (timeleft > 60) ? "s" : ""); @@ -525,6 +530,9 @@ getoffset(char *timearg) time(&now); lt = localtime(&now); /* current time val */ + if (lt == NULL) + badtime(); + switch (strlen(timearg)) { case 10: this_year = lt->tm_year; @@ -595,10 +603,17 @@ nolog(time_t timeleft) (void)signal(SIGTERM, finish); shuttime = time(NULL) + timeleft; tm = localtime(&shuttime); - if (tm && (logfd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT|O_TRUNC, + if ((logfd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT|O_TRUNC, 0664)) >= 0) { - strftime(when, sizeof(when), "at %H:%M %Z", tm); - dprintf(logfd, "\n\nNO LOGINS: System going down %s\n\n", when); + if (tm) { + strftime(when, sizeof(when), "at %H:%M %Z", tm); + dprintf(logfd, + "\n\nNO LOGINS: System going down %s\n\n", when); + } else + dprintf(logfd, + "\n\nNO LOGINS: System going in %lld minute%s\n\n", + (long long)(timeleft / 60), + (timeleft > 60) ? "s" : ""); close(logfd); } } diff --git a/sbin/unwind/libunbound/util/log.c b/sbin/unwind/libunbound/util/log.c index a15ee920c0f..86a3acee43c 100644 --- a/sbin/unwind/libunbound/util/log.c +++ b/sbin/unwind/libunbound/util/log.c @@ -271,8 +271,8 @@ log_vmsg(int pri, const char* type, } now = (time_t)time(NULL); #if defined(HAVE_STRFTIME) && defined(HAVE_LOCALTIME_R) - if(log_time_asc && strftime(tmbuf, sizeof(tmbuf), "%b %d %H:%M:%S", - localtime_r(&now, &tm))%(sizeof(tmbuf)) != 0) { + if(log_time_asc && localtime_r(&now, &tm) && strftime(tmbuf, + sizeof(tmbuf), "%b %d %H:%M:%S", &tm)%(sizeof(tmbuf)) != 0) { /* %sizeof buf!=0 because old strftime returned max on error */ fprintf(logfile, "%s %s[%d:%x] %s: %s\n", tmbuf, ident, (int)getpid(), tid?*tid:0, type, message); -- 2.20.1