Skip to content

Commit

Permalink
[MERGE #6500 @boingoing] ChakraCore Servicing update for 2020.09B
Browse files Browse the repository at this point in the history
Merge pull request #6500 from boingoing:servicing/2009

[CVE-2020-0878]
[CVE-2020-1180]
[CVE-2020-1057]
[CVE-2020-1172]
  • Loading branch information
boingoing committed Sep 8, 2020
2 parents b12499b + 337129e commit 63c5099
Show file tree
Hide file tree
Showing 17 changed files with 259 additions and 52 deletions.
2 changes: 1 addition & 1 deletion Build/NuGet/.pack-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.11.21
1.11.22
15 changes: 1 addition & 14 deletions lib/Backend/BackwardPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8648,20 +8648,7 @@ BackwardPass::SetWriteThroughSymbolsSetForRegion(BasicBlock * catchOrFinallyBloc
bool
BackwardPass::CheckWriteThroughSymInRegion(Region* region, StackSym* sym)
{
if (region->GetType() == RegionTypeRoot)
{
return false;
}

// if the current region is a try region, check in its write-through set,
// otherwise (current = catch region) look in the first try ancestor's write-through set
Region * selfOrFirstTryAncestor = region->GetSelfOrFirstTryAncestor();
if (!selfOrFirstTryAncestor)
{
return false;
}
Assert(selfOrFirstTryAncestor->GetType() == RegionTypeTry);
return selfOrFirstTryAncestor->writeThroughSymbolsSet && selfOrFirstTryAncestor->writeThroughSymbolsSet->Test(sym->m_id);
return region->CheckWriteThroughSym(sym);
}

#if DBG
Expand Down
11 changes: 11 additions & 0 deletions lib/Backend/Func.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Func::Func(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,
m_localClosureSym(nullptr),
m_paramClosureSym(nullptr),
m_localFrameDisplaySym(nullptr),
m_inlineeFrameDisplaySyms(nullptr),
m_bailoutReturnValueSym(nullptr),
m_hasBailedOutSym(nullptr),
m_inlineeFrameStartSym(nullptr),
Expand Down Expand Up @@ -1124,6 +1125,16 @@ void Func::InitLocalClosureSyms()
}
}

void
Func::AddInlineeFrameDisplaySym(StackSym *inlineeFrameDisplaySym)
{
if (m_inlineeFrameDisplaySyms == nullptr)
{
m_inlineeFrameDisplaySyms = JitAnew(this->m_alloc, SList<StackSym*>, this->m_alloc);
}
m_inlineeFrameDisplaySyms->Prepend(inlineeFrameDisplaySym);
}

bool
Func::IsTrackCompoundedIntOverflowDisabled() const
{
Expand Down
2 changes: 2 additions & 0 deletions lib/Backend/Func.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ static const unsigned __int64 c_debugFillPattern8 = 0xcececececececece;

StackSym *GetLocalFrameDisplaySym() const { return m_localFrameDisplaySym; }
void SetLocalFrameDisplaySym(StackSym *sym) { m_localFrameDisplaySym = sym; }
void AddInlineeFrameDisplaySym(StackSym *sym);

intptr_t GetJittedLoopIterationsSinceLastBailoutAddress() const;
void EnsurePinnedTypeRefs();
Expand Down Expand Up @@ -678,6 +679,7 @@ static const unsigned __int64 c_debugFillPattern8 = 0xcececececececece;
StackSym * m_paramClosureSym;
StackSym * m_localFrameDisplaySym;
StackSym * m_bailoutReturnValueSym;
SList<StackSym*> * m_inlineeFrameDisplaySyms;
StackSym * m_hasBailedOutSym;
uint m_forInLoopMaxDepth;
uint m_forInLoopBaseDepth;
Expand Down
2 changes: 2 additions & 0 deletions lib/Backend/GlobOpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,8 @@ class GlobOpt
void KillAllObjectTypes(BVSparse<JitArenaAllocator>* liveFields = nullptr);
void EndFieldLifetime(IR::SymOpnd *symOpnd);
PropertySym * CopyPropPropertySymObj(IR::SymOpnd *opnd, IR::Instr *instr);
void OnCopyPropInPrePass(StackSym * copySym, IR::Instr * instr, BasicBlock * block);
void UpdateUpwardExposedUses(StackSym * sym, IR::Instr * instrLast, BasicBlock * block, JsUtil::Stack<BasicBlock*, JitArenaAllocator, true> *blockStack, BVSparse<JitArenaAllocator>* blocksProcessed);
static bool NeedsTypeCheckBailOut(const IR::Instr *instr, IR::PropertySymOpnd *propertySymOpnd, bool isStore, bool* pIsTypeCheckProtected, IR::BailOutKind *pBailOutKind);
IR::Instr * PreOptPeep(IR::Instr *instr);
IR::Instr * OptPeep(IR::Instr *instr, Value *src1Val, Value *src2Val);
Expand Down
76 changes: 76 additions & 0 deletions lib/Backend/GlobOptFields.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1917,6 +1917,11 @@ GlobOpt::CopyPropPropertySymObj(IR::SymOpnd *symOpnd, IR::Instr *instr)
symOpnd->m_sym = newProp;
symOpnd->SetIsJITOptimizedReg(true);

if (this->IsLoopPrePass())
{
this->OnCopyPropInPrePass(copySym, instr, this->currentBlock);
}

if (symOpnd->IsPropertySymOpnd())
{
IR::PropertySymOpnd *propertySymOpnd = symOpnd->AsPropertySymOpnd();
Expand Down Expand Up @@ -1959,6 +1964,77 @@ GlobOpt::CopyPropPropertySymObj(IR::SymOpnd *symOpnd, IR::Instr *instr)
return propertySym;
}

void
GlobOpt::OnCopyPropInPrePass(StackSym * copySym, IR::Instr * instr, BasicBlock * block)
{
// Copy prop in the prepass may make upwardExposedUses out of date. Update it now.

if (block->upwardExposedUses->Test(copySym->m_id))
{
// Nothing to do
return;
}

// Use a to-do stack to avoid recursion and a bv to avoid repeated work
JsUtil::Stack<BasicBlock*, JitArenaAllocator, true> blockStack(this->tempAlloc);
BVSparse<JitArenaAllocator> blocksProcessed(this->tempAlloc);

blocksProcessed.Set(block->GetBlockNum());
this->UpdateUpwardExposedUses(copySym, instr, block, &blockStack, &blocksProcessed);

while (!blockStack.Empty())
{
block = blockStack.Pop();
Assert(blocksProcessed.Test(block->GetBlockNum()));
this->UpdateUpwardExposedUses(copySym, block->GetLastInstr(), block, &blockStack, &blocksProcessed);
}
}

void
GlobOpt::UpdateUpwardExposedUses(StackSym * sym, IR::Instr * instrLast, BasicBlock * block, JsUtil::Stack<BasicBlock*, JitArenaAllocator, true> *blockStack, BVSparse<JitArenaAllocator>* blocksProcessed)
{
Assert(blocksProcessed->Test(block->GetBlockNum()));
Assert(!block->upwardExposedUses->Test(sym->m_id));

// Walk the block backward looking for a def. If the sym is write-through in this block, though,
// treat it as upward-exposed regardless of the presence of defs.
IR::LabelInstr * instrFirst = block->GetFirstInstr()->AsLabelInstr();
Region * region = instrFirst->GetRegion();
if (region == nullptr || !region->CheckWriteThroughSym(sym))
{
FOREACH_INSTR_BACKWARD_IN_RANGE(instr, instrLast, instrFirst)
{
// If the instr defines the sym, quit without setting upwardExposedUses
IR::Opnd * dst = instr->GetDst();
if (dst != nullptr && dst->GetStackSym() == sym)
{
return;
}
Assert(dst == nullptr || dst->GetStackSym() == nullptr || dst->GetStackSym()->m_id != sym->m_id);
}
NEXT_INSTR_BACKWARD_IN_RANGE;
}

// The sym is upward exposed at this block. Now update the to-do set with the predecessors.

Assert(block->GetBlockNum() != 0);
block->upwardExposedUses->Set(sym->m_id);
FOREACH_PREDECESSOR_BLOCK(blockPred, block)
{
if (blockPred->upwardExposedUses == nullptr || blockPred->upwardExposedUses->Test(sym->m_id))
{
// If the bv is null, that means the main pass is done with this block
// and so done with its predecessors
continue;
}
if (!blocksProcessed->TestAndSet(blockPred->GetBlockNum()))
{
blockStack->Push(blockPred);
}
}
NEXT_PREDECESSOR_BLOCK;
}

void
GlobOpt::UpdateObjPtrValueType(IR::Opnd * opnd, IR::Instr * instr)
{
Expand Down
5 changes: 5 additions & 0 deletions lib/Backend/IRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,11 @@ IRBuilder::Build()
dstOpnd, m_func),
offset);
}
else if (m_func->GetTopFunc()->DoStackFrameDisplay())
{
Assert(m_func->GetLocalFrameDisplaySym() != nullptr);
m_func->GetTopFunc()->AddInlineeFrameDisplaySym(m_func->GetLocalFrameDisplaySym());
}
}
}
}
Expand Down
47 changes: 45 additions & 2 deletions lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ Lowerer::Lower()
{
EnsureStackFunctionListStackSym();
}
StackSym * symInlineeFrameDisplayEnd = nullptr;
if (m_func->DoStackFrameDisplay() && !m_func->IsLoopBody())
{
AllocStackClosure();
symInlineeFrameDisplayEnd = StackSym::New(m_func);
AllocStackClosure(symInlineeFrameDisplayEnd);
}

