Skip to content

Commit 757bd0d

Browse files
committed
[1.11>master] [1.10>1.11] [MERGE #5869 @akroshg] December 2018, servicing update
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
2 parents 0ede3da + 8288d6f commit 757bd0d

File tree

7 files changed

+71
-21
lines changed

7 files changed

+71
-21
lines changed

lib/Backend/BackwardPass.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8688,7 +8688,15 @@ BackwardPass::RestoreInductionVariableValuesAfterMemOp(Loop *loop)
86888688

86898689
IR::Opnd *inductionVariableOpnd = IR::RegOpnd::New(sym, IRType::TyInt32, localFunc);
86908690
IR::Opnd *sizeOpnd = globOpt->GenerateInductionVariableChangeForMemOp(loop, inductionVariableChangeInfo.unroll);
8691-
loop->landingPad->InsertAfter(IR::Instr::New(opCode, inductionVariableOpnd, inductionVariableOpnd, sizeOpnd, loop->GetFunc()));
8691+
IR::Instr* restoreInductionVarInstr = IR::Instr::New(opCode, inductionVariableOpnd, inductionVariableOpnd, sizeOpnd, loop->GetFunc());
8692+
8693+
// The IR that restores the induction variable's value is placed before the MemOp. Since this IR can
8694+
// bailout to the loop's landing pad, placing this IR before the MemOp avoids performing the MemOp,
8695+
// bailing out because of this IR, and then performing the effects of the loop again.
8696+
loop->landingPad->InsertInstrBefore(restoreInductionVarInstr, loop->memOpInfo->instr);
8697+
8698+
// If restoring an induction variable results in an overflow, bailout to the loop's landing pad.
8699+
restoreInductionVarInstr->ConvertToBailOutInstr(loop->bailOutInfo, IR::BailOutOnOverflow);
86928700
};
86938701

86948702
for (auto it = loop->memOpInfo->inductionVariableChangeInfoMap->GetIterator(); it.IsValid(); it.MoveNext())

lib/Backend/FlowGraph.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5266,7 +5266,7 @@ BasicBlock::MergePredBlocksValueMaps(GlobOpt* globOpt)
52665266
}
52675267
if(symsRequiringCompensationToMergedValueInfoMap.Count() != 0)
52685268
{
5269-
globOpt->InsertValueCompensation(pred, symsRequiringCompensationToMergedValueInfoMap);
5269+
globOpt->InsertValueCompensation(pred, &symsRequiringCompensationToMergedValueInfoMap);
52705270
}
52715271
}
52725272
} NEXT_PREDECESSOR_EDGE_EDITING;
@@ -5325,6 +5325,12 @@ BasicBlock::MergePredBlocksValueMaps(GlobOpt* globOpt)
53255325
loop->liveFieldsOnEntry = JitAnew(globOpt->alloc, BVSparse<JitArenaAllocator>, globOpt->alloc);
53265326
loop->liveFieldsOnEntry->Copy(this->globOptData.liveFields);
53275327

5328+
if (symsRequiringCompensationToMergedValueInfoMap.Count() != 0)
5329+
{
5330+
loop->symsRequiringCompensationToMergedValueInfoMap = JitAnew(globOpt->alloc, SymToValueInfoMap, globOpt->alloc);
5331+
loop->symsRequiringCompensationToMergedValueInfoMap->Copy(&symsRequiringCompensationToMergedValueInfoMap);
5332+
}
5333+
53285334
if(globOpt->DoBoundCheckHoist() && loop->inductionVariables)
53295335
{
53305336
globOpt->FinalizeInductionVariables(loop, &blockData);

lib/Backend/FlowGraph.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ class Loop
575575
BVSparse<JitArenaAllocator> *lossyInt32SymsOnEntry; // see GlobOptData::liveLossyInt32Syms
576576
BVSparse<JitArenaAllocator> *float64SymsOnEntry;
577577
BVSparse<JitArenaAllocator> *liveFieldsOnEntry;
578+
SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap;
578579

579580
BVSparse<JitArenaAllocator> *symsUsedBeforeDefined; // stack syms that are live in the landing pad, and used before they are defined in the loop
580581
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
@@ -694,6 +695,7 @@ class Loop
694695
// Temporary map to reuse existing startIndexOpnd while emitting
695696
// 0 = !increment & !alreadyChanged, 1 = !increment & alreadyChanged, 2 = increment & !alreadyChanged, 3 = increment & alreadyChanged
696697
IR::RegOpnd* startIndexOpndCache[4];
698+
IR::Instr* instr;
697699
} MemOpInfo;
698700

