diff -rup a/time/tzfile.c b/time/tzfile.c --- a/time/tzfile.c 2011-10-19 05:03:31.000000000 -0600 +++ b/time/tzfile.c 2011-12-15 11:49:26.763121459 -0700 @@ -107,7 +107,7 @@ __tzfile_read (const char *file, size_t size_t num_isstd, num_isgmt; register FILE *f; struct tzhead tzhead; - size_t chars; + size_t chars, tmp; register size_t i; size_t total_size; size_t types_idx; @@ -238,11 +238,25 @@ __tzfile_read (const char *file, size_t total_size = ((total_size + __alignof__ (struct ttinfo) - 1) & ~(__alignof__ (struct ttinfo) - 1)); types_idx = total_size; - total_size += num_types * sizeof (struct ttinfo) + chars; + + tmp = num_types * sizeof (struct ttinfo); + if (total_size + tmp < tmp) + goto lose; + total_size += tmp; + + if (total_size + chars < chars) + goto lose; + total_size += chars; + total_size = ((total_size + __alignof__ (struct leap) - 1) & ~(__alignof__ (struct leap) - 1)); leaps_idx = total_size; - total_size += num_leaps * sizeof (struct leap); + + tmp = num_leaps * sizeof (struct leap); + if (total_size + tmp < tmp) + goto lose; + total_size += tmp; + tzspec_len = (sizeof (time_t) == 8 && trans_width == 8 ? st.st_size - (ftello (f) + num_transitions * (8 + 1) @@ -254,7 +268,15 @@ __tzfile_read (const char *file, size_t /* Allocate enough memory including the extra block requested by the caller. */ - transitions = (time_t *) malloc (total_size + tzspec_len + extra); + if (total_size + tzspec_len < total_size) + goto lose; + total_size += tzspec_len; + + if (total_size + extra < extra) + goto lose; + total_size += extra; + + transitions = (time_t *) malloc (total_size); if (transitions == NULL) goto lose;