Skip to content

Commit d52c72d

Browse files
pleathaneeshdk
authored andcommitted
[CVE-2018-8266] Edge - RCE bug in Microsoft Edge - Individual
1 parent 63ae30a commit d52c72d

File tree

5 files changed

+54
-8
lines changed

5 files changed

+54
-8
lines changed

lib/Backend/BackwardPass.cpp

Lines changed: 5 additions & 0 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))

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/GlobOptFields.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -788,17 +788,34 @@ GlobOpt::FinishOptPropOp(IR::Instr *instr, IR::PropertySymOpnd *opnd, BasicBlock
788788
{
789789
this->KillObjectHeaderInlinedTypeSyms(block, isObjTypeSpecialized, opndId);
790790
}
791+
else if (!isObjTypeChecked && this->HasLiveObjectHeaderInlinedTypeSym(block, true, opndId))
792+
{
793+
opnd->SetTypeCheckRequired(true);
794+
}
791795
}
792796

793797
return isObjTypeSpecialized;
794798
}
795799

796800
void
797801
GlobOpt::KillObjectHeaderInlinedTypeSyms(BasicBlock *block, bool isObjTypeSpecialized, SymID opndId)
802+
{
803+
this->MapObjectHeaderInlinedTypeSymsUntil(block, isObjTypeSpecialized, opndId, [&](SymID symId)->bool { this->currentBlock->globOptData.liveFields->Clear(symId); return false; });
804+
}
805+
806+
bool
807+
GlobOpt::HasLiveObjectHeaderInlinedTypeSym(BasicBlock *block, bool isObjTypeSpecialized, SymID opndId)
808+
{
809+
return this->MapObjectHeaderInlinedTypeSymsUntil(block, true, opndId, [&](SymID symId)->bool { return this->currentBlock->globOptData.liveFields->Test(symId); });
810+
}
811+
812+
template<class Fn>
813+
bool
814+
GlobOpt::MapObjectHeaderInlinedTypeSymsUntil(BasicBlock *block, bool isObjTypeSpecialized, SymID opndId, Fn fn)
798815
{
799816
if (this->objectTypeSyms == nullptr)
800817
{
801-
return;
818+
return false;
802819
}
803820

804821
FOREACH_BITSET_IN_SPARSEBV(symId, this->objectTypeSyms)
@@ -821,7 +838,10 @@ GlobOpt::KillObjectHeaderInlinedTypeSyms(BasicBlock *block, bool isObjTypeSpecia
821838
{
822839
if (type->GetTypeHandler()->IsObjectHeaderInlinedTypeHandler())
823840
{
824-
this->currentBlock->globOptData.liveFields->Clear(symId);
841+
if (fn(symId))
842+
{
843+
return true;
844+
}
825845
}
826846
}
827847
}
@@ -835,7 +855,10 @@ GlobOpt::KillObjectHeaderInlinedTypeSyms(BasicBlock *block, bool isObjTypeSpecia
835855
{
836856
if (type->GetTypeHandler()->IsObjectHeaderInlinedTypeHandler())
837857
{
838-
this->currentBlock->globOptData.liveFields->Clear(symId);
858+
if (fn(symId))
859+
{
860+
return true;
861+
}
839862
break;
840863
}
841864
}
@@ -844,6 +867,8 @@ GlobOpt::KillObjectHeaderInlinedTypeSyms(BasicBlock *block, bool isObjTypeSpecia
844867
}
845868
}
846869
NEXT_BITSET_IN_SPARSEBV;
870+
871+
return false;
847872
}
848873

849874
bool

lib/Backend/Lower.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7380,7 +7380,7 @@ Lowerer::GenerateStFldWithCachedType(IR::Instr *instrStFld, bool* continueAsHelp
73807380

73817381
if (hasTypeCheckBailout)
73827382
{
7383-
AssertMsg(PHASE_ON1(Js::ObjTypeSpecIsolatedFldOpsWithBailOutPhase) || !propertySymOpnd->IsTypeDead(),
7383+
AssertMsg(PHASE_ON1(Js::ObjTypeSpecIsolatedFldOpsWithBailOutPhase) || !propertySymOpnd->IsTypeDead() || propertySymOpnd->TypeCheckRequired(),
73847384
"Why does a field store have a type check bailout, if its type is dead?");
73857385

73867386
if (instrStFld->GetBailOutInfo()->bailOutInstr != instrStFld)
@@ -7442,10 +7442,11 @@ Lowerer::GenerateCachedTypeCheck(IR::Instr *instrChk, IR::PropertySymOpnd *prope
74427442
// cache and no type check bailout. In the latter case, we can wind up doing expensive failed equivalence checks
74437443
// repeatedly and never rejit.
74447444
bool doEquivTypeCheck =
7445-
propertySymOpnd->HasEquivalentTypeSet() &&
7446-
!(propertySymOpnd->HasFinalType() && propertySymOpnd->HasInitialType()) &&
7447-
!propertySymOpnd->MustDoMonoCheck() &&
7448-
(propertySymOpnd->IsPoly() || instrChk->HasTypeCheckBailOut());
7445+
(instrChk->HasEquivalentTypeCheckBailOut() && propertySymOpnd->TypeCheckRequired()) ||
7446+
(propertySymOpnd->HasEquivalentTypeSet() &&
7447+
!(propertySymOpnd->HasFinalType() && propertySymOpnd->HasInitialType()) &&
7448+
!propertySymOpnd->MustDoMonoCheck() &&
7449+
(propertySymOpnd->IsPoly() || instrChk->HasTypeCheckBailOut()));
74497450
Assert(doEquivTypeCheck || !instrChk->HasEquivalentTypeCheckBailOut());
74507451

74517452
// Create and initialize the property guard if required. Note that for non-shared monomorphic checks we can refer

lib/Backend/Opnd.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ class PropertySymOpnd sealed : public SymOpnd
647647
bool initialTypeChecked: 1;
648648
bool typeMismatch: 1;
649649
bool writeGuardChecked: 1;
650+
bool typeCheckRequired: 1;
650651
};
651652
uint8 typeCheckSeqFlags;
652653
};
@@ -1014,6 +1015,17 @@ class PropertySymOpnd sealed : public SymOpnd
10141015
this->writeGuardChecked = value;
10151016
}
10161017

1018+
bool TypeCheckRequired() const
1019+
{
1020+
return this->typeCheckRequired;
1021+
}
1022+
1023+
void SetTypeCheckRequired(bool value)
1024+
{
1025+
Assert(IsTypeCheckSeqCandidate());
1026+
this->typeCheckRequired = value;
1027+
}
1028+
10171029
uint16 GetObjTypeSpecFlags() const
10181030
{
10191031
return this->objTypeSpecFlags;

0 commit comments

Comments
 (0)