]> jfr.im git - solanum.git/commitdiff
Make valid_temp_time overflow-resistant
authorEd Kellett <redacted>
Fri, 18 Mar 2022 18:13:31 +0000 (18:13 +0000)
committerEd Kellett <redacted>
Wed, 13 Apr 2022 00:09:27 +0000 (01:09 +0100)
include/s_newconf.h
ircd/s_newconf.c

index 82a466dd76dd14d437a0f0b6586e6ab8cd654686..87319892385b6cf893fc704b3d77b2c31ea9346c 100644 (file)
@@ -40,6 +40,8 @@
 #include <openssl/rsa.h>
 #endif
 
+#define MAX_TEMP_TIME (52 * 7 * 24 * 60 * 60)
+
 struct Client;
 struct ConfItem;
 
index 0ee96e3e310eae50d003defc8cb758911ab7dbf4..6688c6ef3a68d37e926c9e00640631e1a7bab8d1 100644 (file)
@@ -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. */