chromiumembedded / cef

Chromium Embedded Framework (CEF). A simple framework for embedding Chromium-based browsers in other applications.
https://bitbucket.org/chromiumembedded/cef/
Other
3.28k stars 457 forks source link

SiteIsolation: OnLoadError call in render process when loading page that contains cross-domain iframe #2857

Open magreenblatt opened 4 years ago

magreenblatt commented 4 years ago

Original report by Masako Toda (Bitbucket: truenip).


I’m not sure if this is a bug or intended behavior.

STEPS:

  1. 79.0.10 on Windows 10.
  2. Navigate to http://sakisakisoftware.com/test/iframe-cross-domain.html
  3. Notice CefLoadHandler::OnLoadError is called in render process (see the attachment)

It doesn’t happen if I run with --disable-site-isolation-trials

magreenblatt commented 4 years ago

Is the OnLoadError call in the old renderer process? If so, it sounds like this is “expected behavior” in cases where the iframe will instead be loaded in a new renderer process due to site isolation.

If the OnLoadError call is problematic for you then perhaps we can identify a way to filter it out.

magreenblatt commented 4 years ago

Original comment by Masako Toda (Bitbucket: truenip).


Yes, it’s in the old renderer process. And I understand it can be an expected behavior for site-isolation. The reason why I reported is because I encountered an issue as follows:

If I call frame->ExecuteJavaScript or frame->GetV8Context in CefLoadHandler::OnLoadError, the renderer process crashes. Currently, I’m checking if the frame is still part of the browser in our client code as a workaround. It would be nice if CEF doesn’t call OnLoadError for those frames.

magreenblatt commented 4 years ago

I think the OnLoadError callback could still be valuable to notify the current renderer that the request will be handled in a different renderer (by checking the error code). Maybe we can do something to keep the CefFrame methods from crashing in this case. Can you post a call stack for the crash from calling ExecuteJavaScript or GetV8Context in this case?

magreenblatt commented 4 years ago

Original comment by Masako Toda (Bitbucket: truenip).


I missed your reply. Sorry about the delayed response.

I modified cefclient code as follows:

void ClientAppRenderer::OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
  ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) override {
  if (browser && frame->IsValid())
    (void)frame->GetV8Context();
}

