Skip to content

Commit bc9e381

Browse files
author
Thomas Moore (CHAKRA)
committed
[1.10>1.11] [MERGE #5764 @thomasmo] October 2018 Security Update
Merge pull request #5764 from thomasmo:1810 October 2018 Security Update that addresses the following issues in ChakraCore: CVE-2018-8473 CVE-2018-8500 CVE-2018-8503 CVE-2018-8505 CVE-2018-8510 CVE-2018-8511 CVE-2018-8513
2 parents d6bb4ce + f40b55c commit bc9e381

10 files changed

+48
-55
lines changed

lib/Backend/GlobOpt.cpp

+13-40
Original file line numberDiff line numberDiff line change
@@ -1013,28 +1013,17 @@ BOOL GlobOpt::PRE::PreloadPRECandidate(Loop *loop, GlobHashBucket* candidate)
10131013
// Create instr to put in landing pad for compensation
10141014
Assert(IsPREInstrCandidateLoad(ldInstrInLoop->m_opcode));
10151015

1016-
IR::Instr * ldInstr = InsertPropertySymPreloadWithoutDstInLandingPad(ldInstrInLoop, loop, propertySym);
1016+
IR::Instr * ldInstr = InsertPropertySymPreloadInLandingPad(ldInstrInLoop, loop, propertySym);
10171017
if (!ldInstr)
10181018
{
10191019
return false;
10201020
}
10211021

10221022
Assert(ldInstr->GetDst() == nullptr);
1023-
if (ldInstrInLoop->GetDst())
1024-
{
1025-
Assert(ldInstrInLoop->GetDst()->IsRegOpnd());
1026-
if (ldInstrInLoop->GetDst()->AsRegOpnd()->m_sym != symStore)
1027-
{
1028-
ldInstr->SetDst(IR::RegOpnd::New(symStore->AsStackSym(), TyVar, this->globOpt->func));
1029-
loop->fieldPRESymStores->Set(symStore->m_id);
1030-
}
1031-
else
1032-
{
1033-
ldInstr->SetDst(ldInstrInLoop->GetDst()->Copy(ldInstrInLoop->m_func));
1034-
}
1035-
landingPad->globOptData.liveVarSyms->Set(ldInstr->GetDst()->AsRegOpnd()->m_sym->m_id);
1036-
}
1037-
1023+
ldInstr->SetDst(IR::RegOpnd::New(symStore->AsStackSym(), TyVar, this->globOpt->func));
1024+
loop->fieldPRESymStores->Set(symStore->m_id);
1025+
landingPad->globOptData.liveVarSyms->Set(symStore->m_id);
1026+
10381027
Value * objPtrValue = landingPad->globOptData.FindValue(objPtrSym);
10391028

10401029
objPtrCopyPropSym = objPtrCopyPropSym ? objPtrCopyPropSym : objPtrValue ? landingPad->globOptData.GetCopyPropSym(objPtrSym, objPtrValue) : nullptr;
@@ -3310,7 +3299,7 @@ GlobOpt::OptSrc(IR::Opnd *opnd, IR::Instr * *pInstr, Value **indirIndexValRef, I
33103299
// Can this be done in one call?
33113300
if (!this->prePassInstrMap->ContainsKey(sym->m_id))
33123301
{
3313-
this->prePassInstrMap->AddNew(sym->m_id, instr);
3302+
this->prePassInstrMap->AddNew(sym->m_id, instr->CopyWithoutDst());
33143303
}
33153304
}
33163305
}
@@ -17235,7 +17224,7 @@ GlobOpt::PRE::InsertSymDefinitionInLandingPad(StackSym * sym, Loop * loop, Sym *
1723517224
// #1 is done next. #2 and #3 are done as part of preloading T1.y
1723617225

1723717226
// Insert T1 = o.x
17238-
if (!InsertPropertySymPreloadInLandingPad(symDefInstr, loop, propSym))
17227+
if (!InsertPropertySymPreloadInLandingPad(symDefInstr->Copy(), loop, propSym))
1723917228
{
1724017229
return false;
1724117230
}
@@ -17248,7 +17237,7 @@ GlobOpt::PRE::InsertSymDefinitionInLandingPad(StackSym * sym, Loop * loop, Sym *
1724817237
if (loop->landingPad->globOptData.IsLive(*objPtrCopyPropSym))
1724917238
{
1725017239
// insert T1 = o.x
17251-
if (!InsertPropertySymPreloadInLandingPad(symDefInstr, loop, propSym))
17240+
if (!InsertPropertySymPreloadInLandingPad(symDefInstr->Copy(), loop, propSym))
1725217241
{
1725317242
return false;
1725417243
}
@@ -17336,25 +17325,6 @@ GlobOpt::PRE::InsertInstrInLandingPad(IR::Instr * instr, Loop * loop)
1733617325

1733717326
IR::Instr *
1733817327
GlobOpt::PRE::InsertPropertySymPreloadInLandingPad(IR::Instr * ldInstr, Loop * loop, PropertySym * propertySym)
17339-
{
17340-
IR::Instr * instr = InsertPropertySymPreloadWithoutDstInLandingPad(ldInstr, loop, propertySym);
17341-
if (!instr)
17342-
{
17343-
return nullptr;
17344-
}
17345-
17346-
if (ldInstr->GetDst())
17347-
{
17348-
instr->SetDst(ldInstr->GetDst()->Copy(ldInstr->m_func));
17349-
instr->GetDst()->SetIsJITOptimizedReg(true);
17350-
loop->landingPad->globOptData.liveVarSyms->Set(instr->GetDst()->GetStackSym()->m_id);
17351-
}
17352-
17353-
return instr;
17354-
}
17355-
17356-
IR::Instr *
17357-
GlobOpt::PRE::InsertPropertySymPreloadWithoutDstInLandingPad(IR::Instr * ldInstr, Loop * loop, PropertySym * propertySym)
1735817328
{
1735917329
IR::SymOpnd *ldSrc = ldInstr->GetSrc1()->AsSymOpnd();
1736017330

@@ -17369,8 +17339,6 @@ GlobOpt::PRE::InsertPropertySymPreloadWithoutDstInLandingPad(IR::Instr * ldInstr
1736917339
}
1737017340
}
1737117341

17372-
ldInstr = ldInstr->CopyWithoutDst();
17373-
1737417342
// Consider: Shouldn't be necessary once we have copy-prop in prepass...
1737517343
ldInstr->GetSrc1()->AsSymOpnd()->m_sym = propertySym;
1737617344
ldSrc = ldInstr->GetSrc1()->AsSymOpnd();
@@ -17384,6 +17352,11 @@ GlobOpt::PRE::InsertPropertySymPreloadWithoutDstInLandingPad(IR::Instr * ldInstr
1738417352
ldInstr->ReplaceSrc1(newPropSymOpnd);
1738517353
}
1738617354

17355+
if (ldInstr->GetDst())
17356+
{
17357+
loop->landingPad->globOptData.liveVarSyms->Set(ldInstr->GetDst()->GetStackSym()->m_id);
17358+
}
17359+
1738717360
InsertInstrInLandingPad(ldInstr, loop);
1738817361

1738917362
return ldInstr;

lib/Backend/GlobOpt.h

-1
Original file line numberDiff line numberDiff line change
@@ -1029,7 +1029,6 @@ class GlobOpt::PRE
10291029
void FindPossiblePRECandidates(Loop *loop, JitArenaAllocator *alloc);
10301030
void PreloadPRECandidates(Loop *loop);
10311031
BOOL PreloadPRECandidate(Loop *loop, GlobHashBucket* candidate);
1032-
IR::Instr * InsertPropertySymPreloadWithoutDstInLandingPad(IR::Instr * origLdInstr, Loop * loop, PropertySym * propertySym);
10331032
IR::Instr * InsertPropertySymPreloadInLandingPad(IR::Instr * origLdInstr, Loop * loop, PropertySym * propertySym);
10341033
void InsertInstrInLandingPad(IR::Instr * instr, Loop * loop);
10351034
bool InsertSymDefinitionInLandingPad(StackSym * sym, Loop * loop, Sym ** objPtrCopyPropSym);

lib/Backend/GlobOptArrays.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,8 @@ void GlobOpt::ArraySrcOpt::CheckVirtualArrayBounds()
320320
{
321321
Assert(instr->m_opcode == Js::OpCode::InlineArrayPush ||
322322
instr->m_opcode == Js::OpCode::InlineArrayPop ||
323-
instr->m_opcode == Js::OpCode::LdLen_A);
323+
instr->m_opcode == Js::OpCode::LdLen_A ||
324+
instr->m_opcode == Js::OpCode::IsIn);
324325
}
325326

326327
eliminatedLowerBoundCheck = true;
@@ -1988,6 +1989,8 @@ void GlobOpt::ArraySrcOpt::Optimize()
19881989
{
19891990
TRACE_TESTTRACE_PHASE_INSTR(Js::Phase::BoundCheckEliminationPhase, instr, _u("Eliminating IsIn\n"));
19901991

1992+
globOpt->CaptureByteCodeSymUses(instr);
1993+
19911994
instr->m_opcode = Js::OpCode::Ld_A;
19921995

19931996
IR::AddrOpnd * addrOpnd = IR::AddrOpnd::New(func->GetScriptContextInfo()->GetTrueAddr(), IR::AddrOpndKindDynamicVar, func, true);

lib/Backend/GlobOptBailOut.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,8 @@ GlobOpt::TrackCalls(IR::Instr * instr)
583583
instr->m_func->m_hasInlineArgsOpt = true;
584584
InlineeFrameInfo* frameInfo = InlineeFrameInfo::New(func->m_alloc);
585585
instr->m_func->frameInfo = frameInfo;
586+
frameInfo->functionSymStartValue = instr->GetSrc1()->GetSym() ?
587+
CurrentBlockData()->FindValue(instr->GetSrc1()->GetSym()) : nullptr;
586588
frameInfo->floatSyms = CurrentBlockData()->liveFloat64Syms->CopyNew(this->alloc);
587589
frameInfo->intSyms = CurrentBlockData()->liveInt32Syms->MinusNew(CurrentBlockData()->liveLossyInt32Syms, this->alloc);
588590
frameInfo->varSyms = CurrentBlockData()->liveVarSyms->CopyNew(this->alloc);
@@ -762,6 +764,15 @@ void GlobOpt::RecordInlineeFrameInfo(IR::Instr* inlineeEnd)
762764
}
763765
else
764766
{
767+
// If the value of the functionObject symbol has changed between the inlineeStart and the inlineeEnd,
768+
// we don't record the inlinee frame info (see OS#18318884).
769+
Assert(frameInfo->functionSymStartValue != nullptr);
770+
if (!frameInfo->functionSymStartValue->IsEqualTo(CurrentBlockData()->FindValue(functionObject->m_sym)))
771+
{
772+
argInstr->m_func->DisableCanDoInlineArgOpt();
773+
return true;
774+
}
775+
765776
frameInfo->function = InlineFrameInfoValue(functionObject->m_sym);
766777
}
767778
}

lib/Backend/InlineeFrameInfo.h

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
#pragma once
77

8+
class Value;
9+
810
struct BailoutConstantValue {
911
public:
1012
void InitIntConstValue(int32 value) { this->type = TyInt32; this->u.intConst.value = (IntConstType)value; };
@@ -150,6 +152,7 @@ struct InlineeFrameInfo
150152
BVSparse<JitArenaAllocator>* floatSyms;
151153
BVSparse<JitArenaAllocator>* intSyms;
152154
BVSparse<JitArenaAllocator>* varSyms;
155+
Value* functionSymStartValue;
153156

154157
bool isRecorded;
155158

lib/Runtime/Base/FunctionBody.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2105,7 +2105,7 @@ namespace Js
21052105
{
21062106
FunctionTypeWeakRefList* typeList = EnsureFunctionObjectTypeList();
21072107

2108-
Assert(functionType != deferredPrototypeType);
2108+
Assert(functionType != deferredPrototypeType && functionType != undeferredFunctionType);
21092109
Recycler * recycler = this->GetScriptContext()->GetRecycler();
21102110
FunctionTypeWeakRef* weakRef = recycler->CreateWeakReferenceHandle(functionType);
21112111
typeList->SetAtFirstFreeSpot(weakRef);

lib/Runtime/Base/FunctionBody.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -1088,8 +1088,10 @@ namespace Js
10881088
{
10891089
func(this->deferredPrototypeType);
10901090
}
1091-
// NOTE: We deliberately do not map the undeferredFunctionType here, since it's in the list
1092-
// of registered function object types we processed above.
1091+
if (this->undeferredFunctionType)
1092+
{
1093+
func(this->undeferredFunctionType);
1094+
}
10931095
}
10941096

10951097
static uint GetOffsetOfDeferredPrototypeType() { return static_cast<uint>(offsetof(Js::FunctionProxy, deferredPrototypeType)); }

lib/Runtime/Language/JavascriptOperators.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -4950,13 +4950,18 @@ using namespace Js;
49504950
}
49514951
else if (instanceType == TypeIds_NativeIntArray)
49524952
{
4953-
// Only accept tagged int. Also covers case for MissingItem
4953+
// Only accept tagged int.
49544954
if (!TaggedInt::Is(value))
49554955
{
49564956
return false;
49574957
}
49584958
int32 intValue = 0;
49594959
if (!MemsetConversion<int32, JavascriptConversion::ToInt32>(value, scriptContext, &intValue))
4960+
{
4961+
return false;
4962+
}
4963+
// Special case for missing item
4964+
if (SparseArraySegment<int32>::IsMissingItem(&intValue))
49604965
{
49614966
return false;
49624967
}

lib/Runtime/Library/JavascriptArray.cpp

+3-9
Original file line numberDiff line numberDiff line change
@@ -1499,13 +1499,11 @@ using namespace Js;
14991499

15001500
bool isTaggedInt = TaggedInt::Is(item);
15011501
bool isTaggedIntMissingValue = false;
1502-
#ifdef TARGET_64
15031502
if (isTaggedInt)
15041503
{
15051504
int32 iValue = TaggedInt::ToInt32(item);
15061505
isTaggedIntMissingValue = Js::SparseArraySegment<int32>::IsMissingItem(&iValue);
15071506
}
1508-
#endif
15091507
if (isTaggedInt && !isTaggedIntMissingValue)
15101508
{
15111509
// This is taggedInt case and we verified that item is not missing value in AMD64.
@@ -3426,16 +3424,12 @@ using namespace Js;
34263424
{
34273425
if (TaggedInt::Is(aItem))
34283426
{
3429-
pDestArray->DirectSetItemAt(idxDest, TaggedInt::ToInt32(aItem));
3427+
int32 int32Value = TaggedInt::ToInt32(aItem);
3428+
Assert(!SparseArraySegment<int32>::IsMissingItem(&int32Value));
3429+
pDestArray->DirectSetItemAt(idxDest, int32Value);
34303430
}
34313431
else
34323432
{
3433-
#if DBG
3434-
int32 int32Value;
3435-
Assert(
3436-
JavascriptNumber::TryGetInt32Value(JavascriptNumber::GetValue(aItem), &int32Value) &&
3437-
!SparseArraySegment<int32>::IsMissingItem(&int32Value));
3438-
#endif
34393433
pDestArray->DirectSetItemAt(idxDest, static_cast<int32>(JavascriptNumber::GetValue(aItem)));
34403434
}
34413435
++idxDest;

lib/Runtime/Types/PathTypeHandler.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1476,6 +1476,9 @@ namespace Js
14761476
if (!(attributes[descriptor->GetDataPropertyIndex<false>()] & ObjectSlotAttr_Accessor))
14771477
{
14781478
// Setter without a getter; this is a stale entry, so ignore it
1479+
// Just consume the slot so no descriptor refers to it.
1480+
Assert(i == newTypeHandler->nextPropertyIndex);
1481+
::Math::PostInc(newTypeHandler->nextPropertyIndex);
14791482
continue;
14801483
}
14811484
Assert(oldTypeHandler->GetSetterSlotIndex(descriptor->GetDataPropertyIndex<false>()) == newTypeHandler->nextPropertyIndex);

0 commit comments

Comments
 (0)