Skip to content

Commit 8f90719

Browse files
committed
[MERGE #5596 @aneeshdk] August 2018 Security Update
Merge pull request #5596 from aneeshdk:servicing/1808_1.10 This update address the following issues in ChakraCore.dll : CVE-2018-8380, CVE-2018-8359, CVE-2018-8385, CVE-2018-8390, CVE-2018-8266, CVE-2018-8384, CVE-2018-8372, CVE-2018-8355 and CVE-2018-8381
2 parents 2c4085b + cd84156 commit 8f90719

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+708
-296
lines changed

Build/NuGet/.pack-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.10.1
1+
1.10.2

lib/Backend/BackwardPass.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,6 +2245,11 @@ BackwardPass::DeadStoreTypeCheckBailOut(IR::Instr * instr)
22452245
IR::PropertySymOpnd *propertySymOpnd =
22462246
(instr->GetDst() && instr->GetDst()->IsSymOpnd()) ? instr->GetDst()->AsPropertySymOpnd() : instr->GetSrc1()->AsPropertySymOpnd();
22472247

2248+
if (propertySymOpnd->TypeCheckRequired())
2249+
{
2250+
return;
2251+
}
2252+
22482253
bool isTypeCheckProtected = false;
22492254
IR::BailOutKind bailOutKind;
22502255
if (GlobOpt::NeedsTypeCheckBailOut(instr, propertySymOpnd, propertySymOpnd == instr->GetDst(), &isTypeCheckProtected, &bailOutKind))
@@ -4902,8 +4907,8 @@ BackwardPass::UpdateArrayBailOutKind(IR::Instr *const instr)
49024907
}
49034908

