Plugin create can end up destroying its renderer.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Jul 2015 05:55:20 +0000 (05:55 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Jul 2015 05:55:20 +0000 (05:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=146824
rdar://problem/18921429

Reviewed by Andreas Kling.

Plugins can run arbitrary code during initialization. If the plugin
happens to destroy the associated node, its renderer becomes invalid.
This patch checks whether the renderer survived the createPlugin() call.
(This WeakPtr pattern is also used in RenderWidget to avoid dangling pointers.)

Speculative fix. Not reproducible.

* loader/SubframeLoader.cpp:
(WebCore::SubframeLoader::loadPlugin):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@186666 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/loader/SubframeLoader.cpp

index 9de2ad5..146e312 100644 (file)
@@ -1,3 +1,21 @@
+2015-07-09  Zalan Bujtas  <zalan@apple.com>
+
+        Plugin create can end up destroying its renderer.
+        https://bugs.webkit.org/show_bug.cgi?id=146824
+        rdar://problem/18921429
+
+        Reviewed by Andreas Kling.
+
+        Plugins can run arbitrary code during initialization. If the plugin
+        happens to destroy the associated node, its renderer becomes invalid.
+        This patch checks whether the renderer survived the createPlugin() call.
+        (This WeakPtr pattern is also used in RenderWidget to avoid dangling pointers.)
+
+        Speculative fix. Not reproducible.
+
+        * loader/SubframeLoader.cpp:
+        (WebCore::SubframeLoader::loadPlugin):
+
 2015-07-09  Dan Bernstein  <mitz@apple.com>
 
         WebCore part of Track and expose policies for external URL schemes and App Links separately
index a6e155b..4569b25 100644 (file)
@@ -391,10 +391,12 @@ Document* SubframeLoader::document() const
 
 bool SubframeLoader::loadPlugin(HTMLPlugInImageElement& pluginElement, const URL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback)
 {
-    RenderEmbeddedObject* renderer = pluginElement.renderEmbeddedObject();
+    if (useFallback)
+        return false;
 
+    RenderEmbeddedObject* renderer = pluginElement.renderEmbeddedObject();
     // FIXME: This code should not depend on renderer!
-    if (!renderer || useFallback)
+    if (!renderer)
         return false;
 
     pluginElement.subframeLoaderWillCreatePlugIn(url);
@@ -408,7 +410,11 @@ bool SubframeLoader::loadPlugin(HTMLPlugInImageElement& pluginElement, const URL
         loadManually = false;
 #endif
 
+    WeakPtr<RenderWidget> weakRenderer = renderer->createWeakPtr();
+    // createPlugin *may* cause this renderer to disappear from underneath.
     RefPtr<Widget> widget = m_frame.loader().client().createPlugin(contentSize, &pluginElement, url, paramNames, paramValues, mimeType, loadManually);
+    if (!weakRenderer)
+        return false;
 
     if (!widget) {
         if (!renderer->isPluginUnavailable())