Title: [184883] trunk/Source/bmalloc
Revision
184883
Author
[email protected]
Date
2015-05-26 15:48:13 -0700 (Tue, 26 May 2015)

Log Message

Integer overflow in XLarge allocation (due to unchecked roundUpToMultipleOf)
https://bugs.webkit.org/show_bug.cgi?id=145385

Reviewed by Andreas Kling.

Added some checking to verify that round-up operations will not overflow
a size_t.

The simplest way to do this was to introduce a notion of xLargeMax, like
we have for smallMax, mediumMax, and largeMax. It's a bit surprising at
first to think that there is an xLargeMax, since xLarge is what we use
to handle the biggest things. But computers have limits, so it makes sense.

FWIW, TCMalloc used to have an xLargeMax too, which it called kMaxValidPages.

No test because this bug was found by code inspection and I don't know
of a practical way to convince WebKit to make an allocation this large.

* bmalloc/Allocator.cpp:
(bmalloc::Allocator::tryAllocate):
(bmalloc::Allocator::allocate):
(bmalloc::Allocator::reallocate):
(bmalloc::Allocator::allocateSlowCase): Check against xLargeMax to avoid
overflow when rounding up.

* bmalloc/BAssert.h: Added support for explicit crashing.

* bmalloc/Sizes.h:

Modified Paths

Diff

Modified: trunk/Source/bmalloc/ChangeLog (184882 => 184883)


--- trunk/Source/bmalloc/ChangeLog	2015-05-26 22:31:04 UTC (rev 184882)
+++ trunk/Source/bmalloc/ChangeLog	2015-05-26 22:48:13 UTC (rev 184883)
@@ -1,3 +1,34 @@
+2015-05-26  Geoffrey Garen  <[email protected]>
+
+        Integer overflow in XLarge allocation (due to unchecked roundUpToMultipleOf)
+        https://bugs.webkit.org/show_bug.cgi?id=145385
+
+        Reviewed by Andreas Kling.
+
+        Added some checking to verify that round-up operations will not overflow
+        a size_t.
+
+        The simplest way to do this was to introduce a notion of xLargeMax, like
+        we have for smallMax, mediumMax, and largeMax. It's a bit surprising at
+        first to think that there is an xLargeMax, since xLarge is what we use
+        to handle the biggest things. But computers have limits, so it makes sense.
+
+        FWIW, TCMalloc used to have an xLargeMax too, which it called kMaxValidPages.
+
+        No test because this bug was found by code inspection and I don't know
+        of a practical way to convince WebKit to make an allocation this large.
+
+        * bmalloc/Allocator.cpp:
+        (bmalloc::Allocator::tryAllocate):
+        (bmalloc::Allocator::allocate):
+        (bmalloc::Allocator::reallocate):
+        (bmalloc::Allocator::allocateSlowCase): Check against xLargeMax to avoid
+        overflow when rounding up.
+
+        * bmalloc/BAssert.h: Added support for explicit crashing.
+
+        * bmalloc/Sizes.h:
+
 2015-05-26  Dan Bernstein  <[email protected]>
 
         <rdar://problem/21104551> Update build settings

Modified: trunk/Source/bmalloc/bmalloc/Allocator.cpp (184882 => 184883)


--- trunk/Source/bmalloc/bmalloc/Allocator.cpp	2015-05-26 22:31:04 UTC (rev 184882)
+++ trunk/Source/bmalloc/bmalloc/Allocator.cpp	2015-05-26 22:48:13 UTC (rev 184883)
@@ -59,8 +59,12 @@
     if (size <= largeMax)
         return allocate(size);
 
-    std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
-    return PerProcess<Heap>::get()->tryAllocateXLarge(lock, superChunkSize, roundUpToMultipleOf<xLargeAlignment>(size));
+    if (size <= xLargeMax) {
+        std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+        return PerProcess<Heap>::getFastCase()->tryAllocateXLarge(lock, superChunkSize, roundUpToMultipleOf<xLargeAlignment>(size));
+    }
+
+    return nullptr;
 }
 
 void* Allocator::allocate(size_t alignment, size_t size)
