Changeset 196191 in webkit


Ignore:
Timestamp:
Feb 5, 2016 2:30:04 PM (8 years ago)
Author:
beidson@apple.com
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.

Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r196174 r196191  
     12016-02-05  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: UniqueIDBDatabase's m_databaseInfo is unsafely used from multiple threads.
     4        https://bugs.webkit.org/show_bug.cgi?id=153912
     5
     6        Reviewed by Alex Christensen.
     7
     8        No new tests (Anything testable about this patch is already covered by existing tests).
     9
     10        * Modules/indexeddb/server/IDBBackingStore.h:
     11
     12        * Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
     13        (WebCore::IDBServer::MemoryIDBBackingStore::infoForObjectStore):
     14        * Modules/indexeddb/server/MemoryIDBBackingStore.h:
     15
     16        Teach the SQLiteIDBBackingStore to actually keep its m_databaseInfo up to date as it changes,
     17        and to revert it when version change transactions abort:
     18        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
     19        (WebCore::IDBServer::SQLiteIDBBackingStore::beginTransaction):
     20        (WebCore::IDBServer::SQLiteIDBBackingStore::abortTransaction):
     21        (WebCore::IDBServer::SQLiteIDBBackingStore::commitTransaction):
     22        (WebCore::IDBServer::SQLiteIDBBackingStore::createObjectStore):
     23        (WebCore::IDBServer::SQLiteIDBBackingStore::deleteObjectStore):
     24        (WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
     25        (WebCore::IDBServer::SQLiteIDBBackingStore::deleteIndex):
     26        (WebCore::IDBServer::SQLiteIDBBackingStore::infoForObjectStore):
     27        * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
     28
     29        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
     30        (WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd): Use the IDBBackingStore's copy of the
     31          IDBObjectStoreInfo, meant only for the database thread, instead of the UniqueIDBDatabase's copy,
     32          which is meant only for the main thread.
     33
    1342016-02-05  Alex Christensen  <achristensen@webkit.org>
    235
  • trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h

    r195689 r196191  
    7878    virtual IDBError iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBKeyData&, uint32_t count, IDBGetResult& outResult) = 0;
    7979
     80    virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) = 0;
    8081    virtual void deleteBackingStore() = 0;
    8182    virtual bool supportsSimultaneousTransactions() = 0;
  • trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp

    r195689 r196191  
    482482}
    483483
     484IDBObjectStoreInfo* MemoryIDBBackingStore::infoForObjectStore(uint64_t objectStoreIdentifier)
     485{
     486    ASSERT(m_databaseInfo);
     487    return m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
     488}
     489
    484490void MemoryIDBBackingStore::deleteBackingStore()
    485491{
  • trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h

    r195689 r196191  
    7070    virtual IDBError iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBKeyData&, uint32_t count, IDBGetResult& outResult) override final;
    7171
     72    virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) override final;
    7273    virtual void deleteBackingStore() override final;
    7374    virtual bool supportsSimultaneousTransactions() override final { return true; }
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp

    r196038 r196191  
    613613    ASSERT(m_sqliteDB);
    614614    ASSERT(m_sqliteDB->isOpen());
     615    ASSERT(m_databaseInfo);
    615616
    616617    auto addResult = m_transactions.add(info.identifier(), nullptr);
     
    621622
    622623    addResult.iterator->value = std::make_unique<SQLiteIDBTransaction>(*this, info);
    623     return addResult.iterator->value->begin(*m_sqliteDB);
     624
     625    auto error = addResult.iterator->value->begin(*m_sqliteDB);
     626    if (error.isNull() && info.mode() == IndexedDB::TransactionMode::VersionChange)
     627        m_originalDatabaseInfoBeforeVersionChange = std::make_unique<IDBDatabaseInfo>(*m_databaseInfo);
     628
     629    return error;
    624630}
    625631
     
    637643    }
    638644
     645
     646    if (transaction->mode() == IndexedDB::TransactionMode::VersionChange) {
     647        ASSERT(m_originalDatabaseInfoBeforeVersionChange);
     648        m_databaseInfo = WTFMove(m_originalDatabaseInfoBeforeVersionChange);
     649    }
     650
    639651    return transaction->abort();
    640652}
     
    653665    }
    654666
    655     return transaction->commit();
     667    auto error = transaction->commit();
     668    if (!error.isNull()) {
     669        if (transaction->mode() == IndexedDB::TransactionMode::VersionChange) {
     670            ASSERT(m_originalDatabaseInfoBeforeVersionChange);
     671            m_databaseInfo = WTFMove(m_originalDatabaseInfoBeforeVersionChange);
     672        }
     673    } else
     674        m_originalDatabaseInfoBeforeVersionChange = nullptr;
     675
     676    return error;
    656677}
    657678
     
    703724    }
    704725
     726    m_databaseInfo->addExistingObjectStore(info);
     727
    705728    return { };
    706729}
     
    777800        }
    778801    }
     802
     803    m_databaseInfo->deleteObjectStore(objectStoreIdentifier);
    779804
    780805    return true;
     
    891916    }
    892917
     918    auto* objectStore = m_databaseInfo->infoForExistingObjectStore(info.objectStoreIdentifier());
     919    ASSERT(objectStore);
     920    objectStore->addExistingIndex(info);
     921
    893922    return { };
    894923}
     
    10321061        }
    10331062    }
     1063
     1064    auto* objectStore = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
     1065    ASSERT(objectStore);
     1066    objectStore->deleteIndex(indexIdentifier);
    10341067
    10351068    return { };
     
    16231656}
    16241657
     1658IDBObjectStoreInfo* SQLiteIDBBackingStore::infoForObjectStore(uint64_t objectStoreIdentifier)
     1659{
     1660    ASSERT(m_databaseInfo);
     1661    return m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
     1662}
     1663
    16251664void SQLiteIDBBackingStore::deleteBackingStore()
    16261665{
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h

    r196038 r196191  
    7474    virtual IDBError iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBKeyData&, uint32_t count, IDBGetResult& outResult) override final;
    7575
     76    virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) override final;
    7677    virtual void deleteBackingStore() override final;
    7778    virtual bool supportsSimultaneousTransactions() override final { return false; }
     
    105106    IDBDatabaseIdentifier m_identifier;
    106107    std::unique_ptr<IDBDatabaseInfo> m_databaseInfo;
     108    std::unique_ptr<IDBDatabaseInfo> m_originalDatabaseInfoBeforeVersionChange;
    107109
    108110    std::unique_ptr<SQLiteDatabase> m_sqliteDB;
  • trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp

    r196021 r196191  
    691691    IDBError error;
    692692
    693     auto objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
     693    auto* objectStoreInfo = m_backingStore->infoForObjectStore(objectStoreIdentifier);
    694694    if (!objectStoreInfo) {
    695695        error = IDBError(IDBDatabaseException::InvalidStateError, ASCIILiteral("Object store cannot be found in the backing store"));
Note: See TracChangeset for help on using the changeset viewer.