- 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));