Title: [234916] trunk/Source/_javascript_Core
Revision
234916
Author
[email protected]
Date
2018-08-16 02:41:36 -0700 (Thu, 16 Aug 2018)

Log Message

[YARR] Align allocation size in BumpPointerAllocator with sizeof(void*)
https://bugs.webkit.org/show_bug.cgi?id=188571

Reviewed by Saam Barati.

UBSan finds YarrInterpreter performs misaligned accesses. This is because YarrInterpreter
allocates DisjunctionContext and ParenthesesDisjunctionContext from BumpPointerAllocator
without considering alignment of them. This patch adds DisjunctionContext::allocationSize
and ParenthesesDisjunctionContext::allocationSize to calculate allocation sizes for them.
The size is always rounded to `sizeof(void*)` so that these classes are always allocated
with `sizeof(void*)` alignment. We also ensure the alignments of both classes are less
than or equal to `sizeof(void*)` by `static_assert`.

* yarr/YarrInterpreter.cpp:
(JSC::Yarr::Interpreter::DisjunctionContext::allocationSize):
(JSC::Yarr::Interpreter::allocDisjunctionContext):
(JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::ParenthesesDisjunctionContext):
(JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::getDisjunctionContext):
(JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::allocationSize):
(JSC::Yarr::Interpreter::allocParenthesesDisjunctionContext):
(JSC::Yarr::Interpreter::Interpreter):
(JSC::Yarr::Interpreter::DisjunctionContext::DisjunctionContext): Deleted.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (234915 => 234916)


--- trunk/Source/_javascript_Core/ChangeLog	2018-08-16 08:15:54 UTC (rev 234915)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-08-16 09:41:36 UTC (rev 234916)
@@ -1,3 +1,28 @@
+2018-08-14  Yusuke Suzuki  <[email protected]>
+
+        [YARR] Align allocation size in BumpPointerAllocator with sizeof(void*)
+        https://bugs.webkit.org/show_bug.cgi?id=188571
+
+        Reviewed by Saam Barati.
+
+        UBSan finds YarrInterpreter performs misaligned accesses. This is because YarrInterpreter
+        allocates DisjunctionContext and ParenthesesDisjunctionContext from BumpPointerAllocator
+        without considering alignment of them. This patch adds DisjunctionContext::allocationSize
+        and ParenthesesDisjunctionContext::allocationSize to calculate allocation sizes for them.
+        The size is always rounded to `sizeof(void*)` so that these classes are always allocated
+        with `sizeof(void*)` alignment. We also ensure the alignments of both classes are less
+        than or equal to `sizeof(void*)` by `static_assert`.
+
+        * yarr/YarrInterpreter.cpp:
+        (JSC::Yarr::Interpreter::DisjunctionContext::allocationSize):
+        (JSC::Yarr::Interpreter::allocDisjunctionContext):
+        (JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::ParenthesesDisjunctionContext):
+        (JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::getDisjunctionContext):
+        (JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::allocationSize):
+        (JSC::Yarr::Interpreter::allocParenthesesDisjunctionContext):
+        (JSC::Yarr::Interpreter::Interpreter):
+        (JSC::Yarr::Interpreter::DisjunctionContext::DisjunctionContext): Deleted.
+
 2018-08-15  Keith Miller  <[email protected]>
 
         Remove evernote hacks

Modified: trunk/Source/_javascript_Core/yarr/YarrInterpreter.cpp (234915 => 234916)


--- trunk/Source/_javascript_Core/yarr/YarrInterpreter.cpp	2018-08-16 08:15:54 UTC (rev 234915)
+++ trunk/Source/_javascript_Core/yarr/YarrInterpreter.cpp	2018-08-16 09:41:36 UTC (rev 234916)
@@ -32,6 +32,7 @@
 #include "Yarr.h"
 #include "YarrCanonicalize.h"
 #include <wtf/BumpPointerAllocator.h>
+#include <wtf/CheckedArithmetic.h>
 #include <wtf/DataLog.h>
 #include <wtf/text/CString.h>
 #include <wtf/text/WTFString.h>
