diff --git a/time/tzfile.c b/time/tzfile.c index 144e20b..5177148 100644 --- a/time/tzfile.c +++ b/time/tzfile.c @@ -234,14 +234,27 @@ __tzfile_read (const char *file, size_t extra, char **extrap) goto read_again; } + if (num_transitions + > ((SIZE_MAX - (__alignof__ (struct ttinfo) - 1)) / (sizeof (time_t) + 1))) + goto lose; total_size = num_transitions * (sizeof (time_t) + 1); total_size = ((total_size + __alignof__ (struct ttinfo) - 1) & ~(__alignof__ (struct ttinfo) - 1)); types_idx = total_size; + if (num_types > SIZE_MAX / sizeof (struct ttinfo) + || total_size + num_types * sizeof (struct ttinfo) < total_size + || total_size + num_types * sizeof (struct ttinfo) + chars < chars + || ((total_size + num_types * sizeof (struct ttinfo) + chars + + __alignof__ (struct leap) - 1) + < __alignof__ (struct leap) - 1)) + goto lose; total_size += num_types * sizeof (struct ttinfo) + chars; total_size = ((total_size + __alignof__ (struct leap) - 1) & ~(__alignof__ (struct leap) - 1)); leaps_idx = total_size; + if (num_leaps > SIZE_MAX / sizeof (struct leap) + || total_size + num_leaps * sizeof (struct leap) < total_size) + goto lose; total_size += num_leaps * sizeof (struct leap); tzspec_len = (sizeof (time_t) == 8 && trans_width == 8 ? st.st_size - (ftello (f) @@ -251,6 +264,9 @@ __tzfile_read (const char *file, size_t extra, char **extrap) + num_leaps * 12 + num_isstd + num_isgmt) - 1 : 0); + if (total_size + tzspec_len < tzspec_len + || total_size + tzspec_len + extra < extra) + goto lose; /* Allocate enough memory including the extra block requested by the caller. */