Changeset 211124 in webkit


Ignore:
Timestamp:
Jan 24, 2017, 5:04:26 PM (9 years ago)
Author:
msaboff@apple.com
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):

Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r211122 r211124  
     12017-01-24  Michael Saboff  <msaboff@apple.com>
     2
     3        InferredTypeTable entry manipulation is not TOCTOU race safe
     4        https://bugs.webkit.org/show_bug.cgi?id=167344
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Made the accesses to table values safe from Time of Check,
     9        Time of Use races with local temporary values.
     10
     11        Fixed point that we set an entry in the table to access the
     12        current table entry instead of using the local entry.  In that case,
     13        we reload the now changed entry.
     14
     15        * runtime/InferredTypeTable.cpp:
     16        (JSC::InferredTypeTable::visitChildren):
     17        (JSC::InferredTypeTable::get):
     18        (JSC::InferredTypeTable::willStoreValue):
     19        (JSC::InferredTypeTable::makeTop):
     20
    1212017-01-24  Filip Pizlo  <fpizlo@apple.com>
    222
  • trunk/Source/JavaScriptCore/runtime/InferredTypeTable.cpp

    r211112 r211124  
    5858   
    5959    for (auto& entry : inferredTypeTable->m_table) {
    60         if (!entry.value)
     60        auto entryValue = entry.value;
     61
     62        if (!entryValue)
    6163            continue;
    62         if (entry.value->isRelevant())
    63             visitor.append(entry.value);
     64        if (entryValue->isRelevant())
     65            visitor.append(entryValue);
    6466        else
    6567            entry.value.clear();
     
    7072{
    7173    auto iter = m_table.find(uid);
    72     if (iter == m_table.end() || !iter->value)
     74    if (iter == m_table.end())
     75        return nullptr;
     76
     77    InferredType* entryValue = iter->value.get();
     78    if (!entryValue)
    7379        return nullptr;
    7480
    7581    // Take this opportunity to prune invalidated types.
    76     if (!iter->value->isRelevant()) {
     82    if (!entryValue->isRelevant()) {
    7783        iter->value.clear();
    7884        return nullptr;
    7985    }
    8086
    81     return iter->value.get();
     87    return entryValue;
    8288}
    8389
     
    100106    if (age == OldProperty) {
    101107        TableType::iterator iter = m_table.find(propertyName.uid());
    102         if (iter == m_table.end() || !iter->value)
     108        if (iter == m_table.end())
    103109            return false; // Absence on replace => top.
     110
     111        InferredType* entryValue = iter->value.get();
     112        if (!entryValue)
     113            return false;
    104114       
    105         if (iter->value->willStoreValue(vm, propertyName, value))
     115        if (entryValue->willStoreValue(vm, propertyName, value))
    106116            return true;
    107117       
     
    115125        result = m_table.add(propertyName.uid(), WriteBarrier<InferredType>());
    116126    }
     127    InferredType* entryValue = result.iterator->value.get();
     128
    117129    if (result.isNewEntry) {
    118130        InferredType* inferredType = InferredType::create(vm);
    119131        WTF::storeStoreFence();
    120132        result.iterator->value.set(vm, this, inferredType);
    121     } else if (!result.iterator->value)
     133        entryValue = inferredType;
     134    } else if (!entryValue)
    122135        return false;
    123136   
    124     if (result.iterator->value->willStoreValue(vm, propertyName, value))
     137    if (entryValue->willStoreValue(vm, propertyName, value))
    125138        return true;
    126139   
     
    134147    if (age == OldProperty) {
    135148        TableType::iterator iter = m_table.find(propertyName.uid());
    136         if (iter == m_table.end() || !iter->value)
     149        if (iter == m_table.end())
    137150            return; // Absence on replace => top.
    138151
    139         iter->value->makeTop(vm, propertyName);
     152        InferredType* entryValue = iter->value.get();
     153
     154        if (!entryValue)
     155            return;
     156
     157        entryValue->makeTop(vm, propertyName);
    140158        iter->value.clear();
    141159        return;
Note: See TracChangeset for help on using the changeset viewer.