From patchwork Wed Oct 29 07:33:19 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Eggert X-Patchwork-Id: 3459 Received: (qmail 24493 invoked by alias); 29 Oct 2014 07:33:28 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 24478 invoked by uid 89); 29 Oct 2014 07:33:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-HELO: smtp.cs.ucla.edu Message-ID: <5450983F.3030608@cs.ucla.edu> Date: Wed, 29 Oct 2014 00:33:19 -0700 From: Paul Eggert User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: Alan Modra , libc-alpha@sourceware.org, bug-gnulib@gnu.org Subject: Re: [PATCH 0/5] obstacks again References: <20141029033201.GI4267@bubble.grove.modra.org> In-Reply-To: <20141029033201.GI4267@bubble.grove.modra.org> Thanks for doing all this. The gnulib patches are good as far as they go, but they need one more change: alignments should also change from int to size_t. The first attached gnulib patch does that, plus it fixes a longstanding integer overflow bug that can occur with large alignments (plus large sizes). While we're in the neighborhood we should be using C11's alignof rather than reinventing that particular wheel; the second attached gnulib patch does that. I've installed your five gnulib patches plus the two attached patches into gnulib. Two things for the glibc patch. First, the updated gnulib patches need to be merged into the glibc patch. Second, the manual needs to be updated to match the revised API induced by all these patches. And thanks again. 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 *)