Skip to content

Commit

Permalink
[CVE-2017-0229] Non-blinded constants remaining in jit
Browse files Browse the repository at this point in the history
Fix instances of non-blinded possibly large constants in the jit
  • Loading branch information
rajatd committed May 10, 2017
1 parent 0cdbf2f commit d8ef97d
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 18 deletions.
11 changes: 5 additions & 6 deletions lib/Backend/GlobOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions lib/Backend/IRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
8 changes: 4 additions & 4 deletions lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down
31 changes: 26 additions & 5 deletions lib/Backend/LowerMDShared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand All @@ -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
Expand Down Expand Up @@ -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))
{
Expand Down Expand Up @@ -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))
{
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/LowerMDShared.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class LowererMD
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;
Expand Down

0 comments on commit d8ef97d

Please sign in to comment.