| Index: extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
|
| diff --git a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
|
| index bec7d1c852016119b6a3df2e7c81ffbda0047867..77bc51f90115172134dee545dd4d04e3e0f5b7bd 100644
|
| --- a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
|
| +++ b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
|
| @@ -15,6 +15,7 @@
|
| #include "components/guest_view/renderer/iframe_guest_view_request.h"
|
| #include "content/public/child/v8_value_converter.h"
|
| #include "content/public/renderer/render_frame.h"
|
| +#include "content/public/renderer/render_frame_observer.h"
|
| #include "content/public/renderer/render_thread.h"
|
| #include "content/public/renderer/render_view.h"
|
| #include "extensions/common/extension.h"
|
| @@ -57,6 +58,18 @@ content::RenderFrame* GetRenderFrame(v8::Handle<v8::Value> value) {
|
| return content::RenderFrame::FromWebFrame(frame);
|
| }
|
|
|
| +class RenderFrameStatus : public content::RenderFrameObserver {
|
| + public:
|
| + explicit RenderFrameStatus(content::RenderFrame* render_frame)
|
| + : content::RenderFrameObserver(render_frame) {}
|
| + ~RenderFrameStatus() final {}
|
| +
|
| + bool is_ok() { return render_frame() != nullptr; }
|
| +
|
| + // RenderFrameObserver implementation.
|
| + void OnDestruct() final {}
|
| +};
|
| +
|
| } // namespace
|
|
|
| GuestViewInternalCustomBindings::GuestViewInternalCustomBindings(
|
| @@ -144,6 +157,8 @@ void GuestViewInternalCustomBindings::AttachGuest(
|
| // is invalid?
|
| if (!guest_view_container)
|
| return;
|
| + // Retain a weak pointer so we can easily test if the container goes away.
|
| + auto weak_ptr = guest_view_container->GetWeakPtr();
|
|
|
| int guest_instance_id = args[1]->Int32Value();
|
|
|
| @@ -155,6 +170,12 @@ void GuestViewInternalCustomBindings::AttachGuest(
|
| params = base::DictionaryValue::From(std::move(params_as_value));
|
| CHECK(params);
|
| }
|
| + // We should be careful that some malicious JS in the GuestView's embedder
|
| + // hasn't destroyed |guest_view_container| during the enumeration of the
|
| + // properties of the guest's object during extraction of |params| above
|
| + // (see https://crbug.com/683523).
|
| + if (!weak_ptr)
|
| + return;
|
|
|
| // Add flag to |params| to indicate that the element size is specified in
|
| // logical units.
|
| @@ -221,6 +242,12 @@ void GuestViewInternalCustomBindings::AttachIframeGuest(
|
| int element_instance_id = args[0]->Int32Value();
|
| int guest_instance_id = args[1]->Int32Value();
|
|
|
| + // Get the WebLocalFrame before (possibly) executing any user-space JS while
|
| + // getting the |params|. We track the status of the RenderFrame via an
|
| + // observer in case it is deleted during user code execution.
|
| + content::RenderFrame* render_frame = GetRenderFrame(args[3]);
|
| + RenderFrameStatus render_frame_status(render_frame);
|
| +
|
| std::unique_ptr<base::DictionaryValue> params;
|
| {
|
| std::unique_ptr<V8ValueConverter> converter(V8ValueConverter::create());
|
| @@ -229,19 +256,19 @@ void GuestViewInternalCustomBindings::AttachIframeGuest(
|
| params = base::DictionaryValue::From(std::move(params_as_value));
|
| CHECK(params);
|
| }
|
| + if (!render_frame_status.is_ok())
|
| + return;
|
|
|
| - // Add flag to |params| to indicate that the element size is specified in
|
| - // logical units.
|
| - params->SetBoolean(guest_view::kElementSizeIsLogical, true);
|
| -
|
| - content::RenderFrame* render_frame = GetRenderFrame(args[3]);
|
| blink::WebLocalFrame* frame = render_frame->GetWebFrame();
|
| -
|
| // Parent must exist.
|
| blink::WebFrame* parent_frame = frame->parent();
|
| DCHECK(parent_frame);
|
| DCHECK(parent_frame->isWebLocalFrame());
|
|
|
| + // Add flag to |params| to indicate that the element size is specified in
|
| + // logical units.
|
| + params->SetBoolean(guest_view::kElementSizeIsLogical, true);
|
| +
|
| content::RenderFrame* embedder_parent_frame =
|
| content::RenderFrame::FromWebFrame(parent_frame);
|
|
|
|
|