And then attempted to load http://sakisakisoftware.com/test/iframe-cross-domain.html to make a renderer process crash. The callstack is as follows:

    libcef.dll!logging::LogMessage::~LogMessage() Line 953  C++
    libcef.dll!blink::Document::CanExecuteScripts(blink::ReasonForCallingCanExecuteScripts reason) Line 7085    C++
    libcef.dll!blink::FrameLoader::DispatchDidClearWindowObjectInMainWorld() Line 1522  C++
    libcef.dll!blink::LocalWindowProxy::Initialize() Line 208   C++
    [Inline Frame] libcef.dll!blink::WindowProxyManager::GetWindowProxy(blink::DOMWrapperWorld & world) Line 49 C++
    libcef.dll!blink::Frame::GetWindowProxy(blink::DOMWrapperWorld & world) Line 199    C++
    libcef.dll!blink::LocalFrame::WindowProxy(blink::DOMWrapperWorld & world) Line 604  C++
    libcef.dll!blink::ToV8ContextEvenIfDetached(blink::LocalFrame * frame, blink::DOMWrapperWorld & world) Line 768 C++
    libcef.dll!blink::ToScriptStateImpl(blink::LocalFrame * frame, blink::DOMWrapperWorld & world) Line 724 C++
    libcef.dll!blink::ToScriptState(blink::LocalFrame * frame, blink::DOMWrapperWorld & world) Line 786 C++
    libcef.dll!blink::ToScriptStateForMainWorld(blink::LocalFrame * frame) Line 789 C++
    libcef.dll!blink::WebLocalFrameImpl::MainWorldScriptContext() Line 916  C++
    libcef.dll!CefFrameImpl::GetV8Context() Line 239    C++
    libcef.dll!`anonymous namespace'::frame_get_v8context(_cef_frame_t * self) Line 367 C++
    cefclient.exe!CefFrameCToCpp::GetV8Context() Line 373   C++
>   cefclient.exe!client::ClientAppRenderer::OnLoadError(scoped_refptr<CefBrowser> browser, scoped_refptr<CefFrame> frame, cef_errorcode_t errorCode, const CefStringBase<CefStringTraitsUTF16> & errorText, const CefStringBase<CefStringTraitsUTF16> & failedUrl) Line 109    C++
    cefclient.exe!`anonymous namespace'::load_handler_on_load_error(_cef_load_handler_t * self, _cef_browser_t * browser, _cef_frame_t * frame, cef_errorcode_t errorCode, const _cef_string_utf16_t * errorText, const _cef_string_utf16_t * failedUrl) Line 129   C++
    libcef.dll!CefLoadHandlerCToCpp::OnLoadError(scoped_refptr<CefBrowser> browser, scoped_refptr<CefFrame> frame, <unnamed-tag> errorCode, const CefStringBase<CefStringTraitsUTF16> & errorText, const CefStringBase<CefStringTraitsUTF16> & failedUrl) Line 129  C++
    libcef.dll!CefRenderFrameObserver::OnLoadError() Line 244   C++
    libcef.dll!content::RenderFrameImpl::NotifyObserversOfFailedProvisionalLoad() Line 2756 C++
    libcef.dll!content::RenderFrameImpl::AbortClientNavigation() Line 4602  C++
    libcef.dll!blink::FrameLoader::CancelClientNavigation() Line 1472   C++
    libcef.dll!blink::FrameLoader::StopAllLoaders() Line 1041   C++
    libcef.dll!blink::LocalFrame::DetachImpl(blink::FrameDetachType type) Line 439  C++
    libcef.dll!blink::Frame::Detach(blink::FrameDetachType type) Line 88    C++
    libcef.dll!blink::WebFrame::Swap(blink::WebFrame * frame) Line 102  C++
    libcef.dll!content::RenderFrameImpl::OnUnload(int proxy_routing_id, bool is_loading, const content::FrameReplicationState & replicated_frame_state) Line 2329   C++
    [Inline Frame] libcef.dll!base::DispatchToMethodImpl(content::RenderFrameImpl * const & method, void(content::RenderFrameImpl::*)(int, bool, const content::FrameReplicationState &) args, std::__1::tuple<int,bool,content::FrameReplicationState> &&, std::__1::integer_sequence<unsigned int,0,1,2>) Line 52 C++
    [Inline Frame] libcef.dll!base::DispatchToMethod(content::RenderFrameImpl * const & method, void(content::RenderFrameImpl::*)(int, bool, const content::FrameReplicationState &) args, std::__1::tuple<int,bool,content::FrameReplicationState> &&) Line 60 C++
    [Inline Frame] libcef.dll!IPC::DispatchToMethod(content::RenderFrameImpl * obj, void(content::RenderFrameImpl::*)(int, bool, const content::FrameReplicationState &) method, void *, std::__1::tuple<int,bool,content::FrameReplicationState> && tuple) Line 51 C++
    libcef.dll!IPC::MessageT<UnfreezableFrameMsg_Unload_Meta,std::__1::tuple<int,bool,content::FrameReplicationState>,void>::Dispatch<content::RenderFrameImpl,content::RenderFrameImpl,void,void (content::RenderFrameImpl::*)(int, bool, const content::FrameReplicationState &) __attribute__((thiscall))>(const IPC::Message * msg, content::RenderFrameImpl * obj, content::RenderFrameImpl * sender, void * parameter, void(content::RenderFrameImpl::*)(int, bool, const content::FrameReplicationState &) func) Line 139    C++
    libcef.dll!content::RenderFrameImpl::OnMessageReceived(const IPC::Message & msg) Line 2192  C++
    libcef.dll!IPC::ChannelProxy::Context::OnDispatchMessage(const IPC::Message & message) Line 328 C++
    [Inline Frame] libcef.dll!base::internal::FunctorTraits<bool (content::BrowserMessageFilter::Internal::*)(const IPC::Message &) __attribute__((thiscall)),void>::Invoke(bool(content::BrowserMessageFilter::Internal::*)(const IPC::Message &) method, scoped_refptr<content::BrowserMessageFilter::Internal> && receiver_ptr, IPC::Message && args) Line 489   C++
    [Inline Frame] libcef.dll!base::internal::FunctorTraits<base::internal::IgnoreResultHelper<bool (content::BrowserMessageFilter::Internal::*)(const IPC::Message &) __attribute__((thiscall))>,void>::Invoke(base::internal::IgnoreResultHelper<bool (content::BrowserMessageFilter::Internal::*)(const IPC::Message &) __attribute__((thiscall))> && ignore_result_helper, scoped_refptr<content::BrowserMessageFilter::Internal> && args, IPC::Message && args) Line 568   C++
    [Inline Frame] libcef.dll!base::internal::InvokeHelper<0,void>::MakeItSo(base::internal::IgnoreResultHelper<bool (content::BrowserMessageFilter::Internal::*)(const IPC::Message &) __attribute__((thiscall))> && functor, scoped_refptr<content::BrowserMessageFilter::Internal> && args, IPC::Message && args) Line 623   C++
    [Inline Frame] libcef.dll!base::internal::Invoker<base::internal::BindState<base::internal::IgnoreResultHelper<bool (content::BrowserMessageFilter::Internal::*)(const IPC::Message &) __attribute__((thiscall))>,scoped_refptr<content::BrowserMessageFilter::Internal>,IPC::Message>,void ()>::RunImpl(base::internal::IgnoreResultHelper<bool (content::BrowserMessageFilter::Internal::*)(const IPC::Message &) __attribute__((thiscall))> && functor, std::__1::tuple<scoped_refptr<content::BrowserMessageFilter::Internal>,IPC::Message> && bound, std::__1::integer_sequence<unsigned int,0,1>) Line 696    C++
    libcef.dll!base::internal::Invoker<base::internal::BindState<base::internal::IgnoreResultHelper<bool (content::BrowserMessageFilter::Internal::*)(const IPC::Message &) __attribute__((thiscall))>,scoped_refptr<content::BrowserMessageFilter::Internal>,IPC::Message>,void ()>::RunOnce(base::internal::BindStateBase * base) Line 669    C++
    [Inline Frame] libcef.dll!base::OnceCallback<void ()>::Run() Line 98    C++
    libcef.dll!base::TaskAnnotator::RunTask(const char * trace_event_name, base::PendingTask * pending_task) Line 142   C++
    libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::sequence_manager::LazyNow * continuation_lazy_now, bool * ran_task) Line 325 C++
    libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() Line 250 C++
    libcef.dll!base::MessagePumpDefault::Run(base::MessagePump::Delegate * delegate) Line 41    C++
    libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool application_tasks_allowed, base::TimeDelta timeout) Line 433 C++
    libcef.dll!base::RunLoop::Run() Line 126    C++
    libcef.dll!content::RendererMain(const content::MainFunctionParams & parameters) Line 227   C++
    libcef.dll!content::RunOtherNamedProcessTypeMain(const std::__1::basic_string<char,std::__1::char_traits<char>,std::__1::allocator<char>> & process_type, const content::MainFunctionParams & main_function_params, content::ContentMainDelegate * delegate) Line 556   C++
    libcef.dll!content::ContentMainRunnerImpl::Run(bool start_service_manager_only) Line 883    C++
    libcef.dll!content::ContentServiceManagerMainDelegate::RunEmbedderProcess() Line 52 C++
    libcef.dll!service_manager::MainRun(service_manager::MainParams & params) Line 461  C++
    libcef.dll!service_manager::Main(service_manager::MainParams & params) Line 508 C++
    libcef.dll!content::ContentMain(const content::ContentMainParams & params) Line 19  C++
    libcef.dll!CefExecuteProcess(const CefMainArgs & args, scoped_refptr<CefApp> application, void * windows_sandbox_info) Line 293 C++
    libcef.dll!cef_execute_process(const _cef_main_args_t * args, _cef_app_t * application, void * windows_sandbox_info) Line 78    C++
    cefclient.exe!CefExecuteProcess(const CefMainArgs & args, scoped_refptr<CefApp> application, void * windows_sandbox_info) Line 81   C++
    cefclient.exe!client::`anonymous namespace'::RunMain(HINSTANCE__ * hInstance, int nCmdShow) Line 66 C++
    cefclient.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 134    C++
    cefclient.exe!invoke_main() Line 123    C++
    cefclient.exe!__scrt_common_main_seh() Line 288 C++
    cefclient.exe!__scrt_common_main() Line 331 C++
    cefclient.exe!wWinMainCRTStartup() Line 17  C++
    kernel32.dll!74d40419() Unknown
    [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  Unknown
    ntdll.dll!775a66dd()    Unknown
    ntdll.dll!775a66ad()    Unknown

Lastly, I got this callstack with 83.0.4103.97_windows32.

magreenblatt commented 4 years ago