Skip to content

Commit e2ae5db

Browse files
committed
[1.11>master] [1.10>1.11] [MERGE #5688 @MikeHolman] September 2018 Security 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
2 parents 5949139 + 1987607 commit e2ae5db

19 files changed

+413
-50
lines changed

lib/Backend/GlobOpt.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14520,13 +14520,23 @@ GlobOpt::OptHoistUpdateValueType(
1452014520
// Replace above will free srcOpnd, so reassign it
1452114521
*srcOpndPtr = srcOpnd = reinterpret_cast<IR::Opnd *>(strOpnd);
1452214522

14523-
if (loop->bailOutInfo->bailOutInstr)
14523+
if (IsImplicitCallBailOutCurrentlyNeeded(convPrimStrInstr, opndValueInLandingPad, nullptr, landingPad, landingPad->globOptData.liveFields->IsEmpty(), true, true))
1452414524
{
14525+
EnsureBailTarget(loop);
1452514526
loop->bailOutInfo->bailOutInstr->InsertBefore(convPrimStrInstr);
14527+
convPrimStrInstr = convPrimStrInstr->ConvertToBailOutInstr(convPrimStrInstr, IR::BailOutOnImplicitCallsPreOp, loop->bailOutInfo->bailOutOffset);
14528+
convPrimStrInstr->ReplaceBailOutInfo(loop->bailOutInfo);
1452614529
}
1452714530
else
1452814531
{
14529-
landingPad->InsertAfter(convPrimStrInstr);
14532+
if (loop->bailOutInfo->bailOutInstr)
14533+
{
14534+
loop->bailOutInfo->bailOutInstr->InsertBefore(convPrimStrInstr);
14535+
}
14536+
else
14537+
{
14538+
landingPad->InsertAfter(convPrimStrInstr);
14539+
}
1453014540
}
1453114541

1453214542
// If we came here opndSym can't be PropertySym

lib/Backend/GlobOpt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ class GlobOpt
705705
void DetermineLoopCount(Loop *const loop);
706706
void GenerateLoopCount(Loop *const loop, LoopCount *const loopCount);
707707
void GenerateLoopCountPlusOne(Loop *const loop, LoopCount *const loopCount);
708-
void GenerateSecondaryInductionVariableBound(Loop *const loop, StackSym *const inductionVariableSym, const LoopCount *const loopCount, const int maxMagnitudeChange, StackSym *const boundSym);
708+
void GenerateSecondaryInductionVariableBound(Loop *const loop, StackSym *const inductionVariableSym, LoopCount *const loopCount, const int maxMagnitudeChange, const bool needsMagnitudeAdjustment, StackSym *const boundSym);
709709

710710
private:
711711
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);

lib/Backend/GlobOptArrays.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -912,30 +912,37 @@ void GlobOpt::ArraySrcOpt::DoLowerBoundCheck()
912912
Assert(hoistInfo.Loop()->bailOutInfo);
913913
globOpt->EnsureBailTarget(hoistInfo.Loop());
914914

915+
bool needsMagnitudeAdjustment = false;
915916
if (hoistInfo.LoopCount())
916917
{
917918
// Generate the loop count and loop count based bound that will be used for the bound check
918919
if (!hoistInfo.LoopCount()->HasBeenGenerated())
919920
{
920921
globOpt->GenerateLoopCount(hoistInfo.Loop(), hoistInfo.LoopCount());
921922
}
923+
needsMagnitudeAdjustment = (hoistInfo.MaxMagnitudeChange() > 0)
924+
? (hoistInfo.IndexOffset() < hoistInfo.MaxMagnitudeChange())
925+
: (hoistInfo.IndexOffset() > hoistInfo.MaxMagnitudeChange());
926+
922927
globOpt->GenerateSecondaryInductionVariableBound(
923928
hoistInfo.Loop(),
924929
indexVarSym->GetInt32EquivSym(nullptr),
925930
hoistInfo.LoopCount(),
926931
hoistInfo.MaxMagnitudeChange(),
932+
needsMagnitudeAdjustment,
927933
hoistInfo.IndexSym());
928934
}
929935

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

934941
// 0 <= indexSym + offset (src1 <= src2 + dst)
935942
IR::Instr *const boundCheck = globOpt->CreateBoundsCheckInstr(
936943
lowerBound,
937944
upperBound,
938-
hoistInfo.Offset(),
945+
offset,
939946
hoistInfo.IsLoopCountBasedBound()
940947
? IR::BailOutOnFailedHoistedLoopCountBasedBoundCheck
941948
: IR::BailOutOnFailedHoistedBoundCheck,
@@ -1158,18 +1165,23 @@ void GlobOpt::ArraySrcOpt::DoUpperBoundCheck()
11581165
Assert(hoistInfo.Loop()->bailOutInfo);
11591166
globOpt->EnsureBailTarget(hoistInfo.Loop());
11601167

1168+
bool needsMagnitudeAdjustment = false;
11611169
if (hoistInfo.LoopCount())
11621170
{
11631171
// Generate the loop count and loop count based bound that will be used for the bound check
11641172
if (!hoistInfo.LoopCount()->HasBeenGenerated())
11651173
{
11661174
globOpt->GenerateLoopCount(hoistInfo.Loop(), hoistInfo.LoopCount());
11671175
}
1176+
needsMagnitudeAdjustment = (hoistInfo.MaxMagnitudeChange() > 0)
1177+
? (hoistInfo.IndexOffset() < hoistInfo.MaxMagnitudeChange())
1178+
: (hoistInfo.IndexOffset() > hoistInfo.MaxMagnitudeChange());
11681179
globOpt->GenerateSecondaryInductionVariableBound(
11691180
hoistInfo.Loop(),
11701181
indexVarSym->GetInt32EquivSym(nullptr),
11711182
hoistInfo.LoopCount(),
11721183
hoistInfo.MaxMagnitudeChange(),
1184+
needsMagnitudeAdjustment,
11731185
hoistInfo.IndexSym());
11741186
}
11751187

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

1199+
int offset = needsMagnitudeAdjustment ? (hoistInfo.IndexOffset() + hoistInfo.Offset()) : hoistInfo.Offset();
1200+
11871201
// indexSym <= headSegmentLength + offset (src1 <= src2 + dst)
11881202
IR::Instr *const boundCheck = globOpt->CreateBoundsCheckInstr(
11891203
lowerBound,
11901204
upperBound,
1191-
hoistInfo.Offset(),
1205+
offset,
11921206
hoistInfo.IsLoopCountBasedBound()
11931207
? IR::BailOutOnFailedHoistedLoopCountBasedBoundCheck
11941208
: IR::BailOutOnFailedHoistedBoundCheck,
@@ -1207,7 +1221,7 @@ void GlobOpt::ArraySrcOpt::DoUpperBoundCheck()
12071221
landingPad->GetBlockNum(),
12081222
hoistInfo.IndexSym()->m_id,
12091223
headSegmentLengthSym->m_id,
1210-
hoistInfo.Offset());
1224+
offset);
12111225
}
12121226
else
12131227
{
@@ -1219,7 +1233,7 @@ void GlobOpt::ArraySrcOpt::DoUpperBoundCheck()
12191233
landingPad->GetBlockNum(),
12201234
hoistInfo.IndexConstantBounds().LowerBound(),
12211235
headSegmentLengthSym->m_id,
1222-
hoistInfo.Offset());
1236+
offset);
12231237
}
12241238

