This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch master updated. glibc-2.29.9000-20-gb8c7238
- From: fw at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 3 Feb 2019 21:15:56 -0000
- Subject: GNU C Library master sources branch master updated. glibc-2.29.9000-20-gb8c7238
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".
The branch, master has been updated
via b8c7238167de4c080b8b0909213bc7b5abef46e3 (commit)
from 11f382ee780649549428cb25af3a9f1d3465868d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b8c7238167de4c080b8b0909213bc7b5abef46e3
commit b8c7238167de4c080b8b0909213bc7b5abef46e3
Author: Florian Weimer <fweimer@redhat.com>
Date: Sun Feb 3 22:13:51 2019 +0100
time: Use struct alloc_buffer in __tzfile_read
The computation of tzspec_len is moved in front of the total_size
computation, so that the allocation size computation and the
suballocations are next to each other. Also add an assert that
tzspec_len is positive when it is actually used later.
diff --git a/ChangeLog b/ChangeLog
index 8260429..bc1b17f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2019-02-03 Florian Weimer <fweimer@redhat.com>
+
+ * time/tzfile.c (__tzfile_read): Use struct alloc_buffer and its
+ implicit overflow checks.
+
2019-02-03 Aurelien Jarno <aurelien@aurel32.net>
* stdlib/isomac.c: Include <unistd.h>.
diff --git a/time/tzfile.c b/time/tzfile.c
index a07e7c5..e107b33 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -25,6 +25,7 @@
#include <unistd.h>
#include <sys/stat.h>
#include <stdint.h>
+#include <alloc_buffer.h>
#include <timezone/tzfile.h>
@@ -105,12 +106,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
struct tzhead tzhead;
size_t chars;
size_t i;
- size_t total_size;
- size_t types_idx;
- size_t leaps_idx;
int was_using_tzfile = __use_tzfile;
int trans_width = 4;
- size_t tzspec_len;
char *new = NULL;
_Static_assert (sizeof (__time64_t) == 8,
@@ -215,32 +212,9 @@ __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 (__time64_t) + 1)), 0))
- goto lose;
- total_size = num_transitions * (sizeof (__time64_t) + 1);
- total_size = ((total_size + __alignof__ (struct ttinfo) - 1)
- & ~(__alignof__ (struct ttinfo) - 1));
- types_idx = total_size;
- if (__builtin_expect (num_types
- > (SIZE_MAX - total_size) / sizeof (struct ttinfo), 0))
- goto lose;
- total_size += num_types * sizeof (struct ttinfo);
- if (__glibc_unlikely (chars > SIZE_MAX - total_size))
- 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 = 0;
+ /* Compute the size of the POSIX time zone specification in the
+ file. */
+ size_t tzspec_len;
if (trans_width == 8)
{
off_t rem = st.st_size - __ftello (f);
@@ -262,30 +236,56 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
if (__glibc_unlikely (tzspec_len == 0 || tzspec_len - 1 < num_isgmt))
goto lose;
tzspec_len -= num_isgmt + 1;
- if (__glibc_unlikely (tzspec_len == 0
- || SIZE_MAX - total_size < tzspec_len))
+ if (tzspec_len == 0)
goto lose;
}
- if (__glibc_unlikely (SIZE_MAX - total_size - tzspec_len < extra))
- goto lose;
-
- /* Allocate enough memory including the extra block requested by the
- caller. */
- transitions = malloc (total_size + tzspec_len + extra);
- if (transitions == NULL)
- goto lose;
-
- type_idxs = (unsigned char *) transitions + (num_transitions
- * sizeof (__time64_t));
- types = (struct ttinfo *) ((char *) transitions + types_idx);
- zone_names = (char *) types + num_types * sizeof (struct ttinfo);
- leaps = (struct leap *) ((char *) transitions + leaps_idx);
+ else
+ tzspec_len = 0;
+
+ /* The file is parsed into a single heap allocation, comprising of
+ the following arrays:
+
+ __time64_t transitions[num_transitions];
+ struct ttinfo types[num_types];
+ unsigned char type_idxs[num_types];
+ char zone_names[chars];
+ struct leap leaps[num_leaps];
+ char extra_array[extra]; // Stored into *pextras if requested.
+ char tzspec[tzspec_len];
+
+ The piece-wise allocations from buf below verify that no
+ overflow/wraparound occurred in these computations. */
+ struct alloc_buffer buf;
+ {
+ size_t total_size = num_transitions * (sizeof (__time64_t) + 1);
+ total_size = ((total_size + __alignof__ (struct ttinfo) - 1)
+ & ~(__alignof__ (struct ttinfo) - 1));
+ total_size += num_types * sizeof (struct ttinfo) + chars;
+ total_size = ((total_size + __alignof__ (struct leap) - 1)
+ & ~(__alignof__ (struct leap) - 1));
+ total_size += num_leaps * sizeof (struct leap) + tzspec_len + extra;
+
+ transitions = malloc (total_size);
+ if (transitions == NULL)
+ goto lose;
+ buf = alloc_buffer_create (transitions, total_size);
+ }
+
+ /* The address of the first allocation is already stored in the
+ pointer transitions. */
+ (void) alloc_buffer_alloc_array (&buf, __time64_t, num_transitions);
+ type_idxs = alloc_buffer_alloc_array (&buf, unsigned char, num_transitions);
+ types = alloc_buffer_alloc_array (&buf, struct ttinfo, num_types);
+ zone_names = alloc_buffer_alloc_array (&buf, char, chars);
+ leaps = alloc_buffer_alloc_array (&buf, struct leap, num_leaps);
+ if (extra > 0)
+ *extrap = alloc_buffer_alloc_array (&buf, char, extra);
if (trans_width == 8)
- tzspec = (char *) leaps + num_leaps * sizeof (struct leap) + extra;
+ tzspec = alloc_buffer_alloc_array (&buf, char, tzspec_len);
else
tzspec = NULL;
- if (extra > 0)
- *extrap = (char *) &leaps[num_leaps];
+ if (alloc_buffer_has_failed (&buf))
+ goto lose;
if (__builtin_expect (trans_width == 8, 1))
{
@@ -390,6 +390,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
/* Read the POSIX TZ-style information if possible. */
if (tzspec != NULL)
{
+ assert (tzspec_len > 0);
/* Skip over the newline first. */
if (__getc_unlocked (f) != '\n'
|| (__fread_unlocked (tzspec, 1, tzspec_len - 1, f)
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 5 +++
time/tzfile.c | 99 +++++++++++++++++++++++++++++----------------------------
2 files changed, 55 insertions(+), 49 deletions(-)
hooks/post-receive
--
GNU C Library master sources