Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(360)

Unified Diff: content/browser/indexed_db/indexed_db_callbacks.cc

Issue 2892223003: [IndexedDB] Added wrapper to cursor to avoid use-after-free on shutdown. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/indexed_db/indexed_db_callbacks.cc
diff --git a/content/browser/indexed_db/indexed_db_callbacks.cc b/content/browser/indexed_db/indexed_db_callbacks.cc
index 3cd348c5a5a6678ee10b884a95b5f2fc36016799..052eb61df016274ec7c28fdcbac54b802c1e569b 100644
--- a/content/browser/indexed_db/indexed_db_callbacks.cc
+++ b/content/browser/indexed_db/indexed_db_callbacks.cc
@@ -44,10 +44,8 @@ namespace content {
namespace {
-// If this is destructed with the connection still living inside it, we assume
-// we have been killed due to IO thread shutdown, and we need to safely schedule
-// the destruction of the connection on the IDB thread, as we should still be in
-// a transaction's operation queue, where we cannot destroy the transaction.
+// The following two objects protect the given objects from being destructed on
+// the IO thread if we have a shutdown or an error.
struct SafeIOThreadConnectionWrapper {
SafeIOThreadConnectionWrapper(std::unique_ptr<IndexedDBConnection> connection)
: connection(std::move(connection)),
@@ -72,6 +70,23 @@ struct SafeIOThreadConnectionWrapper {
DISALLOW_COPY_AND_ASSIGN(SafeIOThreadConnectionWrapper);
};
+struct SafeIOThreadCursorWrapper {
+ SafeIOThreadCursorWrapper(std::unique_ptr<IndexedDBCursor> cursor)
+ : cursor(std::move(cursor)),
+ idb_runner(base::ThreadTaskRunnerHandle::Get()) {}
+ ~SafeIOThreadCursorWrapper() {
+ if (cursor)
+ idb_runner->DeleteSoon(FROM_HERE, cursor.release());
+ }
+ SafeIOThreadCursorWrapper(SafeIOThreadCursorWrapper&& other) = default;
+
+ std::unique_ptr<IndexedDBCursor> cursor;
+ scoped_refptr<base::SequencedTaskRunner> idb_runner;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SafeIOThreadCursorWrapper);
+};
+
void ConvertBlobInfo(
const std::vector<IndexedDBBlobInfo>& blob_info,
std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info) {
@@ -129,7 +144,7 @@ class IndexedDBCallbacks::IOThreadHelper {
const content::IndexedDBDatabaseMetadata& metadata);
void SendSuccessDatabase(SafeIOThreadConnectionWrapper connection,
const content::IndexedDBDatabaseMetadata& metadata);
- void SendSuccessCursor(std::unique_ptr<IndexedDBCursor> cursor,
+ void SendSuccessCursor(SafeIOThreadCursorWrapper cursor,
const IndexedDBKey& key,
const IndexedDBKey& primary_key,
::indexed_db::mojom::ValuePtr value,
@@ -328,12 +343,14 @@ void IndexedDBCallbacks::OnSuccess(std::unique_ptr<IndexedDBCursor> cursor,
blob_info.swap(value->blob_info);
}
+ SafeIOThreadCursorWrapper cursor_wrapper(std::move(cursor));
+
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&IOThreadHelper::SendSuccessCursor,
- base::Unretained(io_helper_.get()), base::Passed(&cursor), key,
- primary_key, base::Passed(&mojo_value),
- base::Passed(&blob_info)));
+ base::Unretained(io_helper_.get()),
+ base::Passed(&cursor_wrapper), key, primary_key,
+ base::Passed(&mojo_value), base::Passed(&blob_info)));
complete_ = true;
}
@@ -574,7 +591,7 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessDatabase(
}
void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursor(
- std::unique_ptr<IndexedDBCursor> cursor,
+ SafeIOThreadCursorWrapper cursor,
const IndexedDBKey& key,
const IndexedDBKey& primary_key,
::indexed_db::mojom::ValuePtr value,
@@ -587,7 +604,7 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursor(
return;
}
auto cursor_impl = base::MakeUnique<CursorImpl>(
- std::move(cursor), origin_, dispatcher_host_.get(), idb_runner_);
+ std::move(cursor.cursor), origin_, dispatcher_host_.get(), idb_runner_);
if (value && !CreateAllBlobs(blob_info, &value->blob_or_file_info))
return;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698