]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Check values from TZ file header
authorUlrich Drepper <drepper@gmail.com>
Sun, 18 Dec 2011 01:18:42 +0000 (20:18 -0500)
committerUlrich Drepper <drepper@gmail.com>
Sun, 18 Dec 2011 01:18:42 +0000 (20:18 -0500)
ChangeLog
NEWS
time/tzfile.c

index 4aad7eec6ed09e2d407cc4f42a2e935124bc3091..93f8760812331ac7abdac849a7cd50dd7c4518a1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2011-12-17  Ulrich Drepper  <drepper@gmail.com>
+
+       [BZ #13506]
+       * time/tzfile.c (__tzfile_read): Check values from file header.
+
 2011-11-21  Will Schmidt  <will_schmidt@vnet.ibm.com>
 
        * powerpc/powerpc32/sysdep.h: Define SETUP_GOT_ACCESS() macro.
diff --git a/NEWS b/NEWS
index 241a4e9d98086f1306d536ca14fe9820d47fb970..6e0c1d7e7c902c2b88fcf87ff95270662441860f 100644 (file)
--- 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.
index 144e20ba2ee6a7cc641734384c88418290c0d28c..402389c9f3ddb2b08d987c1160f8b7a93ac32879 100644 (file)
@@ -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.  */