diff options
author | cmumford <cmumford@chromium.org> | 2015-04-23 11:56:12 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-23 18:57:15 +0000 |
commit | 29777a8ee0f45b8160ec004e74013d5b62b6828a (patch) | |
tree | b5f5899f752d857e23724270265e72f8ace13859 /content/browser/indexed_db | |
parent | c3a924fd8ec1041f3320c6d784d98da681719d95 (diff) | |
download | chromium_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.cc | 21 |
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); }; |