Title: [196191] trunk/Source/WebCore
Revision
196191
Author
beid...@apple.com
Date
2016-02-05 14:30:04 -0800 (Fri, 05 Feb 2016)

Log Message

Modern IDB: UniqueIDBDatabase's m_databaseInfo is unsafely used from multiple threads.
https://bugs.webkit.org/show_bug.cgi?id=153912

Reviewed by Alex Christensen.

No new tests (Anything testable about this patch is already covered by existing tests).

* Modules/indexeddb/server/IDBBackingStore.h:

* Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
(WebCore::IDBServer::MemoryIDBBackingStore::infoForObjectStore):
* Modules/indexeddb/server/MemoryIDBBackingStore.h:

Teach the SQLiteIDBBackingStore to actually keep its m_databaseInfo up to date as it changes,
and to revert it when version change transactions abort:
* Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
(WebCore::IDBServer::SQLiteIDBBackingStore::beginTransaction):
(WebCore::IDBServer::SQLiteIDBBackingStore::abortTransaction):
(WebCore::IDBServer::SQLiteIDBBackingStore::commitTransaction):
(WebCore::IDBServer::SQLiteIDBBackingStore::createObjectStore):
(WebCore::IDBServer::SQLiteIDBBackingStore::deleteObjectStore):
(WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
(WebCore::IDBServer::SQLiteIDBBackingStore::deleteIndex):
(WebCore::IDBServer::SQLiteIDBBackingStore::infoForObjectStore):
* Modules/indexeddb/server/SQLiteIDBBackingStore.h:

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd): Use the IDBBackingStore's copy of the
  IDBObjectStoreInfo, meant only for the database thread, instead of the UniqueIDBDatabase's copy,
  which is meant only for the main thread.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (196190 => 196191)


--- trunk/Source/WebCore/ChangeLog	2016-02-05 22:28:20 UTC (rev 196190)
+++ trunk/Source/WebCore/ChangeLog	2016-02-05 22:30:04 UTC (rev 196191)
@@ -1,3 +1,36 @@
+2016-02-05  Brady Eidson  <beid...@apple.com>
+
+        Modern IDB: UniqueIDBDatabase's m_databaseInfo is unsafely used from multiple threads.
+        https://bugs.webkit.org/show_bug.cgi?id=153912
+
+        Reviewed by Alex Christensen.
+
+        No new tests (Anything testable about this patch is already covered by existing tests).
+
+        * Modules/indexeddb/server/IDBBackingStore.h:
+
+        * Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
+        (WebCore::IDBServer::MemoryIDBBackingStore::infoForObjectStore):
+        * Modules/indexeddb/server/MemoryIDBBackingStore.h:
+
+        Teach the SQLiteIDBBackingStore to actually keep its m_databaseInfo up to date as it changes,
+        and to revert it when version change transactions abort:
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+        (WebCore::IDBServer::SQLiteIDBBackingStore::beginTransaction):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::abortTransaction):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::commitTransaction):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::createObjectStore):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::deleteObjectStore):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::deleteIndex):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::infoForObjectStore):
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
+
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd): Use the IDBBackingStore's copy of the 
+          IDBObjectStoreInfo, meant only for the database thread, instead of the UniqueIDBDatabase's copy, 
+          which is meant only for the main thread.
+
 2016-02-05  Alex Christensen  <achristen...@webkit.org>
 
         Clean up Blob code

Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h (196190 => 196191)


--- trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h	2016-02-05 22:28:20 UTC (rev 196190)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h	2016-02-05 22:30:04 UTC (rev 196191)
@@ -77,6 +77,7 @@
     virtual IDBError openCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo&, IDBGetResult& outResult) = 0;
     virtual IDBError iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBKeyData&, uint32_t count, IDBGetResult& outResult) = 0;
 
+    virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) = 0;
     virtual void deleteBackingStore() = 0;
     virtual bool supportsSimultaneousTransactions() = 0;
 };

Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp (196190 => 196191)


--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp	2016-02-05 22:28:20 UTC (rev 196190)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp	2016-02-05 22:30:04 UTC (rev 196191)
@@ -481,6 +481,12 @@
     return objectStoreByIdentifier;
 }
 
+IDBObjectStoreInfo* MemoryIDBBackingStore::infoForObjectStore(uint64_t objectStoreIdentifier)
+{
+    ASSERT(m_databaseInfo);
+    return m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
+}
+
 void MemoryIDBBackingStore::deleteBackingStore()
 {
     // The in-memory IDB backing store doesn't need to do any cleanup when it is deleted.

Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h (196190 => 196191)


--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h	2016-02-05 22:28:20 UTC (rev 196190)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h	2016-02-05 22:30:04 UTC (rev 196191)
@@ -69,6 +69,7 @@
     virtual IDBError openCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo&, IDBGetResult& outResult) override final;
     virtual IDBError iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBKeyData&, uint32_t count, IDBGetResult& outResult) override final;
 
