From 91dc6f8599979f2beba46e329be70f0788fa0889 Mon Sep 17 00:00:00 2001 From: Matthew McGovern Date: Wed, 4 Apr 2018 15:37:37 -0700 Subject: [PATCH] [CVE-2018-0990] Edge - UAF leads to potential RCE in latest version - Qihoo 360 --- lib/Runtime/Types/DictionaryTypeHandler.cpp | 55 +++++++++++++-------- lib/Runtime/Types/DictionaryTypeHandler.h | 2 +- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/lib/Runtime/Types/DictionaryTypeHandler.cpp b/lib/Runtime/Types/DictionaryTypeHandler.cpp index 7dd7a1432a6..cd3641b73ba 100644 --- a/lib/Runtime/Types/DictionaryTypeHandler.cpp +++ b/lib/Runtime/Types/DictionaryTypeHandler.cpp @@ -716,9 +716,14 @@ namespace Js template template - void DictionaryTypeHandlerBase::SetPropertyWithDescriptor(DynamicObject* instance, PropertyId propertyId, DictionaryPropertyDescriptor * descriptor, + void DictionaryTypeHandlerBase::SetPropertyWithDescriptor(DynamicObject* instance, + PropertyRecord const* propertyRecord, + DictionaryPropertyDescriptor ** pdescriptor, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) { + Assert(pdescriptor && *pdescriptor); + DictionaryPropertyDescriptor * descriptor = *pdescriptor; + PropertyId propertyId = propertyRecord->GetPropertyId(); Assert(instance); Assert((descriptor->Attributes & PropertyDeleted) == 0 || (allowLetConstGlobal && descriptor->IsShadowed)); @@ -784,14 +789,23 @@ namespace Js // Wait for the setter to return before setting up the inline cache info, as the setter may change // the attributes - T dataSlot = descriptor->template GetDataPropertyIndex(); - if (dataSlot != NoSlots) + + if (propertyMap->TryGetReference(propertyRecord, pdescriptor)) { - SetPropertyValueInfo(info, instance, dataSlot, descriptor->Attributes); + descriptor = *pdescriptor; + T dataSlot = descriptor->template GetDataPropertyIndex(); + if (dataSlot != NoSlots) + { + SetPropertyValueInfo(info, instance, dataSlot, descriptor->Attributes); + } + else if (descriptor->GetSetterPropertyIndex() != NoSlots) + { + SetPropertyValueInfo(info, instance, descriptor->GetSetterPropertyIndex(), descriptor->Attributes, InlineCacheSetterFlag); + } } - else if (descriptor->GetSetterPropertyIndex() != NoSlots) + else { - SetPropertyValueInfo(info, instance, descriptor->GetSetterPropertyIndex(), descriptor->Attributes, InlineCacheSetterFlag); + *pdescriptor = nullptr; } } SetPropertyUpdateSideEffect(instance, propertyId, value, SideEffects_Any); @@ -854,7 +868,7 @@ namespace Js { descriptor->ConvertToData(); } - SetPropertyWithDescriptor(instance, propertyId, descriptor, value, flags, info); + SetPropertyWithDescriptor(instance, propertyRecord, &descriptor, value, flags, info); return true; } @@ -1895,25 +1909,26 @@ namespace Js if (attributes & PropertyLetConstGlobal) { - SetPropertyWithDescriptor(instance, propertyId, descriptor, value, flags, info); + SetPropertyWithDescriptor(instance, propertyRecord, &descriptor, value, flags, info); } else { - SetPropertyWithDescriptor(instance, propertyId, descriptor, value, flags, info); + SetPropertyWithDescriptor(instance, propertyRecord, &descriptor, value, flags, info); } - - if (descriptor->Attributes & PropertyEnumerable) + if (descriptor != nullptr) //descriptor can dissappear, so this reference may not exist. { - instance->SetHasNoEnumerableProperties(false); - } - - if (!(descriptor->Attributes & PropertyWritable)) - { - this->ClearHasOnlyWritableDataProperties(); - if(GetFlags() & IsPrototypeFlag) + if (descriptor->Attributes & PropertyEnumerable) { - scriptContext->InvalidateStoreFieldCaches(propertyId); - instance->GetLibrary()->NoPrototypeChainsAreEnsuredToHaveOnlyWritableDataProperties(); + instance->SetHasNoEnumerableProperties(false); + } + if (!(descriptor->Attributes & PropertyWritable)) + { + this->ClearHasOnlyWritableDataProperties(); + if (GetFlags() & IsPrototypeFlag) + { + scriptContext->InvalidateStoreFieldCaches(propertyId); + instance->GetLibrary()->NoPrototypeChainsAreEnsuredToHaveOnlyWritableDataProperties(); + } } } diff --git a/lib/Runtime/Types/DictionaryTypeHandler.h b/lib/Runtime/Types/DictionaryTypeHandler.h index 86a40e8c9cb..813be74d3ea 100644 --- a/lib/Runtime/Types/DictionaryTypeHandler.h +++ b/lib/Runtime/Types/DictionaryTypeHandler.h @@ -247,7 +247,7 @@ namespace Js template inline DescriptorFlags GetSetterFromDescriptor(DynamicObject* instance, DictionaryPropertyDescriptor * descriptor, Var* setterValue, PropertyValueInfo* info); template - inline void SetPropertyWithDescriptor(DynamicObject* instance, PropertyId propertyId, DictionaryPropertyDescriptor * descriptor, + inline void SetPropertyWithDescriptor(DynamicObject* instance, PropertyRecord const* propertyRecord, DictionaryPropertyDescriptor ** pdescriptor, Var value, PropertyOperationFlags flags, PropertyValueInfo* info); protected: