Changeset 134797 in webkit


Ignore:
Timestamp:
Nov 15, 2012 10:53:20 AM (11 years ago)
Author:
mhahnenberg@apple.com
Message:

Windows Fibers can corrupt the cached StackBounds
https://bugs.webkit.org/show_bug.cgi?id=102411

Reviewed by Geoffrey Garen.

Windows has support for something called fibers, which are like lightweight versions of
threads. Multiple fibers can run within the context of a single thread and they have access
to the same thread local storage but have different stacks. If we create a new JSGlobalContext
on one fiber, then switch to another fiber and create a JSGlobalContext there, we will call
initializeThreading() once for each new JSGlobalContext created. However, since these fibers
are technically running inside the same thread, they will clobber each other's wtfThreadData(),
which is stored using thread local storage. This can lead to corruption of the WTFThreadData
structure for the fibers other than the last one to create a new JSGlobalContext, including
the StackBounds data structure which is used during conservative scanning, among other things.
This can lead to crashes during garbage collection on Windows if fibers are used.

A quick fix would be to always get a fresh StackBounds data structure when asking for it
instead of using the cached version from the thread local storage. There is a larger problem
in that these fibers can corrupt other WebKit data that uses thread local storage. We'll leave
those theoretical fixes for future theoretical bugs.

  • wtf/WTFThreadData.h:

(WTF::WTFThreadData::stack): We now refresh the m_stackBounds field whenever somebody asks for
the StackBounds.

Location:
trunk/Source/WTF
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r134791 r134797  
     12012-11-15  Mark Hahnenberg  <mhahnenberg@apple.com>
     2
     3        Windows Fibers can corrupt the cached StackBounds
     4        https://bugs.webkit.org/show_bug.cgi?id=102411
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Windows has support for something called fibers, which are like lightweight versions of
     9        threads. Multiple fibers can run within the context of a single thread and they have access
     10        to the same thread local storage but have different stacks. If we create a new JSGlobalContext
     11        on one fiber, then switch to another fiber and create a JSGlobalContext there, we will call
     12        initializeThreading() once for each new JSGlobalContext created. However, since these fibers
     13        are technically running inside the same thread, they will clobber each other's wtfThreadData(),
     14        which is stored using thread local storage. This can lead to corruption of the WTFThreadData
     15        structure for the fibers other than the last one to create a new JSGlobalContext, including
     16        the StackBounds data structure which is used during conservative scanning, among other things.
     17        This can lead to crashes during garbage collection on Windows if fibers are used.
     18
     19        A quick fix would be to always get a fresh StackBounds data structure when asking for it
     20        instead of using the cached version from the thread local storage. There is a larger problem
     21        in that these fibers can corrupt other WebKit data that uses thread local storage. We'll leave
     22        those theoretical fixes for future theoretical bugs.
     23
     24        * wtf/WTFThreadData.h:
     25        (WTF::WTFThreadData::stack): We now refresh the m_stackBounds field whenever somebody asks for
     26        the StackBounds.
     27
    1282012-11-15  Maciej Stachowiak  <mjs@apple.com>
    229
  • trunk/Source/WTF/wtf/WTFThreadData.h

    r131938 r134797  
    106106    }
    107107
    108     const StackBounds& stack() const
     108    const StackBounds& stack()
    109109    {
     110        // We need to always get a fresh StackBounds from the OS due to how fibers work.
     111        // See https://bugs.webkit.org/show_bug.cgi?id=102411
     112#if OS(WINDOWS)
     113        m_stackBounds = StackBounds::currentThreadStackBounds();
     114#endif
    110115        return m_stackBounds;
    111116    }
Note: See TracChangeset for help on using the changeset viewer.