Prechádzať zdrojové kódy

CVE-2018-8624 Edge - Chakra JIT Overflow

Wyatt Richter 7 rokov pred
rodič
commit
8264b9bcdb

+ 9 - 1
lib/Backend/BackwardPass.cpp

@@ -8669,7 +8669,15 @@ BackwardPass::RestoreInductionVariableValuesAfterMemOp(Loop *loop)
 
 
         IR::Opnd *inductionVariableOpnd = IR::RegOpnd::New(sym, IRType::TyInt32, localFunc);
         IR::Opnd *inductionVariableOpnd = IR::RegOpnd::New(sym, IRType::TyInt32, localFunc);
         IR::Opnd *sizeOpnd = globOpt->GenerateInductionVariableChangeForMemOp(loop, inductionVariableChangeInfo.unroll);
         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())
     for (auto it = loop->memOpInfo->inductionVariableChangeInfoMap->GetIterator(); it.IsValid(); it.MoveNext())

+ 1 - 0
lib/Backend/FlowGraph.h

@@ -694,6 +694,7 @@ public:
         // Temporary map to reuse existing startIndexOpnd while emitting
         // Temporary map to reuse existing startIndexOpnd while emitting
         // 0 = !increment & !alreadyChanged, 1 = !increment & alreadyChanged, 2 = increment & !alreadyChanged, 3 = increment & alreadyChanged
         // 0 = !increment & !alreadyChanged, 1 = !increment & alreadyChanged, 2 = increment & !alreadyChanged, 3 = increment & alreadyChanged
         IR::RegOpnd* startIndexOpndCache[4];
         IR::RegOpnd* startIndexOpndCache[4];
+        IR::Instr* instr;
     } MemOpInfo;
     } MemOpInfo;
 
 
     bool doMemOp : 1;
     bool doMemOp : 1;

+ 3 - 0
lib/Backend/GlobOpt.cpp

@@ -16854,6 +16854,9 @@ GlobOpt::EmitMemop(Loop * loop, LoopCount *loopCount, const MemOpEmitData* emitD
     memopInstr->SetSrc2(sizeOpnd);
     memopInstr->SetSrc2(sizeOpnd);
     insertBeforeInstr->InsertBefore(memopInstr);
     insertBeforeInstr->InsertBefore(memopInstr);
 
 
+
+    loop->memOpInfo->instr = memopInstr;
+
 #if DBG_DUMP
 #if DBG_DUMP
     if (DO_MEMOP_TRACE())
     if (DO_MEMOP_TRACE())
     {
     {