Crash if an IPC connection is invalidated before it's completely set up
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Jun 2013 22:54:33 +0000 (22:54 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Jun 2013 22:54:33 +0000 (22:54 +0000)
https://bugs.webkit.org/show_bug.cgi?id=117274
<rdar://problem/13319035>

Reviewed by Andreas Kling.

Resume our dispatch sources on the connection queue so we won't get invalidation callbacks before
all sources have been set up.

* Platform/CoreIPC/mac/ConnectionMac.cpp:
(CoreIPC::Connection::open):
(CoreIPC::Connection::sendOutgoingMessage):
(CoreIPC::Connection::initializeDeadNameSource):
(CoreIPC::Connection::receiveSourceEventHandler):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@151246 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/Platform/CoreIPC/mac/ConnectionMac.cpp

index 60b4aad..ad7e22d 100644 (file)
@@ -1,3 +1,20 @@
+2013-06-05  Anders Carlsson  <andersca@apple.com>
+
+        Crash if an IPC connection is invalidated before it's completely set up
+        https://bugs.webkit.org/show_bug.cgi?id=117274
+        <rdar://problem/13319035>
+
+        Reviewed by Andreas Kling.
+
+        Resume our dispatch sources on the connection queue so we won't get invalidation callbacks before
+        all sources have been set up.
+
+        * Platform/CoreIPC/mac/ConnectionMac.cpp:
+        (CoreIPC::Connection::open):
+        (CoreIPC::Connection::sendOutgoingMessage):
+        (CoreIPC::Connection::initializeDeadNameSource):
+        (CoreIPC::Connection::receiveSourceEventHandler):
+
 2013-06-05  Tim Horton  <timothy_horton@apple.com>
 
         [wk2] WebProcess' page-in-window count can be wrong
index ba566f6..441d906 100644 (file)
@@ -96,6 +96,10 @@ void Connection::platformInitialize(Identifier identifier)
         m_sendPort = identifier.port;
     }
 
+    m_deadNameSource = nullptr;
+    m_receivePortDataAvailableSource = nullptr;
+    m_exceptionPortDataAvailableSource = nullptr;
+
 #if HAVE(XPC)
     m_xpcConnection = identifier.xpcConnection;
     // FIXME: Instead of explicitly retaining the connection here, Identifier::xpcConnection
@@ -137,7 +141,6 @@ bool Connection::open()
 
         sendMessage(encoder.release());
 
-        // Set the dead name handler for our send port.
         initializeDeadNameSource();
     }
 
@@ -146,12 +149,10 @@ bool Connection::open()
 
     // Register the data available handler.
     m_receivePortDataAvailableSource = createDataAvailableSource(m_receivePort, m_connectionQueue.get(), bind(&Connection::receiveSourceEventHandler, this));
-    dispatch_resume(m_receivePortDataAvailableSource);
 
     // If we have an exception port, register the data available handler and send over the port to the other end.
     if (m_exceptionPort) {
         m_exceptionPortDataAvailableSource = createDataAvailableSource(m_exceptionPort, m_connectionQueue.get(), bind(&Connection::exceptionSourceEventHandler, this));
-        dispatch_resume(m_exceptionPortDataAvailableSource);
 
         OwnPtr<MessageEncoder> encoder = MessageEncoder::create("IPC", "SetExceptionPort", 0);
         encoder->encode(MachPort(m_exceptionPort, MACH_MSG_TYPE_MAKE_SEND));
@@ -159,6 +160,18 @@ bool Connection::open()
         sendMessage(encoder.release());
     }
 
+    ref();
+    dispatch_async(m_connectionQueue->dispatchQueue(), ^{
+        dispatch_resume(m_receivePortDataAvailableSource);
+
+        if (m_deadNameSource)
+            dispatch_resume(m_deadNameSource);
+        if (m_exceptionPortDataAvailableSource)
+            dispatch_resume(m_exceptionPortDataAvailableSource);
+
+        deref();
+    });
+
     return true;
 }
 
@@ -259,7 +272,7 @@ bool Connection::sendOutgoingMessage(PassOwnPtr<MessageEncoder> encoder)
         memcpy(messageData, encoder->buffer(), encoder->bufferSize());
 
     ASSERT(m_sendPort);
-    
+
     // Send the message.
     kern_return_t kr = mach_msg(header, MACH_SEND_MSG, messageSize, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
     if (kr != KERN_SUCCESS) {
@@ -279,8 +292,6 @@ void Connection::initializeDeadNameSource()
         // Release our send right.
         mach_port_deallocate(mach_task_self(), sendPort);
     });
-
-    dispatch_resume(m_deadNameSource);
 }
 
 static PassOwnPtr<MessageDecoder> createMessageDecoder(mach_msg_header_t* header)
@@ -407,10 +418,11 @@ void Connection::receiveSourceEventHandler()
 
         m_sendPort = port.port();
         
-        // Set the dead name source if needed.
-        if (m_sendPort)
+        if (m_sendPort) {
             initializeDeadNameSource();
-        
+            dispatch_resume(m_deadNameSource);
+        }
+
         m_isConnected = true;
 
         // Send any pending outgoing messages.