From ba95896969f7227c9931259b43ebc150d535894b Mon Sep 17 00:00:00 2001 From: Ed Kellett Date: Fri, 18 Mar 2022 18:13:31 +0000 Subject: [PATCH] Make valid_temp_time overflow-resistant --- include/s_newconf.h | 2 ++ ircd/s_newconf.c | 23 ++++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/s_newconf.h b/include/s_newconf.h index 82a466dd..87319892 100644 --- a/include/s_newconf.h +++ b/include/s_newconf.h @@ -40,6 +40,8 @@ #include #endif +#define MAX_TEMP_TIME (52 * 7 * 24 * 60 * 60) + struct Client; struct ConfItem; diff --git a/ircd/s_newconf.c b/ircd/s_newconf.c index 0ee96e3e..6688c6ef 100644 --- a/ircd/s_newconf.c +++ b/ircd/s_newconf.c @@ -687,8 +687,11 @@ valid_temp_time(const char *p) time_t result = 0; long current = 0; + time_t max_time = (uintmax_t) (~(time_t)0) >> 1; + while (*p) { char *endp; + int mul; errno = 0; current = strtol(p, &endp, 10); @@ -703,28 +706,38 @@ valid_temp_time(const char *p) switch (*endp) { case '\0': /* No unit was given so send it back as minutes */ case 'm': - result += current * 60; + mul = 60; break; case 'h': - result += current * 3600; + mul = 3600; break; case 'd': - result += current * 86400; + mul = 86400; break; case 'w': - result += current * 604800; + mul = 604800; break; default: return -1; } + if (current > LONG_MAX / mul) + return MAX_TEMP_TIME; + + current *= mul; + + if (current > max_time - result) + return MAX_TEMP_TIME; + + result += current; + if (*endp == '\0') break; p = endp + 1; } - return MIN(result, 60 * 60 * 24 * 7 * 52); + return MIN(result, MAX_TEMP_TIME); } /* Propagated bans are expired elsewhere. */