Skip to content
This repository has been archived by the owner on Oct 15, 2020. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
…] 17-10 Security Update that addresses the following issues in ChakraCore

Merge pull request #3917 from agarwal-sandeep:1710Fixes

CVE-2017-11792, CVE-2017-11796, CVE-2017-11797, CVE-2017-11799, CVE-2017-11801, CVE-2017-11802, CVE-2017-11805, CVE-2017-11806, CVE-2017-11807, CVE-2017-11808, CVE-2017-11809, CVE-2017-11811, CVE-2017-11812, CVE-2017-11821
  • Loading branch information
chakrabot authored and kfarnung committed Jan 9, 2018
1 parent 53ddf53 commit 7b2ce30
Show file tree
Hide file tree
Showing 47 changed files with 505 additions and 131 deletions.
2 changes: 1 addition & 1 deletion deps/chakrashim/core/Build/NuGet/.pack-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.7.2
1.7.3
2 changes: 1 addition & 1 deletion deps/chakrashim/core/lib/Backend/GlobOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17122,7 +17122,7 @@ GlobOpt::IsSwitchOptEnabled(Func const * func)
{
Assert(func->IsTopFunc());
return !PHASE_OFF(Js::SwitchOptPhase, func) && !func->IsSwitchOptDisabled() && !IsTypeSpecPhaseOff(func)
&& func->DoGlobOpt() && !func->HasTry();
&& DoAggressiveIntTypeSpec(func) && func->DoGlobOpt() && !func->HasTry();
}

bool
Expand Down
25 changes: 10 additions & 15 deletions deps/chakrashim/core/lib/Backend/IRBuilderAsmJs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,11 @@ IRBuilderAsmJs::BuildEmpty(Js::OpCodeAsmJs newOpcode, uint32 offset)
Js::RegSlot retSlot;
switch (newOpcode)
{
case Js::OpCodeAsmJs::CheckHeap:
instr = IR::Instr::New(Js::OpCode::ArrayDetachedCheck, m_func);
instr->SetSrc1(IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::ArrayReg, TyVar), Js::ArrayBuffer::GetIsDetachedOffset(), TyInt8, m_func));
AddInstr(instr, offset);
break;
case Js::OpCodeAsmJs::Unreachable_Void:
instr = IR::Instr::New(Js::OpCode::ThrowRuntimeError, m_func);
instr->SetSrc1(IR::IntConstOpnd::New(SCODE_CODE(WASMERR_Unreachable), TyInt32, instr->m_func));
Expand Down Expand Up @@ -1775,23 +1780,13 @@ IRBuilderAsmJs::BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::ArgSl
{
m_func->m_argSlotsForFunctionsCalled = argCount;
}
if (m_asmFuncInfo->UsesHeapBuffer())
{
// heap buffer can change for wasm
#ifdef ENABLE_WASM
if (m_func->GetJITFunctionBody()->IsWasmFunction())
{
BuildHeapBufferReload(offset);
}
#endif
// after foreign function call, we need to make sure that the heap hasn't been detached
if (newOpcode == Js::OpCodeAsmJs::Call)
{
IR::Instr * instrArrayDetachedCheck = IR::Instr::New(Js::OpCode::ArrayDetachedCheck, m_func);
instrArrayDetachedCheck->SetSrc1(IR::IndirOpnd::New(BuildSrcOpnd(AsmJsRegSlots::ArrayReg, TyVar), Js::ArrayBuffer::GetIsDetachedOffset(), TyInt8, m_func));
AddInstr(instrArrayDetachedCheck, offset);
}
// heap buffer can change for wasm
if (m_asmFuncInfo->UsesHeapBuffer() && m_func->GetJITFunctionBody()->IsWasmFunction())
{
BuildHeapBufferReload(offset);
}
#endif
}

void
Expand Down
22 changes: 16 additions & 6 deletions deps/chakrashim/core/lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13373,6 +13373,14 @@ Lowerer::GenerateBailOut(IR::Instr * instr, IR::BranchInstr * branchInstr, IR::L
// src1 on BailOnNotStackArgs is helping CSE
instr->FreeSrc1();
}

if (instr->GetSrc2() != nullptr)
{
// Ideally we should never be in this situation but incase we reached a
// condition where we didn't freed src2. Free it here.
instr->FreeSrc2();
}

// Call the bail out wrapper
instr->m_opcode = Js::OpCode::Call;
if(instr->GetDst())
Expand Down Expand Up @@ -23366,7 +23374,7 @@ Lowerer::GenerateRecyclerAlloc(IR::JnHelperMethod allocHelper, size_t allocSize,
}

