Commit e1c6431e authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

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.
parent be6928d6
Loading
Loading
Loading
Loading

changes/bug4230

0 → 100644
+5 −0
Original line number Diff line number Diff line
  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.
+14 −5
Original line number Diff line number Diff line
@@ -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;
    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;
    tor_assert(higher > 0); /* detect overflow */
    }
    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));
  }
}