+    virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) override final;
     virtual void deleteBackingStore() override final;
     virtual bool supportsSimultaneousTransactions() override final { return true; }
 

Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (196190 => 196191)


--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp	2016-02-05 22:28:20 UTC (rev 196190)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp	2016-02-05 22:30:04 UTC (rev 196191)
@@ -612,6 +612,7 @@
 
     ASSERT(m_sqliteDB);
     ASSERT(m_sqliteDB->isOpen());
+    ASSERT(m_databaseInfo);
 
     auto addResult = m_transactions.add(info.identifier(), nullptr);
     if (!addResult.isNewEntry) {
@@ -620,7 +621,12 @@
     }
 
     addResult.iterator->value = std::make_unique<SQLiteIDBTransaction>(*this, info);
-    return addResult.iterator->value->begin(*m_sqliteDB);
+
+    auto error = addResult.iterator->value->begin(*m_sqliteDB);
+    if (error.isNull() && info.mode() == IndexedDB::TransactionMode::VersionChange)
+        m_originalDatabaseInfoBeforeVersionChange = std::make_unique<IDBDatabaseInfo>(*m_databaseInfo);
+
+    return error;
 }
 
 IDBError SQLiteIDBBackingStore::abortTransaction(const IDBResourceIdentifier& identifier)
@@ -636,6 +642,12 @@
         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to abort a transaction that hasn't been established") };
     }
 
+
+    if (transaction->mode() == IndexedDB::TransactionMode::VersionChange) {
+        ASSERT(m_originalDatabaseInfoBeforeVersionChange);
+        m_databaseInfo = WTFMove(m_originalDatabaseInfoBeforeVersionChange);
+    }
+
     return transaction->abort();
 }
 
@@ -652,7 +664,16 @@
         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to commit a transaction that hasn't been established") };
     }
 
-    return transaction->commit();
+    auto error = transaction->commit();
+    if (!error.isNull()) {
+        if (transaction->mode() == IndexedDB::TransactionMode::VersionChange) {
+            ASSERT(m_originalDatabaseInfoBeforeVersionChange);
+            m_databaseInfo = WTFMove(m_originalDatabaseInfoBeforeVersionChange);
+        }
+    } else
+        m_originalDatabaseInfoBeforeVersionChange = nullptr;
+
+    return error;
 }
 
 IDBError SQLiteIDBBackingStore::createObjectStore(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& info)
@@ -702,6 +723,8 @@
         }
     }
 
+    m_databaseInfo->addExistingObjectStore(info);
+
     return { };
 }
 
@@ -777,6 +800,8 @@
         }
     }
 
+    m_databaseInfo->deleteObjectStore(objectStoreIdentifier);
+
     return true;
 }
 
@@ -890,6 +915,10 @@
         }
     }
 
+    auto* objectStore = m_databaseInfo->infoForExistingObjectStore(info.objectStoreIdentifier());
+    ASSERT(objectStore);
+    objectStore->addExistingIndex(info);
+
     return { };
 }
 
@@ -1032,6 +1061,10 @@
         }
     }
 
+    auto* objectStore = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
+    ASSERT(objectStore);
+    objectStore->deleteIndex(indexIdentifier);
+
     return { };
 }
 
@@ -1622,6 +1655,12 @@
     return { };
 }
 
+IDBObjectStoreInfo* SQLiteIDBBackingStore::infoForObjectStore(uint64_t objectStoreIdentifier)
+{
+    ASSERT(m_databaseInfo);
+    return m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
+}
+
 void SQLiteIDBBackingStore::deleteBackingStore()
 {
     String dbFilename = fullDatabasePath();

Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h (196190 => 196191)


--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h	2016-02-05 22:28:20 UTC (rev 196190)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h	2016-02-05 22:30:04 UTC (rev 196191)
@@ -73,6 +73,7 @@
     virtual IDBError openCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo&, IDBGetResult& outResult) override final;
     virtual IDBError iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBKeyData&, uint32_t count, IDBGetResult& outResult) override final;
 
+    virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) override final;
     virtual void deleteBackingStore() override final;
     virtual bool supportsSimultaneousTransactions() override final { return false; }
 
@@ -104,6 +105,7 @@
 
     IDBDatabaseIdentifier m_identifier;
     std::unique_ptr<IDBDatabaseInfo> m_databaseInfo;
+    std::unique_ptr<IDBDatabaseInfo> m_originalDatabaseInfoBeforeVersionChange;
 
     std::unique_ptr<SQLiteDatabase> m_sqliteDB;
 

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


--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp	2016-02-05 22:28:20 UTC (rev 196190)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp	2016-02-05 22:30:04 UTC (rev 196191)
@@ -690,7 +690,7 @@
     IDBKeyData usedKey;
     IDBError error;
 
-    auto objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
+    auto* objectStoreInfo = m_backingStore->infoForObjectStore(objectStoreIdentifier);
     if (!objectStoreInfo) {
         error = IDBError(IDBDatabaseException::InvalidStateError, ASCIILiteral("Object store cannot be found in the backing store"));
         m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to