Title: [211124] trunk/Source/_javascript_Core
Revision
211124
Author
[email protected]
Date
2017-01-24 17:04:26 -0800 (Tue, 24 Jan 2017)

Log Message

InferredTypeTable entry manipulation is not TOCTOU race safe
https://bugs.webkit.org/show_bug.cgi?id=167344

Reviewed by Filip Pizlo.

Made the accesses to table values safe from Time of Check,
Time of Use races with local temporary values.

Fixed point that we set an entry in the table to access the
current table entry instead of using the local entry.  In that case,
we reload the now changed entry.

* runtime/InferredTypeTable.cpp:
(JSC::InferredTypeTable::visitChildren):
(JSC::InferredTypeTable::get):
(JSC::InferredTypeTable::willStoreValue):
(JSC::InferredTypeTable::makeTop):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (211123 => 211124)


--- trunk/Source/_javascript_Core/ChangeLog	2017-01-25 00:55:10 UTC (rev 211123)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-01-25 01:04:26 UTC (rev 211124)
@@ -1,3 +1,23 @@
+2017-01-24  Michael Saboff  <[email protected]>
+
+        InferredTypeTable entry manipulation is not TOCTOU race safe
+        https://bugs.webkit.org/show_bug.cgi?id=167344
+
+        Reviewed by Filip Pizlo.
+
+        Made the accesses to table values safe from Time of Check,
+        Time of Use races with local temporary values.
+
+        Fixed point that we set an entry in the table to access the
+        current table entry instead of using the local entry.  In that case,
+        we reload the now changed entry.
+
+        * runtime/InferredTypeTable.cpp:
+        (JSC::InferredTypeTable::visitChildren):
+        (JSC::InferredTypeTable::get):
+        (JSC::InferredTypeTable::willStoreValue):
+        (JSC::InferredTypeTable::makeTop):
+
 2017-01-24  Filip Pizlo  <[email protected]>
 
         Atomics.store should return the int-converted value, not the value that it stored

Modified: trunk/Source/_javascript_Core/runtime/InferredTypeTable.cpp (211123 => 211124)


--- trunk/Source/_javascript_Core/runtime/InferredTypeTable.cpp	2017-01-25 00:55:10 UTC (rev 211123)
+++ trunk/Source/_javascript_Core/runtime/InferredTypeTable.cpp	2017-01-25 01:04:26 UTC (rev 211124)
@@ -57,10 +57,12 @@
     ConcurrentJSLocker locker(inferredTypeTable->m_lock);
     
     for (auto& entry : inferredTypeTable->m_table) {
-        if (!entry.value)
+        auto entryValue = entry.value;
+
+        if (!entryValue)
             continue;
-        if (entry.value->isRelevant())
-            visitor.append(entry.value);
+        if (entryValue->isRelevant())
+            visitor.append(entryValue);
         else
             entry.value.clear();
     }
@@ -69,16 +71,20 @@
 InferredType* InferredTypeTable::get(const ConcurrentJSLocker&, UniquedStringImpl* uid)
 {
     auto iter = m_table.find(uid);
-    if (iter == m_table.end() || !iter->value)
+    if (iter == m_table.end())
         return nullptr;
 
+    InferredType* entryValue = iter->value.get();
+    if (!entryValue)
+        return nullptr;
+
     // Take this opportunity to prune invalidated types.
-    if (!iter->value->isRelevant()) {
+    if (!entryValue->isRelevant()) {
         iter->value.clear();
         return nullptr;
     }
 
-    return iter->value.get();
+    return entryValue;
 }
 
 InferredType* InferredTypeTable::get(UniquedStringImpl* uid)
@@ -99,10 +105,14 @@
     
     if (age == OldProperty) {
         TableType::iterator iter = m_table.find(propertyName.uid());
-        if (iter == m_table.end() || !iter->value)
+        if (iter == m_table.end())
             return false; // Absence on replace => top.
+
+        InferredType* entryValue = iter->value.get();
+        if (!entryValue)
+            return false;
         
-        if (iter->value->willStoreValue(vm, propertyName, value))
+        if (entryValue->willStoreValue(vm, propertyName, value))
             return true;
         
         iter->value.clear();
@@ -114,14 +124,17 @@
         ConcurrentJSLocker locker(m_lock);
         result = m_table.add(propertyName.uid(), WriteBarrier<InferredType>());
     }
+    InferredType* entryValue = result.iterator->value.get();
+
     if (result.isNewEntry) {
         InferredType* inferredType = InferredType::create(vm);
         WTF::storeStoreFence();
         result.iterator->value.set(vm, this, inferredType);
-    } else if (!result.iterator->value)
+        entryValue = inferredType;
+    } else if (!entryValue)
         return false;
     
-    if (result.iterator->value->willStoreValue(vm, propertyName, value))
+    if (entryValue->willStoreValue(vm, propertyName, value))
         return true;
     
     result.iterator->value.clear();
@@ -133,10 +146,15 @@
     // The algorithm here relies on the fact that only one thread modifies the hash map.
     if (age == OldProperty) {
         TableType::iterator iter = m_table.find(propertyName.uid());
-        if (iter == m_table.end() || !iter->value)
+        if (iter == m_table.end())
             return; // Absence on replace => top.
 
-        iter->value->makeTop(vm, propertyName);
+        InferredType* entryValue = iter->value.get();
+
+        if (!entryValue)
+            return;
+
+        entryValue->makeTop(vm, propertyName);
         iter->value.clear();
         return;
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to