about summary refs log tree commit diff
path: root/time/tzfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'time/tzfile.c')
-rw-r--r--time/tzfile.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/time/tzfile.c b/time/tzfile.c
index bcb408fcdb..46d4fc71ae 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -200,6 +200,9 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
   num_isstd = (size_t) decode (tzhead.tzh_ttisstdcnt);
   num_isgmt = (size_t) decode (tzhead.tzh_ttisgmtcnt);
 
+  if (__glibc_unlikely (num_isstd > num_types || num_isgmt > num_types))
+    goto lose;
+
   /* For platforms with 64-bit time_t we use the new format if available.  */
   if (sizeof (time_t) == 8 && trans_width == 4
       && tzhead.tzh_version[0] != '\0')
@@ -434,13 +437,21 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
 	goto lose;
 
       tzspec_len = st.st_size - off - 1;
-      char *tzstr = alloca (tzspec_len);
+      if (tzspec_len == 0)
+	goto lose;
+      char *tzstr = malloc (tzspec_len);
+      if (tzstr == NULL)
+	goto lose;
       if (getc_unlocked (f) != '\n'
 	  || (__fread_unlocked (tzstr, 1, tzspec_len - 1, f)
 	      != tzspec_len - 1))
-	goto lose;
+	{
+	  free (tzstr);
+	  goto lose;
+	}
       tzstr[tzspec_len - 1] = '\0';
       tzspec = __tzstring (tzstr);
+      free (tzstr);
     }
 
   /* Don't use an empty TZ string.  */