Skip to content

Commit 91dc6f8

Browse files
mcgovrajatd
authored andcommitted
[CVE-2018-0990] Edge - UAF leads to potential RCE in latest version - Qihoo 360
1 parent 2637140 commit 91dc6f8

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

lib/Runtime/Types/DictionaryTypeHandler.cpp

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -716,9 +716,14 @@ namespace Js
716716

717717
template <typename T>
718718
template <bool allowLetConstGlobal>
719-
void DictionaryTypeHandlerBase<T>::SetPropertyWithDescriptor(DynamicObject* instance, PropertyId propertyId, DictionaryPropertyDescriptor<T> * descriptor,
719+
void DictionaryTypeHandlerBase<T>::SetPropertyWithDescriptor(DynamicObject* instance,
720+
PropertyRecord const* propertyRecord,
721+
DictionaryPropertyDescriptor<T> ** pdescriptor,
720722
Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
721723
{
724+
Assert(pdescriptor && *pdescriptor);
725+
DictionaryPropertyDescriptor<T> * descriptor = *pdescriptor;
726+
PropertyId propertyId = propertyRecord->GetPropertyId();
722727
Assert(instance);
723728
Assert((descriptor->Attributes & PropertyDeleted) == 0 || (allowLetConstGlobal && descriptor->IsShadowed));
724729

@@ -784,14 +789,23 @@ namespace Js
784789

785790
// Wait for the setter to return before setting up the inline cache info, as the setter may change
786791
// the attributes
787-
T dataSlot = descriptor->template GetDataPropertyIndex<false>();
788-
if (dataSlot != NoSlots)
792+
793+
if (propertyMap->TryGetReference(propertyRecord, pdescriptor))
789794
{
790-
SetPropertyValueInfo(info, instance, dataSlot, descriptor->Attributes);
795+
descriptor = *pdescriptor;
796+
T dataSlot = descriptor->template GetDataPropertyIndex<false>();
797+
if (dataSlot != NoSlots)
798+
{
799+
SetPropertyValueInfo(info, instance, dataSlot, descriptor->Attributes);
800+
}
801+
else if (descriptor->GetSetterPropertyIndex() != NoSlots)
802+
{
803+
SetPropertyValueInfo(info, instance, descriptor->GetSetterPropertyIndex(), descriptor->Attributes, InlineCacheSetterFlag);
804+
}
791805
}
792-
else if (descriptor->GetSetterPropertyIndex() != NoSlots)
806+
else
793807
{
794-
SetPropertyValueInfo(info, instance, descriptor->GetSetterPropertyIndex(), descriptor->Attributes, InlineCacheSetterFlag);
808+
*pdescriptor = nullptr;
795809
}
796810
}
797811
SetPropertyUpdateSideEffect(instance, propertyId, value, SideEffects_Any);
@@ -854,7 +868,7 @@ namespace Js
854868
{
855869
descriptor->ConvertToData();
856870
}
857-
SetPropertyWithDescriptor<allowLetConstGlobal>(instance, propertyId, descriptor, value, flags, info);
871+
SetPropertyWithDescriptor<allowLetConstGlobal>(instance, propertyRecord, &descriptor, value, flags, info);
858872
return true;
859873
}
860874

@@ -1895,25 +1909,26 @@ namespace Js
18951909

18961910
if (attributes & PropertyLetConstGlobal)
18971911
{
1898-
SetPropertyWithDescriptor<true>(instance, propertyId, descriptor, value, flags, info);
1912+
SetPropertyWithDescriptor<true>(instance, propertyRecord, &descriptor, value, flags, info);
18991913
}
19001914
else
19011915
{
1902-
SetPropertyWithDescriptor<false>(instance, propertyId, descriptor, value, flags, info);
1916+
SetPropertyWithDescriptor<false>(instance, propertyRecord, &descriptor, value, flags, info);
19031917
}
1904-
1905-
if (descriptor->Attributes & PropertyEnumerable)
1918+
if (descriptor != nullptr) //descriptor can dissappear, so this reference may not exist.
19061919
{
1907-
instance->SetHasNoEnumerableProperties(false);
1908-
}
1909-
1910-
if (!(descriptor->Attributes & PropertyWritable))
1911-
{
1912-
this->ClearHasOnlyWritableDataProperties();
1913-
if(GetFlags() & IsPrototypeFlag)
1920+
if (descriptor->Attributes & PropertyEnumerable)
19141921
{
1915-
scriptContext->InvalidateStoreFieldCaches(propertyId);
1916-
instance->GetLibrary()->NoPrototypeChainsAreEnsuredToHaveOnlyWritableDataProperties();
1922+
instance->SetHasNoEnumerableProperties(false);
1923+
}
1924+
if (!(descriptor->Attributes & PropertyWritable))
1925+
{
1926+
this->ClearHasOnlyWritableDataProperties();
1927+
if (GetFlags() & IsPrototypeFlag)
1928+
{
1929+
scriptContext->InvalidateStoreFieldCaches(propertyId);
1930+
instance->GetLibrary()->NoPrototypeChainsAreEnsuredToHaveOnlyWritableDataProperties();
1931+
}
19171932
}
19181933
}
19191934

lib/Runtime/Types/DictionaryTypeHandler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ namespace Js
247247
template<bool allowLetConstGlobal>
248248
inline DescriptorFlags GetSetterFromDescriptor(DynamicObject* instance, DictionaryPropertyDescriptor<T> * descriptor, Var* setterValue, PropertyValueInfo* info);
249249
template <bool allowLetConstGlobal>
250-
inline void SetPropertyWithDescriptor(DynamicObject* instance, PropertyId propertyId, DictionaryPropertyDescriptor<T> * descriptor,
250+
inline void SetPropertyWithDescriptor(DynamicObject* instance, PropertyRecord const* propertyRecord, DictionaryPropertyDescriptor<T> ** pdescriptor,
251251
Var value, PropertyOperationFlags flags, PropertyValueInfo* info);
252252

253253
protected:

0 commit comments

Comments
 (0)