@@ -93,18 +97,25 @@
         }
     }
 
-    size = std::max(largeMin, roundUpToMultipleOf<largeAlignment>(size));
-    alignment = roundUpToMultipleOf<largeAlignment>(alignment);
-    size_t unalignedSize = largeMin + alignment + size;
-    if (unalignedSize <= largeMax && alignment <= largeChunkSize / 2) {
+    if (size <= largeMax && alignment <= largeMax) {
+        size = std::max(largeMin, roundUpToMultipleOf<largeAlignment>(size));
+        alignment = roundUpToMultipleOf<largeAlignment>(alignment);
+        size_t unalignedSize = largeMin + alignment + size;
+        if (unalignedSize <= largeMax && alignment <= largeChunkSize / 2) {
+            std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+            return PerProcess<Heap>::getFastCase()->allocateLarge(lock, alignment, size, unalignedSize);
+        }
+    }
+
+    if (size <= xLargeMax && alignment <= xLargeMax) {
+        size = roundUpToMultipleOf<xLargeAlignment>(size);
+        alignment = std::max(superChunkSize, alignment);
         std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
-        return PerProcess<Heap>::getFastCase()->allocateLarge(lock, alignment, size, unalignedSize);
+        return PerProcess<Heap>::getFastCase()->allocateXLarge(lock, alignment, size);
     }
 
-    size = roundUpToMultipleOf<xLargeAlignment>(size);
-    alignment = std::max(superChunkSize, alignment);
-    std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
-    return PerProcess<Heap>::getFastCase()->allocateXLarge(lock, alignment, size);
+    BCRASH();
+    return nullptr;
 }
 
 void* Allocator::reallocate(void* object, size_t newSize)
@@ -242,7 +253,11 @@
     if (size <= largeMax)
         return allocateLarge(size);
 
-    return allocateXLarge(size);
+    if (size <= xLargeMax)
+        return allocateXLarge(size);
+
+    BCRASH();
+    return nullptr;
 }
 
 } // namespace bmalloc

Modified: trunk/Source/bmalloc/bmalloc/BAssert.h (184882 => 184883)


--- trunk/Source/bmalloc/bmalloc/BAssert.h	2015-05-26 22:31:04 UTC (rev 184882)
+++ trunk/Source/bmalloc/bmalloc/BAssert.h	2015-05-26 22:48:13 UTC (rev 184883)
@@ -26,10 +26,14 @@
 #ifndef BAssert_h
 #define BAssert_h
 
+#define BCRASH() do { \
+    *(int*)0xbbadbeef = 0; \
+} while (0);
+
 #define BASSERT_IMPL(x) do { \
     if (!(x)) \
-        *(int*)0xbbadbeef = 0; \
-} while(0);
+        BCRASH(); \
+} while (0);
 
 #define RELEASE_BASSERT(x) BASSERT_IMPL(x)
 

Modified: trunk/Source/bmalloc/bmalloc/Sizes.h (184882 => 184883)


--- trunk/Source/bmalloc/bmalloc/Sizes.h	2015-05-26 22:31:04 UTC (rev 184882)
+++ trunk/Source/bmalloc/bmalloc/Sizes.h	2015-05-26 22:48:13 UTC (rev 184883)
@@ -80,6 +80,7 @@
     static const size_t largeMin = mediumMax;
     
     static const size_t xLargeAlignment = vmPageSize;
+    static const size_t xLargeMax = std::numeric_limits<size_t>::max() - xLargeAlignment; // Make sure that rounding up to xLargeAlignment does not overflow.
 
     static const size_t freeListSearchDepth = 16;
     static const size_t freeListGrowFactor = 2;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to