Skip to content

Commit daa5d25

Browse files
committed
[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 1d129ac + c04787f commit daa5d25

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
@@ -8669,7 +8669,15 @@ BackwardPass::RestoreInductionVariableValuesAfterMemOp(Loop *loop)
86698669

86708670
IR::Opnd *inductionVariableOpnd = IR::RegOpnd::New(sym, IRType::TyInt32, localFunc);
86718671
IR::Opnd *sizeOpnd = globOpt->GenerateInductionVariableChangeForMemOp(loop, inductionVariableChangeInfo.unroll);
8672-
loop->landingPad->InsertAfter(IR::Instr::New(opCode, inductionVariableOpnd, inductionVariableOpnd, sizeOpnd, loop->GetFunc()));
8672+
IR::Instr* restoreInductionVarInstr = IR::Instr::New(opCode, inductionVariableOpnd, inductionVariableOpnd, sizeOpnd, loop->GetFunc());
8673+
8674+
// The IR that restores the induction variable's value is placed before the MemOp. Since this IR can
8675+
// bailout to the loop's landing pad, placing this IR before the MemOp avoids performing the MemOp,
8676+
// bailing out because of this IR, and then performing the effects of the loop again.
8677+
loop->landingPad->InsertInstrBefore(restoreInductionVarInstr, loop->memOpInfo->instr);
8678+
8679+
// If restoring an induction variable results in an overflow, bailout to the loop's landing pad.
8680+
restoreInductionVarInstr->ConvertToBailOutInstr(loop->bailOutInfo, IR::BailOutOnOverflow);
86738681
};
86748682

86758683
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
@@ -599,6 +599,11 @@ GlobOpt::OptBlock(BasicBlock *block)
599599
this->tempBv->And(liveOnBackEdge);
600600
this->ToFloat64(this->tempBv, block->loop->landingPad);
601601

602+
if (block->loop->symsRequiringCompensationToMergedValueInfoMap)
603+
{
604+
InsertValueCompensation(block, block->loop->symsRequiringCompensationToMergedValueInfoMap);
605+
}
606+
602607
// Now that we're done with the liveFields within this loop, trim the set to those syms
603608
// that the backward pass told us were live out of the loop.
604609
// This assumes we have no further need of the liveFields within the loop.
@@ -1151,10 +1156,10 @@ void GlobOpt::FieldPRE(Loop *loop)
11511156

11521157
void GlobOpt::InsertValueCompensation(
11531158
BasicBlock *const predecessor,
1154-
const SymToValueInfoMap &symsRequiringCompensationToMergedValueInfoMap)
1159+
const SymToValueInfoMap *symsRequiringCompensationToMergedValueInfoMap)
11551160
{
11561161
Assert(predecessor);
1157-
Assert(symsRequiringCompensationToMergedValueInfoMap.Count() != 0);
1162+
Assert(symsRequiringCompensationToMergedValueInfoMap->Count() != 0);
11581163

11591164
IR::Instr *insertBeforeInstr = predecessor->GetLastInstr();
11601165
Func *const func = insertBeforeInstr->m_func;
@@ -1193,7 +1198,7 @@ void GlobOpt::InsertValueCompensation(
11931198
}
11941199
};
11951200
JsUtil::List<DelayChangeValueInfo, ArenaAllocator> delayChangeValueInfo(alloc);
1196-
for(auto it = symsRequiringCompensationToMergedValueInfoMap.GetIterator(); it.IsValid(); it.MoveNext())
1201+
for(auto it = symsRequiringCompensationToMergedValueInfoMap->GetIterator(); it.IsValid(); it.MoveNext())
11971202
{
11981203
const auto &entry = it.Current();
11991204
Sym *const sym = entry.Key();
@@ -1840,6 +1845,10 @@ GlobOpt::IsAllowedForMemOpt(IR::Instr* instr, bool isMemset, IR::RegOpnd *baseOp
18401845
return false;
18411846
}
18421847
}
1848+
else
1849+
{
1850+
return false;
1851+
}
18431852

18441853
if (!baseValueType.IsTypedArray())
18451854
{
@@ -2843,12 +2852,6 @@ GlobOpt::OptDst(
28432852
{
28442853
this->FinishOptPropOp(instr, opnd->AsPropertySymOpnd());
28452854
}
2846-
else if (instr->m_opcode == Js::OpCode::StElemI_A ||
2847-
instr->m_opcode == Js::OpCode::StElemI_A_Strict ||
2848-
instr->m_opcode == Js::OpCode::InitComputedProperty)
2849-
{
2850-
this->KillObjectHeaderInlinedTypeSyms(this->currentBlock, false);
2851-
}
28522855

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

16860+
16861+
loop->memOpInfo->instr = memopInstr;
16862+
1685716863
#if DBG_DUMP
1685816864
if (DO_MEMOP_TRACE())
1685916865
{

lib/Backend/GlobOpt.h

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