Просмотр исходного кода

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.
Nick Mathewson 12 лет назад
Родитель
Сommit
e1c6431e42
2 измененных файлов с 19 добавлено и 5 удалено
  1. 5 0
      changes/bug4230
  2. 14 5
      src/common/container.c

+ 5 - 0
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.
+

+ 14 - 5
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));
   }
 }