Fix use-after-free in ~TextureInfo
In some paths, the TextureInfo (refcounted) may outlive the TextureManager,
accessing a stale pointer in its destructor. This fixes it.
BUG=chromium-os:25634
TEST=pepper flash, reload videos many times.
Review URL: http://codereview.chromium.org/9374004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121188 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 34c6916e..c440108 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1519,6 +1519,9 @@
TextureToIOSurfaceMap texture_to_io_surface_map_;
#endif
+ typedef std::vector<GLES2DecoderImpl*> ChildList;
+ ChildList children_;
+
DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
};
@@ -2699,6 +2702,10 @@
void GLES2DecoderImpl::Destroy() {
bool have_context = context_.get() && MakeCurrent();
+ ChildList children = children_;
+ for (ChildList::iterator it = children.begin(); it != children.end(); ++it)
+ (*it)->SetParent(NULL, 0);
+ DCHECK(children_.empty());
SetParent(NULL, 0);
// Unbind everything.
@@ -2801,6 +2808,12 @@
// parent pointer is a weak pointer so it will be null if the parent has
// already been destroyed.
if (parent_) {
+ ChildList::iterator it = std::find(
+ parent_->children_.begin(),
+ parent_->children_.end(),
+ this);
+ DCHECK(it != parent_->children_.end());
+ parent_->children_.erase(it);
// First check the texture has been mapped into the parent. This might not
// be the case if initialization failed midway through.
GLuint service_id = offscreen_saved_color_texture_->id();
@@ -2813,6 +2826,14 @@
GLES2DecoderImpl* new_parent_impl = static_cast<GLES2DecoderImpl*>(
new_parent);
if (new_parent_impl) {
+#ifndef NDEBUG
+ ChildList::iterator it = std::find(
+ new_parent_impl->children_.begin(),
+ new_parent_impl->children_.end(),
+ this);
+ DCHECK(it == new_parent_impl->children_.end());
+#endif
+ new_parent_impl->children_.push_back(this);
// Map the ID of the saved offscreen texture into the parent so that
// it can reference it.
GLuint service_id = offscreen_saved_color_texture_->id();