Skip to content

Commit f61a97a

Browse files
committed
[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 d4fb4df + b116253 commit f61a97a

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
@@ -1403,6 +1403,7 @@ BailOutRecord::BailOutHelper(Js::JavascriptCallStackLayout * layout, Js::ScriptF
14031403
//
14041404
Js::Arguments generatorArgs = generator->GetArguments();
14051405
Js::InterpreterStackFrame::Setup setup(function, generatorArgs, true, isInlinee);
1406+
Assert(setup.GetStackAllocationVarCount() == 0);
14061407
size_t varAllocCount = setup.GetAllocationVarCount();
14071408
size_t varSizeInBytes = varAllocCount * sizeof(Js::Var);
14081409
DWORD_PTR stackAddr = reinterpret_cast<DWORD_PTR>(&generator); // as mentioned above, use any stack address from this frame to ensure correct debugging functionality
@@ -1415,11 +1416,14 @@ BailOutRecord::BailOutHelper(Js::JavascriptCallStackLayout * layout, Js::ScriptF
14151416
// Allocate invalidVar on GC instead of stack since this InterpreterStackFrame will out live the current real frame
14161417
Js::Var invalidVar = (Js::RecyclableObject*)RecyclerNewPlusLeaf(functionScriptContext->GetRecycler(), sizeof(Js::RecyclableObject), Js::Var);
14171418
memset(invalidVar, 0xFE, sizeof(Js::RecyclableObject));
1418-
newInstance = setup.InitializeAllocation(allocation, false, false, loopHeaderArray, stackAddr, invalidVar);
1419-
#else
1420-
newInstance = setup.InitializeAllocation(allocation, false, false, loopHeaderArray, stackAddr);
14211419
#endif
14221420

1421+
newInstance = setup.InitializeAllocation(allocation, nullptr, false, false, loopHeaderArray, stackAddr
1422+
#if DBG
1423+
, invalidVar
1424+
#endif
1425+
);
1426+
14231427
newInstance->m_reader.Create(executeFunction);
14241428

14251429
generator->SetFrame(newInstance, varSizeInBytes);
@@ -1429,18 +1433,28 @@ BailOutRecord::BailOutHelper(Js::JavascriptCallStackLayout * layout, Js::ScriptF
14291433
{
14301434
Js::InterpreterStackFrame::Setup setup(function, args, true, isInlinee);
14311435
size_t varAllocCount = setup.GetAllocationVarCount();
1432-
size_t varSizeInBytes = varAllocCount * sizeof(Js::Var);
1436+
size_t stackVarAllocCount = setup.GetStackAllocationVarCount();
1437+
size_t varSizeInBytes;
1438+
Js::Var *stackAllocation = nullptr;
14331439

14341440
// If the locals area exceeds a certain limit, allocate it from a private arena rather than
14351441
// this frame. The current limit is based on an old assert on the number of locals we would allow here.
1436-
if (varAllocCount > Js::InterpreterStackFrame::LocalsThreshold)
1442+
if ((varAllocCount + stackVarAllocCount) > Js::InterpreterStackFrame::LocalsThreshold)
14371443
{
14381444
ArenaAllocator *tmpAlloc = nullptr;
14391445
fReleaseAlloc = functionScriptContext->EnsureInterpreterArena(&tmpAlloc);
1446+
varSizeInBytes = varAllocCount * sizeof(Js::Var);
14401447
allocation = (Js::Var*)tmpAlloc->Alloc(varSizeInBytes);
1448+
if (stackVarAllocCount != 0)
1449+
{
1450+
size_t stackVarSizeInBytes = stackVarAllocCount * sizeof(Js::Var);
1451+
PROBE_STACK_PARTIAL_INITIALIZED_BAILOUT_FRAME(functionScriptContext, Js::Constants::MinStackInterpreter + stackVarSizeInBytes, returnAddress);
1452+
stackAllocation = (Js::Var*)_alloca(stackVarSizeInBytes);
1453+
}
14411454
}
14421455
else
14431456
{
1457+
varSizeInBytes = (varAllocCount + stackVarAllocCount) * sizeof(Js::Var);
14441458
PROBE_STACK_PARTIAL_INITIALIZED_BAILOUT_FRAME(functionScriptContext, Js::Constants::MinStackInterpreter + varSizeInBytes, returnAddress);
14451459
allocation = (Js::Var*)_alloca(varSizeInBytes);
14461460
}
@@ -1465,11 +1479,14 @@ BailOutRecord::BailOutHelper(Js::JavascriptCallStackLayout * layout, Js::ScriptF
14651479
#if DBG
14661480
Js::Var invalidStackVar = (Js::RecyclableObject*)_alloca(sizeof(Js::RecyclableObject));
14671481
memset(invalidStackVar, 0xFE, sizeof(Js::RecyclableObject));
1468-
newInstance = setup.InitializeAllocation(allocation, false, false, loopHeaderArray, frameStackAddr, invalidStackVar);
1469-
#else
1470-
newInstance = setup.InitializeAllocation(allocation, false, false, loopHeaderArray, frameStackAddr);
14711482
#endif
14721483

1484+
newInstance = setup.InitializeAllocation(allocation, stackAllocation, false, false, loopHeaderArray, frameStackAddr
1485+
#if DBG
1486+
, invalidStackVar
1487+
#endif
1488+
);
1489+
14731490
newInstance->m_reader.Create(executeFunction);
14741491
}
14751492

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
@@ -601,7 +601,7 @@ GlobOpt::OptBlock(BasicBlock *block)
601601

602602
if (block->loop->symsRequiringCompensationToMergedValueInfoMap)
603603
{
604-
InsertValueCompensation(block, block->loop->symsRequiringCompensationToMergedValueInfoMap);
604+
InsertValueCompensation(block, succ, block->loop->symsRequiringCompensationToMergedValueInfoMap);
605605
}
606606

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

11571157
void GlobOpt::InsertValueCompensation(
11581158
BasicBlock *const predecessor,
1159+
BasicBlock *const successor,
11591160
const SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap)
11601161
{
11611162
Assert(predecessor);
1163+
Assert(successor);
1164+
AssertOrFailFast(predecessor != successor);
11621165
Assert(symsRequiringCompensationToMergedValueInfoMap->Count() != 0);
11631166

11641167
IR::Instr *insertBeforeInstr = predecessor->GetLastInstr();
@@ -1182,7 +1185,7 @@ void GlobOpt::InsertValueCompensation(
11821185
}
11831186

11841187
GlobOptBlockData &predecessorBlockData = predecessor->globOptData;
1185-
GlobOptBlockData &successorBlockData = *CurrentBlockData();
1188+
GlobOptBlockData &successorBlockData = successor->globOptData;
11861189
struct DelayChangeValueInfo
11871190
{
11881191
Value* predecessorValue;

lib/Backend/GlobOpt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ class GlobOpt
737737
void PreLowerCanonicalize(IR::Instr *instr, Value **pSrc1Val, Value **pSrc2Val);
738738
void ProcessKills(IR::Instr *instr);
739739
void InsertCloneStrs(BasicBlock *toBlock, GlobOptBlockData *toData, GlobOptBlockData *fromData);
740-
void InsertValueCompensation(BasicBlock *const predecessor, const SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap);
740+
void InsertValueCompensation(BasicBlock *const predecessor, BasicBlock *const successor, const SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap);
741741
IR::Instr * ToVarUses(IR::Instr *instr, IR::Opnd *opnd, bool isDst, Value *val);
742742
void ToVar(BVSparse<JitArenaAllocator> *bv, BasicBlock *block);
743743
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
@@ -450,9 +450,24 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
450450
break;
451451

452452
case IR::JnHelperMethod::HelperRegExp_Exec:
453+
case IR::JnHelperMethod::HelperRegExp_ExecResultNotUsed:
454+
case IR::JnHelperMethod::HelperRegExp_ExecResultUsed:
455+
case IR::JnHelperMethod::HelperRegExp_ExecResultUsedAndMayBeTemp:
456+
case IR::JnHelperMethod::HelperRegExp_MatchResultNotUsed:
457+
case IR::JnHelperMethod::HelperRegExp_MatchResultUsed:
458+
case IR::JnHelperMethod::HelperRegExp_MatchResultUsedAndMayBeTemp:
459+
case IR::JnHelperMethod::HelperRegExp_ReplaceStringResultUsed:
460+
case IR::JnHelperMethod::HelperRegExp_ReplaceStringResultNotUsed:
461+
case IR::JnHelperMethod::HelperRegExp_SplitResultNotUsed:
462+
case IR::JnHelperMethod::HelperRegExp_SplitResultUsed:
463+
case IR::JnHelperMethod::HelperRegExp_SplitResultUsedAndMayBeTemp:
464+
case IR::JnHelperMethod::HelperRegExp_SymbolSearch:
453465
case IR::JnHelperMethod::HelperString_Match:
466+
case IR::JnHelperMethod::HelperString_Search:
467+
case IR::JnHelperMethod::HelperString_Split:
454468
case IR::JnHelperMethod::HelperString_Replace:
455469
// Consider: We may not need to kill all fields here.
470+
// We need to kill all the built-in properties that can be written, though, and there are a lot of those.
456471
this->KillAllFields(bv);
457472
break;
458473
}

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
@@ -1758,7 +1758,7 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
17581758
}
17591759

17601760
case Js::OpCode::NewScObjectSimple:
1761-
dstValueType = ValueType::GetObject(ObjectType::UninitializedObject);
1761+
dstValueType = ValueType::GetObject(ObjectType::Object);
17621762
// fall-through
17631763
case Js::OpCode::LdFuncExpr:
17641764
m_func->DisableCanDoInlineArgOpt();
@@ -5050,7 +5050,7 @@ IRBuilder::BuildAuxiliary(Js::OpCode newOpcode, uint32 offset)
50505050
// lower take it from there...
50515051
srcOpnd = IR::IntConstOpnd::New(auxInsn->Offset, TyUint32, m_func);
50525052
dstOpnd = this->BuildDstOpnd(dstRegSlot);
5053-
dstOpnd->SetValueType(ValueType::GetObject(ObjectType::UninitializedObject));
5053+
dstOpnd->SetValueType(ValueType::GetObject(ObjectType::Object));
50545054
instr = IR::Instr::New(newOpcode, dstOpnd, srcOpnd, m_func);
50555055

50565056
// 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)