Title: [241967] trunk/Source/WebCore
Revision
241967
Author
[email protected]
Date
2019-02-22 15:41:16 -0800 (Fri, 22 Feb 2019)

Log Message

Crash under IDBServer::IDBConnectionToClient::identifier() const
https://bugs.webkit.org/show_bug.cgi?id=194843
<rdar://problem/48203102>

Reviewed by Geoffrey Garen.

UniqueIDBDatabase should ignore requests from connections that are already closed.

Tests are hard to create without some tricks on UniqueIDBDatabase so this fix is verified manually.
One test is created by adding delay to UniqueIDBDatabase::openBackingStore on the background thread to make sure
disconnection of web process happens before UniqueIDBDatabase::didOpenBackingStore, because didOpenBackingStore
may start a version change transaction and ask for identifier from the connection that is already gone.

* Modules/indexeddb/server/IDBConnectionToClient.cpp:
(WebCore::IDBServer::IDBConnectionToClient::connectionToClientClosed):
* Modules/indexeddb/server/IDBConnectionToClient.h:
(WebCore::IDBServer::IDBConnectionToClient::isClosed):
* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::clearStalePendingOpenDBRequests):
(WebCore::IDBServer::UniqueIDBDatabase::handleDatabaseOperations):
(WebCore::IDBServer::UniqueIDBDatabase::operationAndTransactionTimerFired):
* Modules/indexeddb/server/UniqueIDBDatabase.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (241966 => 241967)


--- trunk/Source/WebCore/ChangeLog	2019-02-22 22:59:55 UTC (rev 241966)
+++ trunk/Source/WebCore/ChangeLog	2019-02-22 23:41:16 UTC (rev 241967)
@@ -1,3 +1,28 @@
+2019-02-22  Sihui Liu  <[email protected]>
+
+        Crash under IDBServer::IDBConnectionToClient::identifier() const
+        https://bugs.webkit.org/show_bug.cgi?id=194843
+        <rdar://problem/48203102>
+
+        Reviewed by Geoffrey Garen.
+
+        UniqueIDBDatabase should ignore requests from connections that are already closed.
+
+        Tests are hard to create without some tricks on UniqueIDBDatabase so this fix is verified manually. 
+        One test is created by adding delay to UniqueIDBDatabase::openBackingStore on the background thread to make sure
+        disconnection of web process happens before UniqueIDBDatabase::didOpenBackingStore, because didOpenBackingStore
+        may start a version change transaction and ask for identifier from the connection that is already gone.
+
+        * Modules/indexeddb/server/IDBConnectionToClient.cpp:
+        (WebCore::IDBServer::IDBConnectionToClient::connectionToClientClosed):
+        * Modules/indexeddb/server/IDBConnectionToClient.h:
+        (WebCore::IDBServer::IDBConnectionToClient::isClosed):
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::clearStalePendingOpenDBRequests):
+        (WebCore::IDBServer::UniqueIDBDatabase::handleDatabaseOperations):
+        (WebCore::IDBServer::UniqueIDBDatabase::operationAndTransactionTimerFired):
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+
 2019-02-22  Wenson Hsieh  <[email protected]>
 
         Input type "formatSetInlineTextDirection" is dispatched when changing paragraph-level text direction

Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp (241966 => 241967)


--- trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp	2019-02-22 22:59:55 UTC (rev 241966)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp	2019-02-22 23:41:16 UTC (rev 241967)
@@ -207,6 +207,7 @@
             connection->connectionClosedFromClient();
     }
 
+    m_isClosed = true;
     m_databaseConnections.clear();
 }
 

Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h (241966 => 241967)


--- trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h	2019-02-22 22:59:55 UTC (rev 241966)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h	2019-02-22 23:41:16 UTC (rev 241967)
@@ -79,12 +79,13 @@
     void registerDatabaseConnection(UniqueIDBDatabaseConnection&);
     void unregisterDatabaseConnection(UniqueIDBDatabaseConnection&);
     void connectionToClientClosed();
-
+    bool isClosed() { return m_isClosed; }
 private:
     IDBConnectionToClient(IDBConnectionToClientDelegate&);
     
     WeakPtr<IDBConnectionToClientDelegate> m_delegate;
     HashSet<UniqueIDBDatabaseConnection*> m_databaseConnections;
+    bool m_isClosed { false };
 };
 
 } // namespace IDBServer

Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (241966 => 241967)


--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp	2019-02-22 22:59:55 UTC (rev 241966)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp	2019-02-22 23:41:16 UTC (rev 241967)
@@ -344,6 +344,12 @@
     invokeOperationAndTransactionTimer();
 }
 
+void UniqueIDBDatabase::clearStalePendingOpenDBRequests()
+{
+    while (!m_pendingOpenDBRequests.isEmpty() && m_pendingOpenDBRequests.first()->connection().isClosed())
+        m_pendingOpenDBRequests.removeFirst();
+}
+
 void UniqueIDBDatabase::handleDatabaseOperations()
 {
     ASSERT(isMainThread());
@@ -353,7 +359,9 @@
     if (m_deleteBackingStoreInProgress)
         return;
 
-    if (m_versionChangeDatabaseConnection || m_versionChangeTransaction || m_currentOpenDBRequest) {
+    clearStalePendingOpenDBRequests();
+
+    if (m_versionChangeDatabaseConnection || m_versionChangeTransaction || (m_currentOpenDBRequest && !m_currentOpenDBRequest->connection().isClosed())) {
         // We can't start any new open-database operations right now, but we might be able to start handling a delete operation.
         if (!m_currentOpenDBRequest && !m_pendingOpenDBRequests.isEmpty() && m_pendingOpenDBRequests.first()->isDeleteRequest())
             m_currentOpenDBRequest = m_pendingOpenDBRequests.takeFirst();
@@ -365,8 +373,10 @@
         return;
     }
 
-    if (m_pendingOpenDBRequests.isEmpty())
+    if (m_pendingOpenDBRequests.isEmpty()) {
+        m_currentOpenDBRequest = nullptr;
         return;
+    }
 
     m_currentOpenDBRequest = m_pendingOpenDBRequests.takeFirst();
     LOG(IndexedDB, "UniqueIDBDatabase::handleDatabaseOperations - Popped an operation, now there are %u pending", m_pendingOpenDBRequests.size());
@@ -1575,10 +1585,9 @@
 
     // The current operation might require multiple attempts to handle, so try to
     // make further progress on it now.
-    if (m_currentOpenDBRequest)
+    if (m_currentOpenDBRequest && !m_currentOpenDBRequest->connection().isClosed())
         handleCurrentOperation();
-
-    if (!m_currentOpenDBRequest)
+    else
         handleDatabaseOperations();
 
     bool hadDeferredTransactions = false;

Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h (241966 => 241967)


--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h	2019-02-22 22:59:55 UTC (rev 241966)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h	2019-02-22 23:41:16 UTC (rev 241967)
@@ -214,6 +214,8 @@
     RefPtr<UniqueIDBDatabaseTransaction> takeNextRunnableTransaction(bool& hadDeferredTransactions);
 
     bool prepareToFinishTransaction(UniqueIDBDatabaseTransaction&);
+    
+    void clearStalePendingOpenDBRequests();
 
     void postDatabaseTask(CrossThreadTask&&);
     void postDatabaseTaskReply(CrossThreadTask&&);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to