Commit 7bc96c2d authored by Daniel Murphy's avatar Daniel Murphy Committed by Commit Bot

[IndexedDB] Fix force_closing_ state's effect on connections_

A recent bug fix caused another problem with re-entry (or lack of
re-entry) where the connections_ list was no longer updated during force
close, causing uaf issues when that list was iterated later.

R=pwnall@chromium.org

Bug: 966557
Change-Id: I3d5ed163b030c1da8a6515d32108e86868be75b9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1632287
Commit-Queue: Daniel Murphy <dmurph@chromium.org>
Commit-Queue: Victor Costan <pwnall@chromium.org>
Auto-Submit: Daniel Murphy <dmurph@chromium.org>
Reviewed-by: default avatarVictor Costan <pwnall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#663987}
parent bb29f7f6
......@@ -233,7 +233,7 @@ class IndexedDBDatabase::OpenRequest
// Requested version is higher than current version - upgrade needed.
DCHECK_GT(new_version, old_version);
if (db_->connections_.empty()) {
if (db_->HasNoConnections()) {
std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = {
{kDatabaseRangeLockLevel, GetDatabaseLockRange(db_->metadata_.id),
ScopesLockManager::LockType::kExclusive}};
......@@ -251,8 +251,7 @@ class IndexedDBDatabase::OpenRequest
// "versionchange" event was ignored.
DCHECK_NE(pending_->data_loss_info.status,
blink::mojom::IDBDataLoss::Total);
for (const auto* connection : db_->connections_)
connection->callbacks()->OnVersionChange(old_version, new_version);
db_->SendVersionChangeToAllConnections(old_version, new_version);
// When all connections have closed the upgrade can proceed.
}
......@@ -278,7 +277,7 @@ class IndexedDBDatabase::OpenRequest
return;
}
if (!db_->connections_.empty())
if (!db_->HasNoConnections())
return;
std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = {
......@@ -375,7 +374,7 @@ class IndexedDBDatabase::DeleteRequest
weak_factory_(this) {}
void Perform() override {
if (db_->connections_.empty()) {
if (db_->HasNoConnections()) {
// No connections, so delete immediately.
DoDelete();
return;
......@@ -385,8 +384,7 @@ class IndexedDBDatabase::DeleteRequest
// close_pending set.
const int64_t old_version = db_->metadata_.version;
const int64_t new_version = IndexedDBDatabaseMetadata::NO_VERSION;
for (const auto* connection : db_->connections_)
connection->callbacks()->OnVersionChange(old_version, new_version);
db_->SendVersionChangeToAllConnections(old_version, new_version);
}
void OnVersionChangeIgnored() const override {
......@@ -394,7 +392,7 @@ class IndexedDBDatabase::DeleteRequest
}
void OnConnectionClosed(IndexedDBConnection* connection) override {
if (!db_->connections_.empty())
if (!db_->HasNoConnections())
return;
DoDelete();
......@@ -599,6 +597,18 @@ void IndexedDBDatabase::VersionChangeIgnored() {
active_request_->OnVersionChangeIgnored();
}
bool IndexedDBDatabase::HasNoConnections() const {
return force_closing_ || connections_.empty();
}
void IndexedDBDatabase::SendVersionChangeToAllConnections(int64_t old_version,
int64_t new_version) {
if (force_closing_)
return;
for (const auto* connection : connections_)
connection->callbacks()->OnVersionChange(old_version, new_version);
}
void IndexedDBDatabase::ConnectionClosed(IndexedDBConnection* connection) {
if (force_closing_)
return;
......@@ -1991,7 +2001,8 @@ void IndexedDBDatabase::TransactionFinished(
// connections to close, or the actual upgrade transaction from an active
// request. Notify the active request if it's the latter.
if (active_request_ &&
mode == blink::mojom::IDBTransactionMode::VersionChange) {
mode == blink::mojom::IDBTransactionMode::VersionChange &&
!force_closing_) {
active_request_->UpgradeTransactionFinished(committed);
}
}
......
......@@ -366,6 +366,11 @@ class CONTENT_EXPORT IndexedDBDatabase {
// pending connection.
void VersionChangeIgnored();
bool HasNoConnections() const;
void SendVersionChangeToAllConnections(int64_t old_version,
int64_t new_version);
// This can only be called when the given connection is closed and no longer
// has any transaction objects.
void ConnectionClosed(IndexedDBConnection* connection);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment