From a1dcc55a70bd1ca2c3ff7d41fd7251235d229a28 Mon Sep 17 00:00:00 2001 From: Kevin McCarthy Date: Sun, 23 Oct 2016 13:43:56 -0700 Subject: Prevent an integer overflow in mutt_mktime() (closes #3880) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check to make sure the year passed in isn't bigger than can be represented using time_t on the platform. Also add a (time_t) cast to an intermediate "years * 365" calculation to prevent an overflow there. Thanks to TAKAHASHI Tamotsu for his patch, and to Vincent Lefèvre for his improvement. I merely took their code and commited it. --- date.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'date.c') diff --git a/date.c b/date.c index c173fe65..6fd7eaf9 100644 --- a/date.c +++ b/date.c @@ -63,6 +63,10 @@ time_t mutt_local_tz (time_t t) return (compute_tz (t, &utc)); } +/* theoretically time_t can be float but it is integer on most (if not all) systems */ +#define TIME_T_MAX ((((time_t) 1 << (sizeof(time_t) * 8 - 2)) - 1) * 2 + 1) +#define TM_YEAR_MAX (1970 + (((((TIME_T_MAX - 59) / 60) - 59) / 60) - 23) / 24 / 366) + /* converts struct tm to time_t, but does not take the local timezone into account unless ``local'' is nonzero */ time_t mutt_mktime (struct tm *t, int local) @@ -73,6 +77,10 @@ time_t mutt_mktime (struct tm *t, int local) 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + /* Prevent an integer overflow */ + if (t->tm_year > TM_YEAR_MAX) + return TIME_T_MAX; + /* Compute the number of days since January 1 in the same year */ g = AccumDaysPerMonth [t->tm_mon % 12]; @@ -84,7 +92,7 @@ time_t mutt_mktime (struct tm *t, int local) t->tm_yday = g; /* Compute the number of days since January 1, 1970 */ - g += (t->tm_year - 70) * 365; + g += (t->tm_year - 70) * (time_t)365; g += (t->tm_year - 69) / 4; /* Compute the number of hours */ -- cgit v1.2.3