]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Fix fr_unix_time_from_t crash from clusterfuzz
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 31 Oct 2021 06:24:48 +0000 (02:24 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 31 Oct 2021 06:26:00 +0000 (02:26 -0400)
For some reason maximum month value was set to 13, which created a buffer overrun.

src/lib/util/time.c

index 444aebc72611d426a4e642eeb97ea0bdca6fe2f1..df36cc9de48b8f6eaf7f909b155b616ae487452c 100644 (file)
@@ -644,7 +644,12 @@ fr_unix_time_t fr_unix_time_from_tm(struct tm *tm)
        uint32_t year_adj = tm->tm_year + 4800 + 1900;  /* Ensure positive year, multiple of 400. */
        uint32_t febs = year_adj - (tm->tm_mon <= 2 ? 1 : 0);  /* Februaries since base. */
        uint32_t leap_days = 1 + (febs / 4) - (febs / 100) + (febs / 400);
-       uint32_t days = 365 * year_adj + leap_days + month_yday[tm->tm_mon] + tm->tm_mday - 1;
+       uint32_t days;
+
+       /* Prevent crash if tm->tm_mon is invalid - seen in clusterfuzz */
+       if (unlikely(tm->tm_mon > (__typeof__(tm->tm_mon))NUM_ELEMENTS(month_yday))) return fr_unix_time_min();
+
+       days = 365 * year_adj + leap_days + month_yday[tm->tm_mon] + tm->tm_mday - 1;
 
 #define CHECK(_x, _max) if ((tm->tm_ ## _x < 0) || (tm->tm_ ## _x >= _max)) tm->tm_ ## _x = _max - 1
 
@@ -830,7 +835,7 @@ int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_re
                p = tail + 1;
                s_tm.tm_year = tmp - 1900; /* 'struct tm' starts years in 1900 */
 
-               if (get_part(&p, &s_tm.tm_mon, 1, 13, '-', "month") < 0) return -1;
+               if (get_part(&p, &s_tm.tm_mon, 1, 12, '-', "month") < 0) return -1;
                s_tm.tm_mon--;  /* ISO is 1..12, where 'struct tm' is 0..11 */
 
                if (get_part(&p, &s_tm.tm_mday, 1, 31, 'T', "day") < 0) return -1;