Parcourir la source

[CVE-2019-1106] Chakra JIT Overflow

Michael Holman il y a 6 ans
Parent
commit
362e96537a

+ 9 - 0
lib/Backend/Func.cpp

@@ -345,6 +345,9 @@ Func::Codegen(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,
             case RejitReason::TrackIntOverflowDisabled:
                 outputData->disableTrackCompoundedIntOverflow = TRUE;
                 break;
+            case RejitReason::MemOpDisabled:
+                outputData->disableMemOp = TRUE;
+                break;
             default:
                 Assume(UNREACHED);
             }
@@ -1124,6 +1127,12 @@ Func::IsTrackCompoundedIntOverflowDisabled() const
     return (HasProfileInfo() && GetReadOnlyProfileInfo()->IsTrackCompoundedIntOverflowDisabled()) || m_output.IsTrackCompoundedIntOverflowDisabled();
 }
 
+bool
+Func::IsMemOpDisabled() const
+{
+    return (HasProfileInfo() && GetReadOnlyProfileInfo()->IsMemOpDisabled()) || m_output.IsMemOpDisabled();
+}
+
 bool
 Func::IsArrayCheckHoistDisabled() const
 {

+ 1 - 0
lib/Backend/Func.h

@@ -995,6 +995,7 @@ public:
     void SetScopeObjSym(StackSym * sym);
     StackSym * GetScopeObjSym();
     bool IsTrackCompoundedIntOverflowDisabled() const;
+    bool IsMemOpDisabled() const;
     bool IsArrayCheckHoistDisabled() const;
     bool IsStackArgOptDisabled() const;
     bool IsSwitchOptDisabled() const;

+ 9 - 2
lib/Backend/GlobOpt.cpp

@@ -2624,7 +2624,7 @@ GlobOpt::OptInstr(IR::Instr *&instr, bool* isInstrRemoved)
         !(instr->IsJitProfilingInstr()) &&
         this->currentBlock->loop && !IsLoopPrePass() &&
         !func->IsJitInDebugMode() &&
-        (func->HasProfileInfo() && !func->GetReadOnlyProfileInfo()->IsMemOpDisabled()) &&
+        !func->IsMemOpDisabled() &&
         this->currentBlock->loop->doMemOp)
     {
         CollectMemOpInfo(instrPrev, instr, src1Val, src2Val);
@@ -16686,7 +16686,14 @@ GlobOpt::GenerateInductionVariableChangeForMemOp(Loop *loop, byte unroll, IR::In
     }
     else
     {
-        uint size = (loopCount->LoopCountMinusOneConstantValue() + 1)  * unroll;
+        int32 loopCountMinusOnePlusOne;
+        int32 size;
+        if (Int32Math::Add(loopCount->LoopCountMinusOneConstantValue(), 1, &loopCountMinusOnePlusOne) ||
+            Int32Math::Mul(loopCountMinusOnePlusOne, unroll, &size))
+        {
+            throw Js::RejitException(RejitReason::MemOpDisabled);
+        }
+        Assert(size > 0);
         sizeOpnd = IR::IntConstOpnd::New(size, IRType::TyUint32, localFunc);
     }
     loop->memOpInfo->inductionVariableOpndPerUnrollMap->Add(unroll, sizeOpnd);

+ 6 - 0
lib/Backend/JITOutput.cpp

@@ -65,6 +65,12 @@ JITOutput::IsTrackCompoundedIntOverflowDisabled() const
     return m_outputData->disableTrackCompoundedIntOverflow != FALSE;
 }
 
+bool
+JITOutput::IsMemOpDisabled() const
+{
+    return m_outputData->disableMemOp != FALSE;
+}
+
 bool
 JITOutput::IsArrayCheckHoistDisabled() const
 {

+ 1 - 0
lib/Backend/JITOutput.h

@@ -22,6 +22,7 @@ public:
     void RecordXData(BYTE * xdata);
 #endif
     bool IsTrackCompoundedIntOverflowDisabled() const;
+    bool IsMemOpDisabled() const;
     bool IsArrayCheckHoistDisabled() const;
     bool IsStackArgOptDisabled() const;
     bool IsSwitchOptDisabled() const;

+ 4 - 0
lib/Backend/NativeCodeGenerator.cpp

@@ -1234,6 +1234,10 @@ NativeCodeGenerator::CodeGen(PageAllocator * pageAllocator, CodeGenWorkItem* wor
         {
             body->GetAnyDynamicProfileInfo()->DisableTrackCompoundedIntOverflow();
         }
+        if (jitWriteData.disableMemOp)
+        {
+            body->GetAnyDynamicProfileInfo()->DisableMemOp();
+        }
     }
 
     if (jitWriteData.disableInlineApply)

+ 10 - 5
lib/JITIDL/JITTypes.h

@@ -838,37 +838,42 @@ typedef struct JITOutputIDL
     boolean disableStackArgOpt;
     boolean disableSwitchOpt;
     boolean disableTrackCompoundedIntOverflow;
-    boolean isInPrereservedRegion;
+    boolean disableMemOp;
 
+    boolean isInPrereservedRegion;
     boolean hasBailoutInstr;
-
     boolean hasJittedStackClosure;
+    IDL_PAD1(0)
 
     unsigned short pdataCount;
     unsigned short xdataSize;
 
     unsigned short argUsedForBranch;
+    IDL_PAD2(1)
 
     int localVarSlotsOffset; // FunctionEntryPointInfo only
+
     int localVarChangedOffset; // FunctionEntryPointInfo only
     unsigned int frameHeight;
 
-
     unsigned int codeSize;
     unsigned int throwMapOffset;
+
     unsigned int throwMapCount;
     unsigned int inlineeFrameOffsetArrayOffset;
-    unsigned int inlineeFrameOffsetArrayCount;
 
+    unsigned int inlineeFrameOffsetArrayCount;
     unsigned int propertyGuardCount;
+
     unsigned int ctorCachesCount;
+    X64_PAD4(2)
 
 #if TARGET_64
     CHAKRA_PTR xdataAddr;
 #elif defined(_M_ARM)
     unsigned int xdataOffset;
 #else
-    X86_PAD4(0)
+    X86_PAD4(3)
 #endif
     CHAKRA_PTR codeAddress;
     CHAKRA_PTR thunkAddress;