AllocStackForInObjectEnumeratorArray();
Expand Down Expand Up @@ -140,6 +142,11 @@ Lowerer::Lower()
EnsureZeroLastStackFunctionNext();
}

if (symInlineeFrameDisplayEnd != nullptr)
{
InitializeInlineeFrameDisplays(symInlineeFrameDisplayEnd);
}

if (!m_func->IsSimpleJit())
{
#if 0 // TODO michhol oop jit, reenable assert
Expand Down Expand Up @@ -6755,10 +6762,40 @@ Lowerer::EnsureStackFunctionListStackSym()
}

void
Lowerer::AllocStackClosure()
Lowerer::AllocStackClosure(StackSym * symInlineeFrameDisplayEnd)
{
m_func->StackAllocate(m_func->GetLocalFrameDisplaySym(), sizeof(Js::Var));
m_func->StackAllocate(m_func->GetLocalClosureSym(), sizeof(Js::Var));

if (m_func->m_inlineeFrameDisplaySyms != nullptr)
{
FOREACH_SLIST_ENTRY(StackSym*, sym, m_func->m_inlineeFrameDisplaySyms)
{
m_func->StackAllocate(sym, sizeof(Js::Var));
}
NEXT_SLIST_ENTRY;
}
m_func->StackAllocate(symInlineeFrameDisplayEnd, sizeof(Js::Var));
}

void
Lowerer::InitializeInlineeFrameDisplays(StackSym * symInlineeFrameDisplayEnd)
{
if (m_func->m_inlineeFrameDisplaySyms != nullptr)
{
FOREACH_SLIST_ENTRY(StackSym*, sym, m_func->m_inlineeFrameDisplaySyms)
{
Assert(sym->IsAllocated());
InsertMove(IR::SymOpnd::New(sym, TyMachReg, m_func),
IR::AddrOpnd::New(m_func->GetThreadContextInfo()->GetNullFrameDisplayAddr(), IR::AddrOpndKindDynamicMisc, m_func),
m_func->GetFunctionEntryInsertionPoint());
}
NEXT_SLIST_ENTRY;
}
Assert(symInlineeFrameDisplayEnd->IsAllocated());
InsertMove(IR::SymOpnd::New(symInlineeFrameDisplayEnd, TyMachReg, m_func),
IR::AddrOpnd::New((void*)0, IR::AddrOpndKindDynamicMisc, m_func),
m_func->GetFunctionEntryInsertionPoint());
}

void
Expand Down Expand Up @@ -27112,6 +27149,12 @@ void Lowerer::LowerLdFrameDisplay(IR::Instr *instr, bool doStackFrameDisplay)
else
{
GenerateRecyclerAlloc(IR::HelperAllocMemForFrameDisplay, allocSize, dstOpnd, instr);
if (instr->m_func != this->m_func && this->m_func->DoStackFrameDisplay())
{
StackSym * inlineeFrameDisplaySym = instr->m_func->GetLocalFrameDisplaySym();
Assert(inlineeFrameDisplaySym->IsAllocated());
InsertMove(IR::SymOpnd::New(inlineeFrameDisplaySym, TyMachReg, m_func), dstOpnd, instr);
}
}

// Copy contents of environment
Expand Down
3 changes: 2 additions & 1 deletion lib/Backend/Lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ class Lowerer

void EnsureStackFunctionListStackSym();
void EnsureZeroLastStackFunctionNext();
void AllocStackClosure();
void AllocStackClosure(StackSym * symInlineeFrameDisplayEnd);
void InitializeInlineeFrameDisplays(StackSym * symInlineeFrameDisplayEnd);
IR::Instr * GenerateNewStackScFunc(IR::Instr * newScFuncInstr, IR::RegOpnd ** ppEnvOpnd);
void GenerateStackScriptFunctionInit(StackSym * stackSym, Js::FunctionInfoPtrPtr nestedInfo);
void GenerateScriptFunctionInit(IR::RegOpnd * regOpnd, IR::Opnd * vtableAddressOpnd,
Expand Down
18 changes: 18 additions & 0 deletions lib/Backend/Region.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,21 @@ Region::GetFirstAncestorOfNonExceptingFinally()
return ancestor;
}

