From 421a53ad006c9ad9a1cad0b1e42246c01ffa3154 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 28 Oct 2014 23:58:42 -0700 Subject: [PATCH 1/2] obstack: use size_t alignments and check for overflow * lib/obstack.c, lib/obstack.h (_obstack_begin, _obstack_begin_1): * lib/obstack.c (_obstack_begin_worker, _obstack_newchunk): * lib/obstack.h (struct obstack.alignment_mask): Use _OBSTACK_SIZE_T, not int, for alignments. * lib/obstack.c (_obstack_newchunk): Fail if the size calculation overflows, e.g., when adding the alignment. --- ChangeLog | 10 ++++++++++ lib/obstack.c | 18 +++++++++++------- lib/obstack.h | 8 +++++--- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7aac7eb..8bf2baa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2014-10-28 Paul Eggert + + obstack: use size_t alignments and check for overflow + * lib/obstack.c, lib/obstack.h (_obstack_begin, _obstack_begin_1): + * lib/obstack.c (_obstack_begin_worker, _obstack_newchunk): + * lib/obstack.h (struct obstack.alignment_mask): + Use _OBSTACK_SIZE_T, not int, for alignments. + * lib/obstack.c (_obstack_newchunk): Fail if the size calculation + overflows, e.g., when adding the alignment. + 2014-10-24 Paul Eggert socketlib, sockets, sys_socket: Use AC_REQUIRE to pacify autoconf. diff --git a/lib/obstack.c b/lib/obstack.c index 8e247fb..342f9f8 100644 --- a/lib/obstack.c +++ b/lib/obstack.c @@ -106,7 +106,7 @@ typedef void (*freefun_type) (void *, struct _obstack_chunk *); static int _obstack_begin_worker (struct obstack *h, - _OBSTACK_SIZE_T size, int alignment, + _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment, chunkfun_type chunkfun, freefun_type freefun) { struct _obstack_chunk *chunk; /* points to new chunk */ @@ -150,7 +150,7 @@ _obstack_begin_worker (struct obstack *h, int _obstack_begin (struct obstack *h, - _OBSTACK_SIZE_T size, int alignment, + _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment, void *(*chunkfun) (size_t), void (*freefun) (void *)) { @@ -162,7 +162,7 @@ _obstack_begin (struct obstack *h, int _obstack_begin_1 (struct obstack *h, - _OBSTACK_SIZE_T size, int alignment, + _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment, void *(*chunkfun) (void *, size_t), void (*freefun) (void *, void *), void *arg) @@ -184,18 +184,22 @@ void _obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length) { struct _obstack_chunk *old_chunk = h->chunk; - struct _obstack_chunk *new_chunk; - size_t new_size; + struct _obstack_chunk *new_chunk = 0; size_t obj_size = h->next_free - h->object_base; char *object_base; /* Compute size for new chunk. */ - new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100; + size_t sum1 = obj_size + length; + size_t sum2 = sum1 + h->alignment_mask; + size_t new_size = sum2 + (obj_size >> 3) + 100; + if (new_size < sum2) + new_size = sum2; if (new_size < h->chunk_size) new_size = h->chunk_size; /* Allocate and initialize the new chunk. */ - new_chunk = CALL_CHUNKFUN (h, new_size); + if (obj_size <= sum1 && sum1 <= sum2) + new_chunk = CALL_CHUNKFUN (h, new_size); if (!new_chunk) (*obstack_alloc_failed_handler)(); h->chunk = new_chunk; diff --git a/lib/obstack.h b/lib/obstack.h index 909d0d3..ba4de1d 100644 --- a/lib/obstack.h +++ b/lib/obstack.h @@ -166,7 +166,7 @@ struct obstack /* control current object in current chunk */ _OBSTACK_SIZE_T i; void *p; } temp; /* Temporary for some macros. */ - int alignment_mask; /* Mask of alignment for each object. */ + _OBSTACK_SIZE_T alignment_mask; /* Mask of alignment for each object. */ /* These prototypes vary based on 'use_extra_arg', and we use casts to the prototypeless function type in all assignments, but having prototypes here quiets -Wstrict-prototypes. */ @@ -187,9 +187,11 @@ struct obstack /* control current object in current chunk */ extern void _obstack_newchunk (struct obstack *, _OBSTACK_SIZE_T); extern void _obstack_free (struct obstack *, void *); -extern int _obstack_begin (struct obstack *, _OBSTACK_SIZE_T, int, +extern int _obstack_begin (struct obstack *, + _OBSTACK_SIZE_T, _OBSTACK_SIZE_T, void *(*)(size_t), void (*)(void *)); -extern int _obstack_begin_1 (struct obstack *, _OBSTACK_SIZE_T, int, +extern int _obstack_begin_1 (struct obstack *, + _OBSTACK_SIZE_T, _OBSTACK_SIZE_T, void *(*)(void *, size_t), void (*)(void *, void *), void *); extern _OBSTACK_SIZE_T _obstack_memory_used (struct obstack *) -- 1.9.3