Skip to content

Commit 63bda3b

Browse files
committed
[1.11>master] [MERGE #6385 @pleath] ChakraCore Servicing Update for 2020.03B
Merge pull request #6385 from pleath:servicing/2003 Changes to address the following issues: CVE-2020-0768 CVE-2020-0811 CVE-2020-0812 CVE-2020-0813 CVE-2020-0823 CVE-2020-0825 CVE-2020-0826 CVE-2020-0827 CVE-2020-0828 CVE-2020-0829 CVE-2020-0830 CVE-2020-0831 CVE-2020-0848
2 parents 409b0a2 + fdf0aeb commit 63bda3b

25 files changed

+28575
-28538
lines changed

lib/Backend/BackwardPass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6097,7 +6097,7 @@ BackwardPass::InsertTypeTransitionsAtPotentialKills()
60976097
// This is the sym we're tracking. No aliasing to worry about.
60986098
return false;
60996099
}
6100-
if (propertySymOpnd->IsMono() && data->GetInitialType() != propertySymOpnd->GetType())
6100+
if (propertySymOpnd->NeedsMonoCheck() && data->GetInitialType() != propertySymOpnd->GetType())
61016101
{
61026102
// Type mismatch in a monomorphic case -- no aliasing.
61036103
return false;

lib/Backend/GlobOpt.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2958,7 +2958,12 @@ GlobOpt::OptTagChecks(IR::Instr *instr)
29582958
// the byteCodeUse fields...
29592959
TrackByteCodeUsesForInstrAddedInOptInstr(bailOutInstr, [&]()
29602960
{
2961-
TryHoistInvariant(bailOutInstr, this->currentBlock, nullptr, value, nullptr, true, false, false, IR::BailOutOnTaggedValue);
2961+
if (TryHoistInvariant(bailOutInstr, this->currentBlock, nullptr, value, nullptr, true, false, false, IR::BailOutOnTaggedValue))
2962+
{
2963+
Value* landingPadValue = this->currentBlock->loop->landingPad->globOptData.FindValue(stackSym);
2964+
ValueType newLandingPadValueType = landingPadValue->GetValueInfo()->Type().SetCanBeTaggedValue(false);
2965+
ChangeValueType(nullptr, landingPadValue, newLandingPadValueType, false);
2966+
}
29622967
});
29632968
}
29642969
if (symOpnd)

lib/Backend/GlobOptArrays.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,13 @@ void GlobOpt::ArraySrcOpt::CheckLoops()
508508
if (doArrayChecks)
509509
{
510510
hoistChecksOutOfLoop = loop;
511+
512+
// If BailOnNotObject isn't hoisted, the value may still be tagged in the landing pad
513+
if (baseValueInLoopLandingPad->GetValueInfo()->Type().CanBeTaggedValue())
514+
{
515+
baseValueType = baseValueType.SetCanBeTaggedValue(true);
516+
baseOpnd->SetValueType(baseValueType);
517+
}
511518
}
512519

513520
if (isLikelyJsArray && loopKills.KillsArrayHeadSegments())
@@ -1714,9 +1721,7 @@ void GlobOpt::ArraySrcOpt::Optimize()
17141721

17151722
baseOpnd->SetValueType(baseValueType);
17161723

1717-
if (!baseValueType.IsLikelyAnyOptimizedArray() ||
1718-
!globOpt->DoArrayCheckHoist(baseValueType, globOpt->currentBlock->loop, instr) ||
1719-
(baseOwnerIndir && !globOpt->ShouldExpectConventionalArrayIndexValue(baseOwnerIndir)))
1724+
if (!baseValueType.IsLikelyAnyOptimizedArray())
17201725
{
17211726
return;
17221727
}
@@ -1731,6 +1736,16 @@ void GlobOpt::ArraySrcOpt::Optimize()
17311736
return;
17321737
}
17331738

