Skip to content

Commit

Permalink
[MERGE #5869 @akroshg] December 2018, servicing update
Browse files Browse the repository at this point in the history
Merge pull request #5869 from akroshg:servicing/1812

Addresses followings
CVE-2018-8583
CVE-2018-8624
CVE-2018-8618
CVE-2018-8629
CVE-2018-8617
  • Loading branch information
akroshg committed Dec 11, 2018
2 parents 1d129ac + c04787f commit daa5d25
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 21 deletions.
10 changes: 9 additions & 1 deletion lib/Backend/BackwardPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8669,7 +8669,15 @@ BackwardPass::RestoreInductionVariableValuesAfterMemOp(Loop *loop)

IR::Opnd *inductionVariableOpnd = IR::RegOpnd::New(sym, IRType::TyInt32, localFunc);
IR::Opnd *sizeOpnd = globOpt->GenerateInductionVariableChangeForMemOp(loop, inductionVariableChangeInfo.unroll);
loop->landingPad->InsertAfter(IR::Instr::New(opCode, inductionVariableOpnd, inductionVariableOpnd, sizeOpnd, loop->GetFunc()));
IR::Instr* restoreInductionVarInstr = IR::Instr::New(opCode, inductionVariableOpnd, inductionVariableOpnd, sizeOpnd, loop->GetFunc());

// The IR that restores the induction variable's value is placed before the MemOp. Since this IR can
// bailout to the loop's landing pad, placing this IR before the MemOp avoids performing the MemOp,
// bailing out because of this IR, and then performing the effects of the loop again.
loop->landingPad->InsertInstrBefore(restoreInductionVarInstr, loop->memOpInfo->instr);

// If restoring an induction variable results in an overflow, bailout to the loop's landing pad.
restoreInductionVarInstr->ConvertToBailOutInstr(loop->bailOutInfo, IR::BailOutOnOverflow);
};

for (auto it = loop->memOpInfo->inductionVariableChangeInfoMap->GetIterator(); it.IsValid(); it.MoveNext())
Expand Down
8 changes: 7 additions & 1 deletion lib/Backend/FlowGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5266,7 +5266,7 @@ BasicBlock::MergePredBlocksValueMaps(GlobOpt* globOpt)
}
if(symsRequiringCompensationToMergedValueInfoMap.Count() != 0)
{
globOpt->InsertValueCompensation(pred, symsRequiringCompensationToMergedValueInfoMap);
globOpt->InsertValueCompensation(pred, &symsRequiringCompensationToMergedValueInfoMap);
}
}
} NEXT_PREDECESSOR_EDGE_EDITING;
Expand Down Expand Up @@ -5325,6 +5325,12 @@ BasicBlock::MergePredBlocksValueMaps(GlobOpt* globOpt)
loop->liveFieldsOnEntry = JitAnew(globOpt->alloc, BVSparse<JitArenaAllocator>, globOpt->alloc);
loop->liveFieldsOnEntry->Copy(this->globOptData.liveFields);

if (symsRequiringCompensationToMergedValueInfoMap.Count() != 0)
{
loop->symsRequiringCompensationToMergedValueInfoMap = JitAnew(globOpt->alloc, SymToValueInfoMap, globOpt->alloc);
loop->symsRequiringCompensationToMergedValueInfoMap->Copy(&symsRequiringCompensationToMergedValueInfoMap);
}

if(globOpt->DoBoundCheckHoist() && loop->inductionVariables)
{
globOpt->FinalizeInductionVariables(loop, &blockData);
Expand Down
5 changes: 4 additions & 1 deletion lib/Backend/FlowGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ class Loop
BVSparse<JitArenaAllocator> *lossyInt32SymsOnEntry; // see GlobOptData::liveLossyInt32Syms
BVSparse<JitArenaAllocator> *float64SymsOnEntry;
BVSparse<JitArenaAllocator> *liveFieldsOnEntry;
SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap;

BVSparse<JitArenaAllocator> *symsUsedBeforeDefined; // stack syms that are live in the landing pad, and used before they are defined in the loop
BVSparse<JitArenaAllocator> *likelyIntSymsUsedBeforeDefined; // stack syms that are live in the landing pad with a likely-int value, and used before they are defined in the loop
Expand Down Expand Up @@ -694,6 +695,7 @@ class Loop
// Temporary map to reuse existing startIndexOpnd while emitting
// 0 = !increment & !alreadyChanged, 1 = !increment & alreadyChanged, 2 = increment & !alreadyChanged, 3 = increment & alreadyChanged
IR::RegOpnd* startIndexOpndCache[4];
IR::Instr* instr;
} MemOpInfo;

bool doMemOp : 1;
Expand Down Expand Up @@ -741,7 +743,8 @@ class Loop
allFieldsKilled(false),
isLeaf(true),
isProcessed(false),
initialValueFieldMap(alloc)
initialValueFieldMap(alloc),
symsRequiringCompensationToMergedValueInfoMap(nullptr)
{
this->loopNumber = ++func->loopCount;
}
Expand Down
24 changes: 15 additions & 9 deletions lib/Backend/GlobOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,11 @@ GlobOpt::OptBlock(BasicBlock *block)
this->tempBv->And(liveOnBackEdge);
this->ToFloat64(this->tempBv, block->loop->landingPad);

if (block->loop->symsRequiringCompensationToMergedValueInfoMap)
{
InsertValueCompensation(block, block->loop->symsRequiringCompensationToMergedValueInfoMap);
}

// Now that we're done with the liveFields within this loop, trim the set to those syms
// that the backward pass told us were live out of the loop.
// This assumes we have no further need of the liveFields within the loop.
Expand Down Expand Up @@ -1151,10 +1156,10 @@ void GlobOpt::FieldPRE(Loop *loop)

void GlobOpt::InsertValueCompensation(
BasicBlock *const predecessor,
const SymToValueInfoMap &symsRequiringCompensationToMergedValueInfoMap)
const SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap)
{
Assert(predecessor);
Assert(symsRequiringCompensationToMergedValueInfoMap.Count() != 0);
Assert(symsRequiringCompensationToMergedValueInfoMap->Count() != 0);

IR::Instr *insertBeforeInstr = predecessor->GetLastInstr();
Func *const func = insertBeforeInstr->m_func;
Expand Down Expand Up @@ -1193,7 +1198,7 @@ void GlobOpt::InsertValueCompensation(
}
};
JsUtil::List<DelayChangeValueInfo, ArenaAllocator> delayChangeValueInfo(alloc);
for(auto it = symsRequiringCompensationToMergedValueInfoMap.GetIterator(); it.IsValid(); it.MoveNext())
for(auto it = symsRequiringCompensationToMergedValueInfoMap->GetIterator(); it.IsValid(); it.MoveNext())
{
const auto &entry = it.Current();
Sym *const sym = entry.Key();
Expand Down Expand Up @@ -1840,6 +1845,10 @@ GlobOpt::IsAllowedForMemOpt(IR::Instr* instr, bool isMemset, IR::RegOpnd *baseOp
return false;
}
}
else
{
return false;
}