12251239
TESTTRACE_PHASE_INSTR(

lib/Backend/GlobOptFields.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,6 +1915,10 @@ GlobOpt::UpdateObjPtrValueType(IR::Opnd * opnd, IR::Instr * instr)
19151915
}
19161916
}
19171917
break;
1918+
case Js::TypeIds_NativeIntArray:
1919+
case Js::TypeIds_NativeFloatArray:
1920+
// Do not mark these values as definite to protect against array conversion
1921+
break;
19181922
case Js::TypeIds_Array:
19191923
// Because array can change type id, we can only make it definite if we are doing array check hoist
19201924
// so that implicit call will be installed between the array checks.

lib/Backend/GlobOptIntBounds.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ void GlobOpt::ArrayLowerBoundCheckHoistInfo::SetLoop(
7878
void GlobOpt::ArrayLowerBoundCheckHoistInfo::SetLoop(
7979
::Loop *const loop,
8080
StackSym *const indexSym,
81+
const int indexOffset,
8182
const int offset,
8283
Value *const indexValue,
8384
const IntConstantBounds &indexConstantBounds,
@@ -91,6 +92,7 @@ void GlobOpt::ArrayLowerBoundCheckHoistInfo::SetLoop(
9192

9293
this->loop = loop;
9394
this->indexSym = indexSym;
95+
this->indexOffset = indexOffset;
9496
this->offset = offset;
9597
this->indexValueNumber = indexValue->GetValueNumber();
9698
this->indexValue = indexValue;
@@ -142,6 +144,7 @@ void GlobOpt::ArrayUpperBoundCheckHoistInfo::SetLoop(
142144
void GlobOpt::ArrayUpperBoundCheckHoistInfo::SetLoop(
143145
::Loop *const loop,
144146
StackSym *const indexSym,
147+
const int indexOffset,
145148
const int offset,
146149
Value *const indexValue,
147150
const IntConstantBounds &indexConstantBounds,
@@ -151,7 +154,7 @@ void GlobOpt::ArrayUpperBoundCheckHoistInfo::SetLoop(
151154
{
152155
Assert(headSegmentLengthValue);
153156

154-
SetLoop(loop, indexSym, offset, indexValue, indexConstantBounds, isLoopCountBasedBound);
157+
SetLoop(loop, indexSym, indexOffset, offset, indexValue, indexConstantBounds, isLoopCountBasedBound);
155158
this->headSegmentLengthValue = headSegmentLengthValue;
156159
this->headSegmentLengthConstantBounds = headSegmentLengthConstantBounds;
157160
}
@@ -1831,8 +1834,9 @@ void GlobOpt::GenerateLoopCountPlusOne(Loop *const loop, LoopCount *const loopCo
18311834
void GlobOpt::GenerateSecondaryInductionVariableBound(
18321835
Loop *const loop,
18331836
StackSym *const inductionVariableSym,
1834-
const LoopCount *const loopCount,
1837+
LoopCount *const loopCount,
18351838
const int maxMagnitudeChange,
1839+
const bool needsMagnitudeAdjustment,
18361840
StackSym *const boundSym)
18371841
{
18381842
Assert(loop);
@@ -1857,18 +1861,33 @@ void GlobOpt::GenerateSecondaryInductionVariableBound(
18571861
Assert(insertBeforeInstr);
18581862
Func *const func = bailOutInfo->bailOutFunc;
18591863

1864+
StackSym* loopCountSym = nullptr;
1865+
1866+
// If indexOffset < maxMagnitudeChange, we need to account for the difference between them in the bound check
1867+
// i.e. BoundCheck: inductionVariable + loopCountMinusOne * maxMagnitudeChange + maxMagnitudeChange - indexOffset <= length - offset
1868+
// Since the BoundCheck instruction already deals with offset, we can simplify this to
1869+
// BoundCheck: inductionVariable + loopCount * maxMagnitudeChange <= length + indexOffset - offset
1870+
if (needsMagnitudeAdjustment)
1871+
{
1872+
GenerateLoopCountPlusOne(loop, loopCount);
1873+
loopCountSym = loopCount->LoopCountSym();
1874+
}
1875+
else
1876+
{
1877+
loopCountSym = loopCount->LoopCountMinusOneSym();
1878+
}
18601879
// intermediateValue = loopCount * maxMagnitudeChange
18611880
StackSym *intermediateValueSym;
18621881
if(maxMagnitudeChange == 1 || maxMagnitudeChange == -1)
18631882
{
1864-
intermediateValueSym = loopCount->LoopCountMinusOneSym();
1883+
intermediateValueSym = loopCountSym;
18651884
}
18661885
else
18671886
{
18681887
IR::BailOutInstr *const instr = IR::BailOutInstr::New(Js::OpCode::Mul_I4, bailOutKind, bailOutInfo, func);
18691888

18701889
instr->SetSrc1(
1871-
IR::RegOpnd::New(loopCount->LoopCountMinusOneSym(), loopCount->LoopCountMinusOneSym()->GetType(), func));
1890+
IR::RegOpnd::New(loopCountSym, loopCountSym->GetType(), func));
18721891
instr->GetSrc1()->SetIsJITOptimizedReg(true);
18731892

18741893
instr->SetSrc2(IR::IntConstOpnd::New(maxMagnitudeChange, TyInt32, func, true));
@@ -2418,6 +2437,7 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
24182437
loop,
24192438
indexSym,
24202439
lowerOffset,
2440+
lowerOffset,
24212441
landingPadIndexValue,
24222442
landingPadIndexConstantBounds);
24232443
}
@@ -2469,11 +2489,13 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
24692489
// Normalize the offset such that:
24702490
// boundBase <= headSegmentLength + offset
24712491
// Where (offset = -1 - boundOffset), and -1 is to simulate < instead of <=.
2492+
int indexOffset = upperOffset;
24722493
upperOffset = -1 - upperOffset;
24732494

24742495
upperHoistInfo.SetLoop(
24752496
loop,
24762497
indexSym,
2498+
indexOffset,
24772499
upperOffset,
24782500
landingPadIndexValue,
24792501
landingPadIndexConstantBounds,
@@ -2619,6 +2641,7 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
26192641
loop,
26202642
indexBoundBaseSym,
26212643
offset,
2644+
offset,
26222645
landingPadIndexBoundBaseValue,
26232646
landingPadIndexBoundBaseConstantBounds);
26242647
break;
@@ -2643,11 +2666,13 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
26432666
// Normalize the offset such that:
26442667
// boundBase <= headSegmentLength + offset
26452668
// Where (offset = -1 - boundOffset), and -1 is to simulate < instead of <=.
2669+
int indexOffset = offset;
26462670
offset = -1 - offset;
26472671

26482672
upperHoistInfo.SetLoop(
26492673
loop,
26502674
indexBoundBaseSym,
2675+
indexOffset,
26512676
offset,
26522677
landingPadIndexBoundBaseValue,
26532678
landingPadIndexBoundBaseConstantBounds,
@@ -3139,6 +3164,7 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
31393164
lowerHoistInfo.SetLoop(
31403165
currentLoop,
31413166
indexLoopCountBasedBoundBaseSym,
3167+
indexOffset,
31423168
offset,
31433169
indexLoopCountBasedBoundBaseValue,
31443170
indexLoopCountBasedBoundBaseConstantBounds,
@@ -3153,6 +3179,7 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
31533179
upperHoistInfo.SetLoop(
31543180
currentLoop,
31553181
indexLoopCountBasedBoundBaseSym,
3182+
indexOffset,
31563183
offset,
31573184
indexLoopCountBasedBoundBaseValue,
31583185
indexLoopCountBasedBoundBaseConstantBounds,
@@ -3242,4 +3269,4 @@ GlobOpt::EmitIntRangeChecks(IR::Instr* instr)
32423269
EmitIntRangeChecks(instr, instr->GetDst());
32433270
}
32443271
}
3245-
#endif
3272+
#endif

lib/Backend/GlobOptIntBounds.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ class GlobOpt::ArrayLowerBoundCheckHoistInfo
240240

241241
// Info populated for a compatible bound check and for hoisting out of loop
242242
StackSym *indexSym;
243+
int indexOffset;
243244
int offset;
244245
ValueNumber indexValueNumber;
245246

@@ -287,6 +288,12 @@ class GlobOpt::ArrayLowerBoundCheckHoistInfo
287288
return offset;
288289
}
289290

291+
int32 IndexOffset() const
292+
{
293+
Assert(HasAnyInfo());
294+
return indexOffset;
295+
}
296+
290297
void UpdateOffset(int newOffset)
291298
{
292299
Assert(HasAnyInfo());
@@ -334,7 +341,7 @@ class GlobOpt::ArrayLowerBoundCheckHoistInfo
334341
public:
335342
void SetCompatibleBoundCheck(BasicBlock *const compatibleBoundCheckBlock, StackSym *const indexSym, const int offset, const ValueNumber indexValueNumber);
336343
void SetLoop(::Loop *const loop, const int indexConstantValue, const bool isLoopCountBasedBound = false);
337-
void SetLoop(::Loop *const loop, StackSym *const indexSym, const int offset, Value *const indexValue, const IntConstantBounds &indexConstantBounds, const bool isLoopCountBasedBound = false);
344+
void SetLoop(::Loop *const loop, StackSym *const indexSym, const int indexOffset, const int offset, Value *const indexValue, const IntConstantBounds &indexConstantBounds, const bool isLoopCountBasedBound = false);
338345
void SetLoopCount(::LoopCount *const loopCount, const int maxMagnitudeChange);
339346
};
340347

@@ -353,6 +360,7 @@ class GlobOpt::ArrayUpperBoundCheckHoistInfo : protected ArrayLowerBoundCheckHoi
353360
using Base::CompatibleBoundCheckBlock;
354361
using Base::Loop;
355362
using Base::IndexSym;
363+
using Base::IndexOffset;
356364
using Base::Offset;
357365
using Base::UpdateOffset;
358366
using Base::IndexValueNumber;
@@ -385,5 +393,5 @@ class GlobOpt::ArrayUpperBoundCheckHoistInfo : protected ArrayLowerBoundCheckHoi
385393
public:
386394
void SetCompatibleBoundCheck(BasicBlock *const compatibleBoundCheckBlock, const int indexConstantValue);
387395
void SetLoop(::Loop *const loop, const int indexConstantValue, Value *const headSegmentLengthValue, const IntConstantBounds &headSegmentLengthConstantBounds, const bool isLoopCountBasedBound = false);
388-
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);
396+
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);
389397
};

0 commit comments

Comments
 (0)