diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 1f4e837c6c3c..dd334d26bc65 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -1606,6 +1606,25 @@ ContentParent::OnChannelError() PContentParent::OnChannelError(); } +void +ContentParent::OnBeginSyncTransaction() { + if (XRE_GetProcessType() == GeckoProcessType_Default) { + nsCOMPtr console(do_GetService(NS_CONSOLESERVICE_CONTRACTID)); + JSContext *cx = nsContentUtils::GetCurrentJSContext(); + if (console && cx) { + nsAutoString filename; + uint32_t lineno = 0; + nsJSUtils::GetCallingLocation(cx, filename, &lineno); + nsCOMPtr error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID)); + error->Init(NS_LITERAL_STRING("unsafe CPOW usage"), filename, EmptyString(), + lineno, 0, nsIScriptError::warningFlag, "chrome javascript"); + console->LogMessage(error); + } else { + NS_WARNING("Unsafe synchronous IPC message"); + } + } +} + void ContentParent::OnChannelConnected(int32_t pid) { diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index f6b723836c5b..4101b9b84b19 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -253,6 +253,8 @@ public: virtual void OnChannelError() MOZ_OVERRIDE; + virtual void OnBeginSyncTransaction() MOZ_OVERRIDE; + virtual PCrashReporterParent* AllocPCrashReporterParent(const NativeThreadId& tid, const uint32_t& processType) MOZ_OVERRIDE; diff --git a/ipc/glue/MessageChannel.cpp b/ipc/glue/MessageChannel.cpp index 2a4f87ed3811..9ca1a10fd764 100644 --- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -719,6 +719,9 @@ MessageChannel::Send(Message* aMsg, Message* aReply) AssertWorkerThread(); mMonitor->AssertNotCurrentThreadOwns(); + if (mCurrentTransaction == 0) + mListener->OnBeginSyncTransaction(); + #ifdef OS_WIN SyncStackFrame frame(this, false); #endif diff --git a/ipc/glue/MessageLink.h b/ipc/glue/MessageLink.h index 42535c02c73b..069024c7799e 100644 --- a/ipc/glue/MessageLink.h +++ b/ipc/glue/MessageLink.h @@ -88,6 +88,10 @@ class MessageListener virtual void OnExitedCall() { NS_RUNTIMEABORT("default impl shouldn't be invoked"); } + /* This callback is called when a sync message is sent that begins a new IPC transaction + (i.e., when it is not part of an existing sequence of nested messages). */ + virtual void OnBeginSyncTransaction() { + } virtual RacyInterruptPolicy MediateInterruptRace(const Message& parent, const Message& child) {