Skip to content

Commit

Permalink
[1.11>master] [1.10>1.11] [MERGE #5688 @MikeHolman] September 2018 Se…
Browse files Browse the repository at this point in the history
…curity Update

Merge pull request #5688 from MikeHolman:servicing/1809

September 2018 Security Update that addresses the following issues in ChakraCore:

CVE-2018-8315
CVE-2018-8354
CVE-2018-8367
CVE-2018-8452
CVE-2018-8456
CVE-2018-8459
CVE-2018-8465
CVE-2018-8466
CVE-2018-8467
  • Loading branch information
MikeHolman committed Sep 11, 2018
2 parents 5949139 + 1987607 commit e2ae5db
Show file tree
Hide file tree
Showing 19 changed files with 413 additions and 50 deletions.
14 changes: 12 additions & 2 deletions lib/Backend/GlobOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14520,13 +14520,23 @@ GlobOpt::OptHoistUpdateValueType(
// Replace above will free srcOpnd, so reassign it
*srcOpndPtr = srcOpnd = reinterpret_cast<IR::Opnd *>(strOpnd);

if (loop->bailOutInfo->bailOutInstr)
if (IsImplicitCallBailOutCurrentlyNeeded(convPrimStrInstr, opndValueInLandingPad, nullptr, landingPad, landingPad->globOptData.liveFields->IsEmpty(), true, true))
{
EnsureBailTarget(loop);
loop->bailOutInfo->bailOutInstr->InsertBefore(convPrimStrInstr);
convPrimStrInstr = convPrimStrInstr->ConvertToBailOutInstr(convPrimStrInstr, IR::BailOutOnImplicitCallsPreOp, loop->bailOutInfo->bailOutOffset);
convPrimStrInstr->ReplaceBailOutInfo(loop->bailOutInfo);
}
else
{
landingPad->InsertAfter(convPrimStrInstr);
if (loop->bailOutInfo->bailOutInstr)
{
loop->bailOutInfo->bailOutInstr->InsertBefore(convPrimStrInstr);
}
else
{
landingPad->InsertAfter(convPrimStrInstr);
}
}

// If we came here opndSym can't be PropertySym
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/GlobOpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ class GlobOpt
void DetermineLoopCount(Loop *const loop);
void GenerateLoopCount(Loop *const loop, LoopCount *const loopCount);
void GenerateLoopCountPlusOne(Loop *const loop, LoopCount *const loopCount);
void GenerateSecondaryInductionVariableBound(Loop *const loop, StackSym *const inductionVariableSym, const LoopCount *const loopCount, const int maxMagnitudeChange, StackSym *const boundSym);
void GenerateSecondaryInductionVariableBound(Loop *const loop, StackSym *const inductionVariableSym, LoopCount *const loopCount, const int maxMagnitudeChange, const bool needsMagnitudeAdjustment, StackSym *const boundSym);

private:
void DetermineArrayBoundCheckHoistability(bool needLowerBoundCheck, bool needUpperBoundCheck, ArrayLowerBoundCheckHoistInfo &lowerHoistInfo, ArrayUpperBoundCheckHoistInfo &upperHoistInfo, const bool isJsArray, StackSym *const indexSym, Value *const indexValue, const IntConstantBounds &indexConstantBounds, StackSym *const headSegmentLengthSym, Value *const headSegmentLengthValue, const IntConstantBounds &headSegmentLengthConstantBounds, Loop *const headSegmentLengthInvariantLoop, bool &failedToUpdateCompatibleLowerBoundCheck, bool &failedToUpdateCompatibleUpperBoundCheck);
Expand Down
22 changes: 18 additions & 4 deletions lib/Backend/GlobOptArrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -912,30 +912,37 @@ void GlobOpt::ArraySrcOpt::DoLowerBoundCheck()
Assert(hoistInfo.Loop()->bailOutInfo);
globOpt->EnsureBailTarget(hoistInfo.Loop());

bool needsMagnitudeAdjustment = false;
if (hoistInfo.LoopCount())
{
// Generate the loop count and loop count based bound that will be used for the bound check
if (!hoistInfo.LoopCount()->HasBeenGenerated())
{
globOpt->GenerateLoopCount(hoistInfo.Loop(), hoistInfo.LoopCount());
}
needsMagnitudeAdjustment = (hoistInfo.MaxMagnitudeChange() > 0)
? (hoistInfo.IndexOffset() < hoistInfo.MaxMagnitudeChange())
: (hoistInfo.IndexOffset() > hoistInfo.MaxMagnitudeChange());

globOpt->GenerateSecondaryInductionVariableBound(
hoistInfo.Loop(),
indexVarSym->GetInt32EquivSym(nullptr),
hoistInfo.LoopCount(),
hoistInfo.MaxMagnitudeChange(),
needsMagnitudeAdjustment,
hoistInfo.IndexSym());
}

IR::Opnd* lowerBound = IR::IntConstOpnd::New(0, TyInt32, instr->m_func, true);
IR::Opnd* upperBound = IR::RegOpnd::New(indexIntSym, TyInt32, instr->m_func);
int offset = needsMagnitudeAdjustment ? (hoistInfo.IndexOffset() - hoistInfo.Offset()) : hoistInfo.Offset();
upperBound->SetIsJITOptimizedReg(true);

// 0 <= indexSym + offset (src1 <= src2 + dst)
IR::Instr *const boundCheck = globOpt->CreateBoundsCheckInstr(
lowerBound,
upperBound,
hoistInfo.Offset(),
offset,
hoistInfo.IsLoopCountBasedBound()
? IR::BailOutOnFailedHoistedLoopCountBasedBoundCheck
: IR::BailOutOnFailedHoistedBoundCheck,
Expand Down Expand Up @@ -1158,18 +1165,23 @@ void GlobOpt::ArraySrcOpt::DoUpperBoundCheck()
Assert(hoistInfo.Loop()->bailOutInfo);
globOpt->EnsureBailTarget(hoistInfo.Loop());

bool needsMagnitudeAdjustment = false;
if (hoistInfo.LoopCount())
{
// Generate the loop count and loop count based bound that will be used for the bound check
if (!hoistInfo.LoopCount()->HasBeenGenerated())
{
globOpt->GenerateLoopCount(hoistInfo.Loop(), hoistInfo.LoopCount());
}
needsMagnitudeAdjustment = (hoistInfo.MaxMagnitudeChange() > 0)
? (hoistInfo.IndexOffset() < hoistInfo.MaxMagnitudeChange())
: (hoistInfo.IndexOffset() > hoistInfo.MaxMagnitudeChange());
globOpt->GenerateSecondaryInductionVariableBound(
hoistInfo.Loop(),
indexVarSym->GetInt32EquivSym(nullptr),
hoistInfo.LoopCount(),
hoistInfo.MaxMagnitudeChange(),
needsMagnitudeAdjustment,
hoistInfo.IndexSym());
}

Expand All @@ -1184,11 +1196,13 @@ void GlobOpt::ArraySrcOpt::DoUpperBoundCheck()
IR::Opnd* upperBound = IR::RegOpnd::New(headSegmentLengthSym, headSegmentLengthSym->GetType(), instr->m_func);
upperBound->SetIsJITOptimizedReg(true);

int offset = needsMagnitudeAdjustment ? (hoistInfo.IndexOffset() + hoistInfo.Offset()) : hoistInfo.Offset();

// indexSym <= headSegmentLength + offset (src1 <= src2 + dst)
IR::Instr *const boundCheck = globOpt->CreateBoundsCheckInstr(
lowerBound,
upperBound,
hoistInfo.Offset(),
offset,
hoistInfo.IsLoopCountBasedBound()
? IR::BailOutOnFailedHoistedLoopCountBasedBoundCheck
: IR::BailOutOnFailedHoistedBoundCheck,
Expand All @@ -1207,7 +1221,7 @@ void GlobOpt::ArraySrcOpt::DoUpperBoundCheck()
landingPad->GetBlockNum(),
hoistInfo.IndexSym()->m_id,
headSegmentLengthSym->m_id,
hoistInfo.Offset());
offset);
}
else
{
Expand All @@ -1219,7 +1233,7 @@ void GlobOpt::ArraySrcOpt::DoUpperBoundCheck()
landingPad->GetBlockNum(),
hoistInfo.IndexConstantBounds().LowerBound(),
headSegmentLengthSym->m_id,
hoistInfo.Offset());
offset);
}

