Skip to content

Commit

Permalink
[1.10>1.11] [MERGE #5764 @thomasmo] October 2018 Security Update
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Thomas Moore (CHAKRA) committed Oct 9, 2018
2 parents d6bb4ce + f40b55c commit bc9e381
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 55 deletions.
53 changes: 13 additions & 40 deletions lib/Backend/GlobOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1013,28 +1013,17 @@ BOOL GlobOpt::PRE::PreloadPRECandidate(Loop *loop, GlobHashBucket* candidate)
// Create instr to put in landing pad for compensation
Assert(IsPREInstrCandidateLoad(ldInstrInLoop->m_opcode));

IR::Instr * ldInstr = InsertPropertySymPreloadWithoutDstInLandingPad(ldInstrInLoop, loop, propertySym);
IR::Instr * ldInstr = InsertPropertySymPreloadInLandingPad(ldInstrInLoop, loop, propertySym);
if (!ldInstr)
{
return false;
}

Assert(ldInstr->GetDst() == nullptr);
if (ldInstrInLoop->GetDst())
{
Assert(ldInstrInLoop->GetDst()->IsRegOpnd());
if (ldInstrInLoop->GetDst()->AsRegOpnd()->m_sym != symStore)
{
ldInstr->SetDst(IR::RegOpnd::New(symStore->AsStackSym(), TyVar, this->globOpt->func));
loop->fieldPRESymStores->Set(symStore->m_id);
}
else
{
ldInstr->SetDst(ldInstrInLoop->GetDst()->Copy(ldInstrInLoop->m_func));
}
landingPad->globOptData.liveVarSyms->Set(ldInstr->GetDst()->AsRegOpnd()->m_sym->m_id);
}

ldInstr->SetDst(IR::RegOpnd::New(symStore->AsStackSym(), TyVar, this->globOpt->func));
loop->fieldPRESymStores->Set(symStore->m_id);
landingPad->globOptData.liveVarSyms->Set(symStore->m_id);

Value * objPtrValue = landingPad->globOptData.FindValue(objPtrSym);

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

// Insert T1 = o.x
if (!InsertPropertySymPreloadInLandingPad(symDefInstr, loop, propSym))
if (!InsertPropertySymPreloadInLandingPad(symDefInstr->Copy(), loop, propSym))
{
return false;
}
Expand All @@ -17248,7 +17237,7 @@ GlobOpt::PRE::InsertSymDefinitionInLandingPad(StackSym * sym, Loop * loop, Sym *
if (loop->landingPad->globOptData.IsLive(*objPtrCopyPropSym))
{
// insert T1 = o.x
if (!InsertPropertySymPreloadInLandingPad(symDefInstr, loop, propSym))
if (!InsertPropertySymPreloadInLandingPad(symDefInstr->Copy(), loop, propSym))
{
return false;
}
Expand Down Expand Up @@ -17336,25 +17325,6 @@ GlobOpt::PRE::InsertInstrInLandingPad(IR::Instr * instr, Loop * loop)

IR::Instr *
GlobOpt::PRE::InsertPropertySymPreloadInLandingPad(IR::Instr * ldInstr, Loop * loop, PropertySym * propertySym)
{
IR::Instr * instr = InsertPropertySymPreloadWithoutDstInLandingPad(ldInstr, loop, propertySym);
if (!instr)
{
return nullptr;
}

if (ldInstr->GetDst())
{
instr->SetDst(ldInstr->GetDst()->Copy(ldInstr->m_func));
instr->GetDst()->SetIsJITOptimizedReg(true);
loop->landingPad->globOptData.liveVarSyms->Set(instr->GetDst()->GetStackSym()->m_id);
}

return instr;
}

IR::Instr *
GlobOpt::PRE::InsertPropertySymPreloadWithoutDstInLandingPad(IR::Instr * ldInstr, Loop * loop, PropertySym * propertySym)
{
IR::SymOpnd *ldSrc = ldInstr->GetSrc1()->AsSymOpnd();

Expand All @@ -17369,8 +17339,6 @@ GlobOpt::PRE::InsertPropertySymPreloadWithoutDstInLandingPad(IR::Instr * ldInstr
}
}

ldInstr = ldInstr->CopyWithoutDst();

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

if (ldInstr->GetDst())
{
loop->landingPad->globOptData.liveVarSyms->Set(ldInstr->GetDst()->GetStackSym()->m_id);
}

InsertInstrInLandingPad(ldInstr, loop);

return ldInstr;
Expand Down
1 change: 0 additions & 1 deletion lib/Backend/GlobOpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,6 @@ class GlobOpt::PRE
void FindPossiblePRECandidates(Loop *loop, JitArenaAllocator *alloc);
void PreloadPRECandidates(Loop *loop);
BOOL PreloadPRECandidate(Loop *loop, GlobHashBucket* candidate);
IR::Instr * InsertPropertySymPreloadWithoutDstInLandingPad(IR::Instr * origLdInstr, Loop * loop, PropertySym * propertySym);
IR::Instr * InsertPropertySymPreloadInLandingPad(IR::Instr * origLdInstr, Loop * loop, PropertySym * propertySym);
void InsertInstrInLandingPad(IR::Instr * instr, Loop * loop);
bool InsertSymDefinitionInLandingPad(StackSym * sym, Loop * loop, Sym ** objPtrCopyPropSym);
Expand Down
5 changes: 4 additions & 1 deletion lib/Backend/GlobOptArrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,8 @@ void GlobOpt::ArraySrcOpt::CheckVirtualArrayBounds()
{
Assert(instr->m_opcode == Js::OpCode::InlineArrayPush ||
instr->m_opcode == Js::OpCode::InlineArrayPop ||
instr->m_opcode == Js::OpCode::LdLen_A);
instr->m_opcode == Js::OpCode::LdLen_A ||
instr->m_opcode == Js::OpCode::IsIn);
}

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

globOpt->CaptureByteCodeSymUses(instr);

instr->m_opcode = Js::OpCode::Ld_A;

IR::AddrOpnd * addrOpnd = IR::AddrOpnd::New(func->GetScriptContextInfo()->GetTrueAddr(), IR::AddrOpndKindDynamicVar, func, true);
Expand Down
11 changes: 11 additions & 0 deletions lib/Backend/GlobOptBailOut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,8 @@ GlobOpt::TrackCalls(IR::Instr * instr)
instr->m_func->m_hasInlineArgsOpt = true;
InlineeFrameInfo* frameInfo = InlineeFrameInfo::New(func->m_alloc);
instr->m_func->frameInfo = frameInfo;
frameInfo->functionSymStartValue = instr->GetSrc1()->GetSym() ?
CurrentBlockData()->FindValue(instr->GetSrc1()->GetSym()) : nullptr;
frameInfo->floatSyms = CurrentBlockData()->liveFloat64Syms->CopyNew(this->alloc);
frameInfo->intSyms = CurrentBlockData()->liveInt32Syms->MinusNew(CurrentBlockData()->liveLossyInt32Syms, this->alloc);
frameInfo->varSyms = CurrentBlockData()->liveVarSyms->CopyNew(this->alloc);
Expand Down Expand Up @@ -762,6 +764,15 @@ void GlobOpt::RecordInlineeFrameInfo(IR::Instr* inlineeEnd)
}
else
{
// If the value of the functionObject symbol has changed between the inlineeStart and the inlineeEnd,
// we don't record the inlinee frame info (see OS#18318884).
Assert(frameInfo->functionSymStartValue != nullptr);
if (!frameInfo->functionSymStartValue->IsEqualTo(CurrentBlockData()->FindValue(functionObject->m_sym)))
{
argInstr->m_func->DisableCanDoInlineArgOpt();
return true;
}

frameInfo->function = InlineFrameInfoValue(functionObject->m_sym);
}
}
Expand Down
3 changes: 3 additions & 0 deletions lib/Backend/InlineeFrameInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#pragma once