699701
bool doMemOp : 1;
@@ -741,7 +743,8 @@ class Loop
741743
allFieldsKilled(false),
742744
isLeaf(true),
743745
isProcessed(false),
744-
initialValueFieldMap(alloc)
746+
initialValueFieldMap(alloc),
747+
symsRequiringCompensationToMergedValueInfoMap(nullptr)
745748
{
746749
this->loopNumber = ++func->loopCount;
747750
}

lib/Backend/GlobOpt.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,11 @@ GlobOpt::OptBlock(BasicBlock *block)
603603
this->tempBv->And(liveOnBackEdge);
604604
this->ToFloat64(this->tempBv, block->loop->landingPad);
605605

606+
if (block->loop->symsRequiringCompensationToMergedValueInfoMap)
607+
{
608+
InsertValueCompensation(block, block->loop->symsRequiringCompensationToMergedValueInfoMap);
609+
}
610+
606611
// Now that we're done with the liveFields within this loop, trim the set to those syms
607612
// that the backward pass told us were live out of the loop.
608613
// This assumes we have no further need of the liveFields within the loop.
@@ -1155,10 +1160,10 @@ void GlobOpt::FieldPRE(Loop *loop)
11551160

11561161
void GlobOpt::InsertValueCompensation(
11571162
BasicBlock *const predecessor,
1158-
const SymToValueInfoMap &symsRequiringCompensationToMergedValueInfoMap)
1163+
const SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap)
11591164
{
11601165
Assert(predecessor);
1161-
Assert(symsRequiringCompensationToMergedValueInfoMap.Count() != 0);
1166+
Assert(symsRequiringCompensationToMergedValueInfoMap->Count() != 0);
11621167

11631168
IR::Instr *insertBeforeInstr = predecessor->GetLastInstr();
11641169
Func *const func = insertBeforeInstr->m_func;
@@ -1197,7 +1202,7 @@ void GlobOpt::InsertValueCompensation(
11971202
}
11981203
};
11991204
JsUtil::List<DelayChangeValueInfo, ArenaAllocator> delayChangeValueInfo(alloc);
1200-
for(auto it = symsRequiringCompensationToMergedValueInfoMap.GetIterator(); it.IsValid(); it.MoveNext())
1205+
for(auto it = symsRequiringCompensationToMergedValueInfoMap->GetIterator(); it.IsValid(); it.MoveNext())
12011206
{
12021207
const auto &entry = it.Current();
12031208
Sym *const sym = entry.Key();
@@ -1847,6 +1852,10 @@ GlobOpt::IsAllowedForMemOpt(IR::Instr* instr, bool isMemset, IR::RegOpnd *baseOp
18471852
return false;
18481853
}
18491854
}
1855+
else
1856+
{
1857+
return false;
1858+
}
18501859

