[IndexedDB] Avoiding UAF in IndexedDBConnection list
The IndexedDBDatabase's connection() list can be modified during a call
to FinishAllTransactions. The AbortAllTransactions method didn't protect
against this, so there was a potential UAF. This patch fixes that.
(cherry picked from commit 6be08e8acbe5eaed18a0b9abeb395de5afa2f1aa)
Bug: 969083
Change-Id: I590e3a6c4f978ee6e582394208fb70cbdd9e5347
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1641625
Commit-Queue: Daniel Murphy <dmurph@chromium.org>
Auto-Submit: Daniel Murphy <dmurph@chromium.org>
Reviewed-by: Chase Phillips <cmp@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#666381}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1654510
Reviewed-by: Victor Costan <pwnall@chromium.org>
Cr-Commit-Position: refs/branch-heads/3809@{#245}
Cr-Branched-From: d82dec1a818f378c464ba307ddd9c92133eac355-refs/heads/master@{#665002}
diff --git a/content/browser/indexed_db/indexed_db_origin_state.cc b/content/browser/indexed_db/indexed_db_origin_state.cc
index 02cb72b..27ad7cf 100644
--- a/content/browser/indexed_db/indexed_db_origin_state.cc
+++ b/content/browser/indexed_db/indexed_db_origin_state.cc
@@ -113,10 +113,21 @@
auto it = databases_.find(origin);
if (it == databases_.end())
continue;
- for (IndexedDBConnection* connection : it->second->connections()) {
- connection->FinishAllTransactions(
- IndexedDBDatabaseError(blink::kWebIDBDatabaseExceptionUnknownError,
- "Aborting all transactions for the origin."));
+
+ // Calling FinishAllTransactions can destruct the IndexedDBConnection &
+ // modify the IndexedDBDatabase::connection() list. To prevent UAFs, start
+ // by taking a WeakPtr of all connections, and then iterate that list.
+ std::vector<base::WeakPtr<IndexedDBConnection>> weak_connections;
+ weak_connections.reserve(it->second->connections().size());
+ for (IndexedDBConnection* connection : it->second->connections())
+ weak_connections.push_back(connection->GetWeakPtr());
+
+ for (base::WeakPtr<IndexedDBConnection> connection : weak_connections) {
+ if (connection) {
+ connection->FinishAllTransactions(IndexedDBDatabaseError(
+ blink::kWebIDBDatabaseExceptionUnknownError,
+ "Aborting all transactions for the origin."));
+ }
}
}
if (compact)