summaryrefslogtreecommitdiffstats
path: root/content/browser/indexed_db
diff options
context:
space:
mode:
authorcmumford <cmumford@chromium.org>2015-04-23 11:56:12 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-23 18:57:15 +0000
commit29777a8ee0f45b8160ec004e74013d5b62b6828a (patch)
treeb5f5899f752d857e23724270265e72f8ace13859 /content/browser/indexed_db
parentc3a924fd8ec1041f3320c6d784d98da681719d95 (diff)
downloadchromium_src-29777a8ee0f45b8160ec004e74013d5b62b6828a.zip
chromium_src-29777a8ee0f45b8160ec004e74013d5b62b6828a.tar.gz
chromium_src-29777a8ee0f45b8160ec004e74013d5b62b6828a.tar.bz2
IndexedDB: Protect against use-after-free in ChainedBlobWriter.
This is a speculative fix for a heap user-after-free bug. Was unable to verify using a Windows SyzyASan build. The theory is that if Abort() was called before ChainedBlobWriterImpl::WriteNextFile() could set waiting_for_callback_ then the ReportWriteCompletion() would never know that it was aborted and attempt to use it's dangling raw pointer to a deleted IndexedDBBackingStore instance. Also in this change is the elimination of the redundant aborted_ member variable. BUG=472614 Review URL: https://codereview.chromium.org/1060613002 Cr-Commit-Position: refs/heads/master@{#326597}
Diffstat (limited to 'content/browser/indexed_db')
-rw-r--r--content/browser/indexed_db/indexed_db_backing_store.cc21
1 files changed, 9 insertions, 12 deletions
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc
index e7107c5..5000e50 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -2242,8 +2242,7 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl
: waiting_for_callback_(false),
database_id_(database_id),
backing_store_(backing_store),
- callback_(callback),
- aborted_(false) {
+ callback_(callback) {
blobs_.swap(*blobs);
iter_ = blobs_.begin();
backing_store->task_runner()->PostTask(
@@ -2261,8 +2260,8 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl
if (delegate_.get()) // Only present for Blob, not File.
content::BrowserThread::DeleteSoon(
content::BrowserThread::IO, FROM_HERE, delegate_.release());
- if (aborted_) {
- self_ref_ = NULL;
+ if (aborted_self_ref_.get()) {
+ aborted_self_ref_ = NULL;
return;
}
if (iter_->size() != -1 && iter_->size() != bytes_written)
@@ -2278,38 +2277,36 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl
void Abort() override {
if (!waiting_for_callback_)
return;
- self_ref_ = this;
- aborted_ = true;
+ aborted_self_ref_ = this;
}
private:
- ~ChainedBlobWriterImpl() override {}
+ ~ChainedBlobWriterImpl() override { DCHECK(!waiting_for_callback_); }
void WriteNextFile() {
DCHECK(!waiting_for_callback_);
- DCHECK(!aborted_);
+ DCHECK(!aborted_self_ref_.get());
if (iter_ == blobs_.end()) {
- DCHECK(!self_ref_.get());
callback_->Run(true);
return;
} else {
+ waiting_for_callback_ = true;
if (!backing_store_->WriteBlobFile(database_id_, *iter_, this)) {
+ waiting_for_callback_ = false;
callback_->Run(false);
return;
}
- waiting_for_callback_ = true;
}
}
bool waiting_for_callback_;
- scoped_refptr<ChainedBlobWriterImpl> self_ref_;
+ scoped_refptr<ChainedBlobWriterImpl> aborted_self_ref_;
WriteDescriptorVec blobs_;
WriteDescriptorVec::const_iterator iter_;
int64 database_id_;
IndexedDBBackingStore* backing_store_;
scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback_;
scoped_ptr<FileWriterDelegate> delegate_;
- bool aborted_;
DISALLOW_COPY_AND_ASSIGN(ChainedBlobWriterImpl);
};