From 97ac2654b2d831acaa18a2b018b0736245903fd2 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 17 Dec 2011 20:18:42 -0500 Subject: [PATCH] Check values from TZ file header --- ChangeLog | 5 +++++ NEWS | 2 +- time/tzfile.c | 53 ++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4aad7eec6e..93f8760812 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-17 Ulrich Drepper + + [BZ #13506] + * time/tzfile.c (__tzfile_read): Check values from file header. + 2011-11-21 Will Schmidt * powerpc/powerpc32/sysdep.h: Define SETUP_GOT_ACCESS() macro. diff --git a/NEWS b/NEWS index 241a4e9d98..6e0c1d7e7c 100644 --- a/NEWS +++ b/NEWS @@ -12,7 +12,7 @@ Version 2.15 6779, 6783, 9696, 10103, 10709, 11589, 12403, 12847, 12868, 12852, 12874, 12885, 12892, 12907, 12922, 12935, 13007, 13021, 13067, 13068, 13090, 13092, 13114, 13118, 13123, 13134, 13138, 13147, 13150, 13179, 13192, - 13268, 13276, 13291, 13335, 13337, 13344, 13358, 13367 + 13268, 13276, 13291, 13335, 13337, 13344, 13358, 13367, 13506 * New program pldd to list loaded object of a process Implemented by Ulrich Drepper. diff --git a/time/tzfile.c b/time/tzfile.c index 144e20ba2e..402389c9f3 100644 --- a/time/tzfile.c +++ b/time/tzfile.c @@ -234,23 +234,58 @@ __tzfile_read (const char *file, size_t extra, char **extrap) goto read_again; } + if (__builtin_expect (num_transitions + > ((SIZE_MAX - (__alignof__ (struct ttinfo) - 1)) + / (sizeof (time_t) + 1)), 0)) + 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; - total_size += num_types * sizeof (struct ttinfo) + chars; + if (__builtin_expect (num_types + > (SIZE_MAX - total_size) / sizeof (struct ttinfo), 0)) + goto lose; + total_size += num_types * sizeof (struct ttinfo); + if (__builtin_expect (chars > SIZE_MAX - total_size, 0)) + goto lose; + total_size += chars; + if (__builtin_expect (__alignof__ (struct leap) - 1 + > SIZE_MAX - total_size, 0)) + goto lose; total_size = ((total_size + __alignof__ (struct leap) - 1) & ~(__alignof__ (struct leap) - 1)); leaps_idx = total_size; + if (__builtin_expect (num_leaps + > (SIZE_MAX - total_size) / sizeof (struct leap), 0)) + goto lose; total_size += num_leaps * sizeof (struct leap); - tzspec_len = (sizeof (time_t) == 8 && trans_width == 8 - ? st.st_size - (ftello (f) - + num_transitions * (8 + 1) - + num_types * 6 - + chars - + num_leaps * 12 - + num_isstd - + num_isgmt) - 1 : 0); + tzspec_len = 0; + if (sizeof (time_t) == 8 && trans_width == 8) + { + off_t rem = st.st_size - ftello (f); + if (__builtin_expect (rem < 0 + || (size_t) rem < (num_transitions * (8 + 1) + + num_types * 6 + + chars), 0)) + goto lose; + tzspec_len = (size_t) rem - (num_transitions * (8 + 1) + + num_types * 6 + + chars); + if (__builtin_expect (num_leaps > SIZE_MAX / 12 + || tzspec_len < num_leaps * 12, 0)) + goto lose; + tzspec_len -= num_leaps * 12; + if (__builtin_expect (tzspec_len < num_isstd, 0)) + goto lose; + tzspec_len -= num_isstd; + if (__builtin_expect (tzspec == 0 || tzspec_len - 1 < num_isgmt, 0)) + goto lose; + tzspec_len -= num_isgmt + 1; + if (__builtin_expect (SIZE_MAX - total_size < tzspec_len, 0)) + goto lose; + } + if (__builtin_expect (SIZE_MAX - total_size - tzspec_len < extra, 0)) + goto lose; /* Allocate enough memory including the extra block requested by the caller. */