Title: [232824] trunk/Source
Revision
232824
Author
[email protected]
Date
2018-06-13 19:31:29 -0700 (Wed, 13 Jun 2018)

Log Message

Crash under SWServer::unregisterConnection(Connection&)
https://bugs.webkit.org/show_bug.cgi?id=186584
<rdar://problem/40931680>

Reviewed by Youenn Fablet.

Source/WebCore:

The crash was due to SWServer::Connection objects outliving their SWServer, even
though SWServer::Connection::m_server is a C++ reference. This was possible because
SWServer does not own the connections, StorageToWebProcessConnection does. This
started crashing recently, after r232423, because SWServer can get destroyed now.
The SWServer might get destroyed before the StorageToWebProcessConnection, in which
case the SWServer::Connection objects will get destroyed later. We were crashing
because the SWServer::Connection destructor tries to unregister the connection from
the SWServer (which is dead).

To address the issue, the SWServer now owns the connections. StorageToWebProcessConnection
merely has weak pointers to the connections.

* workers/service/server/SWServer.cpp:
(WebCore::SWServer::Connection::Connection):
(WebCore::SWServer::addConnection):
(WebCore::SWServer::removeConnection):
(WebCore::SWServer::resolveRegistrationReadyRequests):
* workers/service/server/SWServer.h:
(WebCore::SWServer::Connection::~Connection):
(WebCore::SWServer::Connection::server):
(WebCore::SWServer::connection):
* workers/service/server/SWServerRegistration.cpp:
(WebCore::SWServerRegistration::forEachConnection):
(WebCore::SWServerRegistration::notifyClientsOfControllerChange):
(WebCore::SWServerRegistration::controlClient):

Source/WebKit:

* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
* StorageProcess/StorageToWebProcessConnection.cpp:
(WebKit::StorageToWebProcessConnection::~StorageToWebProcessConnection):
(WebKit::StorageToWebProcessConnection::didReceiveMessage):
(WebKit::StorageToWebProcessConnection::didReceiveSyncMessage):
(WebKit::StorageToWebProcessConnection::didClose):
(WebKit::StorageToWebProcessConnection::unregisterSWConnections):
(WebKit::StorageToWebProcessConnection::establishSWServerConnection):
* StorageProcess/StorageToWebProcessConnection.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (232823 => 232824)


--- trunk/Source/WebCore/ChangeLog	2018-06-14 01:36:24 UTC (rev 232823)
+++ trunk/Source/WebCore/ChangeLog	2018-06-14 02:31:29 UTC (rev 232824)
@@ -1,3 +1,37 @@
+2018-06-13  Chris Dumez  <[email protected]>
+
+        Crash under SWServer::unregisterConnection(Connection&)
+        https://bugs.webkit.org/show_bug.cgi?id=186584
+        <rdar://problem/40931680>
+
+        Reviewed by Youenn Fablet.
+
+        The crash was due to SWServer::Connection objects outliving their SWServer, even
+        though SWServer::Connection::m_server is a C++ reference. This was possible because
+        SWServer does not own the connections, StorageToWebProcessConnection does. This
+        started crashing recently, after r232423, because SWServer can get destroyed now.
+        The SWServer might get destroyed before the StorageToWebProcessConnection, in which
+        case the SWServer::Connection objects will get destroyed later. We were crashing
+        because the SWServer::Connection destructor tries to unregister the connection from
+        the SWServer (which is dead).
+
+        To address the issue, the SWServer now owns the connections. StorageToWebProcessConnection
+        merely has weak pointers to the connections.
+
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::Connection::Connection):
+        (WebCore::SWServer::addConnection):
+        (WebCore::SWServer::removeConnection):
+        (WebCore::SWServer::resolveRegistrationReadyRequests):
+        * workers/service/server/SWServer.h:
+        (WebCore::SWServer::Connection::~Connection):
+        (WebCore::SWServer::Connection::server):
+        (WebCore::SWServer::connection):
+        * workers/service/server/SWServerRegistration.cpp:
+        (WebCore::SWServerRegistration::forEachConnection):
+        (WebCore::SWServerRegistration::notifyClientsOfControllerChange):
+        (WebCore::SWServerRegistration::controlClient):
+
 2018-06-13  Zalan Bujtas  <[email protected]>
 
         [Mail] Use the Mail Viewer width as the base for resolving horizontal viewport units

Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (232823 => 232824)


--- trunk/Source/WebCore/workers/service/server/SWServer.cpp	2018-06-14 01:36:24 UTC (rev 232823)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp	2018-06-14 02:31:29 UTC (rev 232824)
@@ -54,14 +54,8 @@
     : m_server(server)
     , m_identifier(generateObjectIdentifier<SWServerConnectionIdentifierType>())
 {
-    m_server.registerConnection(*this);
 }
 