if (!baseValueType.IsTypedArray())
{
Expand Down Expand Up @@ -2843,12 +2852,6 @@ GlobOpt::OptDst(
{
this->FinishOptPropOp(instr, opnd->AsPropertySymOpnd());
}
else if (instr->m_opcode == Js::OpCode::StElemI_A ||
instr->m_opcode == Js::OpCode::StElemI_A_Strict ||
instr->m_opcode == Js::OpCode::InitComputedProperty)
{
this->KillObjectHeaderInlinedTypeSyms(this->currentBlock, false);
}

if (opnd->IsIndirOpnd() && !this->IsLoopPrePass())
{
Expand Down Expand Up @@ -16854,6 +16857,9 @@ GlobOpt::EmitMemop(Loop * loop, LoopCount *loopCount, const MemOpEmitData* emitD
memopInstr->SetSrc2(sizeOpnd);
insertBeforeInstr->InsertBefore(memopInstr);


loop->memOpInfo->instr = memopInstr;

#if DBG_DUMP
if (DO_MEMOP_TRACE())
{
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/GlobOpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,7 @@ class GlobOpt
void PreLowerCanonicalize(IR::Instr *instr, Value **pSrc1Val, Value **pSrc2Val);
void ProcessKills(IR::Instr *instr);
void InsertCloneStrs(BasicBlock *toBlock, GlobOptBlockData *toData, GlobOptBlockData *fromData);
void InsertValueCompensation(BasicBlock *const predecessor, const SymToValueInfoMap &symsRequiringCompensationToMergedValueInfoMap);
void InsertValueCompensation(BasicBlock *const predecessor, const SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap);
IR::Instr * ToVarUses(IR::Instr *instr, IR::Opnd *opnd, bool isDst, Value *val);
void ToVar(BVSparse<JitArenaAllocator> *bv, BasicBlock *block);
IR::Instr * ToVar(IR::Instr *instr, IR::RegOpnd *regOpnd, BasicBlock *block, Value *val, bool needsUpdate);
Expand Down
28 changes: 25 additions & 3 deletions lib/Backend/GlobOptFields.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,10 +328,20 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
Assert(dstOpnd != nullptr);
KillLiveFields(this->lengthEquivBv, bv);
KillLiveElems(dstOpnd->AsIndirOpnd(), bv, inGlobOpt, instr->m_func);
if (inGlobOpt)
{
KillObjectHeaderInlinedTypeSyms(this->currentBlock, false);
}
break;

case Js::OpCode::InitComputedProperty:
case Js::OpCode::InitGetElemI:
case Js::OpCode::InitSetElemI:
KillLiveElems(dstOpnd->AsIndirOpnd(), bv, inGlobOpt, instr->m_func);
if (inGlobOpt)
{
KillObjectHeaderInlinedTypeSyms(this->currentBlock, false);
}
break;

case Js::OpCode::DeleteElemI_A:
Expand Down Expand Up @@ -394,6 +404,10 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
case Js::OpCode::InlineArrayPush:
case Js::OpCode::InlineArrayPop:
KillLiveFields(this->lengthEquivBv, bv);
if (inGlobOpt)
{
KillObjectHeaderInlinedTypeSyms(this->currentBlock, false);
}
break;

case Js::OpCode::InlineeStart:
Expand All @@ -410,10 +424,18 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
fnHelper = instr->GetSrc1()->AsHelperCallOpnd()->m_fnHelper;

// Kill length field for built-ins that can update it.
if(nullptr != this->lengthEquivBv && (fnHelper == IR::JnHelperMethod::HelperArray_Shift || fnHelper == IR::JnHelperMethod::HelperArray_Splice
|| fnHelper == IR::JnHelperMethod::HelperArray_Unshift))
if(fnHelper == IR::JnHelperMethod::HelperArray_Shift
|| fnHelper == IR::JnHelperMethod::HelperArray_Splice
|| fnHelper == IR::JnHelperMethod::HelperArray_Unshift)
{
KillLiveFields(this->lengthEquivBv, bv);
if (nullptr != this->lengthEquivBv)
{
KillLiveFields(this->lengthEquivBv, bv);
}
if (inGlobOpt)
{
KillObjectHeaderInlinedTypeSyms(this->currentBlock, false);
}
}

if ((fnHelper == IR::JnHelperMethod::HelperRegExp_Exec)
Expand Down
15 changes: 10 additions & 5 deletions lib/Backend/GlobOptIntBounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1822,11 +1822,16 @@ void GlobOpt::GenerateLoopCountPlusOne(Loop *const loop, LoopCount *const loopCo
IR::RegOpnd *loopCountOpnd = IR::RegOpnd::New(type, func);
IR::RegOpnd *minusOneOpnd = IR::RegOpnd::New(loopCount->LoopCountMinusOneSym(), type, func);
minusOneOpnd->SetIsJITOptimizedReg(true);
insertBeforeInstr->InsertBefore(IR::Instr::New(Js::OpCode::Add_I4,
loopCountOpnd,
minusOneOpnd,
IR::IntConstOpnd::New(1, type, func, true),
func));
IR::Instr* incrInstr = IR::Instr::New(Js::OpCode::Add_I4,
loopCountOpnd,
minusOneOpnd,
IR::IntConstOpnd::New(1, type, func, true),
func);

insertBeforeInstr->InsertBefore(incrInstr);

// Incrementing to 1 can overflow - add a bounds check bailout here
incrInstr->ConvertToBailOutInstr(bailOutInfo, IR::BailOutOnFailedHoistedLoopCountBasedBoundCheck);
loopCount->SetLoopCountSym(loopCountOpnd->GetStackSym());
}
}
Expand Down

0 comments on commit daa5d25

Please sign in to comment.