|
|
Safari sandbox IPC memory corruption with WebEvent::Wheel | |||||
| Project Member Reported by ianbeer@google.com, Apr 3 2014 | Back to list | |||||
The handler for the WebPageProxy::DidReceiveEvent IPC message fails to check that the WTF::Deque m_currentlyProcessedWheelEvents is not empty before calling takeFirst() when processing an event of type WebEvent::Wheel:
void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
...
case WebEvent::Wheel: {
ASSERT(!m_currentlyProcessedWheelEvents.isEmpty());
OwnPtr<Vector<NativeWebWheelEvent>> oldestCoalescedEvent = m_currentlyProcessedWheelEvents.takeFirst();
...
That debug ASSERT should be a runtime CHECK.
takeFirst() simply returns the head of the queue and bumps the pointer (mod the buffer size,) there is no check that the queue isn't empty.
When this scope is left that OwnPtr will be freed. Exploitability depends on the contents of the buffer backing the queue, a crash stack is show below where the faulting address is clearly a poison value, however the memory pointed to by that poisoned pointer doesn't seem to be reserved, and could probably be easily heap-sprayed too. Further investigation of the operation of WTF::Deque would be required to understand if this could be exploited reliably.
Crash stack:
(lldb) attach 9724
Process 9724 stopped
Executable module set to "/Applications/Safari.app/Contents/MacOS/SafariForWebKitDevelopment".
Architecture set to: x86_64-apple-macosx.
(lldb) c
Process 9724 resuming
Process 9724 stopped
* thread #1: tid = 0x9ef7, 0x0000000101bd1513 WebKit2`WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow>::~Vector(this=0x00000001badbeef5) + 9 at Vector.h:595, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=1, address=0x1badbef01)
frame #0: 0x0000000101bd1513 WebKit2`WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow>::~Vector(this=0x00000001badbeef5) + 9 at Vector.h:595
592
593 ~Vector()
594 {
-> 595 if (m_size)
596 shrink(0);
597 }
598
WebKit2`WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow>::~Vector() + 9 at Vector.h:595:
-> 0x101bd1513: cmp DWORD PTR [RBX + 12], 0
0x101bd1517: je 0x101bd1523 ; WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow>::~Vector() + 25 [inlined] WTF::VectorBufferBase<WebKit::NativeWebWheelEvent>::buffer() at Vector.h:373
WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow>::~Vector() + 25 [inlined] WTF::VectorBuffer<WebKit::NativeWebWheelEvent, 0ul>::~VectorBuffer() at Vector.h:597
WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow>::~Vector() + 25 at Vector.h:597
0x101bd1519: mov RDI, RBX
(lldb) bt
* thread #1: tid = 0x9ef7, 0x0000000101bd1513 WebKit2`WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow>::~Vector(this=0x00000001badbeef5) + 9 at Vector.h:595, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=1, address=0x1badbef01)
frame #0: 0x0000000101bd1513 WebKit2`WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow>::~Vector(this=0x00000001badbeef5) + 9 at Vector.h:595
frame #1: 0x0000000101bd14f4 WebKit2`WTF::OwnPtr<WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow> >::~OwnPtr() [inlined] WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow>::~Vector(this=0x00000001badbeef5, p=0x00000001badbeef5) + 8 at Vector.h:594
frame #2: 0x0000000101bd14ec WebKit2`WTF::OwnPtr<WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow> >::~OwnPtr() [inlined] void WTF::deleteOwnedPtr<WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow> >(ptr=0x00000001badbeef5) at OwnPtrCommon.h:37
frame #3: 0x0000000101bd14ec WebKit2`WTF::OwnPtr<WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow> >::~OwnPtr(this=<unavailable>) + 14 at OwnPtr.h:47
frame #4: 0x0000000101bbd198 WebKit2`WebKit::WebPageProxy::didReceiveEvent(unsigned int, bool) [inlined] WTF::OwnPtr<WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow> >::~OwnPtr(this=0x00000001badbeef5) + 776 at OwnPtr.h:47
frame #5: 0x0000000101bbd193 WebKit2`WebKit::WebPageProxy::didReceiveEvent(this=<unavailable>, opaqueType=<unavailable>, handled=<unavailable>) + 771 at WebPageProxy.cpp:3699
frame #6: 0x0000000101bdb648 WebKit2`void IPC::handleMessage<Messages::WebPageProxy::DidReceiveEvent, WebKit::WebPageProxy, void (WebKit::WebPageProxy::*)(unsigned int, bool)>(IPC::MessageDecoder&, WebKit::WebPageProxy*, void (WebKit::WebPageProxy::*)(unsigned int, bool)) [inlined] void IPC::callMemberFunctionImpl<WebKit::WebPageProxy, void (args=0x0000000100000003, __t=0x0000000100000003, object=<unavailable>)(unsigned int, bool), std::__1::tuple<unsigned int, bool>, 0ul, 1ul>(WebKit::WebPageProxy*, void (WebKit::WebPageProxy::*)(unsigned int, bool), std::__1::tuple<unsigned int, bool>&&, std::index_sequence<0ul, 1ul>) + 73 at HandleMessage.h:16
frame #7: 0x0000000101bdb62a WebKit2`void IPC::handleMessage<Messages::WebPageProxy::DidReceiveEvent, WebKit::WebPageProxy, void (WebKit::WebPageProxy::*)(unsigned int, bool)>(IPC::MessageDecoder&, WebKit::WebPageProxy*, void (WebKit::WebPageProxy::*)(unsigned int, bool)) [inlined] void IPC::callMemberFunction<WebKit::WebPageProxy, void (args=0x0000000100000003, __t=0x0000000100000003)(unsigned int, bool), std::__1::tuple<unsigned int, bool>, std::make_index_sequence<2ul> >(std::__1::tuple<unsigned int, bool>&&, WebKit::WebPageProxy*, void (WebKit::WebPageProxy::*)(unsigned int, bool)) at HandleMessage.h:22
frame #8: 0x0000000101bdb62a WebKit2`void IPC::handleMessage<Messages::WebPageProxy::DidReceiveEvent, WebKit::WebPageProxy, void (decoder=<unavailable>, object=<unavailable>, function=<unavailable>)(unsigned int, bool)>(IPC::MessageDecoder&, WebKit::WebPageProxy*, void (WebKit::WebPageProxy::*)(unsigned int, bool)) + 43 at HandleMessage.h:117
frame #9: 0x0000000101bd8c8e WebKit2`WebKit::WebPageProxy::didReceiveMessage(this=0x00007fc8eb80ea18, connection=<unavailable>, decoder=0x0000000107206820) + 916 at WebPageProxyMessageReceiver.cpp:214
frame #10: 0x0000000101abf7d5 WebKit2`IPC::MessageReceiverMap::dispatchMessage(this=<unavailable>, connection=0x000000010720d780, decoder=0x0000000107206820) + 125 at MessageReceiverMap.cpp:87
frame #11: 0x0000000101a6c947 WebKit2`WebKit::ChildProcessProxy::dispatchMessage(this=<unavailable>, connection=<unavailable>, decoder=<unavailable>) + 13 at ChildProcessProxy.cpp:118
frame #12: 0x0000000101c05328 WebKit2`WebKit::WebProcessProxy::didReceiveMessage(this=0x000000010591ea80, connection=0x000000010720d780, decoder=0x0000000107206820) + 24 at WebProcessProxy.cpp:364
frame #13: 0x0000000101a6dafc WebKit2`IPC::Connection::dispatchMessage(std::__1::unique_ptr<IPC::MessageDecoder, std::__1::default_delete<IPC::MessageDecoder> >) [inlined] IPC::Connection::dispatchMessage(decoder=<unavailable>, this=<unavailable>) + 94 at Connection.cpp:770
frame #14: 0x0000000101a6daef WebKit2`IPC::Connection::dispatchMessage(this=0x000000010720d780, message=0x00007fff5eb85020) + 81 at Connection.cpp:791
frame #15: 0x0000000101a6fb70 WebKit2`IPC::Connection::dispatchOneMessage(this=0x000000010720d780) + 106 at Connection.cpp:817
frame #16: 0x0000000101463a45 JavaScriptCore`WTF::RunLoop::performWork() [inlined] std::__1::function<void (this=0x00007fff5eb850e0)>::operator()() const + 421 at functional:1435
frame #17: 0x0000000101463a3b JavaScriptCore`WTF::RunLoop::performWork(this=0x000000010590df30) + 411 at RunLoop.cpp:104
frame #18: 0x0000000101464122 JavaScriptCore`WTF::RunLoop::performWork(context=<unavailable>) + 34 at RunLoopCF.cpp:38
frame #19: 0x00007fff871bb731 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
frame #20: 0x00007fff871acea2 CoreFoundation`__CFRunLoopDoSources0 + 242
frame #21: 0x00007fff871ac62f CoreFoundation`__CFRunLoopRun + 831
frame #22: 0x00007fff871ac0b5 CoreFoundation`CFRunLoopRunSpecific + 309
frame #23: 0x00007fff90fb1a0d HIToolbox`RunCurrentEventLoopInMode + 226
frame #24: 0x00007fff90fb17b7 HIToolbox`ReceiveNextEventCommon + 479
frame #25: 0x00007fff90fb15bc HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 65
frame #26: 0x00007fff8db9e3de AppKit`_DPSNextEvent + 1434
frame #27: 0x00007fff8db9da2b AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
frame #28: 0x00007fff8a241290 Safari`-[BrowserApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 161
frame #29: 0x00007fff8db91b2c AppKit`-[NSApplication run] + 553
frame #30: 0x00007fff8db7c913 AppKit`NSApplicationMain + 940
frame #31: 0x00007fff8a41306d Safari`SafariMain + 267
frame #32: 0x00007fff83a405fd libdyld.dylib`start + 1
frame #33: 0x00007fff83a405fd libdyld.dylib`start + 1
(lldb) register read
General Purpose Registers:
rax = 0x0000000000000000
rbx = 0x00000001badbeef5
rcx = 0x000000000000000f
rdx = 0x0000000000000000
rdi = 0x00000001badbeef5
rsi = 0x0000000000000003
rbp = 0x00007fff5eb84d50
rsp = 0x00007fff5eb84d40
r8 = 0x0000000000000074
r9 = 0x0000000000000000
r10 = 0x00007fc8eb4caf9c
r11 = 0x00007fff73da4db8 (void *)0x00007fff73da4d90: NSAutoreleasePool
r12 = 0x00007fc8eb80ea18
r13 = 0x00007fff5eb85200
r14 = 0x0000000000000001
r15 = 0x00000001badbeef5
rip = 0x0000000101bd1513 WebKit2`WTF::Vector<WebKit::NativeWebWheelEvent, 0ul, WTF::CrashOnOverflow>::~Vector() + 9 at Vector.h:595
rflags = 0x0000000000010206
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
This issue can be easily reproduced by applying following patch to the renderer code then scrolling using the mouse on a page:
Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp:
ScrollingTree::EventResult result = scrollingTree->tryToHandleWheelEvent(platformWheelEvent);
if (result == ScrollingTree::DidHandleEvent || result == ScrollingTree::DidNotHandleEvent) {
- sendDidReceiveEvent(pageID, wheelEvent, result == ScrollingTree::DidHandleEvent);
+ for (int i = 0; i < 128; i++){
+ sendDidReceiveEvent(pageID, wheelEvent, result == ScrollingTree::DidHandleEvent);
+ }
return;
}
}
Project Member
Comment 1
by
ianbeer@google.com,
Apr 3 2014
,
Apr 4 2014
,
Apr 4 2014
Apple follow-up id: 605055321
,
Apr 4 2014
,
May 22 2014
,
May 22 2014
Fixed in Safari 7.0.4 Apple advisory: http://support.apple.com/kb/HT6254
,
Jul 31 2014
|
||||||
| ► Sign in to add a comment | ||||||