-SWServer::Connection::~Connection()
-{
-    m_server.unregisterConnection(*this);
-}
-
 HashSet<SWServer*>& SWServer::allServers()
 {
     static NeverDestroyed<HashSet<SWServer*>> servers;
@@ -692,23 +686,23 @@
     contextConnection->fireActivateEvent(worker.identifier());
 }
 
-void SWServer::registerConnection(Connection& connection)
+void SWServer::addConnection(std::unique_ptr<Connection>&& connection)
 {
-    auto result = m_connections.add(connection.identifier(), nullptr);
-    ASSERT(result.isNewEntry);
-    result.iterator->value = &connection;
+    auto identifier = connection->identifier();
+    ASSERT(!m_connections.contains(identifier));
+    m_connections.add(identifier, WTFMove(connection));
 }
 
-void SWServer::unregisterConnection(Connection& connection)
+void SWServer::removeConnection(SWServerConnectionIdentifier connectionIdentifier)
 {
-    ASSERT(m_connections.get(connection.identifier()) == &connection);
-    m_connections.remove(connection.identifier());
+    ASSERT(m_connections.contains(connectionIdentifier));
+    m_connections.remove(connectionIdentifier);
 
     for (auto& registration : m_registrations.values())
-        registration->unregisterServerConnection(connection.identifier());
+        registration->unregisterServerConnection(connectionIdentifier);
 
     for (auto& jobQueue : m_jobQueues.values())
-        jobQueue->cancelJobsFromConnection(connection.identifier());
+        jobQueue->cancelJobsFromConnection(connectionIdentifier);
 }
 
 SWServerRegistration* SWServer::doRegistrationMatching(const SecurityOriginData& topOrigin, const URL& clientURL)
@@ -817,7 +811,7 @@
 
 void SWServer::resolveRegistrationReadyRequests(SWServerRegistration& registration)
 {
-    for (auto* connection : m_connections.values())
+    for (auto& connection : m_connections.values())
         connection->resolveRegistrationReadyRequests(registration);
 }
 

Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (232823 => 232824)


--- trunk/Source/WebCore/workers/service/server/SWServer.h	2018-06-14 01:36:24 UTC (rev 232823)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h	2018-06-14 02:31:29 UTC (rev 232824)
@@ -69,7 +69,7 @@
         WTF_MAKE_FAST_ALLOCATED;
         friend class SWServer;
     public:
-        WEBCORE_EXPORT virtual ~Connection();
+        WEBCORE_EXPORT virtual ~Connection() { }
 
         using Identifier = SWServerConnectionIdentifier;
         Identifier identifier() const { return m_identifier; }
@@ -87,9 +87,10 @@
         virtual void notifyClientsOfControllerChange(const HashSet<DocumentIdentifier>& contextIdentifiers, const ServiceWorkerData& newController) = 0;
         virtual void registrationReady(uint64_t registrationReadyRequestIdentifier, ServiceWorkerRegistrationData&&) = 0;
 
+        SWServer& server() { return m_server; }
+
     protected:
         WEBCORE_EXPORT explicit Connection(SWServer&);
-        SWServer& server() { return m_server; }
 
         WEBCORE_EXPORT void finishFetchingScriptInServer(const ServiceWorkerFetchResult&);
         WEBCORE_EXPORT void addServiceWorkerRegistrationInServer(ServiceWorkerRegistrationIdentifier);
@@ -144,7 +145,10 @@
 
     WEBCORE_EXPORT void markAllWorkersForOriginAsTerminated(const SecurityOriginData&);
     
-    Connection* getConnection(SWServerConnectionIdentifier identifier) { return m_connections.get(identifier); }
+    WEBCORE_EXPORT void addConnection(std::unique_ptr<Connection>&&);
+    WEBCORE_EXPORT void removeConnection(SWServerConnectionIdentifier);
+    Connection* connection(SWServerConnectionIdentifier identifier) const { return m_connections.get(identifier); }
+
     SWOriginStore& originStore() { return m_originStore; }
 
     void scriptContextFailedToStart(const std::optional<ServiceWorkerJobDataIdentifier>&, SWServerWorker&, const String& message);
@@ -179,9 +183,6 @@
     void disableServiceWorkerProcessTerminationDelay() { m_shouldDisableServiceWorkerProcessTerminationDelay = true; }
 
 private:
-    void registerConnection(Connection&);
-    void unregisterConnection(Connection&);
-
     void scriptFetchFinished(Connection&, const ServiceWorkerFetchResult&);
 
     void didResolveRegistrationPromise(Connection&, const ServiceWorkerRegistrationKey&);
@@ -208,7 +209,7 @@
     };
     void terminateWorkerInternal(SWServerWorker&, TerminationMode);
 
