This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

integer overflow to heap overrun exploit in glibc


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

As y'all may be aware, there's an integer overflow which can be used
to trigger a heap overrun/corruption in time/tzfile.c

http://dividead.wordpress.com/2009/06/01/glibc-timezone-integer-overflow/


http://rcvalle.com/post/14169476482/exploiting-glibc-tzfile-read-integer-overflow-to


I'm not terribly familiar with the code in question, but ISTM we have
to verify the intermediate computations to determine the amount of
memory to malloc don't overflow/wrap.

Here's a WIP.  It catches the cases I've been made aware of
(overflowing total_size to 0 by creating a tzfile with a very large
tzh_charcnt).  But there may be further overflows I've missed.

Obviously it's not commented and it's unclear to me if we also want to
put in some kind of sanity checks on total_size to prevent it from
trying to malloc unreasoanble amounts of memory.

Your feedback would be greatly appreciated.




-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJO6k6gAAoJEBRtltQi2kC7ASQH/0UmQm0wqk3NRmlsVr5M1r3f
fUelY55y8OQssaFCLDZ9LX1vybam9j85gmvGtRJUU4MJ3134hn/v73k8TYCd3rHJ
/QIQY10zPBHkmEwp8G56+3l9QRl418C+ajTq0W4NAzM1rIHtPUgrqZ3AkNJgFVYU
OAF+2afFDGE5vJ3HR7LSL62tuxjDf7m66r4tHHkbhkSSZgkyW/YxfFUPDupZnlz8
Wl87JU/RWHdMJ+RR+fB1ofgFKrNZnGpIsD3sAc07KWTp63S358DSRpZ1IaF2o3vh
N93z28eCQQKIVciOKgAE5q/qYr1KmcyU/6M4xPk+Pqv5YFdKOz8uNiw5NQu2rv0=
=RKgA
-----END PGP SIGNATURE-----
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;
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]