void
Lowerer::GenerateMemInit(IR::RegOpnd * opnd, int32 offset, int value, IR::Instr * insertBeforeInstr, bool isZeroed)
Lowerer::GenerateMemInit(IR::RegOpnd * opnd, int32 offset, int32 value, IR::Instr * insertBeforeInstr, bool isZeroed)
{
IRType type = TyInt32;
if (isZeroed)
Expand Down Expand Up @@ -24191,7 +24199,7 @@ Lowerer::LowerNewScopeSlots(IR::Instr * instr, bool doStackSlots)
IR::RegOpnd * dst = instr->UnlinkDst()->AsRegOpnd();

// dst = RecyclerAlloc(allocSize)
// dst[EncodedSlotCountSlotIndex = EncodedSlotCountSlotIOndex];
// dst[EncodedSlotCountSlotIndex] = min(actualSlotCount, MaxEncodedSlotCount);
// dst[ScopeMetadataSlotIndex] = FunctionBody;
// mov undefinedOpnd, undefined
// dst[FirstSlotIndex..count] = undefinedOpnd;
Expand All @@ -24202,8 +24210,10 @@ Lowerer::LowerNewScopeSlots(IR::Instr * instr, bool doStackSlots)
{
GenerateRecyclerAlloc(IR::HelperAllocMemForVarArray, allocSize, dst, instr);
}
GenerateMemInit(dst, Js::ScopeSlots::EncodedSlotCountSlotIndex * sizeof(Js::Var),
min<uint>(actualSlotCount, Js::ScopeSlots::MaxEncodedSlotCount), instr, !doStackSlots);

m_lowererMD.GenerateMemInit(dst, Js::ScopeSlots::EncodedSlotCountSlotIndex * sizeof(Js::Var),
(size_t)min<uint>(actualSlotCount, Js::ScopeSlots::MaxEncodedSlotCount), instr, !doStackSlots);

IR::Opnd * functionInfoOpnd = this->LoadFunctionInfoOpnd(instr);
GenerateMemInit(dst, Js::ScopeSlots::ScopeMetadataSlotIndex * sizeof(Js::Var),
functionInfoOpnd, instr, !doStackSlots);
Expand Down Expand Up @@ -25143,7 +25153,7 @@ Lowerer::LowerFrameDisplayCheck(IR::Instr * instr)

indirOpnd = IR::IndirOpnd::New(slotArrayOpnd,
Js::ScopeSlots::EncodedSlotCountSlotIndex * sizeof(Js::Var),
TyUint32, m_func, true);
TyVar, m_func, true);
IR::IntConstOpnd * slotIdOpnd = IR::IntConstOpnd::New(slotId - Js::ScopeSlots::FirstSlotIndex,
TyUint32, m_func);
InsertCompareBranch(indirOpnd, slotIdOpnd, Js::OpCode::BrLe_A, true, errorLabel, insertInstr);
Expand Down Expand Up @@ -25198,7 +25208,7 @@ Lowerer::LowerSlotArrayCheck(IR::Instr * instr)

IR::IndirOpnd * indirOpnd = IR::IndirOpnd::New(IR::RegOpnd::New(stackSym, TyVar, m_func),
Js::ScopeSlots::EncodedSlotCountSlotIndex * sizeof(Js::Var),
TyUint32, m_func, true);
TyVar, m_func, true);

slotIdOpnd->SetValue(slotId - Js::ScopeSlots::FirstSlotIndex);
InsertCompareBranch(indirOpnd, slotIdOpnd, Js::OpCode::BrGt_A, true, continueLabel, insertInstr);
Expand Down
10 changes: 10 additions & 0 deletions deps/chakrashim/core/lib/Backend/LowerMDShared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ LowererMD::GenerateMemRef(intptr_t addr, IRType type, IR::Instr *instr, bool don
return IR::MemRefOpnd::New(addr, type, this->m_func);
}

void
LowererMD::GenerateMemInit(IR::RegOpnd * opnd, int32 offset, size_t value, IR::Instr * insertBeforeInstr, bool isZeroed)
{
#if _M_X64
lowererMDArch.GenerateMemInit(opnd, offset, value, insertBeforeInstr, isZeroed);
#else
m_lowerer->GenerateMemInit(opnd, offset, (uint32)value, insertBeforeInstr, isZeroed);
#endif
}

///----------------------------------------------------------------------------
///
/// LowererMD::InvertBranch
Expand Down
1 change: 1 addition & 0 deletions deps/chakrashim/core/lib/Backend/LowerMDShared.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class LowererMD
public:
void Init(Lowerer *lowerer);
IR::Opnd * GenerateMemRef(intptr_t addr, IRType type, IR::Instr *instr, bool dontEncode = false);
void GenerateMemInit(IR::RegOpnd * opnd, int32 offset, size_t value, IR::Instr * insertBeforeInstr, bool isZeroed = false);
IR::Instr * ChangeToHelperCall(IR::Instr * instr, IR::JnHelperMethod helperMethod, IR::LabelInstr *labelBailOut = nullptr,
IR::Opnd *opndInstance = nullptr, IR::PropertySymOpnd * propSymOpnd = nullptr, bool isHelperContinuation = false);
void FinalLower();
Expand Down
22 changes: 22 additions & 0 deletions deps/chakrashim/core/lib/Backend/amd64/LowererMDArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,28 @@ LowererMDArch::SetMaxArgSlots(Js::ArgSlot actualCount /*including this*/)
return;
}

void
LowererMDArch::GenerateMemInit(IR::RegOpnd * opnd, int32 offset, size_t value, IR::Instr * insertBeforeInstr, bool isZeroed)
{
IRType type = TyVar;
if (isZeroed)
{
if (value == 0)
{
// Recycler memory are zero initialized
return;
}

type = value <= UINT_MAX ?
(value <= USHORT_MAX ?
(value <= UCHAR_MAX ? TyUint8 : TyUint16) :
TyUint32) :
type;
}
Func * func = this->m_func;
lowererMD->GetLowerer()->InsertMove(IR::IndirOpnd::New(opnd, offset, type, func), IR::IntConstOpnd::New(value, type, func), insertBeforeInstr);
}

IR::Instr *
LowererMDArch::LowerCallIDynamic(IR::Instr *callInstr, IR::Instr*saveThisArgOutInstr, IR::Opnd *argsLength, ushort callFlags, IR::Instr * insertBeforeInstrForCFG)
{
Expand Down
1 change: 1 addition & 0 deletions deps/chakrashim/core/lib/Backend/amd64/LowererMDArch.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ class LowererMDArch
IR::LabelInstr * GetBailOutStackRestoreLabel(BailOutInfo * bailOutInfo, IR::LabelInstr * exitTargetInstr);
void GeneratePreCall(IR::Instr * callInstr, IR::Opnd *functionObjOpnd, IR::Instr* insertBeforeInstrForCFGCheck = nullptr);
void SetMaxArgSlots(Js::ArgSlot actualCount /*including this*/);
void GenerateMemInit(IR::RegOpnd * opnd, int32 offset, size_t value, IR::Instr * insertBeforeInstr, bool isZeroed = false);
};

#define REG_EH_TARGET RegArg0
Expand Down
6 changes: 6 additions & 0 deletions deps/chakrashim/core/lib/Backend/arm/LowerMD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,12 @@ LowererMD::SetMaxArgSlots(Js::ArgSlot actualCount /*including this*/)
return;
}

void
LowererMD::GenerateMemInit(IR::RegOpnd * opnd, int32 offset, size_t value, IR::Instr * insertBeforeInstr, bool isZeroed)
{
m_lowerer->GenerateMemInit(opnd, offset, (uint32)value, insertBeforeInstr, isZeroed);
}

IR::Instr *
LowererMD::LowerCallIDynamic(IR::Instr *callInstr, IR::Instr*saveThisArgOutInstr, IR::Opnd *argsLength, ushort callFlags, IR::Instr * insertBeforeInstrForCFG)
{
Expand Down
1 change: 1 addition & 0 deletions deps/chakrashim/core/lib/Backend/arm/LowerMD.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ class LowererMD

void LowerInlineSpreadArgOutLoop(IR::Instr *callInstr, IR::RegOpnd *indexOpnd, IR::RegOpnd *arrayElementsStartOpnd);
void LowerTypeof(IR::Instr * typeOfInstr);
void GenerateMemInit(IR::RegOpnd * opnd, int32 offset, size_t value, IR::Instr * insertBeforeInstr, bool isZeroed = false);

public:
static IR::Instr * InsertCmovCC(const Js::OpCode opCode, IR::Opnd * dst, IR::Opnd* src1, IR::Instr* insertBeforeInstr, bool postRegAlloc);
Expand Down
1 change: 1 addition & 0 deletions deps/chakrashim/core/lib/Backend/arm64/LowerMD.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ class LowererMD

void LowerInlineSpreadArgOutLoop(IR::Instr *callInstr, IR::RegOpnd *indexOpnd, IR::RegOpnd *arrayElementsStartOpnd) { __debugbreak(); }
void LowerTypeof(IR::Instr * typeOfInstr) { __debugbreak(); }
void GenerateMemInit(IR::RegOpnd * opnd, int32 offset, size_t value, IR::Instr * insertBeforeInstr, bool isZeroed = false) { __debugbreak(); }
public:
static IR::Instr * InsertCmovCC(const Js::OpCode opCode, IR::Opnd * dst, IR::Opnd* src1, IR::Instr* insertBeforeInstr, bool postRegAlloc) { __debugbreak(); }
};
2 changes: 1 addition & 1 deletion deps/chakrashim/core/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 7
#define CHAKRA_CORE_PATCH_VERSION 2
#define CHAKRA_CORE_PATCH_VERSION 3
#define CHAKRA_CORE_VERSION_RELEASE_QFE 0 // Redundant with PATCH_VERSION. Keep this value set to 0.