-    HashMap<SWServerConnectionIdentifier, Connection*> m_connections;
+    HashMap<SWServerConnectionIdentifier, std::unique_ptr<Connection>> m_connections;
     HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerRegistration>> m_registrations;
     HashMap<ServiceWorkerRegistrationIdentifier, SWServerRegistration*> m_registrationsByID;
     HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerJobQueue>> m_jobQueues;

Modified: trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp (232823 => 232824)


--- trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp	2018-06-14 01:36:24 UTC (rev 232823)
+++ trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp	2018-06-14 02:31:29 UTC (rev 232824)
@@ -136,7 +136,7 @@
 void SWServerRegistration::forEachConnection(const WTF::Function<void(SWServer::Connection&)>& apply)
 {
     for (auto connectionIdentifierWithClients : m_connectionsWithClientRegistrations.values()) {
-        if (auto* connection = m_server.getConnection(connectionIdentifierWithClients))
+        if (auto* connection = m_server.connection(connectionIdentifierWithClients))
             apply(*connection);
     }
 }
@@ -198,7 +198,7 @@
     ASSERT(activeWorker());
 
     for (auto& item : m_clientsUsingRegistration) {
-        if (auto* connection = m_server.getConnection(item.key))
+        if (auto* connection = m_server.connection(item.key))
             connection->notifyClientsOfControllerChange(item.value, activeWorker()->data());
     }
 }
@@ -346,7 +346,7 @@
 
     HashSet<DocumentIdentifier> identifiers;
     identifiers.add(identifier.contextIdentifier);
-    m_server.getConnection(identifier.serverConnectionIdentifier)->notifyClientsOfControllerChange(identifiers, activeWorker()->data());
+    m_server.connection(identifier.serverConnectionIdentifier)->notifyClientsOfControllerChange(identifiers, activeWorker()->data());
 }
 
 void SWServerRegistration::setIsUninstalling(bool value)

Modified: trunk/Source/WebKit/ChangeLog (232823 => 232824)


--- trunk/Source/WebKit/ChangeLog	2018-06-14 01:36:24 UTC (rev 232823)
+++ trunk/Source/WebKit/ChangeLog	2018-06-14 02:31:29 UTC (rev 232824)
@@ -1,3 +1,22 @@
+2018-06-13  Chris Dumez  <[email protected]>
+
+        Crash under SWServer::unregisterConnection(Connection&)
+        https://bugs.webkit.org/show_bug.cgi?id=186584
+        <rdar://problem/40931680>
+
+        Reviewed by Youenn Fablet.
+
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+        * StorageProcess/StorageToWebProcessConnection.cpp:
+        (WebKit::StorageToWebProcessConnection::~StorageToWebProcessConnection):
+        (WebKit::StorageToWebProcessConnection::didReceiveMessage):
+        (WebKit::StorageToWebProcessConnection::didReceiveSyncMessage):
+        (WebKit::StorageToWebProcessConnection::didClose):
+        (WebKit::StorageToWebProcessConnection::unregisterSWConnections):
+        (WebKit::StorageToWebProcessConnection::establishSWServerConnection):
+        * StorageProcess/StorageToWebProcessConnection.h:
+
 2018-06-13  Dean Jackson  <[email protected]>
 
         Disable AR support in WKWebView clients

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp (232823 => 232824)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp	2018-06-14 01:36:24 UTC (rev 232823)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp	2018-06-14 02:31:29 UTC (rev 232824)
@@ -76,11 +76,6 @@
         server().unregisterServiceWorkerClient(keyValue.value, keyValue.key);
 }
 
-void WebSWServerConnection::disconnectedFromWebProcess()
-{
-    notImplemented();
-}
-
 void WebSWServerConnection::rejectJobInClient(ServiceWorkerJobIdentifier jobIdentifier, const ExceptionData& exceptionData)
 {
     send(Messages::WebSWClientConnection::JobRejectedInServer(jobIdentifier, exceptionData));

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h (232823 => 232824)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h	2018-06-14 01:36:24 UTC (rev 232823)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h	2018-06-14 02:31:29 UTC (rev 232824)
@@ -56,7 +56,6 @@
 
     IPC::Connection& ipcConnection() const { return m_contentConnection.get(); }
 
-    void disconnectedFromWebProcess();
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
     void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&);
 

Modified: trunk/Source/WebKit/StorageProcess/StorageToWebProcessConnection.cpp (232823 => 232824)


