Bug 181802 - REGRESSION (r226068): [X86] Crash in JavaScriptCore ShadowChicken when handling exceptions
Summary: REGRESSION (r226068): [X86] Crash in JavaScriptCore ShadowChicken when handli...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: Other
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Michael Saboff
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-01-18 10:16 PST by Michael Saboff
Modified: 2018-01-18 10:44 PST (History)
6 users (show)

See Also:


Attachments
Patch (5.82 KB, patch)
2018-01-18 10:39 PST, Michael Saboff
fpizlo: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Saboff 2018-01-18 10:16:15 PST
After change set r226068, X86 (32 bit builds) crash handling exceptions in ShadowChicken::update().  Here is a crash in testapi when run from the debugger:

Process 55384 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x004d0892 JavaScriptCore`JSC::ShadowChicken::update(JSC::VM&, JSC::ExecState*) [inlined] WTF::VectorBufferBase<JSC::ShadowChicken::Frame, WTF::FastMalloc>::VectorBufferBase() at Vector.h:337 [opt]
   334 	protected:
   335 	    VectorBufferBase()
   336 	        : m_buffer(0)
-> 337 	        , m_capacity(0)
   338 	        , m_size(0)
   339 	        , m_mask(0)
   340 	    {
Target 0: (testapi) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
  * frame #0: 0x004d0892 JavaScriptCore`JSC::ShadowChicken::update(JSC::VM&, JSC::ExecState*) [inlined] WTF::VectorBufferBase<JSC::ShadowChicken::Frame, WTF::FastMalloc>::VectorBufferBase() at Vector.h:337 [opt]
    frame #1: 0x004d088e JavaScriptCore`JSC::ShadowChicken::update(JSC::VM&, JSC::ExecState*) [inlined] WTF::VectorBuffer<JSC::ShadowChicken::Frame, 0ul, WTF::FastMalloc>::VectorBuffer() at Vector.h:376 [opt]
    frame #2: 0x004d088e JavaScriptCore`JSC::ShadowChicken::update(JSC::VM&, JSC::ExecState*) [inlined] WTF::Vector<JSC::ShadowChicken::Frame, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc>::Vector() at Vector.h:621 [opt]
    frame #3: 0x004d088e JavaScriptCore`JSC::ShadowChicken::update(JSC::VM&, JSC::ExecState*) [inlined] WTF::Vector<JSC::ShadowChicken::Frame, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc>::Vector() at Vector.h:622 [opt]
    frame #4: 0x004d088e JavaScriptCore`JSC::ShadowChicken::update(this=<unavailable>, vm=<unavailable>, exec=<unavailable>) at ShadowChicken.cpp:155 [opt]
    frame #5: 0x004cfd6a JavaScriptCore`JSC::ShadowChicken::log(this=0x07232c40, vm=0x05968000, exec=0xbfffedd8, packet=0xbfffed40) at ShadowChicken.cpp:85 [opt]
    frame #6: 0x004ff550 JavaScriptCore`JSC::genericUnwind(vm=0x05968000, callFrame=<unavailable>, unwindStart=<unavailable>) at JITExceptions.cpp:62 [opt]
    frame #7: 0x004ff6b6 JavaScriptCore`JSC::genericUnwind(vm=0x05968000, callFrame=0xbfffedd8) at JITExceptions.cpp:98 [opt]
    frame #8: 0x0052c034 JavaScriptCore`::operationVMHandleException(exec=0xbfffedd8) at JITOperations.cpp:2354 [opt]
    frame #9: 0x038017a5
    frame #10: 0x000b26fb JavaScriptCore`llint_entry at LowLevelInterpreter.asm:830
    frame #11: 0x000ad51e JavaScriptCore`vmEntryToJavaScript at LowLevelInterpreter32_64.asm:279
    frame #12: 0x004fd56d JavaScriptCore`JSC::JITCode::execute(this=<unavailable>, vm=0x05968000, protoCallFrame=0xbfffeee0) at JITCode.cpp:81 [opt]
    frame #13: 0x004ceed6 JavaScriptCore`JSC::Interpreter::executeProgram(this=0x01d50bb0, source=0xbffff4c0, callFrame=<unavailable>, thisObj=<unavailable>) at Interpreter.cpp:941 [opt]
    frame #14: 0x006d1ba9 JavaScriptCore`JSC::evaluate(exec=<unavailable>, source=<unavailable>, thisValue=JSValue @ 0xbffff488, returnedException=<unavailable>) at Completion.cpp:103 [opt]
    frame #15: 0x000d5ea9 JavaScriptCore`::JSScriptEvaluate(context=<unavailable>, script=0x072e0508, thisValueRef=<unavailable>, exception=<unavailable>) at JSScriptRef.cpp:156 [opt]
    frame #16: 0x0000a362 testapi`main(argc=2, argv=<unavailable>) at testapi.c:1981 [opt]
    frame #17: 0xa73b66e1 libdyld.dylib`start + 1
(lldb) 

It looks like our X86-32 exception handling from our native call thunks don’t properly align the stack before calling exception handling code.  The exception handling code calls into ShadowChicken code to update the shadow stack.  The Vector index masking change made in r226068 added a new field to Vector objects, going from three 4 byte fields to four.  The compiler decided to initialize all fields using a zeroed xmm register.  The crash happened here because ShadowChicken::update() has a local Vector object (alocated on the stack).  Since the stack isn’t aligned on 16 byte boundaries like it’s suppose to, the store of the xmm register to the stack location caused a SEGV.
Comment 1 Michael Saboff 2018-01-18 10:16:41 PST
<rdar://problem/36348520>
Comment 2 Michael Saboff 2018-01-18 10:39:15 PST
Created attachment 331639 [details]
Patch
Comment 3 Michael Saboff 2018-01-18 10:44:32 PST
Committed r227152: <https://trac.webkit.org/changeset/227152>