TESTTRACE_PHASE_INSTR(
Expand Down
4 changes: 4 additions & 0 deletions lib/Backend/GlobOptFields.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1915,6 +1915,10 @@ GlobOpt::UpdateObjPtrValueType(IR::Opnd * opnd, IR::Instr * instr)
}
}
break;
case Js::TypeIds_NativeIntArray:
case Js::TypeIds_NativeFloatArray:
// Do not mark these values as definite to protect against array conversion
break;
case Js::TypeIds_Array:
// Because array can change type id, we can only make it definite if we are doing array check hoist
// so that implicit call will be installed between the array checks.
Expand Down
37 changes: 32 additions & 5 deletions lib/Backend/GlobOptIntBounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ void GlobOpt::ArrayLowerBoundCheckHoistInfo::SetLoop(
void GlobOpt::ArrayLowerBoundCheckHoistInfo::SetLoop(
::Loop *const loop,
StackSym *const indexSym,
const int indexOffset,
const int offset,
Value *const indexValue,
const IntConstantBounds &indexConstantBounds,
Expand All @@ -91,6 +92,7 @@ void GlobOpt::ArrayLowerBoundCheckHoistInfo::SetLoop(

this->loop = loop;
this->indexSym = indexSym;
this->indexOffset = indexOffset;
this->offset = offset;
this->indexValueNumber = indexValue->GetValueNumber();
this->indexValue = indexValue;
Expand Down Expand Up @@ -142,6 +144,7 @@ void GlobOpt::ArrayUpperBoundCheckHoistInfo::SetLoop(
void GlobOpt::ArrayUpperBoundCheckHoistInfo::SetLoop(
::Loop *const loop,
StackSym *const indexSym,
const int indexOffset,
const int offset,
Value *const indexValue,
const IntConstantBounds &indexConstantBounds,
Expand All @@ -151,7 +154,7 @@ void GlobOpt::ArrayUpperBoundCheckHoistInfo::SetLoop(
{
Assert(headSegmentLengthValue);

SetLoop(loop, indexSym, offset, indexValue, indexConstantBounds, isLoopCountBasedBound);
SetLoop(loop, indexSym, indexOffset, offset, indexValue, indexConstantBounds, isLoopCountBasedBound);
this->headSegmentLengthValue = headSegmentLengthValue;
this->headSegmentLengthConstantBounds = headSegmentLengthConstantBounds;
}
Expand Down Expand Up @@ -1831,8 +1834,9 @@ void GlobOpt::GenerateLoopCountPlusOne(Loop *const loop, LoopCount *const loopCo
void GlobOpt::GenerateSecondaryInductionVariableBound(
Loop *const loop,
StackSym *const inductionVariableSym,
const LoopCount *const loopCount,
LoopCount *const loopCount,
const int maxMagnitudeChange,
const bool needsMagnitudeAdjustment,
StackSym *const boundSym)
{
Assert(loop);
Expand All @@ -1857,18 +1861,33 @@ void GlobOpt::GenerateSecondaryInductionVariableBound(
Assert(insertBeforeInstr);
Func *const func = bailOutInfo->bailOutFunc;

StackSym* loopCountSym = nullptr;

// If indexOffset < maxMagnitudeChange, we need to account for the difference between them in the bound check
// i.e. BoundCheck: inductionVariable + loopCountMinusOne * maxMagnitudeChange + maxMagnitudeChange - indexOffset <= length - offset
// Since the BoundCheck instruction already deals with offset, we can simplify this to
// BoundCheck: inductionVariable + loopCount * maxMagnitudeChange <= length + indexOffset - offset
if (needsMagnitudeAdjustment)
{
GenerateLoopCountPlusOne(loop, loopCount);
loopCountSym = loopCount->LoopCountSym();
}
else
{
loopCountSym = loopCount->LoopCountMinusOneSym();
}
// intermediateValue = loopCount * maxMagnitudeChange
StackSym *intermediateValueSym;
if(maxMagnitudeChange == 1 || maxMagnitudeChange == -1)
{
intermediateValueSym = loopCount->LoopCountMinusOneSym();
intermediateValueSym = loopCountSym;
}
else
{
IR::BailOutInstr *const instr = IR::BailOutInstr::New(Js::OpCode::Mul_I4, bailOutKind, bailOutInfo, func);

instr->SetSrc1(
IR::RegOpnd::New(loopCount->LoopCountMinusOneSym(), loopCount->LoopCountMinusOneSym()->GetType(), func));
IR::RegOpnd::New(loopCountSym, loopCountSym->GetType(), func));
instr->GetSrc1()->SetIsJITOptimizedReg(true);

instr->SetSrc2(IR::IntConstOpnd::New(maxMagnitudeChange, TyInt32, func, true));
Expand Down Expand Up @@ -2418,6 +2437,7 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
loop,
indexSym,
lowerOffset,
lowerOffset,
landingPadIndexValue,
landingPadIndexConstantBounds);
}
Expand Down Expand Up @@ -2469,11 +2489,13 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
// Normalize the offset such that:
// boundBase <= headSegmentLength + offset
// Where (offset = -1 - boundOffset), and -1 is to simulate < instead of <=.
int indexOffset = upperOffset;
upperOffset = -1 - upperOffset;

upperHoistInfo.SetLoop(
loop,
indexSym,
indexOffset,
upperOffset,
landingPadIndexValue,
landingPadIndexConstantBounds,
Expand Down Expand Up @@ -2619,6 +2641,7 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
loop,
indexBoundBaseSym,
offset,
offset,
landingPadIndexBoundBaseValue,
landingPadIndexBoundBaseConstantBounds);
break;
Expand All @@ -2643,11 +2666,13 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
// Normalize the offset such that:
// boundBase <= headSegmentLength + offset
// Where (offset = -1 - boundOffset), and -1 is to simulate < instead of <=.
int indexOffset = offset;
offset = -1 - offset;

upperHoistInfo.SetLoop(
loop,
indexBoundBaseSym,
indexOffset,
offset,
landingPadIndexBoundBaseValue,
landingPadIndexBoundBaseConstantBounds,
Expand Down Expand Up @@ -3139,6 +3164,7 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
lowerHoistInfo.SetLoop(
currentLoop,
indexLoopCountBasedBoundBaseSym,
indexOffset,
offset,
indexLoopCountBasedBoundBaseValue,
indexLoopCountBasedBoundBaseConstantBounds,
Expand All @@ -3153,6 +3179,7 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
upperHoistInfo.SetLoop(
currentLoop,
indexLoopCountBasedBoundBaseSym,
indexOffset,
offset,
indexLoopCountBasedBoundBaseValue,
indexLoopCountBasedBoundBaseConstantBounds,
Expand Down Expand Up @@ -3242,4 +3269,4 @@ GlobOpt::EmitIntRangeChecks(IR::Instr* instr)
EmitIntRangeChecks(instr, instr->GetDst());
}
}
#endif
#endif
12 changes: 10 additions & 2 deletions lib/Backend/GlobOptIntBounds.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ class GlobOpt::ArrayLowerBoundCheckHoistInfo

// Info populated for a compatible bound check and for hoisting out of loop
StackSym *indexSym;
int indexOffset;
int offset;
ValueNumber indexValueNumber;

Expand Down Expand Up @@ -287,6 +288,12 @@ class GlobOpt::ArrayLowerBoundCheckHoistInfo
return offset;
}

int32 IndexOffset() const
{
Assert(HasAnyInfo());
return indexOffset;
}

void UpdateOffset(int newOffset)
{
Assert(HasAnyInfo());
Expand Down Expand Up @@ -334,7 +341,7 @@ class GlobOpt::ArrayLowerBoundCheckHoistInfo
public:
void SetCompatibleBoundCheck(BasicBlock *const compatibleBoundCheckBlock, StackSym *const indexSym, const int offset, const ValueNumber indexValueNumber);
void SetLoop(::Loop *const loop, const int indexConstantValue, const bool isLoopCountBasedBound = false);
void SetLoop(::Loop *const loop, StackSym *const indexSym, const int offset, Value *const indexValue, const IntConstantBounds &indexConstantBounds, const bool isLoopCountBasedBound = false);
void SetLoop(::Loop *const loop, StackSym *const indexSym, const int indexOffset, const int offset, Value *const indexValue, const IntConstantBounds &indexConstantBounds, const bool isLoopCountBasedBound = false);
void SetLoopCount(::LoopCount *const loopCount, const int maxMagnitudeChange);
};

Expand All @@ -353,6 +360,7 @@ class GlobOpt::ArrayUpperBoundCheckHoistInfo : protected ArrayLowerBoundCheckHoi
using Base::CompatibleBoundCheckBlock;
using Base::Loop;
using Base::IndexSym;
using Base::IndexOffset;
using Base::Offset;
using Base::UpdateOffset;
using Base::IndexValueNumber;
Expand Down Expand Up @@ -385,5 +393,5 @@ class GlobOpt::ArrayUpperBoundCheckHoistInfo : protected ArrayLowerBoundCheckHoi
public:
void SetCompatibleBoundCheck(BasicBlock *const compatibleBoundCheckBlock, const int indexConstantValue);
void SetLoop(::Loop *const loop, const int indexConstantValue, Value *const headSegmentLengthValue, const IntConstantBounds &headSegmentLengthConstantBounds, const bool isLoopCountBasedBound = false);
void SetLoop(::Loop *const loop, StackSym *const indexSym, const int offset, Value *const indexValue, const IntConstantBounds &indexConstantBounds, Value *const headSegmentLengthValue, const IntConstantBounds &headSegmentLengthConstantBounds, const bool isLoopCountBasedBound = false);
void SetLoop(::Loop *const loop, StackSym *const indexSym, const int indexOffset, const int offset, Value *const indexValue, const IntConstantBounds &indexConstantBounds, Value *const headSegmentLengthValue, const IntConstantBounds &headSegmentLengthConstantBounds, const bool isLoopCountBasedBound = false);
};
Loading

0 comments on commit e2ae5db

Please sign in to comment.