Bug 1202887 - Delay WebBrowserPersist error callbacks caused by IPC ActorDestroy. r=billm

The way IPDL glue currently works, it's unsafe to do Send__delete__ on
another actor in that context, and these callbacks can indirectly cause
that; see bug for details.
This commit is contained in:
Jed Davis 2015-09-14 11:18:28 -07:00
parent d777a7a7e9
commit 8a29eeb71f
3 changed files with 28 additions and 3 deletions

View File

@ -37,7 +37,16 @@ WebBrowserPersistDocumentParent::ActorDestroy(ActorDestroyReason aWhy)
mReflection = nullptr;
}
if (mOnReady) {
mOnReady->OnError(NS_ERROR_FAILURE);
// Bug 1202887: If this is part of a subtree destruction, then
// anything which could cause another actor in that subtree to
// be Send__delete__()ed will cause use-after-free -- such as
// dropping the last reference to another document's
// WebBrowserPersistRemoteDocument. To avoid that, defer the
// callback until after the entire subtree is destroyed.
nsCOMPtr<nsIRunnable> errorLater = NS_NewRunnableMethodWithArg
<nsresult>(mOnReady, &nsIWebBrowserPersistDocumentReceiver::OnError,
NS_ERROR_FAILURE);
NS_DispatchToCurrentThread(errorLater);
mOnReady = nullptr;
}
}

View File

@ -6,6 +6,8 @@
#include "WebBrowserPersistResourcesParent.h"
#include "nsThreadUtils.h"
namespace mozilla {
NS_IMPL_ISUPPORTS(WebBrowserPersistResourcesParent,
@ -29,7 +31,13 @@ void
WebBrowserPersistResourcesParent::ActorDestroy(ActorDestroyReason aWhy)
{
if (aWhy != Deletion && mVisitor) {
mVisitor->EndVisit(mDocument, NS_ERROR_FAILURE);
// See comment in WebBrowserPersistDocumentParent::ActorDestroy
// (or bug 1202887) for why this is deferred.
nsCOMPtr<nsIRunnable> errorLater = NS_NewRunnableMethodWithArgs
<nsCOMPtr<nsIWebBrowserPersistDocument>, nsresult>
(mVisitor, &nsIWebBrowserPersistResourceVisitor::EndVisit,
mDocument, NS_ERROR_FAILURE);
NS_DispatchToCurrentThread(errorLater);
}
mVisitor = nullptr;
}

View File

@ -7,6 +7,7 @@
#include "WebBrowserPersistSerializeParent.h"
#include "nsReadableUtils.h"
#include "nsThreadUtils.h"
namespace mozilla {
@ -74,7 +75,14 @@ WebBrowserPersistSerializeParent::ActorDestroy(ActorDestroyReason aWhy)
{
if (mFinish) {
MOZ_ASSERT(aWhy != Deletion);
mFinish->OnFinish(mDocument, mStream, EmptyCString(), NS_ERROR_FAILURE);
// See comment in WebBrowserPersistDocumentParent::ActorDestroy
// (or bug 1202887) for why this is deferred.
nsCOMPtr<nsIRunnable> errorLater = NS_NewRunnableMethodWithArgs
<nsCOMPtr<nsIWebBrowserPersistDocument>, nsCOMPtr<nsIOutputStream>,
nsCString, nsresult>
(mFinish, &nsIWebBrowserPersistWriteCompletion::OnFinish,
mDocument, mStream, EmptyCString(), NS_ERROR_FAILURE);
NS_DispatchToCurrentThread(errorLater);
mFinish = nullptr;
}
}