Skip to content
This repository was archived by the owner on Jun 24, 2022. It is now read-only.

Commit 4131aa2

Browse files
Fix 32-bit btyecode cache crashes
https://bugs.webkit.org/show_bug.cgi?id=198035 <rdar://problem/49905560> Reviewed by Michael Saboff. There were 2 32-bit issues with the bytecode cache: - UnlinkedFunctionExecutable::m_cachedCodeBlockForConstructOffset was not initialized. The code was relying on the other member of the union, `m_unlinkedCodeBlockForConstruct`, initializing both m_cachedCodeBlockForCallOffset and m_cachedCodeBlockForConstructOffset. This is undefined behavior and is also incorrect in 32-bit. Since m_unlinkedCodeBlockForConstruct is 32-bit, it only initializes the first member of the struct. - Encoder::Page was not aligned at the end. This lead to unaligned allocations on subsequent pages, since the start of the following page would not be aligned. * runtime/CachedTypes.cpp: (JSC::Encoder::release): (JSC::Encoder::Page::alignEnd): (JSC::Encoder::allocateNewPage): (JSC::VariableLengthObject::buffer const): (JSC::VariableLengthObject::allocate): (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245563 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent f2cf4fe commit 4131aa2

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

Source/JavaScriptCore/ChangeLog

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
1+
2019-05-20 Tadeu Zagallo <[email protected]>
2+
3+
Fix 32-bit btyecode cache crashes
4+
https://bugs.webkit.org/show_bug.cgi?id=198035
5+
<rdar://problem/49905560>
6+
7+
Reviewed by Michael Saboff.
8+
9+
There were 2 32-bit issues with the bytecode cache:
10+
- UnlinkedFunctionExecutable::m_cachedCodeBlockForConstructOffset was not initialized.
11+
The code was relying on the other member of the union, `m_unlinkedCodeBlockForConstruct`,
12+
initializing both m_cachedCodeBlockForCallOffset and m_cachedCodeBlockForConstructOffset.
13+
This is undefined behavior and is also incorrect in 32-bit. Since m_unlinkedCodeBlockForConstruct
14+
is 32-bit, it only initializes the first member of the struct.
15+
- Encoder::Page was not aligned at the end. This lead to unaligned allocations on subsequent
16+
pages, since the start of the following page would not be aligned.
17+
18+
* runtime/CachedTypes.cpp:
19+
(JSC::Encoder::release):
20+
(JSC::Encoder::Page::alignEnd):
21+
(JSC::Encoder::allocateNewPage):
22+
(JSC::VariableLengthObject::buffer const):
23+
(JSC::VariableLengthObject::allocate):
24+
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
25+
126
2019-05-20 Ross Kirsling <[email protected]>
227

328
[WinCairo] Implement Remote Web Inspector Client.

Source/JavaScriptCore/runtime/CachedTypes.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ class Encoder {
146146

147147
Ref<CachedBytecode> release()
148148
{
149+
if (!m_currentPage)
150+
return CachedBytecode::create();
151+
152+
m_currentPage->alignEnd();
149153
size_t size = m_baseOffset + m_currentPage->size();
150154
MallocPtr<uint8_t> buffer = MallocPtr<uint8_t>::malloc(size);
151155
unsigned offset = 0;
@@ -193,6 +197,15 @@ class Encoder {
193197
return false;
194198
}
195199

200+
void alignEnd()
201+
{
202+
ptrdiff_t size = roundUpToMultipleOf(alignof(std::max_align_t), m_offset);
203+
if (size == m_offset)
204+
return;
205+
ASSERT(static_cast<size_t>(size) <= m_capacity);
206+
m_offset = size;
207+
}
208+
196209
private:
197210
MallocPtr<uint8_t> m_buffer;
198211
ptrdiff_t m_offset;
@@ -202,8 +215,10 @@ class Encoder {
202215
void allocateNewPage(size_t size = 0)
203216
{
204217
static size_t minPageSize = pageSize();
205-
if (m_currentPage)
218+
if (m_currentPage) {
219+
m_currentPage->alignEnd();
206220
m_baseOffset += m_currentPage->size();
221+
}
207222
if (size < minPageSize)
208223
size = minPageSize;
209224
else
@@ -383,6 +398,7 @@ class VariableLengthObject : public CachedObject<Source>, VariableLengthObjectBa
383398
template<typename T>
384399
const T* buffer() const
385400
{
401+
ASSERT(!(bitwise_cast<uintptr_t>(buffer()) % alignof(T)));
386402
return bitwise_cast<const T*>(buffer());
387403
}
388404

@@ -403,6 +419,7 @@ class VariableLengthObject : public CachedObject<Source>, VariableLengthObjectBa
403419
T* allocate(Encoder& encoder, unsigned size = 1)
404420
{
405421
uint8_t* result = allocate(encoder, sizeof(T) * size);
422+
ASSERT(!(bitwise_cast<uintptr_t>(result) % alignof(T)));
406423
return new (result) T[size];
407424
}
408425

@@ -2100,15 +2117,20 @@ ALWAYS_INLINE UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(Decoder& de
21002117
codeBlockOffset = offset;
21012118
m_isCached = true;
21022119
leafExecutables--;
2120+
return;
21032121
}
21042122
}
2123+
2124+
codeBlockOffset = 0;
21052125
};
21062126

21072127
if (!cachedExecutable.unlinkedCodeBlockForCall().isEmpty() || !cachedExecutable.unlinkedCodeBlockForConstruct().isEmpty()) {
21082128
checkBounds(m_cachedCodeBlockForCallOffset, cachedExecutable.unlinkedCodeBlockForCall());
21092129
checkBounds(m_cachedCodeBlockForConstructOffset, cachedExecutable.unlinkedCodeBlockForConstruct());
21102130
if (m_isCached)
21112131
m_decoder = &decoder;
2132+
else
2133+
m_decoder = nullptr;
21122134
}
21132135

21142136
if (leafExecutables)

0 commit comments

Comments
 (0)