// -------------
Expand Down
3 changes: 3 additions & 0 deletions deps/chakrashim/core/lib/Common/ConfigFlagsList.h
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,9 @@ FLAGPR_REGOVR_EXP(Boolean, ES6, ES6RegExPrototypeProperties, "Enable ES6 propert
#ifndef COMPILE_DISABLE_ES6RegExSymbols
#define COMPILE_DISABLE_ES6RegExSymbols 0
#endif

// When we enable ES6RegExSymbols check all String and Regex built-ins which are inlined in JIT and make sure the helper
// sets implicit call flag before calling into script
FLAGPR_REGOVR_EXP(Boolean, ES6, ES6RegExSymbols , "Enable ES6 RegExp symbols" , DEFAULT_CONFIG_ES6RegExSymbols)

FLAGPR (Boolean, ES6, ES6HasInstance , "Enable ES6 @@hasInstance symbol" , DEFAULT_CONFIG_ES6HasInstance)
Expand Down
2 changes: 1 addition & 1 deletion deps/chakrashim/core/lib/JITClient/JITManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ void * __RPC_USER midl_user_allocate(
#endif
size_t size)
{
return (HeapAlloc(GetProcessHeap(), 0, size));
return (HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size));
}

void __RPC_USER midl_user_free(_Pre_maybenull_ _Post_invalid_ void * ptr)
Expand Down
10 changes: 9 additions & 1 deletion deps/chakrashim/core/lib/Parser/Parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator
m_stoppedDeferredParse = FALSE;
m_hasParallelJob = false;
m_doingFastScan = false;
m_isInParsingArgList = false;
m_hasDestructuringPattern = false;
m_scriptContext = scriptContext;
m_pCurrentAstSize = nullptr;
m_arrayDepth = 0;
Expand Down Expand Up @@ -1252,7 +1254,7 @@ Parser::CreateCallNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2,char
pnode->sxCall.isApplyCall = false;
pnode->sxCall.isEvalCall = false;
pnode->sxCall.isSuperCall = false;

pnode->sxCall.hasDestructuring = false;
pnode->ichMin = ichMin;
pnode->ichLim = ichLim;

