Title: [278887] trunk/Source/WebCore
Revision
278887
Author
wenson_hs...@apple.com
Date
2021-06-15 11:25:07 -0700 (Tue, 15 Jun 2021)

Log Message

[GPU Process] Add a bounds check before reading data length for out-of-line display list items
https://bugs.webkit.org/show_bug.cgi?id=227029
rdar://79343645

Reviewed by Chris Dumez.

Add some additional hardening when decoding out-of-line display list items.

* platform/graphics/displaylists/DisplayListIterator.cpp:
(WebCore::DisplayList::DisplayList::Iterator::updateCurrentItem):

Currently, it's possible to perform an out-of-bounds read in the shared display list item buffer, since we only
perform a bounds check after grabbing the data length (8 bytes) from the buffer after reading and validating an
out-of-line display list item type.

Mitigate this by validating that there is enough buffer capacity for both the padded item type value and encoded
data length, before we attempt to read the encoded data length.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (278886 => 278887)


--- trunk/Source/WebCore/ChangeLog	2021-06-15 18:21:57 UTC (rev 278886)
+++ trunk/Source/WebCore/ChangeLog	2021-06-15 18:25:07 UTC (rev 278887)
@@ -1,3 +1,23 @@
+2021-06-15  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [GPU Process] Add a bounds check before reading data length for out-of-line display list items
+        https://bugs.webkit.org/show_bug.cgi?id=227029
+        rdar://79343645
+
+        Reviewed by Chris Dumez.
+
+        Add some additional hardening when decoding out-of-line display list items.
+
+        * platform/graphics/displaylists/DisplayListIterator.cpp:
+        (WebCore::DisplayList::DisplayList::Iterator::updateCurrentItem):
+
+        Currently, it's possible to perform an out-of-bounds read in the shared display list item buffer, since we only
+        perform a bounds check after grabbing the data length (8 bytes) from the buffer after reading and validating an
+        out-of-line display list item type.
+
+        Mitigate this by validating that there is enough buffer capacity for both the padded item type value and encoded
+        data length, before we attempt to read the encoded data length.
+
 2021-06-15  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         GraphicsContext::apply{Fill,Stroke}Pattern needs to do nothing if there is no fill/stroke pattern set

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListIterator.cpp (278886 => 278887)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListIterator.cpp	2021-06-15 18:21:57 UTC (rev 278886)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListIterator.cpp	2021-06-15 18:25:07 UTC (rev 278887)
@@ -78,10 +78,11 @@
         return;
     }
 
+    auto remainingCapacityInBuffer = static_cast<uint64_t>(m_currentEndOfBuffer - m_cursor);
     auto paddedSizeOfTypeAndItem = paddedSizeOfTypeAndItemInBytes(itemType);
     m_currentBufferForItem = paddedSizeOfTypeAndItem <= sizeOfFixedBufferForCurrentItem ? m_fixedBufferForCurrentItem : static_cast<uint8_t*>(fastMalloc(paddedSizeOfTypeAndItem));
     if (isInlineItem(itemType)) {
-        if (UNLIKELY(static_cast<uint64_t>(m_currentEndOfBuffer - m_cursor) < paddedSizeOfTypeAndItem)) {
+        if (UNLIKELY(remainingCapacityInBuffer < paddedSizeOfTypeAndItem)) {
             m_isValid = false;
             return;
         }
@@ -96,6 +97,12 @@
         auto* client = items.m_readingClient;
         RELEASE_ASSERT(client);
         constexpr auto sizeOfTypeAndDataLength = 2 * sizeof(uint64_t);
+
+        if (UNLIKELY(remainingCapacityInBuffer < sizeOfTypeAndDataLength)) {
+            m_isValid = false;
+            return;
+        }
+
         auto dataLength = reinterpret_cast<uint64_t*>(m_cursor)[1];
         if (UNLIKELY(dataLength >= std::numeric_limits<uint32_t>::max() - alignof(uint64_t) - sizeOfTypeAndDataLength)) {
             m_isValid = false;
@@ -103,7 +110,7 @@
         }
 
         auto itemSizeInBuffer = roundUpToMultipleOf<alignof(uint64_t)>(dataLength) + sizeOfTypeAndDataLength;
-        if (UNLIKELY(static_cast<uint64_t>(m_currentEndOfBuffer - m_cursor) < itemSizeInBuffer)) {
+        if (UNLIKELY(remainingCapacityInBuffer < itemSizeInBuffer)) {
             m_isValid = false;
             return;
         }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to