49044909
IR::BailOutKind includeBailOutKinds = IR::BailOutInvalid;
4905-
if(!baseValueType.IsNotNativeArray() &&
4906-
(!baseValueType.IsLikelyNativeArray() || !instr->GetSrc1()->IsInt32()) &&
4910+
if (!baseValueType.IsNotNativeArray() &&
4911+
(!baseValueType.IsLikelyNativeArray() || instr->GetSrc1()->IsVar()) &&
49074912
!currentBlock->noImplicitCallNativeArrayUses->IsEmpty() &&
49084913
!(instr->GetBailOutKind() & IR::BailOutOnArrayAccessHelperCall))
49094914
{

lib/Backend/BailOut.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,13 @@ uint32 BailOutRecord::GetArgumentsObjectOffset()
506506
return argumentsObjectOffset;
507507
}
508508

509+
Js::FunctionEntryPointInfo *BailOutRecord::GetFunctionEntryPointInfo() const
510+
{
511+
Js::EntryPointInfo* result = this->globalBailOutRecordTable->entryPointInfo;
512+
AssertOrFailFast(result->IsFunctionEntryPointInfo());
513+
return (Js::FunctionEntryPointInfo*)result;
514+
}
515+
509516
Js::Var BailOutRecord::EnsureArguments(Js::InterpreterStackFrame * newInstance, Js::JavascriptCallStackLayout * layout, Js::ScriptContext* scriptContext, Js::Var* pArgumentsObject) const
510517
{
511518
Assert(globalBailOutRecordTable->hasStackArgOpt);
@@ -1706,7 +1713,27 @@ void BailOutRecord::ScheduleFunctionCodeGen(Js::ScriptFunction * function, Js::S
17061713
BailOutRecord * bailOutRecordNotConst = (BailOutRecord *)(void *)bailOutRecord;
17071714
bailOutRecordNotConst->bailOutCount++;
17081715

1709-
Js::FunctionEntryPointInfo *entryPointInfo = function->GetFunctionEntryPointInfo();
1716+
Js::FunctionEntryPointInfo *entryPointInfo = bailOutRecord->GetFunctionEntryPointInfo();
1717+
1718+
#if DBG
1719+
// BailOutRecord is not recycler-allocated, so make sure something the recycler can see was keeping the entry point info alive.
1720+
// We expect the entry point to be kept alive as follows:
1721+
// 1. The function's current type might still have the same entry point info as when we entered the function (easy case)
1722+
// 2. The function might have moved to a successor path type, which still keeps the previous type and its entry point info alive
1723+
// 3. The entry point info might be held by the ThreadContext (QueueFreeOldEntryPointInfoIfInScript):
1724+
// a. If the entry point info was replaced on the type that used to hold it (ScriptFunction::ChangeEntryPoint)
1725+
// b. If the function's last-added property was deleted and it moved to a previous type (ScriptFunction::ReplaceTypeWithPredecessorType)
1726+
// c. If the function's path type got replaced with a dictionary, then all previous entry point infos in that path are queued on the ThreadContext (ScriptFunction::PrepareForConversionToNonPathType)
1727+
bool foundEntryPoint = false;
1728+
executeFunction->MapEntryPointsUntil([&](int index, Js::FunctionEntryPointInfo* info)
1729+
{
1730+
foundEntryPoint = info == entryPointInfo;
1731+
return foundEntryPoint;
1732+
});
1733+
foundEntryPoint = foundEntryPoint || function->GetScriptContext()->GetThreadContext()->IsOldEntryPointInfo(entryPointInfo);
1734+
Assert(foundEntryPoint);
1735+
#endif
1736+
17101737
uint8 callsCount = entryPointInfo->callsCount > 255 ? 255 : static_cast<uint8>(entryPointInfo->callsCount);
17111738
RejitReason rejitReason = RejitReason::None;
17121739
bool reThunk = false;
@@ -2235,7 +2262,7 @@ void BailOutRecord::ScheduleFunctionCodeGen(Js::ScriptFunction * function, Js::S
22352262
if (bailOutRecord->IsForLoopTop() && IR::IsTypeCheckBailOutKind(bailOutRecord->bailOutKind))
22362263
{
22372264
// Disable FieldPRE if we're triggering a type check rejit due to a bailout at the loop top.
2238-
// Most likely this was caused by a CheckFixedFld that was hoisted from a branch block where
2265+
// Most likely this was caused by a CheckFixedFld that was hoisted from a branch block where
22392266
// only certain types flowed, to the loop top, where more types (different or non-equivalent)
22402267
// were flowing in.
22412268
profileInfo->DisableFieldPRE();

lib/Backend/BailOut.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ class BailOutRecord
209209
void SetType(BailoutRecordType type) { this->type = type; }
210210
bool IsShared() const { return type == Shared || type == SharedForLoopTop; }
211211
bool IsForLoopTop() const { return type == SharedForLoopTop; }
212+
213+
Js::FunctionEntryPointInfo *GetFunctionEntryPointInfo() const;
212214
protected:
213215
struct BailOutReturnValue
214216
{
@@ -237,7 +239,7 @@ class BailOutRecord
237239

238240
static void UpdatePolymorphicFieldAccess(Js::JavascriptFunction * function, BailOutRecord const * bailOutRecord);
239241

240-
static void ScheduleFunctionCodeGen(Js::ScriptFunction * function, Js::ScriptFunction * innerMostInlinee, BailOutRecord const * bailOutRecord, IR::BailOutKind bailOutKind,
242+
static void ScheduleFunctionCodeGen(Js::ScriptFunction * function, Js::ScriptFunction * innerMostInlinee, BailOutRecord const * bailOutRecord, IR::BailOutKind bailOutKind,
241243
uint32 actualBailOutOffset, Js::ImplicitCallFlags savedImplicitCallFlags, void * returnAddress);
242244
static void ScheduleLoopBodyCodeGen(Js::ScriptFunction * function, Js::ScriptFunction * innerMostInlinee, BailOutRecord const * bailOutRecord, IR::BailOutKind bailOutKind);
243245
static void CheckPreemptiveRejit(Js::FunctionBody* executeFunction, IR::BailOutKind bailOutKind, BailOutRecord* bailoutRecord, uint8& callsOrIterationsCount, int loopNumber);
@@ -416,6 +418,7 @@ struct GlobalBailOutRecordDataTable
416418
// The offset to 'registerSaveSpace' is hard-coded in LinearScanMD::SaveAllRegisters, so let this be the first member variable
417419
Js::Var *registerSaveSpace;
418420
GlobalBailOutRecordDataRow *globalBailOutRecordDataRows;
421+
Js::EntryPointInfo *entryPointInfo;
419422
uint32 length;
420423
uint32 size;
421424
int32 firstActualStackOffset;

lib/Backend/FunctionJITTimeInfo.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ FunctionJITTimeInfo::BuildJITTimeData(
2727
jitData->isInlined = codeGenData->GetIsInlined();
2828
jitData->weakFuncRef = (intptr_t)codeGenData->GetWeakFuncRef();
2929
jitData->inlineesBv = (BVFixedIDL*)(const BVFixed*)codeGenData->inlineesBv;
30+
jitData->entryPointInfoAddr = (intptr_t)codeGenData->GetEntryPointInfo();
3031

3132
if (!codeGenData->GetFunctionBody() || !codeGenData->GetFunctionBody()->GetByteCode())
3233
{
@@ -62,7 +63,7 @@ FunctionJITTimeInfo::BuildJITTimeData(
6263
Assert(defaultEntryPointInfo->IsFunctionEntryPointInfo());
6364
Js::FunctionEntryPointInfo *functionEntryPointInfo = static_cast<Js::FunctionEntryPointInfo*>(defaultEntryPointInfo);
6465
jitData->callsCountAddress = (intptr_t)&functionEntryPointInfo->callsCount;
65-
66+
6667
jitData->sharedPropertyGuards = codeGenData->sharedPropertyGuards;
6768
jitData->sharedPropGuardCount = codeGenData->sharedPropertyGuardCount;
6869
}
@@ -203,6 +204,12 @@ FunctionJITTimeInfo::GetFunctionInfoAddr() const
203204
return m_data.functionInfoAddr;
204205
}
205206

207+
intptr_t
208+
FunctionJITTimeInfo::GetEntryPointInfoAddr() const
209+
{
210+
return m_data.entryPointInfoAddr;
211+
}
212+
206213
intptr_t
207214
FunctionJITTimeInfo::GetWeakFuncRef() const
208215
{

lib/Backend/FunctionJITTimeInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class FunctionJITTimeInfo
2727
JITTimeFunctionBody * GetBody() const;
2828
bool IsPolymorphicCallSite(Js::ProfileId profiledCallSiteId) const;
2929
intptr_t GetFunctionInfoAddr() const;
30+
intptr_t GetEntryPointInfoAddr() const;
3031
intptr_t GetWeakFuncRef() const;
3132
uint GetLocalFunctionId() const;
3233
uint GetSourceContextId() const;

lib/Backend/GlobOpt.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,9 @@ class GlobOpt
938938
template<bool makeChanges>
939939
bool ProcessPropOpInTypeCheckSeq(IR::Instr* instr, IR::PropertySymOpnd *opnd, BasicBlock* block, bool updateExistingValue, bool* emitsTypeCheckOut = nullptr, bool* changesTypeValueOut = nullptr, bool *isObjTypeChecked = nullptr);
940940
void KillObjectHeaderInlinedTypeSyms(BasicBlock *block, bool isObjTypeSpecialized, SymID symId = SymID_Invalid);
941+
bool HasLiveObjectHeaderInlinedTypeSym(BasicBlock *block, bool isObjTypeSpecialized, SymID symId = SymID_Invalid);
942+
template<class Fn>
943+
bool MapObjectHeaderInlinedTypeSymsUntil(BasicBlock *block, bool isObjTypeSpecialized, SymID opndId, Fn fn);
941944
void ValueNumberObjectType(IR::Opnd *dstOpnd, IR::Instr *instr);
942945
void SetSingleTypeOnObjectTypeValue(Value* value, const JITTypeHolder type);
943946
void SetTypeSetOnObjectTypeValue(Value* value, Js::EquivalentTypeSet* typeSet);

lib/Backend/GlobOptArrays.cpp

Lines changed: 78 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -897,19 +897,8 @@ void GlobOpt::ArraySrcOpt::DoLowerBoundCheck()
897897
Assert(!indexIntSym || indexIntSym->GetType() == TyInt32 || indexIntSym->GetType() == TyUint32);
898898
}
899899

900-
// The info in the landing pad may be better than the info in the current block due to changes made to
901-
// the index sym inside the loop. Check if the bound check we intend to hoist is unnecessary in the
902-
// landing pad.
903-
if (!ValueInfo::IsLessThanOrEqualTo(
904-
nullptr,
905-
0,
906-
0,
907-
hoistInfo.IndexValue(),
908-
hoistInfo.IndexConstantBounds().LowerBound(),
909-
hoistInfo.IndexConstantBounds().UpperBound(),
910-
hoistInfo.Offset()))
900+
if (hoistInfo.IndexSym())
911901
{
912-
Assert(hoistInfo.IndexSym());
913902
Assert(hoistInfo.Loop()->bailOutInfo);
914903
globOpt->EnsureBailTarget(hoistInfo.Loop());
915904

@@ -1156,106 +1145,94 @@ void GlobOpt::ArraySrcOpt::DoUpperBoundCheck()
11561145
Assert(!indexIntSym || indexIntSym->GetType() == TyInt32 || indexIntSym->GetType() == TyUint32);
11571146
}
11581147

1159-
// The info in the landing pad may be better than the info in the current block due to changes made to the
1160-
// index sym inside the loop. Check if the bound check we intend to hoist is unnecessary in the landing pad.
1161-
if (!ValueInfo::IsLessThanOrEqualTo(
1162-
hoistInfo.IndexValue(),
1163-
hoistInfo.IndexConstantBounds().LowerBound(),
1164-
hoistInfo.IndexConstantBounds().UpperBound(),
1165-
hoistInfo.HeadSegmentLengthValue(),
1166-
hoistInfo.HeadSegmentLengthConstantBounds().LowerBound(),
1167-
hoistInfo.HeadSegmentLengthConstantBounds().UpperBound(),
1168-
hoistInfo.Offset()))
1169-
{
1170-
Assert(hoistInfo.Loop()->bailOutInfo);
1171-
globOpt->EnsureBailTarget(hoistInfo.Loop());
1148+
Assert(hoistInfo.Loop()->bailOutInfo);
1149+
globOpt->EnsureBailTarget(hoistInfo.Loop());
11721150

1173-
if (hoistInfo.LoopCount())
1151+
if (hoistInfo.LoopCount())
1152+
{
1153+
// Generate the loop count and loop count based bound that will be used for the bound check
1154+
if (!hoistInfo.LoopCount()->HasBeenGenerated())
11741155
{
1175-
// Generate the loop count and loop count based bound that will be used for the bound check
1176-
if (!hoistInfo.LoopCount()->HasBeenGenerated())
1177-
{
1178-
globOpt->GenerateLoopCount(hoistInfo.Loop(), hoistInfo.LoopCount());
1179-
}
1180-
globOpt->GenerateSecondaryInductionVariableBound(
1181-
hoistInfo.Loop(),
1182-
indexVarSym->GetInt32EquivSym(nullptr),
1183-
hoistInfo.LoopCount(),
1184-
hoistInfo.MaxMagnitudeChange(),
1185-
hoistInfo.IndexSym());
1156+
globOpt->GenerateLoopCount(hoistInfo.Loop(), hoistInfo.LoopCount());
11861157
}
1158+
globOpt->GenerateSecondaryInductionVariableBound(
1159+
hoistInfo.Loop(),
1160+
indexVarSym->GetInt32EquivSym(nullptr),
1161+
hoistInfo.LoopCount(),
1162+
hoistInfo.MaxMagnitudeChange(),
1163+
hoistInfo.IndexSym());
1164+
}
11871165

1188-
IR::Opnd* lowerBound = indexIntSym
1189-
? static_cast<IR::Opnd *>(IR::RegOpnd::New(indexIntSym, TyInt32, instr->m_func))
1190-
: IR::IntConstOpnd::New(
1191-
hoistInfo.IndexConstantBounds().LowerBound(),
1192-
TyInt32,
1193-
instr->m_func);
1194-
1195-
lowerBound->SetIsJITOptimizedReg(true);
1196-
IR::Opnd* upperBound = IR::RegOpnd::New(headSegmentLengthSym, headSegmentLengthSym->GetType(), instr->m_func);
1197-
upperBound->SetIsJITOptimizedReg(true);
1166+
IR::Opnd* lowerBound = indexIntSym
1167+
? static_cast<IR::Opnd *>(IR::RegOpnd::New(indexIntSym, TyInt32, instr->m_func))
1168+
: IR::IntConstOpnd::New(
1169+
hoistInfo.IndexConstantBounds().LowerBound(),
1170+
TyInt32,
1171+
instr->m_func);
11981172

1199-
// indexSym <= headSegmentLength + offset (src1 <= src2 + dst)
1200-
IR::Instr *const boundCheck = globOpt->CreateBoundsCheckInstr(
1201-
lowerBound,
1202-
upperBound,
1203-
hoistInfo.Offset(),
1204-
hoistInfo.IsLoopCountBasedBound()
1205-
? IR::BailOutOnFailedHoistedLoopCountBasedBoundCheck
1206-
: IR::BailOutOnFailedHoistedBoundCheck,
1207-
hoistInfo.Loop()->bailOutInfo,
1208-
hoistInfo.Loop()->bailOutInfo->bailOutFunc);
1173+
lowerBound->SetIsJITOptimizedReg(true);
1174+
IR::Opnd* upperBound = IR::RegOpnd::New(headSegmentLengthSym, headSegmentLengthSym->GetType(), instr->m_func);
1175+
upperBound->SetIsJITOptimizedReg(true);
12091176

1210-
InsertInstrInLandingPad(boundCheck, hoistInfo.Loop());
1177+
// indexSym <= headSegmentLength + offset (src1 <= src2 + dst)
1178+
IR::Instr *const boundCheck = globOpt->CreateBoundsCheckInstr(
1179+
lowerBound,
1180+
upperBound,
1181+
hoistInfo.Offset(),
1182+
hoistInfo.IsLoopCountBasedBound()
1183+
? IR::BailOutOnFailedHoistedLoopCountBasedBoundCheck
1184+
: IR::BailOutOnFailedHoistedBoundCheck,
1185+
hoistInfo.Loop()->bailOutInfo,
1186+
hoistInfo.Loop()->bailOutInfo->bailOutFunc);
12111187

1212-
if (indexIntSym)
1213-
{
1214-
TRACE_PHASE_INSTR(
1215-
Js::Phase::BoundCheckHoistPhase,
1216-
instr,
1217-
_u("Hoisting array upper bound check out of loop %u to landing pad block %u, as (s%u <= s%u + %d)\n"),
1218-
hoistInfo.Loop()->GetLoopNumber(),
1219-
landingPad->GetBlockNum(),
1220-
hoistInfo.IndexSym()->m_id,
1221-
headSegmentLengthSym->m_id,
1222-
hoistInfo.Offset());
1223-
}
1224-
else
1225-
{
1226-
TRACE_PHASE_INSTR(
1227-
Js::Phase::BoundCheckHoistPhase,
1228-
instr,
1229-
_u("Hoisting array upper bound check out of loop %u to landing pad block %u, as (%d <= s%u + %d)\n"),
1230-
hoistInfo.Loop()->GetLoopNumber(),
1231-
landingPad->GetBlockNum(),
1232-
hoistInfo.IndexConstantBounds().LowerBound(),
1233-
headSegmentLengthSym->m_id,
1234-
hoistInfo.Offset());
1235-
}
1188+
InsertInstrInLandingPad(boundCheck, hoistInfo.Loop());
12361189

1237-
TESTTRACE_PHASE_INSTR(
1190+
if (indexIntSym)
1191+
{
1192+
TRACE_PHASE_INSTR(
1193+
Js::Phase::BoundCheckHoistPhase,
1194+
instr,
1195+
_u("Hoisting array upper bound check out of loop %u to landing pad block %u, as (s%u <= s%u + %d)\n"),
1196+
hoistInfo.Loop()->GetLoopNumber(),
1197+
landingPad->GetBlockNum(),
1198+
hoistInfo.IndexSym()->m_id,
1199+
headSegmentLengthSym->m_id,
1200+
hoistInfo.Offset());
1201+
}
1202+
else
1203+
{
1204+
TRACE_PHASE_INSTR(
12381205
Js::Phase::BoundCheckHoistPhase,
12391206
instr,
1240-
_u("Hoisting array upper bound check out of loop\n"));
1207+
_u("Hoisting array upper bound check out of loop %u to landing pad block %u, as (%d <= s%u + %d)\n"),
1208+
hoistInfo.Loop()->GetLoopNumber(),
1209+
landingPad->GetBlockNum(),
1210+
hoistInfo.IndexConstantBounds().LowerBound(),
1211+
headSegmentLengthSym->m_id,
1212+
hoistInfo.Offset());
1213+
}
12411214

1242-
// Record the bound check instruction as available
1243-
const IntBoundCheck boundCheckInfo(
1244-
hoistInfo.IndexValue() ? hoistInfo.IndexValueNumber() : ZeroValueNumber,
1245-
hoistInfo.HeadSegmentLengthValue()->GetValueNumber(),
1246-
boundCheck,
1247-
landingPad);
1248-
{
1249-
const bool added = globOpt->CurrentBlockData()->availableIntBoundChecks->AddNew(boundCheckInfo) >= 0;
1250-
Assert(added || failedToUpdateCompatibleUpperBoundCheck);
1251-
}
1252-
for (InvariantBlockBackwardIterator it(globOpt, globOpt->currentBlock, landingPad, nullptr);
1253-
it.IsValid();
1254-
it.MoveNext())
1255-
{
1256-
const bool added = it.Block()->globOptData.availableIntBoundChecks->AddNew(boundCheckInfo) >= 0;
1257-
Assert(added || failedToUpdateCompatibleUpperBoundCheck);
1258-
}
1215+
TESTTRACE_PHASE_INSTR(
1216+
Js::Phase::BoundCheckHoistPhase,
1217+
instr,
1218+
_u("Hoisting array upper bound check out of loop\n"));
1219+
1220+
// Record the bound check instruction as available
1221+
const IntBoundCheck boundCheckInfo(
1222+
hoistInfo.IndexValue() ? hoistInfo.IndexValueNumber() : ZeroValueNumber,
1223+
hoistInfo.HeadSegmentLengthValue()->GetValueNumber(),
1224+
boundCheck,
1225+
landingPad);
1226+
{
1227+
const bool added = globOpt->CurrentBlockData()->availableIntBoundChecks->AddNew(boundCheckInfo) >= 0;
1228+
Assert(added || failedToUpdateCompatibleUpperBoundCheck);
1229+
}
1230+
for (InvariantBlockBackwardIterator it(globOpt, globOpt->currentBlock, landingPad, nullptr);
1231+
it.IsValid();
1232+
it.MoveNext())
1233+
{
1234+
const bool added = it.Block()->globOptData.availableIntBoundChecks->AddNew(boundCheckInfo) >= 0;
1235+
Assert(added || failedToUpdateCompatibleUpperBoundCheck);
12591236
}
12601237
}
12611238

0 commit comments

Comments
 (0)