1739+
if (!globOpt->DoArrayCheckHoist(baseValueType, globOpt->currentBlock->loop, instr) ||
1740+
(baseOwnerIndir && !globOpt->ShouldExpectConventionalArrayIndexValue(baseOwnerIndir)))
1741+
{
1742+
if (!globOpt->IsLoopPrePass() && baseValueType.IsAnyOptimizedArray())
1743+
{
1744+
globOpt->ProcessNoImplicitCallArrayUses(baseOpnd, nullptr, instr, isLikelyJsArray, isLoad || isStore || instr->m_opcode == Js::OpCode::IsIn);
1745+
}
1746+
return;
1747+
}
1748+
17341749
isLikelyVirtualTypedArray = baseValueType.IsLikelyOptimizedVirtualTypedArray();
17351750
Assert(!(isLikelyJsArray && isLikelyVirtualTypedArray));
17361751

lib/Backend/GlobOptFields.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,19 +1162,6 @@ GlobOpt::ProcessPropOpInTypeCheckSeq(IR::Instr* instr, IR::PropertySymOpnd *opnd
11621162
Assert(opnd->IsTypeCheckSeqCandidate());
11631163
Assert(opnd->HasObjectTypeSym());
11641164

1165-
if (opnd->HasTypeMismatch())
1166-
{
1167-
if (emitsTypeCheckOut != nullptr)
1168-
{
1169-
*emitsTypeCheckOut = false;
1170-
}
1171-
if (changesTypeValueOut != nullptr)
1172-
{
1173-
*changesTypeValueOut = false;
1174-
}
1175-
return false;
1176-
}
1177-
11781165
bool isStore = opnd == instr->GetDst();
11791166
bool isTypeDead = opnd->IsTypeDead();
11801167
bool consumeType = makeChanges && !IsLoopPrePass();
@@ -1214,6 +1201,19 @@ GlobOpt::ProcessPropOpInTypeCheckSeq(IR::Instr* instr, IR::PropertySymOpnd *opnd
12141201
opnd->SetTypeAvailable(true);
12151202
}
12161203

1204+
if (opnd->HasTypeMismatch())
1205+
{
1206+
if (emitsTypeCheckOut != nullptr)
1207+
{
1208+
*emitsTypeCheckOut = false;
1209+
}
1210+
if (changesTypeValueOut != nullptr)
1211+
{
1212+
*changesTypeValueOut = false;
1213+
}
1214+
return false;
1215+
}
1216+
12171217
bool doEquivTypeCheck = opnd->HasEquivalentTypeSet() && !opnd->NeedsMonoCheck();
12181218
if (!doEquivTypeCheck)
12191219
{

lib/Backend/IRBuilder.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,10 @@ IRBuilder::BuildReg2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0, Js::Re
18181818
this->AddInstr(instr, offset);
18191819
return;
18201820
}
1821+
case Js::OpCode::InitConst:
1822+
// Don't use InitConst in the JIT, as some dataflow tracking is missing, and we don't currently optimize for it.
1823+
newOpcode = Js::OpCode::Ld_A;
1824+
break;
18211825
}
18221826

18231827
IR::RegOpnd * dstOpnd = this->BuildDstOpnd(R0, TyVar, false, reuseLoc);

lib/Backend/LinearScan.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2981,9 +2981,9 @@ LinearScan::ProcessEHRegionBoundary(IR::Instr * instr)
29812981
}
29822982

