Skip to content

Commit 95b7191

Browse files
committed
[1.11>master] [MERGE #6016 @pleath] ChakraCore Servicing Release for 1903
Merge pull request #6016 from pleath:servicing/1903 Addresses the following issue: CVE-2019-0592 CVE-2019-0609 CVE-2019-0611 CVE-2019-0639 CVE-2019-0746 CVE-2019-0769 CVE-2019-0773 CVE-2019-0771
2 parents 3a9a3d5 + f61a97a commit 95b7191

23 files changed

+190
-75
lines changed

lib/Backend/BailOut.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,7 @@ BailOutRecord::BailOutHelper(Js::JavascriptCallStackLayout * layout, Js::ScriptF
15271527
//
15281528
Js::Arguments generatorArgs = generator->GetArguments();
15291529
Js::InterpreterStackFrame::Setup setup(function, generatorArgs, true, isInlinee);
1530+
Assert(setup.GetStackAllocationVarCount() == 0);
15301531
size_t varAllocCount = setup.GetAllocationVarCount();
15311532
size_t varSizeInBytes = varAllocCount * sizeof(Js::Var);
15321533
DWORD_PTR stackAddr = reinterpret_cast<DWORD_PTR>(&generator); // as mentioned above, use any stack address from this frame to ensure correct debugging functionality
@@ -1539,11 +1540,14 @@ BailOutRecord::BailOutHelper(Js::JavascriptCallStackLayout * layout, Js::ScriptF
15391540
// Allocate invalidVar on GC instead of stack since this InterpreterStackFrame will out live the current real frame
15401541
Js::Var invalidVar = (Js::RecyclableObject*)RecyclerNewPlusLeaf(functionScriptContext->GetRecycler(), sizeof(Js::RecyclableObject), Js::Var);
15411542
memset(invalidVar, 0xFE, sizeof(Js::RecyclableObject));
1542-
newInstance = setup.InitializeAllocation(allocation, false, false, loopHeaderArray, stackAddr, invalidVar);
1543-
#else
1544-
newInstance = setup.InitializeAllocation(allocation, false, false, loopHeaderArray, stackAddr);
15451543
#endif
15461544

1545+
newInstance = setup.InitializeAllocation(allocation, nullptr, false, false, loopHeaderArray, stackAddr
1546+
#if DBG
1547+
, invalidVar
1548+
#endif
1549+
);
1550+
15471551
newInstance->m_reader.Create(executeFunction);
15481552

15491553
generator->SetFrame(newInstance, varSizeInBytes);
@@ -1553,18 +1557,28 @@ BailOutRecord::BailOutHelper(Js::JavascriptCallStackLayout * layout, Js::ScriptF
15531557
{
15541558
Js::InterpreterStackFrame::Setup setup(function, args, true, isInlinee);
15551559
size_t varAllocCount = setup.GetAllocationVarCount();
1556-
size_t varSizeInBytes = varAllocCount * sizeof(Js::Var);
1560+
size_t stackVarAllocCount = setup.GetStackAllocationVarCount();
1561+
size_t varSizeInBytes;
1562+
Js::Var *stackAllocation = nullptr;
15571563

15581564
// If the locals area exceeds a certain limit, allocate it from a private arena rather than
15591565
// this frame. The current limit is based on an old assert on the number of locals we would allow here.
1560-
if (varAllocCount > Js::InterpreterStackFrame::LocalsThreshold)
1566+
if ((varAllocCount + stackVarAllocCount) > Js::InterpreterStackFrame::LocalsThreshold)
15611567
{
15621568
ArenaAllocator *tmpAlloc = nullptr;
15631569
fReleaseAlloc = functionScriptContext->EnsureInterpreterArena(&tmpAlloc);
1570+
varSizeInBytes = varAllocCount * sizeof(Js::Var);
15641571
allocation = (Js::Var*)tmpAlloc->Alloc(varSizeInBytes);
1572+
if (stackVarAllocCount != 0)
1573+
{
1574+
size_t stackVarSizeInBytes = stackVarAllocCount * sizeof(Js::Var);
1575+
PROBE_STACK_PARTIAL_INITIALIZED_BAILOUT_FRAME(functionScriptContext, Js::Constants::MinStackInterpreter + stackVarSizeInBytes, returnAddress);
1576+
stackAllocation = (Js::Var*)_alloca(stackVarSizeInBytes);
1577+
}
15651578
}
15661579
else
15671580
{
1581+
varSizeInBytes = (varAllocCount + stackVarAllocCount) * sizeof(Js::Var);
15681582
PROBE_STACK_PARTIAL_INITIALIZED_BAILOUT_FRAME(functionScriptContext, Js::Constants::MinStackInterpreter + varSizeInBytes, returnAddress);
15691583
allocation = (Js::Var*)_alloca(varSizeInBytes);
15701584
}
@@ -1589,11 +1603,14 @@ BailOutRecord::BailOutHelper(Js::JavascriptCallStackLayout * layout, Js::ScriptF
15891603
#if DBG
15901604
Js::Var invalidStackVar = (Js::RecyclableObject*)_alloca(sizeof(Js::RecyclableObject));
15911605
memset(invalidStackVar, 0xFE, sizeof(Js::RecyclableObject));
1592-
newInstance = setup.InitializeAllocation(allocation, false, false, loopHeaderArray, frameStackAddr, invalidStackVar);
1593-
#else
1594-
newInstance = setup.InitializeAllocation(allocation, false, false, loopHeaderArray, frameStackAddr);
15951606
#endif
15961607

1608+
newInstance = setup.InitializeAllocation(allocation, stackAllocation, false, false, loopHeaderArray, frameStackAddr
1609+
#if DBG
1610+
, invalidStackVar
1611+
#endif
1612+
);
1613+
15971614
newInstance->m_reader.Create(executeFunction);
15981615
}
15991616

lib/Backend/EmitBuffer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ bool EmitBufferManager<TAlloc, TPreReservedAlloc, SyncObject>::ProtectBufferWith
414414
template <typename TAlloc, typename TPreReservedAlloc, class SyncObject>
415415
bool EmitBufferManager<TAlloc, TPreReservedAlloc, SyncObject>::CommitBufferForInterpreter(TEmitBufferAllocation* allocation, _In_reads_bytes_(bufferSize) BYTE* pBuffer, _In_ size_t bufferSize)
416416
{
417-
Assert(this->criticalSection.IsLocked());
417+
AutoRealOrFakeCriticalSection<SyncObject> autoCs(&this->criticalSection);
418418

419419
Assert(allocation != nullptr);
420420
allocation->bytesUsed += bufferSize;

lib/Backend/FlowGraph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5266,7 +5266,7 @@ BasicBlock::MergePredBlocksValueMaps(GlobOpt* globOpt)
52665266
}
52675267
if(symsRequiringCompensationToMergedValueInfoMap.Count() != 0)
52685268
{
5269-
globOpt->InsertValueCompensation(pred, &symsRequiringCompensationToMergedValueInfoMap);
5269+
globOpt->InsertValueCompensation(pred, this, &symsRequiringCompensationToMergedValueInfoMap);
52705270
}
52715271
}
52725272
} NEXT_PREDECESSOR_EDGE_EDITING;

lib/Backend/GlobOpt.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ GlobOpt::OptBlock(BasicBlock *block)
605605

606606
if (block->loop->symsRequiringCompensationToMergedValueInfoMap)
607607
{
608-
InsertValueCompensation(block, block->loop->symsRequiringCompensationToMergedValueInfoMap);
608+
InsertValueCompensation(block, succ, block->loop->symsRequiringCompensationToMergedValueInfoMap);
609609
}
610610

611611
// Now that we're done with the liveFields within this loop, trim the set to those syms
@@ -1160,9 +1160,12 @@ void GlobOpt::FieldPRE(Loop *loop)
11601160

11611161
void GlobOpt::InsertValueCompensation(
11621162
BasicBlock *const predecessor,
1163+
BasicBlock *const successor,
11631164
const SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap)
11641165
{
11651166
Assert(predecessor);
1167+
Assert(successor);
1168+
AssertOrFailFast(predecessor != successor);
11661169
Assert(symsRequiringCompensationToMergedValueInfoMap->Count() != 0);
11671170

11681171
IR::Instr *insertBeforeInstr = predecessor->GetLastInstr();
@@ -1186,7 +1189,7 @@ void GlobOpt::InsertValueCompensation(
11861189
}
11871190

11881191
GlobOptBlockData &predecessorBlockData = predecessor->globOptData;
1189-
GlobOptBlockData &successorBlockData = *CurrentBlockData();
1192+
GlobOptBlockData &successorBlockData = successor->globOptData;
11901193
struct DelayChangeValueInfo
11911194
{
11921195
Value* predecessorValue;

lib/Backend/GlobOpt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ class GlobOpt
736736
void PreLowerCanonicalize(IR::Instr *instr, Value **pSrc1Val, Value **pSrc2Val);
737737
void ProcessKills(IR::Instr *instr);
738738
void InsertCloneStrs(BasicBlock *toBlock, GlobOptBlockData *toData, GlobOptBlockData *fromData);
739-
void InsertValueCompensation(BasicBlock *const predecessor, const SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap);
739+
void InsertValueCompensation(BasicBlock *const predecessor, BasicBlock *const successor, const SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap);
740740
IR::Instr * ToVarUses(IR::Instr *instr, IR::Opnd *opnd, bool isDst, Value *val);
741741
void ToVar(BVSparse<JitArenaAllocator> *bv, BasicBlock *block);
742742
IR::Instr * ToVar(IR::Instr *instr, IR::RegOpnd *regOpnd, BasicBlock *block, Value *val, bool needsUpdate);

lib/Backend/GlobOptFields.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,24 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
442442
break;
443443

444444
case IR::JnHelperMethod::HelperRegExp_Exec:
445+
case IR::JnHelperMethod::HelperRegExp_ExecResultNotUsed:
446+
case IR::JnHelperMethod::HelperRegExp_ExecResultUsed:
447+
case IR::JnHelperMethod::HelperRegExp_ExecResultUsedAndMayBeTemp:
448+
case IR::JnHelperMethod::HelperRegExp_MatchResultNotUsed:
449+
case IR::JnHelperMethod::HelperRegExp_MatchResultUsed:
450+
case IR::JnHelperMethod::HelperRegExp_MatchResultUsedAndMayBeTemp:
451+
case IR::JnHelperMethod::HelperRegExp_ReplaceStringResultUsed:
452+
case IR::JnHelperMethod::HelperRegExp_ReplaceStringResultNotUsed:
453+
case IR::JnHelperMethod::HelperRegExp_SplitResultNotUsed:
454+
case IR::JnHelperMethod::HelperRegExp_SplitResultUsed:
455+
case IR::JnHelperMethod::HelperRegExp_SplitResultUsedAndMayBeTemp:
456+
case IR::JnHelperMethod::HelperRegExp_SymbolSearch:
445457
case IR::JnHelperMethod::HelperString_Match:
458+
case IR::JnHelperMethod::HelperString_Search:
459+
case IR::JnHelperMethod::HelperString_Split:
446460
case IR::JnHelperMethod::HelperString_Replace:
447461
// Consider: We may not need to kill all fields here.
462+
// We need to kill all the built-in properties that can be written, though, and there are a lot of those.
448463
this->KillAllFields(bv);
449464
break;
450465
}

lib/Backend/GlobOptIntBounds.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2985,7 +2985,11 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
29852985
{
29862986
// The loop count is constant, fold (indexOffset + loopCountMinusOne * maxMagnitudeChange)
29872987
TRACE_PHASE_VERBOSE(Js::Phase::BoundCheckHoistPhase, 3, _u("Loop count is constant, folding\n"));
2988-
if(Int32Math::Mul(loopCount->LoopCountMinusOneConstantValue(), maxMagnitudeChange, &offset) ||
2988+
2989+
int loopCountMinusOnePlusOne = 0;
2990+
2991+
if (Int32Math::Add(loopCount->LoopCountMinusOneConstantValue(), 1, &loopCountMinusOnePlusOne) ||
2992+
Int32Math::Mul(loopCountMinusOnePlusOne, maxMagnitudeChange, &offset) ||
29892993
Int32Math::Add(offset, indexOffset, &offset))
29902994
{
29912995
TRACE_PHASE_VERBOSE(Js::Phase::BoundCheckHoistPhase, 4, _u("Folding failed\n"));

lib/Backend/IRBuilder.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,7 +1674,7 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
16741674
}
16751675

16761676
case Js::OpCode::NewScObjectSimple:
1677-
dstValueType = ValueType::GetObject(ObjectType::UninitializedObject);
1677+
dstValueType = ValueType::GetObject(ObjectType::Object);
16781678
// fall-through
16791679
case Js::OpCode::LdFuncExpr:
16801680
m_func->DisableCanDoInlineArgOpt();
@@ -4992,7 +4992,7 @@ IRBuilder::BuildAuxiliary(Js::OpCode newOpcode, uint32 offset)
49924992
// lower take it from there...
49934993
srcOpnd = IR::IntConstOpnd::New(auxInsn->Offset, TyUint32, m_func);
49944994
dstOpnd = this->BuildDstOpnd(dstRegSlot);
4995-
dstOpnd->SetValueType(ValueType::GetObject(ObjectType::UninitializedObject));
4995+
dstOpnd->SetValueType(ValueType::GetObject(ObjectType::Object));
49964996
instr = IR::Instr::New(newOpcode, dstOpnd, srcOpnd, m_func);
49974997

49984998
// Because we're going to be making decisions based off the value, we have to defer

lib/Backend/ServerScriptContext.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ ServerScriptContext::IsClosed() const
312312
void
313313
ServerScriptContext::AddToDOMFastPathHelperMap(intptr_t funcInfoAddr, IR::JnHelperMethod helper)
314314
{
315+
AutoCriticalSection cs(&m_cs);
315316
m_domFastPathHelperMap->Add(funcInfoAddr, helper);
316317
}
317318

@@ -327,7 +328,7 @@ ServerScriptContext::DecommitEmitBufferManager(bool asmJsManager)
327328
GetEmitBufferManager(asmJsManager)->Decommit();
328329
}
329330

330-
OOPEmitBufferManager *
331+
OOPEmitBufferManagerWithLock *
331332
ServerScriptContext::GetEmitBufferManager(bool asmJsManager)
332333
{
333334
if (asmJsManager)
@@ -343,11 +344,11 @@ ServerScriptContext::GetEmitBufferManager(bool asmJsManager)
343344
IR::JnHelperMethod
344345
ServerScriptContext::GetDOMFastPathHelper(intptr_t funcInfoAddr)
345346
{
347+
AutoCriticalSection cs(&m_cs);
348+
346349
IR::JnHelperMethod helper = IR::HelperInvalid;
347350

348-
m_domFastPathHelperMap->LockResize();
349351
m_domFastPathHelperMap->TryGetValue(funcInfoAddr, &helper);
350-
m_domFastPathHelperMap->UnlockResize();
351352

352353
return helper;
353354
}
@@ -392,6 +393,7 @@ ServerScriptContext::GetCodeGenAllocators()
392393
Field(Js::Var)*
393394
ServerScriptContext::GetModuleExportSlotArrayAddress(uint moduleIndex, uint slotIndex)
394395
{
396+
AutoCriticalSection cs(&m_cs);
395397
AssertOrFailFast(m_moduleRecords.ContainsKey(moduleIndex));
396398
auto record = m_moduleRecords.Item(moduleIndex);
397399
return record->localExportSlotsAddr;
@@ -406,6 +408,7 @@ ServerScriptContext::SetIsPRNGSeeded(bool value)
406408
void
407409
ServerScriptContext::AddModuleRecordInfo(unsigned int moduleId, __int64 localExportSlotsAddr)
408410
{
411+
AutoCriticalSection cs(&m_cs);
409412
Js::ServerSourceTextModuleRecord* record = HeapNewStructZ(Js::ServerSourceTextModuleRecord);
410413
record->moduleId = moduleId;
411414
record->localExportSlotsAddr = (Field(Js::Var)*)localExportSlotsAddr;

lib/Backend/ServerScriptContext.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class ServerScriptContext : public ScriptContextInfo
8080
void SetIsPRNGSeeded(bool value);
8181
void AddModuleRecordInfo(unsigned int moduleId, __int64 localExportSlotsAddr);
8282
void UpdateGlobalObjectThisAddr(intptr_t globalThis);
83-
OOPEmitBufferManager * GetEmitBufferManager(bool asmJsManager);
83+
OOPEmitBufferManagerWithLock * GetEmitBufferManager(bool asmJsManager);
8484
void DecommitEmitBufferManager(bool asmJsManager);
8585
#ifdef PROFILE_EXEC
8686
Js::ScriptContextProfiler* GetCodeGenProfiler(_In_ PageAllocator* pageAllocator);
@@ -100,10 +100,11 @@ class ServerScriptContext : public ScriptContextInfo
100100
Js::ScriptContextProfiler * codeGenProfiler;
101101
CriticalSection profilerCS;
102102
#endif
103+
CriticalSection m_cs;
103104
ArenaAllocator m_sourceCodeArena;
104105

105-
OOPEmitBufferManager m_interpreterThunkBufferManager;
106-
OOPEmitBufferManager m_asmJsInterpreterThunkBufferManager;
106+
OOPEmitBufferManagerWithLock m_interpreterThunkBufferManager;
107+
OOPEmitBufferManagerWithLock m_asmJsInterpreterThunkBufferManager;
107108

108109
ScriptContextDataIDL m_contextData;
109110
intptr_t m_globalThisAddr;

0 commit comments

Comments
 (0)