Title: [233625] trunk/Source/_javascript_Core
Revision
233625
Author
[email protected]
Date
2018-07-08 02:54:51 -0700 (Sun, 08 Jul 2018)

Log Message

PropertyTable::skipDeletedEntries() should guard against iterating past the table end.
https://bugs.webkit.org/show_bug.cgi?id=187444
<rdar://problem/41282849>

Reviewed by Saam Barati.

PropertyTable supports C++ iteration by offering begin() and end() methods, and
an iterator class.  The begin() methods and the iterator operator++() method uses
PropertyTable::skipDeletedEntries() to skip over deleted entries in the table.
However, PropertyTable::skipDeletedEntries() does not prevent the iteration
pointer from being incremented past the end of the table.  As a result, we can
iterate past the end of the table.  Note that the C++ iteration protocol tests
for the iterator not being equal to the end() value.  It does not do a <= test.
If the iterator ever shoots past end, the loop will effectively not terminate.

This issue can manifest if and only if the last entry in the table is a deleted
one, and the key field of the PropertyMapEntry shaped space at the end of the
table (the one beyond the last) contains a 1 (i.e. PROPERTY_MAP_DELETED_ENTRY_KEY)
value.

No test because manifesting this issue requires uncontrollable happenstance where
memory just beyond the end of the table looks like a deleted entry.

* runtime/PropertyMapHashTable.h:
(JSC::PropertyTable::begin):
(JSC::PropertyTable::end):
(JSC::PropertyTable::begin const):
(JSC::PropertyTable::end const):
(JSC::PropertyTable::skipDeletedEntries):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (233624 => 233625)


--- trunk/Source/_javascript_Core/ChangeLog	2018-07-07 22:29:08 UTC (rev 233624)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-07-08 09:54:51 UTC (rev 233625)
@@ -1,3 +1,35 @@
+2018-07-08  Mark Lam  <[email protected]>
+
+        PropertyTable::skipDeletedEntries() should guard against iterating past the table end.
+        https://bugs.webkit.org/show_bug.cgi?id=187444
+        <rdar://problem/41282849>
+
+        Reviewed by Saam Barati.
+
+        PropertyTable supports C++ iteration by offering begin() and end() methods, and
+        an iterator class.  The begin() methods and the iterator operator++() method uses
+        PropertyTable::skipDeletedEntries() to skip over deleted entries in the table.
+        However, PropertyTable::skipDeletedEntries() does not prevent the iteration
+        pointer from being incremented past the end of the table.  As a result, we can
+        iterate past the end of the table.  Note that the C++ iteration protocol tests
+        for the iterator not being equal to the end() value.  It does not do a <= test.
+        If the iterator ever shoots past end, the loop will effectively not terminate.
+
+        This issue can manifest if and only if the last entry in the table is a deleted
+        one, and the key field of the PropertyMapEntry shaped space at the end of the
+        table (the one beyond the last) contains a 1 (i.e. PROPERTY_MAP_DELETED_ENTRY_KEY)
+        value.
+
+        No test because manifesting this issue requires uncontrollable happenstance where
+        memory just beyond the end of the table looks like a deleted entry.
+
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::begin):
+        (JSC::PropertyTable::end):
+        (JSC::PropertyTable::begin const):
+        (JSC::PropertyTable::end const):
+        (JSC::PropertyTable::skipDeletedEntries):
+
 2018-07-07  Yusuke Suzuki  <[email protected]>
 
         [JSC] Optimize layout of SymbolTable to reduce padding

Modified: trunk/Source/_javascript_Core/runtime/PropertyMapHashTable.h (233624 => 233625)


--- trunk/Source/_javascript_Core/runtime/PropertyMapHashTable.h	2018-07-07 22:29:08 UTC (rev 233624)
+++ trunk/Source/_javascript_Core/runtime/PropertyMapHashTable.h	2018-07-08 09:54:51 UTC (rev 233625)
@@ -84,7 +84,7 @@
     public:
         ordered_iterator<T>& operator++()
         {
-            m_valuePtr = skipDeletedEntries(m_valuePtr + 1);
+            m_valuePtr = skipDeletedEntries(m_valuePtr + 1, m_endValuePtr);
             return *this;
         }
 
@@ -108,13 +108,15 @@
             return m_valuePtr;
         }
 
-        ordered_iterator(T* valuePtr)
+        ordered_iterator(T* valuePtr, T* endValuePtr)
             : m_valuePtr(valuePtr)
+            , m_endValuePtr(endValuePtr)
         {
         }
 
     private:
         T* m_valuePtr;
+        T* m_endValuePtr;
     };
 
 public:
@@ -228,12 +230,15 @@
 
     // Used in iterator creation/progression.
     template<typename T>
-    static T* skipDeletedEntries(T* valuePtr);
+    static T* skipDeletedEntries(T* valuePtr, T* endValuePtr);
 
     // The table of values lies after the hash index.
     ValueType* table();
     const ValueType* table() const;
 
+    ValueType* tableEnd() { return table() + usedCount(); }
+    const ValueType* tableEnd() const { return table() + usedCount(); }
+
     // total number of  used entries in the values array - by either valid entries, or deleted ones.
     unsigned usedCount() const;
 
@@ -258,22 +263,26 @@
 
 inline PropertyTable::iterator PropertyTable::begin()
 {
-    return iterator(skipDeletedEntries(table()));
+    auto* tableEnd = this->tableEnd();
+    return iterator(skipDeletedEntries(table(), tableEnd), tableEnd);
 }
 
 inline PropertyTable::iterator PropertyTable::end()
 {
-    return iterator(table() + usedCount());
+    auto* tableEnd = this->tableEnd();
+    return iterator(tableEnd, tableEnd);
 }
 
 inline PropertyTable::const_iterator PropertyTable::begin() const
 {
-    return const_iterator(skipDeletedEntries(table()));
+    auto* tableEnd = this->tableEnd();
+    return const_iterator(skipDeletedEntries(table(), tableEnd), tableEnd);
 }
 
 inline PropertyTable::const_iterator PropertyTable::end() const
 {
-    return const_iterator(table() + usedCount());
+    auto* tableEnd = this->tableEnd();
+    return const_iterator(tableEnd, tableEnd);
 }
 
 inline PropertyTable::find_iterator PropertyTable::find(const KeyType& key)
@@ -520,9 +529,9 @@
 inline unsigned PropertyTable::deletedEntryIndex() const { return tableCapacity() + 1; }
 
 template<typename T>
-inline T* PropertyTable::skipDeletedEntries(T* valuePtr)
+inline T* PropertyTable::skipDeletedEntries(T* valuePtr, T* endValuePtr)
 {
-    while (valuePtr->key == PROPERTY_MAP_DELETED_ENTRY_KEY)
+    while (valuePtr < endValuePtr && valuePtr->key == PROPERTY_MAP_DELETED_ENTRY_KEY)
         ++valuePtr;
     return valuePtr;
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to