29832983
// Spill everything upon entry to the try region and upon a Leave.
2984-
IR::Instr* insertionInstr = instr->m_opcode != Js::OpCode::Leave ? instr : instr->m_prev;
29852984
FOREACH_SLIST_ENTRY_EDITING(Lifetime *, lifetime, this->activeLiveranges, iter)
29862985
{
2986+
IR::Instr* insertionInstr = instr->m_opcode != Js::OpCode::Leave ? instr : instr->m_prev;
29872987
this->activeRegs.Clear(lifetime->reg);
29882988
if (lifetime->IsInt())
29892989
{

lib/Backend/Lower.cpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14125,6 +14125,23 @@ Lowerer::GenerateObjectTestAndTypeLoad(IR::Instr *instrLdSt, IR::RegOpnd *opndBa
1412514125
InsertMove(opndType, opndIndir, instrLdSt);
1412614126
}
1412714127

14128+
void Lowerer::InsertMoveForPolymorphicCacheIndex(IR::Instr * instr, BailOutInfo * bailOutInfo, int bailOutRecordOffset, uint polymorphicCacheIndexValue)
14129+
{
14130+
IR::Opnd * indexOpnd = nullptr;
14131+
14132+
if (this->m_func->IsOOPJIT())
14133+
{
14134+
indexOpnd = IR::IndirOpnd::New(IR::RegOpnd::New(m_func->GetTopFunc()->GetNativeCodeDataSym(), TyVar, m_func), (int)(bailOutRecordOffset + BailOutRecord::GetOffsetOfPolymorphicCacheIndex()), TyUint32, m_func);
14135+
}
14136+
else
14137+
{
14138+
indexOpnd = IR::MemRefOpnd::New((BYTE*)bailOutInfo->bailOutRecord + BailOutRecord::GetOffsetOfPolymorphicCacheIndex(), TyUint32, this->m_func);
14139+
}
14140+
14141+
InsertMove(
14142+
indexOpnd, IR::IntConstOpnd::New(polymorphicCacheIndexValue, TyUint32, this->m_func), instr, false);
14143+
}
14144+
1412814145
IR::LabelInstr *
1412914146
Lowerer::GenerateBailOut(IR::Instr * instr, IR::BranchInstr * branchInstr, IR::LabelInstr *bailOutLabel, IR::LabelInstr * collectRuntimeStatsLabel)
1413014147
{
@@ -14186,23 +14203,19 @@ Lowerer::GenerateBailOut(IR::Instr * instr, IR::BranchInstr * branchInstr, IR::L
1418614203
// Generate code to write the cache index into the bailout record before we jump to the call site.
1418714204
Assert(bailOutInfo->polymorphicCacheIndex != (uint)-1);
1418814205
Assert(bailOutInfo->bailOutRecord);
14189-
IR::Opnd * indexOpnd = nullptr;
14190-
14191-
if (this->m_func->IsOOPJIT())
14192-
{
14193-
indexOpnd = IR::IndirOpnd::New(IR::RegOpnd::New(m_func->GetTopFunc()->GetNativeCodeDataSym(), TyVar, m_func), (int)(bailOutRecordOffset + BailOutRecord::GetOffsetOfPolymorphicCacheIndex()), TyUint32, m_func);
14194-
}
14195-
else
14196-
{
14197-
indexOpnd = IR::MemRefOpnd::New((BYTE*)bailOutInfo->bailOutRecord + BailOutRecord::GetOffsetOfPolymorphicCacheIndex(), TyUint32, this->m_func);
14198-
}
14199-
14200-
InsertMove(
14201-
indexOpnd, IR::IntConstOpnd::New(bailOutInfo->polymorphicCacheIndex, TyUint32, this->m_func), instr, false);
14206+
InsertMoveForPolymorphicCacheIndex(instr, bailOutInfo, bailOutRecordOffset, bailOutInfo->polymorphicCacheIndex);
1420214207
}
1420314208

1420414209
if (bailOutInfo->bailOutRecord->IsShared())
1420514210
{
14211+
// The polymorphicCacheIndex value should be relevant only for field type check bailouts.
14212+
// In case of a shared bailout record, the polymorphicCacheIndex sticks regardless of the bailout kind being different
14213+
// from field type check. Therefore, it results in an out-of-bound write while trying to recrod a field access update.
14214+
if (instr->GetBailOutKind() != IR::BailOutFailedTypeCheck && instr->GetBailOutKind() != IR::BailOutFailedFixedFieldTypeCheck)
14215+
{
14216+
InsertMoveForPolymorphicCacheIndex(instr, bailOutInfo, bailOutRecordOffset, (uint)-1);
14217+
}
14218+
1420614219
IR::Opnd *functionBodyOpnd;
1420714220
if (this->m_func->IsOOPJIT())
1420814221
{

lib/Backend/Lower.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,7 @@ class Lowerer
601601
void PreserveSourcesForBailOnResultCondition(IR::Instr *const instr, IR::LabelInstr *const skipBailOutLabel) const;
602602
void LowerInstrWithBailOnResultCondition(IR::Instr *const instr, const IR::BailOutKind bailOutKind, IR::LabelInstr *const bailOutLabel, IR::LabelInstr *const skipBailOutLabel) const;
603603
void GenerateObjectTestAndTypeLoad(IR::Instr *instrLdSt, IR::RegOpnd *opndBase, IR::RegOpnd *opndType, IR::LabelInstr *labelHelper);
604+
void InsertMoveForPolymorphicCacheIndex(IR::Instr * instr, BailOutInfo * bailOutInfo, int bailOutRecordOffset, uint polymorphicCacheIndexValue);
604605
IR::LabelInstr *GenerateBailOut(IR::Instr * instr, IR::BranchInstr * branchInstr = nullptr, IR::LabelInstr * labelBailOut = nullptr, IR::LabelInstr * collectRuntimeStatsLabel = nullptr);
605606
void GenerateJumpToEpilogForBailOut(BailOutInfo * bailOutInfo, IR::Instr *instrAfter, IR::LabelInstr *exitTargetInstr);
606607
void GenerateThrow(IR::Opnd* errorCode, IR::Instr * instr);

lib/Common/DataStructures/EvalMapString.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ namespace Js
99
template <bool fastHash>
1010
struct EvalMapStringInternal
1111
{
12+
FinalizableObject* owningVar; // This is the Var that originally owns the character buffer corresponding to this EvalMap key.
1213
JsUtil::CharacterBuffer<char16> str;
1314
hash_t hash;
1415
ModuleID moduleID;
1516
BOOL strict;
1617
BOOL isLibraryCode;
1718

18-
EvalMapStringInternal() : str(), moduleID(0), strict(FALSE), isLibraryCode(FALSE), hash(0) {};
19-
EvalMapStringInternal(__in_ecount(charLength) char16 const* content, int charLength, ModuleID moduleID, BOOL strict, BOOL isLibraryCode)
20-
: str(content, charLength), moduleID(moduleID), strict(strict), isLibraryCode(isLibraryCode)
19+
EvalMapStringInternal() : owningVar(nullptr), str(), moduleID(0), strict(FALSE), isLibraryCode(FALSE), hash(0) {};
20+
EvalMapStringInternal(FinalizableObject* obj, __in_ecount(charLength) char16 const* content, int charLength, ModuleID moduleID, BOOL strict, BOOL isLibraryCode)
21+
: owningVar(obj), str(content, charLength), moduleID(moduleID), strict(strict), isLibraryCode(isLibraryCode)
2122
{
2223
// NOTE: this hash is not equivalent to the character buffer hash
2324
// Don't use a CharacteBuffer to do a map lookup on the EvalMapString.

lib/Parser/Parse.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,6 +1980,7 @@ void Parser::BindPidRefsInScope(IdentPtr pid, Symbol *sym, int blockId, uint max
19801980
Assert(funcExprScope->GetScopeType() == ScopeType_FuncExpr);
19811981

19821982
ParseNodeBlock* bodyScope = m_currentNodeFunc->pnodeBodyScope;
1983+
Assert(bodyScope == nullptr || bodyScope->blockType == PnodeBlockType::Function);
19831984

19841985
if (bodyScope && ref->GetScopeId() < bodyScope->blockId && ref->GetScopeId() > blockId)
19851986
{

0 commit comments

Comments
 (0)