Skip to content

Commit

Permalink
[MERGE #6375 @akroshg] ChakraCore servicing fixes for Feb release
Browse files Browse the repository at this point in the history
Merge pull request #6375 from akroshg:servicing/2002

Fixes following CVEs
[CVE-2020-0710]
[CVE-2020-0711]
[CVE-2020-0712]
[CVE-2020-0713]
[CVE-2020-0767]
  • Loading branch information
akroshg committed Feb 11, 2020
2 parents 9741bdf + 23eca47 commit 42485b9
Show file tree
Hide file tree
Showing 18 changed files with 513 additions and 72 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.15
1.11.16
11 changes: 11 additions & 0 deletions lib/Backend/JnHelperMethodList.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,17 @@ HELPERCALLCHK(Op_PatchPutValueWithThisPtrNoLocalFastPathPolymorphic, ((void (*)(
HELPERCALLCHK(Op_PatchPutRootValueNoLocalFastPath, ((void (*)(Js::FunctionBody *const, Js::InlineCache *const, const Js::InlineCacheIndex, Js::Var, Js::PropertyId, Js::Var, Js::PropertyOperationFlags))Js::JavascriptOperators::PatchPutRootValueNoLocalFastPath<true, Js::InlineCache>), AttrCanThrow)
HELPERCALLCHK(Op_PatchPutRootValueNoLocalFastPathPolymorphic, ((void (*)(Js::FunctionBody *const, Js::PolymorphicInlineCache *const, const Js::InlineCacheIndex, Js::Var, Js::PropertyId, Js::Var, Js::PropertyOperationFlags))Js::JavascriptOperators::PatchPutRootValueNoLocalFastPath<true, Js::PolymorphicInlineCache>), AttrCanThrow)

HELPERCALLCHK(Op_PatchInitValueCheckLayout, ((bool (*)(Js::FunctionBody *const, Js::InlineCache *const, const Js::InlineCacheIndex, Js::RecyclableObject*, Js::PropertyId, Js::Var))Js::JavascriptOperators::PatchInitValueCheckLayout<Js::InlineCache>), AttrCanThrow)
HELPERCALLCHK(Op_PatchInitValuePolymorphicCheckLayout, ((bool (*)(Js::FunctionBody *const, Js::PolymorphicInlineCache *const, const Js::InlineCacheIndex, Js::RecyclableObject*, Js::PropertyId, Js::Var))Js::JavascriptOperators::PatchInitValueCheckLayout<Js::PolymorphicInlineCache>), AttrCanThrow)
HELPERCALLCHK(Op_PatchPutValueCheckLayout, ((bool (*)(Js::FunctionBody *const, Js::InlineCache *const, const Js::InlineCacheIndex, Js::Var, Js::PropertyId, Js::Var, Js::PropertyOperationFlags))Js::JavascriptOperators::PatchPutValueCheckLayout<Js::InlineCache>), AttrCanThrow)
HELPERCALLCHK(Op_PatchPutValueWithThisPtrCheckLayout, ((bool (*)(Js::FunctionBody *const, Js::InlineCache *const, const Js::InlineCacheIndex, Js::Var, Js::PropertyId, Js::Var, Js::Var, Js::PropertyOperationFlags))Js::JavascriptOperators::PatchPutValueWithThisPtrCheckLayout<Js::InlineCache>), AttrCanThrow)
HELPERCALLCHK(Op_PatchPutValuePolymorphicCheckLayout, ((bool (*)(Js::FunctionBody *const, Js::PolymorphicInlineCache *const, const Js::InlineCacheIndex, Js::Var, Js::PropertyId, Js::Var, Js::PropertyOperationFlags))Js::JavascriptOperators::PatchPutValueCheckLayout<Js::PolymorphicInlineCache>), AttrCanThrow)
HELPERCALLCHK(Op_PatchPutValueWithThisPtrPolymorphicCheckLayout, ((bool (*)(Js::FunctionBody *const, Js::PolymorphicInlineCache *const, const Js::InlineCacheIndex, Js::Var, Js::PropertyId, Js::Var, Js::Var, Js::PropertyOperationFlags))Js::JavascriptOperators::PatchPutValueWithThisPtrCheckLayout<Js::PolymorphicInlineCache>), AttrCanThrow)
HELPERCALLCHK(Op_PatchPutValueNoLocalFastPathCheckLayout, ((bool (*)(Js::FunctionBody *const, Js::InlineCache *const, const Js::InlineCacheIndex, Js::Var, Js::PropertyId, Js::Var, Js::PropertyOperationFlags))Js::JavascriptOperators::PatchPutValueNoLocalFastPathCheckLayout<Js::InlineCache>), AttrCanThrow)
HELPERCALLCHK(Op_PatchPutValueWithThisPtrNoLocalFastPathCheckLayout, ((bool (*)(Js::FunctionBody *const, Js::InlineCache *const, const Js::InlineCacheIndex, Js::Var, Js::PropertyId, Js::Var, Js::Var, Js::PropertyOperationFlags))Js::JavascriptOperators::PatchPutValueWithThisPtrNoLocalFastPathCheckLayout<Js::InlineCache>), AttrCanThrow)
HELPERCALLCHK(Op_PatchPutValueNoLocalFastPathPolymorphicCheckLayout, ((bool (*)(Js::FunctionBody *const, Js::PolymorphicInlineCache *const, const Js::InlineCacheIndex, Js::Var, Js::PropertyId, Js::Var, Js::PropertyOperationFlags))Js::JavascriptOperators::PatchPutValueNoLocalFastPathCheckLayout<Js::PolymorphicInlineCache>), AttrCanThrow)
HELPERCALLCHK(Op_PatchPutValueWithThisPtrNoLocalFastPathPolymorphicCheckLayout, ((bool (*)(Js::FunctionBody *const, Js::PolymorphicInlineCache *const, const Js::InlineCacheIndex, Js::Var, Js::PropertyId, Js::Var, Js::Var, Js::PropertyOperationFlags))Js::JavascriptOperators::PatchPutValueWithThisPtrNoLocalFastPathCheckLayout<Js::PolymorphicInlineCache>), AttrCanThrow)

HELPERCALLCHK(Op_PatchSetPropertyScoped, ((void (*)(Js::FunctionBody *const, Js::InlineCache *const, const Js::InlineCacheIndex, Js::FrameDisplay*, Js::PropertyId, Js::Var, Js::Var, Js::PropertyOperationFlags))Js::JavascriptOperators::PatchSetPropertyScoped<true, Js::InlineCache>), AttrCanThrow)
HELPERCALLCHK(Op_ConsolePatchSetPropertyScoped, ((void(*)(Js::FunctionBody *const, Js::InlineCache *const, const Js::InlineCacheIndex, Js::FrameDisplay*, Js::PropertyId, Js::Var, Js::Var, Js::PropertyOperationFlags))Js::JavascriptOperators::PatchSetPropertyScoped<true, Js::InlineCache>), AttrCanThrow)

Expand Down
105 changes: 88 additions & 17 deletions lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7107,6 +7107,57 @@ Lowerer::LowerStFld(
IR::Opnd *dst = stFldInstr->UnlinkDst();
AssertMsg(dst->IsSymOpnd() && dst->AsSymOpnd()->m_sym->IsPropertySym(), "Expected property sym as dst of field store");

BailOutInfo * bailOutInfo = nullptr;
bool doCheckLayout = false;
IR::PropertySymOpnd * propertySymOpnd = nullptr;
if (dst->AsSymOpnd()->IsPropertySymOpnd())
{
propertySymOpnd = dst->AsPropertySymOpnd();
if (stFldInstr->HasBailOutInfo() && !propertySymOpnd->IsTypeCheckSeqCandidate() && propertySymOpnd->TypeCheckRequired())
{
IR::Instr * instrBailTarget = stFldInstr->ShareBailOut();
LowerBailTarget(instrBailTarget);
doCheckLayout = true;
bailOutInfo = stFldInstr->GetBailOutInfo();
switch (helperMethod)
{
case IR::HelperOp_PatchPutValue:
helperMethod = IR::HelperOp_PatchPutValueCheckLayout;
break;
case IR::HelperOp_PatchPutValuePolymorphic:
helperMethod = IR::HelperOp_PatchPutValuePolymorphicCheckLayout;
break;
case IR::HelperOp_PatchPutValueNoLocalFastPath:
helperMethod = IR::HelperOp_PatchPutValueNoLocalFastPathCheckLayout;
break;
case IR::HelperOp_PatchPutValueNoLocalFastPathPolymorphic:
helperMethod = IR::HelperOp_PatchPutValueNoLocalFastPathPolymorphicCheckLayout;
break;
case IR::HelperOp_PatchPutValueWithThisPtr:
helperMethod = IR::HelperOp_PatchPutValueWithThisPtrCheckLayout;
break;
case IR::HelperOp_PatchPutValueWithThisPtrPolymorphic:
helperMethod = IR::HelperOp_PatchPutValueWithThisPtrPolymorphicCheckLayout;
break;
case IR::HelperOp_PatchPutValueWithThisPtrNoLocalFastPath:
helperMethod = IR::HelperOp_PatchPutValueWithThisPtrNoLocalFastPathCheckLayout;
break;
case IR::HelperOp_PatchPutValueWithThisPtrNoLocalFastPathPolymorphic:
helperMethod = IR::HelperOp_PatchPutValueWithThisPtrNoLocalFastPathPolymorphicCheckLayout;
break;
case IR::HelperOp_PatchInitValue:
helperMethod = IR::HelperOp_PatchInitValueCheckLayout;
break;
case IR::HelperOp_PatchInitValuePolymorphic:
helperMethod = IR::HelperOp_PatchInitValuePolymorphicCheckLayout;
break;
default:
AssertOrFailFast(false);
break;
}
}
}

IR::Opnd * inlineCacheOpnd = nullptr;
if (withInlineCache)
{
Expand Down Expand Up @@ -7153,7 +7204,20 @@ Lowerer::LowerStFld(
}

IR::RegOpnd *opndBase = dst->AsSymOpnd()->CreatePropertyOwnerOpnd(m_func);
m_lowererMD.ChangeToHelperCall(stFldInstr, helperMethod, labelBailOut, opndBase, dst->AsSymOpnd()->IsPropertySymOpnd() ? dst->AsSymOpnd()->AsPropertySymOpnd() : nullptr, isHelper);

IR::Instr * callInstr =
m_lowererMD.ChangeToHelperCall(stFldInstr, helperMethod, labelBailOut, opndBase, propertySymOpnd, isHelper);

if (doCheckLayout)
{
callInstr->SetDst(IR::RegOpnd::New(TyUint8, bailOutInfo->bailOutFunc));
IR::Instr * bailOutInstr = IR::BailOutInstr::New(Js::OpCode::BailOnNotEqual, IR::BailOutFailedTypeCheck, bailOutInfo, bailOutInfo->bailOutFunc);
bailOutInstr->SetSrc1(callInstr->GetDst());
bailOutInstr->SetSrc2(IR::IntConstOpnd::New(0, TyUint8, bailOutInfo->bailOutFunc));
callInstr->InsertAfter(bailOutInstr);
bailOutInfo->polymorphicCacheIndex = propertySymOpnd->m_inlineCacheIndex;
LowerBailOnEqualOrNotEqual(bailOutInstr, nullptr, nullptr, nullptr, isHelper);
}

return instrPrev;
}
Expand Down Expand Up @@ -24950,9 +25014,9 @@ Lowerer::GenerateLdHomeObj(IR::Instr* instr)
Func *func = instr->m_func;

IR::LabelInstr *labelDone = IR::LabelInstr::New(Js::OpCode::Label, func, false);
IR::LabelInstr *labelInlineFunc = IR::LabelInstr::New(Js::OpCode::Label, func, false);
IR::LabelInstr *testLabel = IR::LabelInstr::New(Js::OpCode::Label, func, false);
IR::LabelInstr *scriptFuncLabel = IR::LabelInstr::New(Js::OpCode::Label, func, false);
LABELNAMESET(scriptFuncLabel, "ScriptFunctionWithHomeObj");
IR::Opnd *opndUndefAddress = this->LoadLibraryValueOpnd(instr, LibraryValue::ValueUndefined);

IR::RegOpnd *instanceRegOpnd = IR::RegOpnd::New(TyMachPtr, func);
Expand All @@ -24973,23 +25037,30 @@ Lowerer::GenerateLdHomeObj(IR::Instr* instr)

if (func->GetJITFunctionBody()->HasHomeObj())
{
// Is this an function with inline cache and home obj??
IR::Opnd * vtableAddressInlineFuncHomObjOpnd = this->LoadVTableValueOpnd(instr, VTableValue::VtableScriptFunctionWithInlineCacheAndHomeObj);
IR::BranchInstr* inlineFuncHomObjOpndBr = InsertCompareBranch(IR::IndirOpnd::New(instanceRegOpnd, 0, TyMachPtr, func), vtableAddressInlineFuncHomObjOpnd, Js::OpCode::BrNeq_A, labelInlineFunc, instr);
InsertObjectPoison(instanceRegOpnd, inlineFuncHomObjOpndBr, instr, false);
IR::IndirOpnd *indirInlineFuncHomeObjOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::FunctionWithHomeObj<Js::ScriptFunctionWithInlineCache>::GetOffsetOfHomeObj(), TyMachPtr, func);
Lowerer::InsertMove(instanceRegOpnd, indirInlineFuncHomeObjOpnd, instr);
InsertBranch(Js::OpCode::Br, testLabel, instr);
IR::RegOpnd* funcObjHasInlineCachesOpnd = IR::RegOpnd::New(TyUint8, instr->m_func);
this->InsertMove(funcObjHasInlineCachesOpnd, IR::IndirOpnd::New(instanceRegOpnd, Js::ScriptFunction::GetOffsetOfHasInlineCaches(), TyUint8, instr->m_func), instr);

instr->InsertBefore(labelInlineFunc);

// Is this a function with inline cache, home obj and computed name??
IR::Opnd * vtableAddressInlineFuncHomObjCompNameOpnd = this->LoadVTableValueOpnd(instr, VTableValue::VtableScriptFunctionWithInlineCacheHomeObjAndComputedName);
IR::BranchInstr* inlineFuncHomObjCompNameBr = InsertCompareBranch(IR::IndirOpnd::New(instanceRegOpnd, 0, TyMachPtr, func), vtableAddressInlineFuncHomObjCompNameOpnd, Js::OpCode::BrNeq_A, scriptFuncLabel, instr);
IR::BranchInstr* inlineFuncHomObjCompNameBr = InsertTestBranch(funcObjHasInlineCachesOpnd, funcObjHasInlineCachesOpnd, Js::OpCode::BrEq_A, scriptFuncLabel, instr);
InsertObjectPoison(instanceRegOpnd, inlineFuncHomObjCompNameBr, instr, false);
IR::IndirOpnd *indirInlineFuncHomeObjCompNameOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::FunctionWithComputedName<Js::FunctionWithHomeObj<Js::ScriptFunctionWithInlineCache>>::GetOffsetOfHomeObj(), TyMachPtr, func);
Lowerer::InsertMove(instanceRegOpnd, indirInlineFuncHomeObjCompNameOpnd, instr);
InsertBranch(Js::OpCode::Br, testLabel, instr);

if (func->GetJITFunctionBody()->HasComputedName())
{
// Is this a function with inline cache, home obj and computed name?
{
IR::IndirOpnd* indirInlineFuncHomeObjCompNameOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::FunctionWithComputedName<Js::FunctionWithHomeObj<Js::ScriptFunctionWithInlineCache>>::GetOffsetOfHomeObj(), TyMachPtr, func);
Lowerer::InsertMove(instanceRegOpnd, indirInlineFuncHomeObjCompNameOpnd, instr);
InsertBranch(Js::OpCode::Br, testLabel, instr);
}
}
else
{
// Is this a function with inline cache and home obj?
{
IR::IndirOpnd* indirInlineFuncHomeObjOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::FunctionWithHomeObj<Js::ScriptFunctionWithInlineCache>::GetOffsetOfHomeObj(), TyMachPtr, func);
Lowerer::InsertMove(instanceRegOpnd, indirInlineFuncHomeObjOpnd, instr);
InsertBranch(Js::OpCode::Br, testLabel, instr);
}
}

instr->InsertBefore(scriptFuncLabel);
IR::IndirOpnd *indirOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::ScriptFunctionWithHomeObj::GetOffsetOfHomeObj(), TyMachPtr, func);
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 15
#define CHAKRA_CORE_PATCH_VERSION 16
#define CHAKRA_CORE_VERSION_RELEASE_QFE 0 // Redundant with PATCH_VERSION. Keep this value set to 0.

// -------------
Expand Down
26 changes: 22 additions & 4 deletions lib/Parser/Parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1738,6 +1738,20 @@ void Parser::BindPidRefsInScope(IdentPtr pid, Symbol *sym, int blockId, uint max
}
}

if (m_currentNodeFunc && m_currentNodeFunc->pnodeName && pid == m_currentNodeFunc->pnodeName->pid && !m_currentNodeFunc->IsDeclaration() && m_currentNodeFunc->IsBodyAndParamScopeMerged())
{
Scope* funcExprScope = m_currentNodeFunc->scope;
Assert(funcExprScope->GetScopeType() == ScopeType_FuncExpr);

ParseNodeBlock* bodyScope = m_currentNodeFunc->pnodeBodyScope;
Assert(bodyScope->blockType == PnodeBlockType::Function);

if (ref->GetScopeId() < bodyScope->blockId && ref->GetScopeId() > blockId)
{
funcExprScope->SetIsObject();
}
}

if (ref->GetScopeId() == blockId)
{
break;
Expand Down Expand Up @@ -4938,6 +4952,12 @@ ParseNodeFnc * Parser::ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, c
pnodeFnc->SetIsBaseClassConstructor((flags & fFncBaseClassConstructor) != 0);
pnodeFnc->SetHomeObjLocation(Js::Constants::NoRegister);

if (this->m_currentScope && this->m_currentScope->GetScopeType() == ScopeType_Parameter)
{
pnodeFnc->SetIsDeclaredInParamScope();
this->m_currentScope->SetHasNestedParamFunc();
}

IdentPtr pFncNamePid = nullptr;
bool needScanRCurly = true;
ParseFncDeclHelper<buildAST>(pnodeFnc, pNameHint, flags, fUnaryOrParen, noStmtContext, &needScanRCurly, fModule, &pFncNamePid, fAllowIn);
Expand Down Expand Up @@ -8378,17 +8398,15 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
// binding operator, be it unary or binary.
Error(ERRsyntax);
}
if (m_currentScope->GetScopeType() == ScopeType_Parameter
|| (m_currentScope->GetScopeType() == ScopeType_Block && m_currentScope->GetEnclosingScope()->GetScopeType() == ScopeType_Parameter)) // Check whether this is a class definition inside param scope
if(m_currentScope->AncestorScopeIsParameter()) // Yield is not allowed within any parameter scope
{
Error(ERRsyntax);
}
}
else if (nop == knopAwait)
{
if (!this->GetScanner()->AwaitIsKeywordRegion() ||
m_currentScope->GetScopeType() == ScopeType_Parameter ||
(m_currentScope->GetScopeType() == ScopeType_Block && m_currentScope->GetEnclosingScope()->GetScopeType() == ScopeType_Parameter)) // Check whether this is a class definition inside param scope
m_currentScope->AncestorScopeIsParameter()) // Await is not allowed within any parameter scope
{
// As with the 'yield' keyword, the case where 'await' is scanned as a keyword (tkAWAIT)
// but the scanner is not treating await as a keyword (!this->GetScanner()->AwaitIsKeyword())
Expand Down
4 changes: 3 additions & 1 deletion lib/Parser/ptree.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ enum FncFlags : uint
kFunctionIsStaticMember = 1 << 24,
kFunctionIsGenerator = 1 << 25, // Function is an ES6 generator function
kFunctionAsmjsMode = 1 << 26,
// Free = 1 << 27,
kFunctionIsDeclaredInParamScope = 1 << 27, // Function is declared in parameter scope (ex: inside default argument)
kFunctionIsAsync = 1 << 28, // function is async
kFunctionHasDirectSuper = 1 << 29, // super()
kFunctionIsDefaultModuleExport = 1 << 30, // function is the default export of a module
Expand Down Expand Up @@ -583,6 +583,7 @@ class ParseNodeFnc : public ParseNode
void SetHasHomeObj(bool set = true) { SetFlags(kFunctionHasHomeObj, set); }
void SetUsesArguments(bool set = true) { SetFlags(kFunctionUsesArguments, set); }
void SetIsDefaultModuleExport(bool set = true) { SetFlags(kFunctionIsDefaultModuleExport, set); }
void SetIsDeclaredInParamScope(bool set = true) { SetFlags(kFunctionIsDeclaredInParamScope, set); }
void SetNestedFuncEscapes(bool set = true) { nestedFuncEscapes = set; }
void SetCanBeDeferred(bool set = true) { canBeDeferred = set; }
void ResetBodyAndParamScopeMerged() { isBodyAndParamScopeMerged = false; }
Expand Down Expand Up @@ -623,6 +624,7 @@ class ParseNodeFnc : public ParseNode
bool HasHomeObj() const { return HasFlags(kFunctionHasHomeObj); }
bool UsesArguments() const { return HasFlags(kFunctionUsesArguments); }
bool IsDefaultModuleExport() const { return HasFlags(kFunctionIsDefaultModuleExport); }
bool IsDeclaredInParamScope() const { return HasFlags(kFunctionIsDeclaredInParamScope); }
bool NestedFuncEscapes() const { return nestedFuncEscapes; }
bool CanBeDeferred() const { return canBeDeferred; }
bool IsBodyAndParamScopeMerged() { return isBodyAndParamScopeMerged; }
Expand Down
Loading

0 comments on commit 42485b9

Please sign in to comment.