Modified: branches/safari-603-branch/Source/_javascript_Core/ChangeLog (211179 => 211180)
--- branches/safari-603-branch/Source/_javascript_Core/ChangeLog 2017-01-26 01:01:12 UTC (rev 211179)
+++ branches/safari-603-branch/Source/_javascript_Core/ChangeLog 2017-01-26 01:40:37 UTC (rev 211180)
@@ -1,3 +1,27 @@
+2017-01-25 Matthew Hanson <[email protected]>
+
+ Merge r211124. rdar://problem/30156092
+
+ 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-25 Dean Jackson <[email protected]>
Disable Variation fonts on this branch.
Modified: branches/safari-603-branch/Source/_javascript_Core/runtime/InferredTypeTable.cpp (211179 => 211180)
--- branches/safari-603-branch/Source/_javascript_Core/runtime/InferredTypeTable.cpp 2017-01-26 01:01:12 UTC (rev 211179)
+++ branches/safari-603-branch/Source/_javascript_Core/runtime/InferredTypeTable.cpp 2017-01-26 01:40:37 UTC (rev 211180)
@@ -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;
}