bool
Region::CheckWriteThroughSym(StackSym * sym)
{
if (this->GetType() == RegionTypeRoot)
{
return false;
}

// if the current region is a try region, check in its write-through set,
// otherwise (current = catch region) look in the first try ancestor's write-through set
Region * selfOrFirstTryAncestor = this->GetSelfOrFirstTryAncestor();
if (!selfOrFirstTryAncestor)
{
return false;
}
Assert(selfOrFirstTryAncestor->GetType() == RegionTypeTry);
return selfOrFirstTryAncestor->writeThroughSymbolsSet && selfOrFirstTryAncestor->writeThroughSymbolsSet->Test(sym->m_id);
}
1 change: 1 addition & 0 deletions lib/Backend/Region.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class Region
Region * GetSelfOrFirstTryAncestor();
Region * GetFirstAncestorOfNonExceptingFinallyParent();
Region * GetFirstAncestorOfNonExceptingFinally();
bool CheckWriteThroughSym(StackSym * sym);

private:
RegionType type;
Expand Down
2 changes: 1 addition & 1 deletion lib/Common/ChakraCoreVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// ChakraCore version number definitions (used in ChakraCore binary metadata)
#define CHAKRA_CORE_MAJOR_VERSION 1
#define CHAKRA_CORE_MINOR_VERSION 11
#define CHAKRA_CORE_PATCH_VERSION 21
#define CHAKRA_CORE_PATCH_VERSION 22
#define CHAKRA_CORE_VERSION_RELEASE_QFE 0 // Redundant with PATCH_VERSION. Keep this value set to 0.

// -------------
Expand Down
13 changes: 11 additions & 2 deletions lib/Parser/Scan.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,15 +241,24 @@ class UTF8EncodingPolicyBase
OLECHAR ReadRest(OLECHAR ch, EncodedCharPtr &p, EncodedCharPtr last)
{
EncodedCharPtr s;
utf8::DecodeOptions decodeOptions = m_decodeOptions;
if (bScan)
{
s = p;
}
OLECHAR result = utf8::DecodeTail(ch, p, last, m_decodeOptions);
if (bScan)
{
// If we are scanning, update m_cMultiUnits counter.
m_cMultiUnits += p - s;
if ((decodeOptions & utf8::doSecondSurrogatePair) && (p - s > 2))
{
// 4 byte utf8 chars equals 2 utf16 chars + 2 multi-unit chars only (refer to case4: in utf8::DecodeTail()).
m_cMultiUnits += 2;
}
else
{
// If we are scanning, update m_cMultiUnits counter.
m_cMultiUnits += p - s;
}
}
return result;
}
Expand Down
2 changes: 2 additions & 0 deletions lib/Runtime/Base/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,12 @@ namespace Js
static const int StackNestedFuncList = 2;
static const int StackFrameDisplay = 3;
static const int StackScopeSlots = 4;
static const int InlineeFrameDisplays = 5;
#if _M_IX86 || _M_AMD64
static const int StackNestedFuncListWithNoArg = 1;
static const int StackFrameDisplayWithNoArg = 2;
static const int StackScopeSlotsWithNoArg = 3;
static const int InlineeFrameDisplaysWithNoArg = 4;
#endif

static const DWORD NonWebWorkerContextId = 0;
Expand Down
2 changes: 2 additions & 0 deletions lib/Runtime/Language/JavascriptFunctionArgIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ namespace Js
JavascriptFunctionArgIndex_StackNestedFuncListWithNoArg = JavascriptFunctionArgIndex_Frame - Js::Constants::StackNestedFuncListWithNoArg,
JavascriptFunctionArgIndex_StackFrameDisplayNoArg = JavascriptFunctionArgIndex_Frame - Js::Constants::StackFrameDisplayWithNoArg,
JavascriptFunctionArgIndex_StackScopeSlotsNoArg = JavascriptFunctionArgIndex_Frame - Js::Constants::StackScopeSlotsWithNoArg,
JavascriptFunctionArgIndex_InlineeFrameDisplaysNoArg = JavascriptFunctionArgIndex_Frame - Js::Constants::InlineeFrameDisplaysWithNoArg,
#endif
JavascriptFunctionArgIndex_StackNestedFuncList = JavascriptFunctionArgIndex_Frame - Js::Constants::StackNestedFuncList,
JavascriptFunctionArgIndex_StackFrameDisplay = JavascriptFunctionArgIndex_Frame - Js::Constants::StackFrameDisplay,
JavascriptFunctionArgIndex_StackScopeSlots = JavascriptFunctionArgIndex_Frame - Js::Constants::StackScopeSlots,
JavascriptFunctionArgIndex_InlineeFrameDisplays = JavascriptFunctionArgIndex_Frame - Js::Constants::InlineeFrameDisplays,
JavascriptFunctionArgIndex_Function = 0,
JavascriptFunctionArgIndex_CallInfo = 1,
JavascriptFunctionArgIndex_This = 2, /* (hidden) first script arg */
Expand Down
Loading

0 comments on commit 63c5099

Please sign in to comment.