From 8264b9bcdb08daf4309415319c7a8e03d1736dce Mon Sep 17 00:00:00 2001 From: Wyatt Richter Date: Wed, 14 Nov 2018 12:30:21 -0800 Subject: [PATCH] CVE-2018-8624 Edge - Chakra JIT Overflow --- lib/Backend/BackwardPass.cpp | 10 +++++++++- lib/Backend/FlowGraph.h | 1 + lib/Backend/GlobOpt.cpp | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/Backend/BackwardPass.cpp b/lib/Backend/BackwardPass.cpp index cdc79c88379..d94e79fab7f 100644 --- a/lib/Backend/BackwardPass.cpp +++ b/lib/Backend/BackwardPass.cpp @@ -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()) diff --git a/lib/Backend/FlowGraph.h b/lib/Backend/FlowGraph.h index 24c8e61798a..bcfbca7c15e 100644 --- a/lib/Backend/FlowGraph.h +++ b/lib/Backend/FlowGraph.h @@ -694,6 +694,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; diff --git a/lib/Backend/GlobOpt.cpp b/lib/Backend/GlobOpt.cpp index 3087b08d586..78651f93bbb 100644 --- a/lib/Backend/GlobOpt.cpp +++ b/lib/Backend/GlobOpt.cpp @@ -16854,6 +16854,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()) {