@@ -67,10 +68,7 @@
 
     struct DisjunctionContext
     {
-        DisjunctionContext()
-            : term(0)
-        {
-        }
+        DisjunctionContext() = default;
 
         void* operator new(size_t, void* where)
         {
@@ -77,7 +75,16 @@
             return where;
         }
 
-        int term;
+        static size_t allocationSize(unsigned numberOfFrames)
+        {
+            static_assert(alignof(DisjunctionContext) <= sizeof(void*), "");
+            size_t rawSize = (sizeof(DisjunctionContext) - sizeof(uintptr_t) + Checked<size_t>(numberOfFrames) * sizeof(uintptr_t)).unsafeGet();
+            size_t roundedSize = roundUpToMultipleOf<sizeof(void*)>(rawSize);
+            RELEASE_ASSERT(roundedSize >= rawSize);
+            return roundedSize;
+        }
+
+        int term { 0 };
         unsigned matchBegin;
         unsigned matchEnd;
         uintptr_t frame[1];
@@ -85,7 +92,7 @@
 
     DisjunctionContext* allocDisjunctionContext(ByteDisjunction* disjunction)
     {
-        size_t size = sizeof(DisjunctionContext) - sizeof(uintptr_t) + disjunction->m_frameSize * sizeof(uintptr_t);
+        size_t size = DisjunctionContext::allocationSize(disjunction->m_frameSize);
         allocatorPool = allocatorPool->ensureCapacity(size);
         RELEASE_ASSERT(allocatorPool);
         return new (allocatorPool->alloc(size)) DisjunctionContext();
@@ -99,7 +106,6 @@
     struct ParenthesesDisjunctionContext
     {
         ParenthesesDisjunctionContext(unsigned* output, ByteTerm& term)
-            : next(0)
         {
             unsigned firstSubpatternId = term.atom.subpatternId;
             unsigned numNestedSubpatterns = term.atom.parenthesesDisjunction->m_numSubpatterns;
@@ -125,16 +131,25 @@
 
         DisjunctionContext* getDisjunctionContext(ByteTerm& term)
         {
-            return reinterpret_cast<DisjunctionContext*>(&(subpatternBackup[term.atom.parenthesesDisjunction->m_numSubpatterns << 1]));
+            return bitwise_cast<DisjunctionContext*>(bitwise_cast<uintptr_t>(this) + allocationSize(term.atom.parenthesesDisjunction->m_numSubpatterns));
         }
 
-        ParenthesesDisjunctionContext* next;
+        static size_t allocationSize(unsigned numberOfSubpatterns)
+        {
+            static_assert(alignof(ParenthesesDisjunctionContext) <= sizeof(void*), "");
+            size_t rawSize = (sizeof(ParenthesesDisjunctionContext) - sizeof(unsigned) + (Checked<size_t>(numberOfSubpatterns) * 2U) * sizeof(unsigned)).unsafeGet();
+            size_t roundedSize = roundUpToMultipleOf<sizeof(void*)>(rawSize);
+            RELEASE_ASSERT(roundedSize >= rawSize);
+            return roundedSize;
+        }
+
+        ParenthesesDisjunctionContext* next { nullptr };
         unsigned subpatternBackup[1];
     };
 
     ParenthesesDisjunctionContext* allocParenthesesDisjunctionContext(ByteDisjunction* disjunction, unsigned* output, ByteTerm& term)
     {
-        size_t size = sizeof(ParenthesesDisjunctionContext) - sizeof(unsigned) + (term.atom.parenthesesDisjunction->m_numSubpatterns << 1) * sizeof(unsigned) + sizeof(DisjunctionContext) - sizeof(uintptr_t) + static_cast<size_t>(disjunction->m_frameSize) * sizeof(uintptr_t);
+        size_t size = (Checked<size_t>(ParenthesesDisjunctionContext::allocationSize(term.atom.parenthesesDisjunction->m_numSubpatterns)) + DisjunctionContext::allocationSize(disjunction->m_frameSize)).unsafeGet();
         allocatorPool = allocatorPool->ensureCapacity(size);
         RELEASE_ASSERT(allocatorPool);
         return new (allocatorPool->alloc(size)) ParenthesesDisjunctionContext(output, term);
@@ -1630,7 +1645,6 @@
         , unicode(pattern->unicode())
         , output(output)
         , input(input, start, length, pattern->unicode())
-        , allocatorPool(0)
         , startOffset(start)
         , remainingMatchCount(matchLimit)
     {
@@ -1641,7 +1655,7 @@
     bool unicode;
     unsigned* output;
     InputStream input;
-    BumpPointerPool* allocatorPool;
+    BumpPointerPool* allocatorPool { nullptr };
     unsigned startOffset;
     unsigned remainingMatchCount;
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to