Changeset 202847 in webkit


Ignore:
Timestamp:
Jul 5, 2016 10:25:06 PM (8 years ago)
Author:
sbarati@apple.com
Message:

StackVisitor::unwindToMachineCodeBlockFrame() may unwind past a VM entry frame when catching an exception and the frame has inlined tail calls
https://bugs.webkit.org/show_bug.cgi?id=159448
<rdar://problem/27084459>

Reviewed by Mark Lam.

Consider the following stack trace:
(machine) foo -> VM entry frame -> (machine) bar -> (inlined tailcall) baz

If an exception is thrown at 'baz', we will do exception unwinding,
which will eventually call unwindToMachineCodeBlockFrame() which will call
gotoNextFrame() on the 'baz' frame. The next logical frame for 'baz' is 'foo' because
'bar' tail called 'baz' even though there is a machine frame for 'bar' on the stack.
This is a bug. unwindToMachineCodeBlockFrame() should not care about the next
logical frame, it just wants to move StackVisitor's state to the current machine
frame. The bug here is that we would end up unwinding past the VM entry frame
which can have all kinds of terrible consequences.

This bug fixes unwindToMachineCodeBlockFrame() by having it not rely
on gotoNextFrame() and instead using its own mechanism for setting
the StackVisotor's state to the current machine frame.

  • interpreter/StackVisitor.cpp:

(JSC::StackVisitor::unwindToMachineCodeBlockFrame):

  • tests/stress/dont-unwind-past-vm-entry-frame.js: Added.

(let.p.new.Proxy):
(let.p.new.Proxy.apply):
(bar):
(let.good):
(getItem):
(start):

Location:
trunk/Source/JavaScriptCore
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r202846 r202847  
     12016-07-05  Saam Barati  <sbarati@apple.com>
     2
     3        StackVisitor::unwindToMachineCodeBlockFrame() may unwind past a VM entry frame when catching an exception and the frame has inlined tail calls
     4        https://bugs.webkit.org/show_bug.cgi?id=159448
     5        <rdar://problem/27084459>
     6
     7        Reviewed by Mark Lam.
     8
     9        Consider the following stack trace:
     10        (machine) foo -> VM entry frame -> (machine) bar -> (inlined tailcall) baz
     11
     12        If an exception is thrown at 'baz', we will do exception unwinding,
     13        which will eventually call unwindToMachineCodeBlockFrame() which will call
     14        gotoNextFrame() on the 'baz' frame. The next logical frame for 'baz' is 'foo' because
     15        'bar' tail called 'baz' even though there is a machine frame for 'bar' on the stack.
     16        This is a bug. unwindToMachineCodeBlockFrame() should not care about the next
     17        logical frame, it just wants to move StackVisitor's state to the current machine
     18        frame. The bug here is that we would end up unwinding past the VM entry frame
     19        which can have all kinds of terrible consequences.
     20
     21        This bug fixes unwindToMachineCodeBlockFrame() by having it not rely
     22        on gotoNextFrame() and instead using its own mechanism for setting
     23        the StackVisotor's state to the current machine frame.
     24
     25        * interpreter/StackVisitor.cpp:
     26        (JSC::StackVisitor::unwindToMachineCodeBlockFrame):
     27        * tests/stress/dont-unwind-past-vm-entry-frame.js: Added.
     28        (let.p.new.Proxy):
     29        (let.p.new.Proxy.apply):
     30        (bar):
     31        (let.good):
     32        (getItem):
     33        (start):
     34
    1352016-07-05  Joseph Pecoraro  <pecoraro@apple.com>
    236
  • trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp

    r201766 r202847  
    8282{
    8383#if ENABLE(DFG_JIT)
    84     while (m_frame.isInlinedFrame())
    85         gotoNextFrame();
     84    if (m_frame.isInlinedFrame()) {
     85        CodeOrigin codeOrigin = m_frame.inlineCallFrame()->directCaller;
     86        while (codeOrigin.inlineCallFrame)
     87            codeOrigin = codeOrigin.inlineCallFrame->directCaller;
     88        readNonInlinedFrame(m_frame.callFrame(), &codeOrigin);
     89    }
    8690#endif
    8791}
  • trunk/Source/JavaScriptCore/jit/JITExceptions.cpp

    r200997 r202847  
    8282        catchRoutine = LLInt::getCodePtr(handleUncaughtException);
    8383   
     84    ASSERT(bitwise_cast<uintptr_t>(callFrame) < bitwise_cast<uintptr_t>(vm->topVMEntryFrame));
     85
    8486    vm->callFrameForCatch = callFrame;
    8587    vm->targetMachinePCForThrow = catchRoutine;
Note: See TracChangeset for help on using the changeset viewer.