Expand Down Expand Up @@ -3660,6 +3662,7 @@ ParseNodePtr Parser::ParsePostfixOperators(
{
case tkLParen:
{
AutoMarkInParsingArgs autoMarkInParsingArgs(this);
if (fInNew)
{
ParseNodePtr pnodeArgs = ParseArgList<buildAST>(&callOfConstants, &spreadArgCount, &count);
Expand All @@ -3672,6 +3675,8 @@ ParseNodePtr Parser::ParsePostfixOperators(
pnode->sxCall.isApplyCall = false;
pnode->sxCall.isEvalCall = false;
pnode->sxCall.isSuperCall = false;
pnode->sxCall.hasDestructuring = m_hasDestructuringPattern;
Assert(!m_hasDestructuringPattern || count > 0);
pnode->sxCall.argCount = count;
pnode->sxCall.spreadArgCount = spreadArgCount;
pnode->ichLim = m_pscan->IchLimTok();
Expand Down Expand Up @@ -3743,6 +3748,8 @@ ParseNodePtr Parser::ParsePostfixOperators(
pnode->sxCall.spreadArgCount = spreadArgCount;
pnode->sxCall.isApplyCall = false;
pnode->sxCall.isEvalCall = fCallIsEval;
pnode->sxCall.hasDestructuring = m_hasDestructuringPattern;
Assert(!m_hasDestructuringPattern || count > 0);
pnode->sxCall.argCount = count;
pnode->ichLim = m_pscan->IchLimTok();
}
Expand Down Expand Up @@ -8630,6 +8637,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,

if (buildAST)
{
this->SetHasDestructuringPattern(true);
pnode = ConvertToPattern(pnode);
}

Expand Down
33 changes: 32 additions & 1 deletion deps/chakrashim/core/lib/Parser/Parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ class Parser
bool IsBackgroundParser() const { return m_isInBackground; }
bool IsDoingFastScan() const { return m_doingFastScan; }

bool GetIsInParsingArgList() const { return m_isInParsingArgList; }
void SetIsInParsingArgList(bool set) { m_isInParsingArgList = set; }

bool GetHasDestructuringPattern() const { return m_hasDestructuringPattern; }
void SetHasDestructuringPattern(bool set) { m_hasDestructuringPattern = set; }

static IdentPtr PidFromNode(ParseNodePtr pnode);

ParseNode* CopyPnode(ParseNode* pnode);
Expand Down Expand Up @@ -395,7 +401,8 @@ class Parser
bool m_isInBackground;
bool m_reparsingLambdaParams;
bool m_disallowImportExportStmt;

bool m_isInParsingArgList;
bool m_hasDestructuringPattern;
// This bool is used for deferring the shorthand initializer error ( {x = 1}) - as it is allowed in the destructuring grammar.
bool m_hasDeferredShorthandInitError;
uint * m_pnestedCount; // count of functions nested at one level below the current node
Expand Down Expand Up @@ -1110,6 +1117,30 @@ class Parser
}
};

class AutoMarkInParsingArgs
{
public:
AutoMarkInParsingArgs(Parser * parser)
: m_parser(parser)
{
m_prevState = m_parser->GetIsInParsingArgList();
m_parser->SetHasDestructuringPattern(false);
m_parser->SetIsInParsingArgList(true);
}
~AutoMarkInParsingArgs()
{
m_parser->SetIsInParsingArgList(m_prevState);
if (!m_prevState)
{
m_parser->SetHasDestructuringPattern(false);
}
}

private:
Parser *m_parser;
bool m_prevState;
};

public:
charcount_t GetSourceIchLim() { return m_sourceLim; }
static BOOL NodeEqualsName(ParseNodePtr pnode, LPCOLESTR sz, uint32 cch);
Expand Down
1 change: 1 addition & 0 deletions deps/chakrashim/core/lib/Parser/ptree.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ struct PnCall
BYTE isApplyCall : 1;
BYTE isEvalCall : 1;
BYTE isSuperCall : 1;
BYTE hasDestructuring : 1;
};

struct PnStmt
Expand Down
4 changes: 4 additions & 0 deletions deps/chakrashim/core/lib/Runtime/Base/CrossSite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,10 @@ namespace Js
Var CrossSite::CommonThunk(RecyclableObject* recyclableObject, JavascriptMethod entryPoint, Arguments args)
{
DynamicObject* function = DynamicObject::FromVar(recyclableObject);

FunctionInfo * functionInfo = (JavascriptFunction::Is(function) ? JavascriptFunction::FromVar(function)->GetFunctionInfo() : nullptr);
AutoDisableRedeferral autoDisableRedeferral(functionInfo);

ScriptContext* targetScriptContext = function->GetScriptContext();
Assert(!targetScriptContext->IsClosed());
Assert(function->IsExternal() || function->IsCrossSiteObject());
Expand Down
5 changes: 3 additions & 2 deletions deps/chakrashim/core/lib/Runtime/Base/FunctionBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1912,8 +1912,9 @@ namespace Js
{
Assert(pnodeFnc->nop == knopFncDecl);

Recycler *recycler = GetScriptContext()->GetRecycler();
this->SetDeferredStubs(BuildDeferredStubTree(pnodeFnc, recycler));
// TODO: Disabling the creation of deferred stubs for now. We need to rethink the design again as the current behavior
// is not usable with precise capturing.
this->SetDeferredStubs(nullptr);
}

FunctionInfoArray ParseableFunctionInfo::GetNestedFuncArray()
Expand Down
4 changes: 2 additions & 2 deletions deps/chakrashim/core/lib/Runtime/Base/FunctionBody.h
Original file line number Diff line number Diff line change
Expand Up @@ -3792,9 +3792,9 @@ namespace Js
slotArray[ScopeMetadataSlotIndex] = scopeMetadataObj;
}

uint GetCount() const
size_t GetCount() const
{
return ::Math::PointerCastToIntegralTruncate<uint>(slotArray[EncodedSlotCountSlotIndex]);
return ::Math::PointerCastToIntegralTruncate<size_t>(slotArray[EncodedSlotCountSlotIndex]);
}

void SetCount(uint count)
Expand Down
Loading

0 comments on commit 7b2ce30

Please sign in to comment.