diff options
author | Michal Klocek <michal.klocek@qt.io> | 2017-05-16 13:04:46 +0200 |
---|---|---|
committer | Michal Klocek <michal.klocek@qt.io> | 2017-07-19 11:04:27 +0000 |
commit | 9966a98c2c90603a7ed3c7bd61609d441b782116 (patch) | |
tree | 5483359e4b97b23ea55117b38a0a2c3e7b812f4f | |
parent | 2c15cc053c4bbb8a3ad3bf9b52c0502cd0a632f8 (diff) |
[Backport] CVE-2017-5054
Merged: [runtime] Ensure that canonical empty dictionaries reallocate upon addition.
Revision: 17ac7c5f4d712c914030e1fb7247d2083b04b929
BUG=chromium:699166
LOG=N
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
Reviewed-on: https://chromium-review.googlesource.com/456703
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/5.8@{#35}
Cr-Branched-From: eda659cc5e307f20ac1ad542ba12ab32eaf4c7ef-refs/heads/5.8.283@{#1}
Cr-Branched-From: 4310cd02d2160b1457baed81a2f40063eb264a21-refs/heads/master@{#43429}
Change-Id: Icb1453cc24519319992629b13846cb46d7e9fc85
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r-- | chromium/v8/src/heap/heap.cc | 4 | ||||
-rw-r--r-- | chromium/v8/src/objects.cc | 26 | ||||
-rw-r--r-- | chromium/v8/src/objects.h | 7 |
3 files changed, 34 insertions, 3 deletions
diff --git a/chromium/v8/src/heap/heap.cc b/chromium/v8/src/heap/heap.cc index 7983d478973..f93adb8b6b8 100644 --- a/chromium/v8/src/heap/heap.cc +++ b/chromium/v8/src/heap/heap.cc @@ -2753,7 +2753,7 @@ void Heap::CreateInitialObjects() { set_intrinsic_function_names(*intrinsic_names); Handle<NameDictionary> empty_properties_dictionary = - NameDictionary::New(isolate(), 0, TENURED); + NameDictionary::NewEmpty(isolate(), TENURED); empty_properties_dictionary->SetRequiresCopyOnCapacityChange(); set_empty_properties_dictionary(*empty_properties_dictionary); @@ -2850,7 +2850,7 @@ void Heap::CreateInitialObjects() { set_script_list(Smi::FromInt(0)); Handle<SeededNumberDictionary> slow_element_dictionary = - SeededNumberDictionary::New(isolate(), 0, TENURED); + SeededNumberDictionary::NewEmpty(isolate(), TENURED); slow_element_dictionary->set_requires_slow_elements(); set_empty_slow_element_dictionary(*slow_element_dictionary); diff --git a/chromium/v8/src/objects.cc b/chromium/v8/src/objects.cc index 5601768da28..9b463de1805 100644 --- a/chromium/v8/src/objects.cc +++ b/chromium/v8/src/objects.cc @@ -17082,7 +17082,13 @@ Handle<Derived> HashTable<Derived, Shape, Key>::New( if (capacity > HashTable::kMaxCapacity) { v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); } + return New(isolate, capacity, pretenure); +} +template <typename Derived, typename Shape, typename Key> +Handle<Derived> HashTable<Derived, Shape, Key>::New(Isolate* isolate, + int capacity, + PretenureFlag pretenure) { Factory* factory = isolate->factory(); int length = EntryToIndex(capacity); Handle<FixedArray> array = factory->NewFixedArray(length, pretenure); @@ -17095,7 +17101,6 @@ Handle<Derived> HashTable<Derived, Shape, Key>::New( return table; } - // Find entry for key otherwise return kNotFound. template <typename Derived, typename Shape> int NameDictionaryBase<Derived, Shape>::FindEntry(Handle<Name> key) { @@ -17363,6 +17368,10 @@ template Handle<SeededNumberDictionary> Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: New(Isolate*, int at_least_space_for, PretenureFlag pretenure); +template Handle<SeededNumberDictionary> +Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, + uint32_t>::NewEmpty(Isolate*, PretenureFlag pretenure); + template Handle<UnseededNumberDictionary> Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: New(Isolate*, int at_least_space_for, PretenureFlag pretenure); @@ -17371,6 +17380,10 @@ template Handle<NameDictionary> Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: New(Isolate*, int n, PretenureFlag pretenure); +template Handle<NameDictionary> +Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::NewEmpty( + Isolate*, PretenureFlag pretenure); + template Handle<GlobalDictionary> Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name> >::New( Isolate*, int n, PretenureFlag pretenure); @@ -18154,6 +18167,17 @@ Handle<FixedArray> Dictionary<Derived, Shape, Key>::BuildIterationIndicesArray( template <typename Derived, typename Shape, typename Key> +Handle<Derived> Dictionary<Derived, Shape, Key>::NewEmpty( + Isolate* isolate, PretenureFlag pretenure) { + Handle<Derived> dict = DerivedHashTable::New(isolate, 1, pretenure); + // Attempt to add one element to the empty dictionary must cause reallocation. + DCHECK(!dict->HasSufficientCapacityToAdd(1)); + // Initialize the next enumeration index. + dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex); + return dict; +} + +template <typename Derived, typename Shape, typename Key> Handle<FixedArray> Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices( Handle<Derived> dictionary) { diff --git a/chromium/v8/src/objects.h b/chromium/v8/src/objects.h index d737a18fe9f..151ab523ddf 100644 --- a/chromium/v8/src/objects.h +++ b/chromium/v8/src/objects.h @@ -3199,6 +3199,9 @@ class HashTable : public HashTableBase { protected: friend class ObjectHashTable; + MUST_USE_RESULT static Handle<Derived> New(Isolate* isolate, int capacity, + PretenureFlag pretenure); + // Find the entry at which to insert element with the given key that // has the given hash value. uint32_t FindInsertionEntry(uint32_t hash); @@ -3415,6 +3418,10 @@ class Dictionary: public HashTable<Derived, Shape, Key> { int at_least_space_for, PretenureFlag pretenure = NOT_TENURED); + // Creates an dictionary with minimal possible capacity. + MUST_USE_RESULT static Handle<Derived> NewEmpty( + Isolate* isolate, PretenureFlag pretenure = NOT_TENURED); + // Ensures that a new dictionary is created when the capacity is checked. void SetRequiresCopyOnCapacityChange(); |