Bug 181802

Summary: REGRESSION (r226068): [X86] Crash in JavaScriptCore ShadowChicken when handling exceptions
Product: WebKit Reporter: Michael Saboff <msaboff>
Component: JavaScriptCoreAssignee: Michael Saboff <msaboff>
Status: RESOLVED FIXED    
Severity: Normal CC: ews-watchlist, fpizlo, keith_miller, mark.lam, saam, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Other   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Patch fpizlo: review+

Michael Saboff
Reported 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.
Attachments
Patch (5.82 KB, patch)
2018-01-18 10:39 PST, Michael Saboff
fpizlo: review+
Michael Saboff
Comment 1 2018-01-18 10:16:41 PST
Michael Saboff
Comment 2 2018-01-18 10:39:15 PST
Michael Saboff
Comment 3 2018-01-18 10:44:32 PST
Note You need to log in before you can comment on or make changes to this bug.