Parcourir la source

[CVE-2017-0229] Non-blinded constants remaining in jit

Fix instances of non-blinded possibly large constants in the jit
Rajat Dua il y a 8 ans
Parent
commit
d8ef97d90c

+ 5 - 6
lib/Backend/GlobOpt.cpp

@@ -16014,7 +16014,7 @@ GlobOpt::AttachBoundsCheckData(IR::Instr* instr, IR::Opnd* lowerBound, IR::Opnd*
     instr->SetSrc2(upperBound);
     if (offset != 0)
     {
-        instr->SetDst(IR::IntConstOpnd::New(offset, TyInt32, instr->m_func, true));
+        instr->SetDst(IR::IntConstOpnd::New(offset, TyInt32, instr->m_func));
     }
     return instr;
 }
@@ -17307,8 +17307,7 @@ GlobOpt::OptArraySrc(IR::Instr * *const instrRef)
                                 : IR::IntConstOpnd::New(
                                     hoistInfo.IndexConstantBounds().LowerBound(),
                                     TyInt32,
-                                    instr->m_func,
-                                    true);
+                                    instr->m_func);
                             lowerBound->SetIsJITOptimizedReg(true);
                             IR::Opnd* upperBound = IR::RegOpnd::New(headSegmentLengthSym, headSegmentLengthSym->GetType(), instr->m_func);
                             upperBound->SetIsJITOptimizedReg(true);
