From: Nick Mathewson Date: Wed, 9 Nov 2011 17:08:28 +0000 (-0500) Subject: Correct the handling of overflow behavior in smartlist_ensure_capacity X-Git-Tag: tor-0.2.2.35~9^2^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1c6431e42bc6b5619c78008cbe92730ead57bbf;p=thirdparty%2Ftor.git Correct the handling of overflow behavior in smartlist_ensure_capacity The old behavior was susceptible to the compiler optimizing out our assertion check, *and* could still overflow size_t on 32-bit systems even when it did work. --- diff --git a/changes/bug4230 b/changes/bug4230 new file mode 100644 index 0000000000..c1ba5847fc --- /dev/null +++ b/changes/bug4230 @@ -0,0 +1,5 @@ + o Minor bugfixes: + - Resolve an integer overflow bug in smartlist_ensure_capacity. + Fixes bug 4230; bugfix on Tor 0.1.0.1-rc. Based on a patch by + Mansour Moufid. + diff --git a/src/common/container.c b/src/common/container.c index c741eb0206..edfcd973f3 100644 --- a/src/common/container.c +++ b/src/common/container.c @@ -61,13 +61,22 @@ smartlist_clear(smartlist_t *sl) static INLINE void smartlist_ensure_capacity(smartlist_t *sl, int size) { +#if SIZEOF_SIZE_T > SIZEOF_INT +#define MAX_CAPACITY (INT_MAX) +#else +#define MAX_CAPACITY (int)((SIZE_MAX / (sizeof(void*)))) +#endif if (size > sl->capacity) { - int higher = sl->capacity * 2; - while (size > higher) - higher *= 2; - tor_assert(higher > 0); /* detect overflow */ + int higher = sl->capacity; + if (PREDICT_UNLIKELY(size > MAX_CAPACITY/2)) { + tor_assert(size <= MAX_CAPACITY); + higher = MAX_CAPACITY; + } else { + while (size > higher) + higher *= 2; + } sl->capacity = higher; - sl->list = tor_realloc(sl->list, sizeof(void*)*sl->capacity); + sl->list = tor_realloc(sl->list, sizeof(void*)*((size_t)sl->capacity)); } }