fix integer overflows in time_t/struct tm conversion code
authorRich Felker <dalias@aerifal.cx>
Thu, 8 Oct 2015 23:30:42 +0000 (23:30 +0000)
committerRich Felker <dalias@aerifal.cx>
Thu, 8 Oct 2015 23:30:42 +0000 (23:30 +0000)
as found and reported by Brian Mastenbrook, the expressions
400*qc_cycles and years+100 in __secs_to_tm were both subject to
integer overflow for extreme values of the input t.

this patch by Szabolcs Nagy fixes the code by switching to larger
types, and matches the original intent I had in mind when writing this
code.

src/time/__secs_to_tm.c

index f3c1cf923e8c529f642416922eeda60f36269155..3a3123a1b457bb65dc7b9c61ecaf017db3f671b1 100644 (file)
 
 int __secs_to_tm(long long t, struct tm *tm)
 {
-       long long days, secs;
+       long long days, secs, years;
        int remdays, remsecs, remyears;
        int qc_cycles, c_cycles, q_cycles;
-       int years, months;
+       int months;
        int wday, yday, leap;
        static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
 
@@ -55,7 +55,7 @@ int __secs_to_tm(long long t, struct tm *tm)
        yday = remdays + 31 + 28 + leap;
        if (yday >= 365+leap) yday -= 365+leap;
 
-       years = remyears + 4*q_cycles + 100*c_cycles + 400*qc_cycles;
+       years = remyears + 4*q_cycles + 100*c_cycles + 400LL*qc_cycles;
 
        for (months=0; days_in_month[months] <= remdays; months++)
                remdays -= days_in_month[months];