Skip to content

Commit

Permalink
[1.11>master] [MERGE #6375 @akroshg] ChakraCore servicing fixes for F…
Browse files Browse the repository at this point in the history
…eb release

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 14, 2020
2 parents fc0d2ac + 42485b9 commit ca5d5f3
Show file tree
Hide file tree
Showing 11 changed files with 293 additions and 98 deletions.
11 changes: 11 additions & 0 deletions lib/Backend/JnHelperMethodList.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,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
150 changes: 102 additions & 48 deletions lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7134,6 +7134,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 @@ -7180,7 +7231,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 @@ -25565,6 +25629,8 @@ Lowerer::GenerateLdHomeObj(IR::Instr* instr)

IR::LabelInstr *labelDone = 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 @@ -25586,65 +25652,53 @@ Lowerer::GenerateLdHomeObj(IR::Instr* instr)
if (func->GetJITFunctionBody()->HasHomeObj())
{
// Is this a generator function with home obj?
if (func->GetJITFunctionBody()->IsCoroutine())
{
IR::LabelInstr* nextCaseLabel = IR::LabelInstr::New(Js::OpCode::Label, func, false);
LABELNAMESET(nextCaseLabel, "GeneratorFunctionWithHomeObjAndComputedName");

IR::Opnd* vtableAddressInlineFuncHomObjOpnd = this->LoadVTableValueOpnd(instr, VTableValue::VtableVirtualJavascriptGeneratorFunctionWithHomeObj);
IR::BranchInstr* inlineFuncHomObjOpndBr = InsertCompareBranch(IR::IndirOpnd::New(instanceRegOpnd, 0, TyMachPtr, func), vtableAddressInlineFuncHomObjOpnd, Js::OpCode::BrNeq_A, nextCaseLabel, instr);
InsertObjectPoison(instanceRegOpnd, inlineFuncHomObjOpndBr, instr, false);
IR::IndirOpnd* indirInlineFuncHomeObjOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::FunctionWithHomeObj<Js::GeneratorVirtualScriptFunction>::GetOffsetOfHomeObj(), TyMachPtr, func);
Lowerer::InsertMove(instanceRegOpnd, indirInlineFuncHomeObjOpnd, instr);
InsertBranch(Js::OpCode::Br, testLabel, instr);
uint32 homeObjectOffset = Js::FunctionWithHomeObj<Js::GeneratorVirtualScriptFunction>::GetOffsetOfHomeObj();

instr->InsertBefore(nextCaseLabel);
}

// Is this a generator function with home obj and computed name?
{
IR::LabelInstr* nextCaseLabel = IR::LabelInstr::New(Js::OpCode::Label, func, false);
LABELNAMESET(nextCaseLabel, "FunctionWithInlineCacheAndHomeObj");

IR::Opnd* vtableAddressInlineFuncHomObjOpnd = this->LoadVTableValueOpnd(instr, VTableValue::VtableVirtualJavascriptGeneratorFunctionWithHomeObjAndComputedName);
IR::BranchInstr* inlineFuncHomObjOpndBr = InsertCompareBranch(IR::IndirOpnd::New(instanceRegOpnd, 0, TyMachPtr, func), vtableAddressInlineFuncHomObjOpnd, Js::OpCode::BrNeq_A, nextCaseLabel, instr);
InsertObjectPoison(instanceRegOpnd, inlineFuncHomObjOpndBr, instr, false);
IR::IndirOpnd* indirInlineFuncHomeObjOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::FunctionWithComputedName<Js::FunctionWithHomeObj<Js::GeneratorVirtualScriptFunction>>::GetOffsetOfHomeObj(), TyMachPtr, func);
Lowerer::InsertMove(instanceRegOpnd, indirInlineFuncHomeObjOpnd, instr);
InsertBranch(Js::OpCode::Br, testLabel, instr);

instr->InsertBefore(nextCaseLabel);
}
// Is this a generator function with home obj and computed name?
if (func->GetJITFunctionBody()->HasComputedName())
{
homeObjectOffset = Js::FunctionWithComputedName<Js::FunctionWithHomeObj<Js::GeneratorVirtualScriptFunction>>::GetOffsetOfHomeObj();
}

// Is this an function with inline cache and home obj?
{
IR::LabelInstr* labelInlineFunc = IR::LabelInstr::New(Js::OpCode::Label, func, false);
LABELNAMESET(labelInlineFunc, "FunctionWithInlineCacheHomeObjAndComputedName");
{
IR::IndirOpnd* indirOpnd = IR::IndirOpnd::New(instanceRegOpnd, homeObjectOffset, TyMachPtr, func);
Lowerer::InsertMove(instanceRegOpnd, indirOpnd, instr);
}

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);

instr->InsertBefore(labelInlineFunc);
}

// Is this a function with inline cache, home obj and computed name?
else
{
IR::LabelInstr* scriptFuncLabel = IR::LabelInstr::New(Js::OpCode::Label, func, false);
LABELNAMESET(scriptFuncLabel, "ScriptFunctionWithHomeObj");
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);

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);

instr->InsertBefore(scriptFuncLabel);
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);

// All other cases
{
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
@@ -1,4 +1,4 @@
//-------------------------------------------------------------------------------------------------------
no//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
Expand Down
12 changes: 8 additions & 4 deletions lib/Parser/Parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5410,6 +5410,12 @@ ParseNodeFnc * Parser::ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, c
this->m_currentScope->SetHasNestedParamFunc();
}

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 @@ -8869,17 +8875,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
Loading

0 comments on commit ca5d5f3

Please sign in to comment.