class Value;

struct BailoutConstantValue {
public:
void InitIntConstValue(int32 value) { this->type = TyInt32; this->u.intConst.value = (IntConstType)value; };
Expand Down Expand Up @@ -150,6 +152,7 @@ struct InlineeFrameInfo
BVSparse<JitArenaAllocator>* floatSyms;
BVSparse<JitArenaAllocator>* intSyms;
BVSparse<JitArenaAllocator>* varSyms;
Value* functionSymStartValue;

bool isRecorded;

Expand Down
2 changes: 1 addition & 1 deletion lib/Runtime/Base/FunctionBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2105,7 +2105,7 @@ namespace Js
{
FunctionTypeWeakRefList* typeList = EnsureFunctionObjectTypeList();

Assert(functionType != deferredPrototypeType);
Assert(functionType != deferredPrototypeType && functionType != undeferredFunctionType);
Recycler * recycler = this->GetScriptContext()->GetRecycler();
FunctionTypeWeakRef* weakRef = recycler->CreateWeakReferenceHandle(functionType);
typeList->SetAtFirstFreeSpot(weakRef);
Expand Down
6 changes: 4 additions & 2 deletions lib/Runtime/Base/FunctionBody.h
Original file line number Diff line number Diff line change
Expand Up @@ -1088,8 +1088,10 @@ namespace Js
{
func(this->deferredPrototypeType);
}
// NOTE: We deliberately do not map the undeferredFunctionType here, since it's in the list
// of registered function object types we processed above.
if (this->undeferredFunctionType)
{
func(this->undeferredFunctionType);
}
}

static uint GetOffsetOfDeferredPrototypeType() { return static_cast<uint>(offsetof(Js::FunctionProxy, deferredPrototypeType)); }
Expand Down
7 changes: 6 additions & 1 deletion lib/Runtime/Language/JavascriptOperators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4950,13 +4950,18 @@ using namespace Js;
}
else if (instanceType == TypeIds_NativeIntArray)
{
// Only accept tagged int. Also covers case for MissingItem
// Only accept tagged int.
if (!TaggedInt::Is(value))
{
return false;
}
int32 intValue = 0;
if (!MemsetConversion<int32, JavascriptConversion::ToInt32>(value, scriptContext, &intValue))
{
return false;
}
// Special case for missing item
if (SparseArraySegment<int32>::IsMissingItem(&intValue))
{
return false;
}
Expand Down
12 changes: 3 additions & 9 deletions lib/Runtime/Library/JavascriptArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1499,13 +1499,11 @@ using namespace Js;

bool isTaggedInt = TaggedInt::Is(item);
bool isTaggedIntMissingValue = false;
#ifdef TARGET_64
if (isTaggedInt)
{
int32 iValue = TaggedInt::ToInt32(item);
isTaggedIntMissingValue = Js::SparseArraySegment<int32>::IsMissingItem(&iValue);
}
#endif
if (isTaggedInt && !isTaggedIntMissingValue)
{
// This is taggedInt case and we verified that item is not missing value in AMD64.
Expand Down Expand Up @@ -3426,16 +3424,12 @@ using namespace Js;
{
if (TaggedInt::Is(aItem))
{
pDestArray->DirectSetItemAt(idxDest, TaggedInt::ToInt32(aItem));
int32 int32Value = TaggedInt::ToInt32(aItem);
Assert(!SparseArraySegment<int32>::IsMissingItem(&int32Value));
pDestArray->DirectSetItemAt(idxDest, int32Value);
}
else
{
#if DBG
int32 int32Value;
Assert(
JavascriptNumber::TryGetInt32Value(JavascriptNumber::GetValue(aItem), &int32Value) &&
!SparseArraySegment<int32>::IsMissingItem(&int32Value));
#endif
pDestArray->DirectSetItemAt(idxDest, static_cast<int32>(JavascriptNumber::GetValue(aItem)));
}
++idxDest;
Expand Down
3 changes: 3 additions & 0 deletions lib/Runtime/Types/PathTypeHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,9 @@ namespace Js
if (!(attributes[descriptor->GetDataPropertyIndex<false>()] & ObjectSlotAttr_Accessor))
{
// Setter without a getter; this is a stale entry, so ignore it
// Just consume the slot so no descriptor refers to it.
Assert(i == newTypeHandler->nextPropertyIndex);
::Math::PostInc(newTypeHandler->nextPropertyIndex);
continue;
}
Assert(oldTypeHandler->GetSetterSlotIndex(descriptor->GetDataPropertyIndex<false>()) == newTypeHandler->nextPropertyIndex);
Expand Down

0 comments on commit bc9e381

Please sign in to comment.