Changeset 252674 in webkit


Ignore:
Timestamp:
Nov 19, 2019 6:28:52 PM (4 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] MetadataTable::sizeInBytes should not touch m_rawBuffer in UnlinkedMetadataTable unless MetadataTable is linked to that UnlinkedMetadataTable
https://bugs.webkit.org/show_bug.cgi?id=204390

Reviewed by Mark Lam.

We have a race issue here. When calling MetadataTable::sizeInBytes, we call UnlinkedMetadataTable::sizeInBytes since we change the result based on
whether this MetadataTable is linked to this UnlinkedMetadataTable or not. The problem is that we are calling UnlinkedMetadataTable::totalSize
unconditionally in UnlinkedMetadataTable::sizeInBytes, and this is touching m_rawBuffer unconditionally. This is not correct since it is possible
that this m_rawBuffer is realloced while we are calling MetadataTable::sizeInBytes in GC thread.

  1. The GC thread is calling MetadataTable::sizeInBytes for MetadataTable "A".
  2. The main thread is destroying MetadataTable "B".
  3. MetadataTable "B" is linked to UnlinkedMetadataTable "C".
  4. MetadataTable "A" is pointing to UnlinkedMetadataTable "C".
  5. "A" is touching UnlinkedMetadataTable::m_rawBuffer in "C", called from MetadataTable::sizeInBytes.
  6. (2) destroys MetadataTable "B", and realloc UnlinkedMetadataTable::m_rawBuffer in "C".
  7. (5) can touch already freed buffer.

This patch fixes UnlinkedMetadataTable::sizeInBytes: not touching m_rawBuffer unless it is owned by the caller's MetadataTable. We need to call
UnlinkedMetadataTable::sizeInBytes anyway since we need to adjust the result based on whether the caller MetadataTable is linked to this UnlinkedMetadataTable.

  • bytecode/UnlinkedMetadataTableInlines.h:

(JSC::UnlinkedMetadataTable::sizeInBytes):

Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r252671 r252674  
     12019-11-19  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] MetadataTable::sizeInBytes should not touch m_rawBuffer in UnlinkedMetadataTable unless MetadataTable is linked to that UnlinkedMetadataTable
     4        https://bugs.webkit.org/show_bug.cgi?id=204390
     5
     6        Reviewed by Mark Lam.
     7
     8        We have a race issue here. When calling MetadataTable::sizeInBytes, we call UnlinkedMetadataTable::sizeInBytes since we change the result based on
     9        whether this MetadataTable is linked to this UnlinkedMetadataTable or not. The problem is that we are calling `UnlinkedMetadataTable::totalSize`
     10        unconditionally in UnlinkedMetadataTable::sizeInBytes, and this is touching m_rawBuffer unconditionally. This is not correct since it is possible
     11        that this m_rawBuffer is realloced while we are calling MetadataTable::sizeInBytes in GC thread.
     12
     13            1. The GC thread is calling MetadataTable::sizeInBytes for MetadataTable "A".
     14            2. The main thread is destroying MetadataTable "B".
     15            3. MetadataTable "B" is linked to UnlinkedMetadataTable "C".
     16            4. MetadataTable "A" is pointing to UnlinkedMetadataTable "C".
     17            5. "A" is touching UnlinkedMetadataTable::m_rawBuffer in "C", called from MetadataTable::sizeInBytes.
     18            6. (2) destroys MetadataTable "B", and realloc UnlinkedMetadataTable::m_rawBuffer in "C".
     19            7. (5) can touch already freed buffer.
     20
     21        This patch fixes UnlinkedMetadataTable::sizeInBytes: not touching m_rawBuffer unless it is owned by the caller's MetadataTable. We need to call
     22        UnlinkedMetadataTable::sizeInBytes anyway since we need to adjust the result based on whether the caller MetadataTable is linked to this UnlinkedMetadataTable.
     23
     24        * bytecode/UnlinkedMetadataTableInlines.h:
     25        (JSC::UnlinkedMetadataTable::sizeInBytes):
     26
    1272019-11-19  Fujii Hironori  <Hironori.Fujii@sony.com>
    228
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTableInlines.h

    r246021 r252674  
    8989    // In this case, we return the size of the table minus the offset table,
    9090    // which was already accounted for in the UnlinkedCodeBlock.
    91     size_t result = totalSize();
     91
     92    // Be careful not to touch m_rawBuffer if this metadataTable is not owning it.
     93    // It is possible that, m_rawBuffer is realloced in the other thread while we are accessing here.
     94    size_t result = metadataTable.totalSize();
    9295    if (metadataTable.buffer() == buffer()) {
    9396        ASSERT(m_isLinked);
Note: See TracChangeset for help on using the changeset viewer.