18511860
if (!baseValueType.IsTypedArray())
18521861
{
@@ -2851,12 +2860,6 @@ GlobOpt::OptDst(
28512860
{
28522861
this->FinishOptPropOp(instr, opnd->AsPropertySymOpnd());
28532862
}
2854-
else if (instr->m_opcode == Js::OpCode::StElemI_A ||
2855-
instr->m_opcode == Js::OpCode::StElemI_A_Strict ||
2856-
instr->m_opcode == Js::OpCode::InitComputedProperty)
2857-
{
2858-
this->KillObjectHeaderInlinedTypeSyms(this->currentBlock, false);
2859-
}
28602863

28612864
if (opnd->IsIndirOpnd() && !this->IsLoopPrePass())
28622865
{
@@ -17111,6 +17114,9 @@ GlobOpt::EmitMemop(Loop * loop, LoopCount *loopCount, const MemOpEmitData* emitD
1711117114
memopInstr->SetSrc2(sizeOpnd);
1711217115
insertBeforeInstr->InsertBefore(memopInstr);
1711317116

17117+
17118+
loop->memOpInfo->instr = memopInstr;
17119+
1711417120
#if DBG_DUMP
1711517121
if (DO_MEMOP_TRACE())
1711617122
{

lib/Backend/GlobOpt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ class GlobOpt
736736
void PreLowerCanonicalize(IR::Instr *instr, Value **pSrc1Val, Value **pSrc2Val);
737737
void ProcessKills(IR::Instr *instr);
738738
void InsertCloneStrs(BasicBlock *toBlock, GlobOptBlockData *toData, GlobOptBlockData *fromData);
739-
void InsertValueCompensation(BasicBlock *const predecessor, const SymToValueInfoMap &symsRequiringCompensationToMergedValueInfoMap);
739+
void InsertValueCompensation(BasicBlock *const predecessor, const SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap);
740740
IR::Instr * ToVarUses(IR::Instr *instr, IR::Opnd *opnd, bool isDst, Value *val);
741741
void ToVar(BVSparse<JitArenaAllocator> *bv, BasicBlock *block);
742742
IR::Instr * ToVar(IR::Instr *instr, IR::RegOpnd *regOpnd, BasicBlock *block, Value *val, bool needsUpdate);

lib/Backend/GlobOptFields.cpp

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,10 +328,20 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
328328
Assert(dstOpnd != nullptr);
329329
KillLiveFields(this->lengthEquivBv, bv);
330330
KillLiveElems(dstOpnd->AsIndirOpnd(), bv, inGlobOpt, instr->m_func);
331+
if (inGlobOpt)
332+
{
333+
KillObjectHeaderInlinedTypeSyms(this->currentBlock, false);
334+
}
331335
break;
332336

333337
case Js::OpCode::InitComputedProperty:
338+
case Js::OpCode::InitGetElemI:
339+
case Js::OpCode::InitSetElemI:
334340
KillLiveElems(dstOpnd->AsIndirOpnd(), bv, inGlobOpt, instr->m_func);
341+
if (inGlobOpt)
342+
{
343+
KillObjectHeaderInlinedTypeSyms(this->currentBlock, false);
344+
}
335345
break;
336346

337347
case Js::OpCode::DeleteElemI_A:
@@ -394,6 +404,10 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
394404
case Js::OpCode::InlineArrayPush:
395405
case Js::OpCode::InlineArrayPop:
396406
KillLiveFields(this->lengthEquivBv, bv);
407+
if (inGlobOpt)
408+
{
409+
KillObjectHeaderInlinedTypeSyms(this->currentBlock, false);
410+
}
397411
break;
398412

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

412426
// Kill length field for built-ins that can update it.
413-
if(nullptr != this->lengthEquivBv && (fnHelper == IR::JnHelperMethod::HelperArray_Shift || fnHelper == IR::JnHelperMethod::HelperArray_Splice
414-
|| fnHelper == IR::JnHelperMethod::HelperArray_Unshift))
427+
if(fnHelper == IR::JnHelperMethod::HelperArray_Shift
428+
|| fnHelper == IR::JnHelperMethod::HelperArray_Splice
429+
|| fnHelper == IR::JnHelperMethod::HelperArray_Unshift)
415430
{
416-
KillLiveFields(this->lengthEquivBv, bv);
431+
if (nullptr != this->lengthEquivBv)
432+
{
433+
KillLiveFields(this->lengthEquivBv, bv);
434+
}
435+
if (inGlobOpt)
436+
{
437+
KillObjectHeaderInlinedTypeSyms(this->currentBlock, false);
438+
}
417439
}
418440

419441
if ((fnHelper == IR::JnHelperMethod::HelperRegExp_Exec)

lib/Backend/GlobOptIntBounds.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,11 +1822,16 @@ void GlobOpt::GenerateLoopCountPlusOne(Loop *const loop, LoopCount *const loopCo
18221822
IR::RegOpnd *loopCountOpnd = IR::RegOpnd::New(type, func);
18231823
IR::RegOpnd *minusOneOpnd = IR::RegOpnd::New(loopCount->LoopCountMinusOneSym(), type, func);
18241824
minusOneOpnd->SetIsJITOptimizedReg(true);
1825-
insertBeforeInstr->InsertBefore(IR::Instr::New(Js::OpCode::Add_I4,
1826-
loopCountOpnd,
1827-
minusOneOpnd,
1828-
IR::IntConstOpnd::New(1, type, func, true),
1829-
func));
1825+
IR::Instr* incrInstr = IR::Instr::New(Js::OpCode::Add_I4,
1826+
loopCountOpnd,
1827+
minusOneOpnd,
1828+
IR::IntConstOpnd::New(1, type, func, true),
1829+
func);
1830+
1831+
insertBeforeInstr->InsertBefore(incrInstr);
1832+
1833+
// Incrementing to 1 can overflow - add a bounds check bailout here
1834+
incrInstr->ConvertToBailOutInstr(bailOutInfo, IR::BailOutOnFailedHoistedLoopCountBasedBoundCheck);
18301835
loopCount->SetLoopCountSym(loopCountOpnd->GetStackSym());
18311836
}
18321837
}

0 commit comments

Comments
 (0)