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 ...@@ -233,7 +233,7 @@ class IndexedDBDatabase::OpenRequest
// Requested version is higher than current version - upgrade needed. // Requested version is higher than current version - upgrade needed.
DCHECK_GT(new_version, old_version); DCHECK_GT(new_version, old_version);
if (db_->connections_.empty()) { if (db_->HasNoConnections()) {
std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = { std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = {
{kDatabaseRangeLockLevel, GetDatabaseLockRange(db_->metadata_.id), {kDatabaseRangeLockLevel, GetDatabaseLockRange(db_->metadata_.id),
ScopesLockManager::LockType::kExclusive}}; ScopesLockManager::LockType::kExclusive}};
...@@ -251,8 +251,7 @@ class IndexedDBDatabase::OpenRequest ...@@ -251,8 +251,7 @@ class IndexedDBDatabase::OpenRequest
// "versionchange" event was ignored. // "versionchange" event was ignored.
DCHECK_NE(pending_->data_loss_info.status, DCHECK_NE(pending_->data_loss_info.status,
blink::mojom::IDBDataLoss::Total); blink::mojom::IDBDataLoss::Total);
for (const auto* connection : db_->connections_) db_->SendVersionChangeToAllConnections(old_version, new_version);
connection->callbacks()->OnVersionChange(old_version, new_version);
// When all connections have closed the upgrade can proceed. // When all connections have closed the upgrade can proceed.
} }
...@@ -278,7 +277,7 @@ class IndexedDBDatabase::OpenRequest ...@@ -278,7 +277,7 @@ class IndexedDBDatabase::OpenRequest
return; return;
} }
if (!db_->connections_.empty()) if (!db_->HasNoConnections())
return; return;
std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = { std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = {
...@@ -375,7 +374,7 @@ class IndexedDBDatabase::DeleteRequest ...@@ -375,7 +374,7 @@ class IndexedDBDatabase::DeleteRequest
weak_factory_(this) {} weak_factory_(this) {}
void Perform() override { void Perform() override {
if (db_->connections_.empty()) { if (db_->HasNoConnections()) {
// No connections, so delete immediately. // No connections, so delete immediately.
DoDelete(); DoDelete();
return; return;
...@@ -385,8 +384,7 @@ class IndexedDBDatabase::DeleteRequest ...@@ -385,8 +384,7 @@ class IndexedDBDatabase::DeleteRequest
// close_pending set. // close_pending set.
const int64_t old_version = db_->metadata_.version; const int64_t old_version = db_->metadata_.version;
const int64_t new_version = IndexedDBDatabaseMetadata::NO_VERSION; const int64_t new_version = IndexedDBDatabaseMetadata::NO_VERSION;
for (const auto* connection : db_->connections_) db_->SendVersionChangeToAllConnections(old_version, new_version);
connection->callbacks()->OnVersionChange(old_version, new_version);
} }
void OnVersionChangeIgnored() const override { void OnVersionChangeIgnored() const override {
...@@ -394,7 +392,7 @@ class IndexedDBDatabase::DeleteRequest ...@@ -394,7 +392,7 @@ class IndexedDBDatabase::DeleteRequest
} }
void OnConnectionClosed(IndexedDBConnection* connection) override { void OnConnectionClosed(IndexedDBConnection* connection) override {
if (!db_->connections_.empty()) if (!db_->HasNoConnections())
return; return;
DoDelete(); DoDelete();
...@@ -599,6 +597,18 @@ void IndexedDBDatabase::VersionChangeIgnored() { ...@@ -599,6 +597,18 @@ void IndexedDBDatabase::VersionChangeIgnored() {
active_request_->OnVersionChangeIgnored(); 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) { void IndexedDBDatabase::ConnectionClosed(IndexedDBConnection* connection) {
if (force_closing_) if (force_closing_)
return; return;
...@@ -1991,7 +2001,8 @@ void IndexedDBDatabase::TransactionFinished( ...@@ -1991,7 +2001,8 @@ void IndexedDBDatabase::TransactionFinished(
// connections to close, or the actual upgrade transaction from an active // connections to close, or the actual upgrade transaction from an active
// request. Notify the active request if it's the latter. // request. Notify the active request if it's the latter.
if (active_request_ && if (active_request_ &&
mode == blink::mojom::IDBTransactionMode::VersionChange) { mode == blink::mojom::IDBTransactionMode::VersionChange &&
!force_closing_) {
active_request_->UpgradeTransactionFinished(committed); active_request_->UpgradeTransactionFinished(committed);
} }
} }
......
...@@ -366,6 +366,11 @@ class CONTENT_EXPORT IndexedDBDatabase { ...@@ -366,6 +366,11 @@ class CONTENT_EXPORT IndexedDBDatabase {
// pending connection. // pending connection.
void VersionChangeIgnored(); 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 // This can only be called when the given connection is closed and no longer
// has any transaction objects. // has any transaction objects.
void ConnectionClosed(IndexedDBConnection* connection); 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