@@ -17456,7 +17455,7 @@ GlobOpt::OptArraySrc(IR::Instr * *const instrRef)
                 {
                     IR::Opnd* lowerBound = baseOwnerIndir->GetIndexOpnd()
                         ? static_cast<IR::Opnd *>(baseOwnerIndir->GetIndexOpnd())
-                        : IR::IntConstOpnd::New(baseOwnerIndir->GetOffset(), TyInt32, instr->m_func, true);
+                        : IR::IntConstOpnd::New(baseOwnerIndir->GetOffset(), TyInt32, instr->m_func);
                     lowerBound->SetIsJITOptimizedReg(true);
                     IR::Opnd* upperBound = IR::RegOpnd::New(headSegmentLengthSym, headSegmentLengthSym->GetType(), instr->m_func);
                     upperBound->SetIsJITOptimizedReg(true);
@@ -21406,7 +21405,7 @@ GlobOpt::GenerateInductionVariableChangeForMemOp(Loop *loop, byte unroll, IR::In
         {
             sizeOpnd = IR::RegOpnd::New(TyUint32, this->func);
 
-            IR::Opnd *unrollOpnd = IR::IntConstOpnd::New(unroll, type, localFunc, true);
+            IR::Opnd *unrollOpnd = IR::IntConstOpnd::New(unroll, type, localFunc);
 
             InsertInstr(IR::Instr::New(Js::OpCode::Mul_I4,
                 sizeOpnd,
@@ -21419,7 +21418,7 @@ GlobOpt::GenerateInductionVariableChangeForMemOp(Loop *loop, byte unroll, IR::In
     else
     {
         uint size = (loopCount->LoopCountMinusOneConstantValue() + 1)  * unroll;
-        sizeOpnd = IR::IntConstOpnd::New(size, IRType::TyUint32, localFunc, true);
+        sizeOpnd = IR::IntConstOpnd::New(size, IRType::TyUint32, localFunc);
     }
     loop->memOpInfo->inductionVariableOpndPerUnrollMap->Add(unroll, sizeOpnd);
     return sizeOpnd;

+ 2 - 2
lib/Backend/IRBuilder.cpp

@@ -4879,14 +4879,14 @@ IRBuilder::BuildAuxiliary(Js::OpCode newOpcode, uint32 offset)
             // The property ID array needs to be both relocatable and available (so we can
             // get the slot capacity), so we need to just pass the offset to lower and let
             // lower take it from there...
-            srcOpnd = IR::IntConstOpnd::New(auxInsn->Offset, TyUint32, m_func, true);
+            srcOpnd = IR::IntConstOpnd::New(auxInsn->Offset, TyUint32, m_func);
             dstOpnd = this->BuildDstOpnd(dstRegSlot);
             dstOpnd->SetValueType(ValueType::GetObject(ObjectType::UninitializedObject));
             instr = IR::Instr::New(newOpcode, dstOpnd, srcOpnd, m_func);
 
             // Because we're going to be making decisions based off the value, we have to defer
             // this until we get to lowering.
-            instr->SetSrc2(IR::IntConstOpnd::New(literalObjectId, TyUint32, m_func, true));
+            instr->SetSrc2(IR::IntConstOpnd::New(literalObjectId, TyUint32, m_func));
 
             if (dstOpnd->m_sym->m_isSingleDef)
             {

+ 4 - 4
lib/Backend/Lower.cpp

@@ -12858,7 +12858,7 @@ void Lowerer::LowerBoundCheck(IR::Instr *const instr)
             true,
             addResultOpnd,
             rightOpnd,
-            offsetOpnd ? offsetOpnd->UseWithNewType(TyInt32, func) : IR::IntConstOpnd::New(offset, TyInt32, func, true),
+            offsetOpnd ? offsetOpnd->UseWithNewType(TyInt32, func) : IR::IntConstOpnd::New(offset, TyInt32, func),
             insertBeforeInstr);
         InsertBranch(LowererMD::MDOverflowBranchOpcode, bailOutLabel, insertBeforeInstr);
 
@@ -12870,7 +12870,7 @@ void Lowerer::LowerBoundCheck(IR::Instr *const instr)
     // $bailOut:
     if(!rightOpnd)
     {
-        rightOpnd = IR::IntConstOpnd::New(offset, TyInt32, func, true);
+        rightOpnd = IR::IntConstOpnd::New(offset, TyInt32, func);
     }
     InsertCompareBranch(leftOpnd, rightOpnd, compareOpCode, doUnsignedCompare, skipBailOutLabel, insertBeforeInstr);
 }
@@ -20571,7 +20571,7 @@ bool Lowerer::GenerateFastEqBoolInt(IR::Instr * instr, bool *pNeedHelper)
         // If it's not zero, then it's either 1, in which case it's true, or it's something else, in which
         // case the two will compare as inequal
         InsertCompareBranch(
-            IR::IntConstOpnd::New((((IntConstType)1) << Js::VarTag_Shift) + Js::AtomTag, IRType::TyVar, this->m_func),
+            IR::IntConstOpnd::New((((IntConstType)1) << Js::VarTag_Shift) + Js::AtomTag, IRType::TyVar, this->m_func, true),
             srcInt->AsRegOpnd(),
             Js::OpCode::BrNeq_A,
             isBranchNotCompare ? inequalResultTarget : forceInequal, // in the case of branching, we can go straight to the inequal target; for compares, we need to load the value
@@ -23891,7 +23891,7 @@ void Lowerer::GenerateSingleCharStrJumpTableLookup(IR::Instr * instr)
 
     // CMP charOpnd, lastCaseIndex - baseCaseIndex
     // JA defaultLabel
-    InsertCompareBranch(charOpnd, IR::IntConstOpnd::New(multiBrInstr->m_lastCaseValue - multiBrInstr->m_baseCaseValue, TyUint32, func, true),
+    InsertCompareBranch(charOpnd, IR::IntConstOpnd::New(multiBrInstr->m_lastCaseValue - multiBrInstr->m_baseCaseValue, TyUint32, func),
         Js::OpCode::BrGt_A, true, defaultLabelInstr, instr);
 
     instr->UnlinkSrc1();

+ 26 - 5
lib/Backend/LowerMDShared.cpp

@@ -1257,7 +1257,7 @@ void LowererMD::ChangeToShift(IR::Instr *const instr, const bool needFlags)
     }
 }
 
-void LowererMD::ChangeToMul(IR::Instr *const instr, bool hasOverflowCheck)
+void LowererMD::ChangeToIMul(IR::Instr *const instr, bool hasOverflowCheck)
 {
     // If non-32 bit overflow check is needed, we have to use the IMUL form.
     if (hasOverflowCheck && !instr->ShouldCheckFor32BitOverflow() && instr->ShouldCheckForNon32BitOverflow())
@@ -1272,8 +1272,29 @@ void LowererMD::ChangeToMul(IR::Instr *const instr, bool hasOverflowCheck)
         {
             // MOV reg, imm
             temp2 = IR::RegOpnd::New(TyInt32, instr->m_func);
+
+            IR::Opnd * src2 = instr->GetSrc2();
+            bool dontEncode = false;
+            if (src2->IsHelperCallOpnd())
+            {
+                dontEncode = true;
+            }
+            else if (src2->IsIntConstOpnd() || src2->IsAddrOpnd())
+            {
+                dontEncode = src2->IsIntConstOpnd() ? src2->AsIntConstOpnd()->m_dontEncode : src2->AsAddrOpnd()->m_dontEncode;
+            }
+            else if (src2->IsInt64ConstOpnd())
+            {
+                dontEncode = false;
+            }
+            else
+            {
+                AssertMsg(false, "Unexpected immediate opnd");
+                throw Js::OperationAbortedException();
+            }
+
             instr->InsertBefore(IR::Instr::New(Js::OpCode::MOV, temp2,
-                IR::IntConstOpnd::New((IntConstType)instr->GetSrc2()->GetImmediateValue(instr->m_func), TyInt32, instr->m_func, true),
+                IR::IntConstOpnd::New((IntConstType)instr->GetSrc2()->GetImmediateValue(instr->m_func), TyInt32, instr->m_func, dontEncode),
                 instr->m_func));
         }
         // eax = IMUL eax, reg
@@ -2061,7 +2082,7 @@ void LowererMD::LegalizeSrc(IR::Instr *const instr, IR::Opnd *src, const uint fo
                 if (!instr->isInlineeEntryInstr)
                 {
                     Assert(forms & L_Reg);
-                    IR::IntConstOpnd * newIntOpnd = IR::IntConstOpnd::New(intOpnd->GetValue(), intOpnd->GetType(), instr->m_func, true);
+                    IR::IntConstOpnd * newIntOpnd = intOpnd->Copy(instr->m_func)->AsIntConstOpnd();
                     IR::IndirOpnd * indirOpnd = instr->m_func->GetTopFunc()->GetConstantAddressIndirOpnd(intOpnd->GetValue(), newIntOpnd, IR::AddrOpndKindConstantAddress, TyMachPtr, Js::OpCode::MOV);
                     if (HoistLargeConstant(indirOpnd, src, instr))
                     {
@@ -2125,7 +2146,7 @@ void LowererMD::LegalizeSrc(IR::Instr *const instr, IR::Opnd *src, const uint fo
                 Assert(!instr->isInlineeEntryInstr);
                 Assert(forms & L_Reg);
                 // TODO: michhol, remove cast after making m_address intptr
-                IR::AddrOpnd * newAddrOpnd = IR::AddrOpnd::New(addrOpnd->m_address, addrOpnd->GetAddrOpndKind(), instr->m_func, true);
+                IR::AddrOpnd * newAddrOpnd = addrOpnd->Copy(instr->m_func)->AsAddrOpnd();
                 IR::IndirOpnd * indirOpnd = instr->m_func->GetTopFunc()->GetConstantAddressIndirOpnd((intptr_t)addrOpnd->m_address, newAddrOpnd, addrOpnd->GetAddrOpndKind(), TyMachPtr, Js::OpCode::MOV);
                 if (HoistLargeConstant(indirOpnd, src, instr))
                 {
@@ -7236,7 +7257,7 @@ LowererMD::LowerInt4MulWithBailOut(
     // Lower the instruction
     if (!simplifiedMul)
     {
-        LowererMD::ChangeToMul(instr, needsOverflowCheck);
+        LowererMD::ChangeToIMul(instr, needsOverflowCheck);
     }
 
     const auto insertBeforeInstr = checkForNegativeZeroLabel ? checkForNegativeZeroLabel : bailOutLabel;

+ 1 - 1
lib/Backend/LowerMDShared.h

@@ -50,7 +50,7 @@ public:
     static void             ChangeToAdd(IR::Instr *const instr, const bool needFlags);
     static void             ChangeToSub(IR::Instr *const instr, const bool needFlags);
     static void             ChangeToShift(IR::Instr *const instr, const bool needFlags);
-    static void             ChangeToMul(IR::Instr *const instr, const bool hasOverflowCheck = false);
+    static void             ChangeToIMul(IR::Instr *const instr, const bool hasOverflowCheck = false);
     static const uint16     GetFormalParamOffset();
     static const Js::OpCode MDUncondBranchOpcode;
     static const Js::OpCode MDExtend32Opcode;