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;
};