--- trunk/Source/WebKit/StorageProcess/StorageToWebProcessConnection.cpp	2018-06-14 01:36:24 UTC (rev 232823)
+++ trunk/Source/WebKit/StorageProcess/StorageToWebProcessConnection.cpp	2018-06-14 02:31:29 UTC (rev 232824)
@@ -61,6 +61,10 @@
 StorageToWebProcessConnection::~StorageToWebProcessConnection()
 {
     m_connection->invalidate();
+
+#if ENABLE(SERVICE_WORKER)
+    unregisterSWConnections();
+#endif
 }
 
 void StorageToWebProcessConnection::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
@@ -86,9 +90,8 @@
 
 #if ENABLE(SERVICE_WORKER)
     if (decoder.messageReceiverName() == Messages::WebSWServerConnection::messageReceiverName()) {
-        auto iterator = m_swConnections.find(makeObjectIdentifier<SWServerConnectionIdentifierType>(decoder.destinationID()));
-        if (iterator != m_swConnections.end())
-            iterator->value->didReceiveMessage(connection, decoder);
+        if (auto swConnection = m_swConnections.get(makeObjectIdentifier<SWServerConnectionIdentifierType>(decoder.destinationID())))
+            swConnection->didReceiveMessage(connection, decoder);
         return;
     }
 
@@ -112,9 +115,8 @@
 
 #if ENABLE(SERVICE_WORKER)
     if (decoder.messageReceiverName() == Messages::WebSWServerConnection::messageReceiverName()) {
-        auto iterator = m_swConnections.find(makeObjectIdentifier<SWServerConnectionIdentifierType>(decoder.destinationID()));
-        if (iterator != m_swConnections.end())
-            iterator->value->didReceiveSyncMessage(connection, decoder, replyEncoder);
+        if (auto swConnection = m_swConnections.get(makeObjectIdentifier<SWServerConnectionIdentifierType>(decoder.destinationID())))
+            swConnection->didReceiveSyncMessage(connection, decoder, replyEncoder);
         return;
     }
 #endif
@@ -143,15 +145,7 @@
 #endif
 
 #if ENABLE(SERVICE_WORKER)
-    Vector<std::unique_ptr<WebSWServerConnection>> connectionVector;
-    connectionVector.reserveInitialCapacity(m_swConnections.size());
-
-    for (auto& connection : m_swConnections.values())
-        connectionVector.uncheckedAppend(WTFMove(connection));
-    for (auto& connection : connectionVector)
-        connection->disconnectedFromWebProcess();
-
-    m_swConnections.clear();
+    unregisterSWConnections();
 #endif
 }
 
@@ -161,6 +155,16 @@
 }
 
 #if ENABLE(SERVICE_WORKER)
+
+void StorageToWebProcessConnection::unregisterSWConnections()
+{
+    auto swConnections = WTFMove(m_swConnections);
+    for (auto& swConnection : swConnections.values()) {
+        if (swConnection)
+            swConnection->server().removeConnection(swConnection->identifier());
+    }
+}
+
 void StorageToWebProcessConnection::establishSWServerConnection(SessionID sessionID, SWServerConnectionIdentifier& serverConnectionIdentifier)
 {
     auto& server = StorageProcess::singleton().swServerForSession(sessionID);
@@ -168,11 +172,12 @@
 
     serverConnectionIdentifier = connection->identifier();
     LOG(ServiceWorker, "StorageToWebProcessConnection::establishSWServerConnection - %s", serverConnectionIdentifier.loggingString().utf8().data());
+
     ASSERT(!m_swConnections.contains(serverConnectionIdentifier));
+    m_swConnections.add(serverConnectionIdentifier, makeWeakPtr(*connection));
+    server.addConnection(WTFMove(connection));
+}
 
-    auto addResult = m_swConnections.add(serverConnectionIdentifier, WTFMove(connection));
-    ASSERT_UNUSED(addResult, addResult.isNewEntry);
-}
 #endif
 
 #if ENABLE(INDEXED_DATABASE)

Modified: trunk/Source/WebKit/StorageProcess/StorageToWebProcessConnection.h (232823 => 232824)


--- trunk/Source/WebKit/StorageProcess/StorageToWebProcessConnection.h	2018-06-14 01:36:24 UTC (rev 232823)
+++ trunk/Source/WebKit/StorageProcess/StorageToWebProcessConnection.h	2018-06-14 02:31:29 UTC (rev 232824)
@@ -70,7 +70,9 @@
 
 #if ENABLE(SERVICE_WORKER)
     void establishSWServerConnection(PAL::SessionID, WebCore::SWServerConnectionIdentifier&);
-    HashMap<WebCore::SWServerConnectionIdentifier, std::unique_ptr<WebSWServerConnection>> m_swConnections;
+    void unregisterSWConnections();
+
+    HashMap<WebCore::SWServerConnectionIdentifier, WeakPtr<WebSWServerConnection>> m_swConnections;
 #endif
 
     Ref<IPC::Connection> m_connection;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to