From a63bc07919d4a7fc83f5fc758bfa2742514e705b Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Tue, 4 Nov 2014 17:38:19 -0800 Subject: [PATCH] Bug 1092446 - [e10s] Allow unprivileged scopes to call content-to-chrome CPOWs (r=bholley) --- dom/base/test/chrome/cpows_child.js | 9 +++++++++ dom/base/test/chrome/cpows_parent.xul | 5 ++++- js/xpconnect/wrappers/WrapperFactory.cpp | 9 +++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/dom/base/test/chrome/cpows_child.js b/dom/base/test/chrome/cpows_child.js index 95bdfb9e1f5a..b81a24a6d662 100644 --- a/dom/base/test/chrome/cpows_child.js +++ b/dom/base/test/chrome/cpows_child.js @@ -87,6 +87,15 @@ function parent_test() addMessageListener("cpows:from_parent", (msg) => { let obj = msg.objects.obj; ok(obj.a == 1, "correct value from parent"); + + // Test that a CPOW reference to a function in the chrome process + // is callable from unprivileged content. Greasemonkey uses this + // functionality. + let func = msg.objects.func; + let sb = Cu.Sandbox('http://www.example.com', {}); + sb.func = func; + ok(sb.eval('func()') == 101, "can call parent's function in child"); + done_count++; if (done_count == 2) sendSyncMessage("cpows:done", {}); diff --git a/dom/base/test/chrome/cpows_parent.xul b/dom/base/test/chrome/cpows_parent.xul index 78ed01d80bb6..bc69541219fe 100644 --- a/dom/base/test/chrome/cpows_parent.xul +++ b/dom/base/test/chrome/cpows_parent.xul @@ -181,8 +181,11 @@ let func = message.objects.func; let result = func(n => 2*n); ok(result == 20, "result == 20"); + function f() { + return 101; + } let obj = {a:1, __exposedProps__: {"a": "r"}}; - savedMM.sendAsyncMessage("cpows:from_parent", {}, {obj: obj}); + savedMM.sendAsyncMessage("cpows:from_parent", {}, {obj: obj, func: f}); } // Make sure errors in this file actually hit window.onerror. diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index 0792b9a343a9..0d8eee539c75 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -16,9 +16,11 @@ #include "xpcprivate.h" #include "XPCMaps.h" #include "mozilla/dom/BindingUtils.h" +#include "JavaScriptParent.h" #include "jsfriendapi.h" #include "mozilla/Likely.h" #include "nsContentUtils.h" +#include "nsXULAppAPI.h" using namespace JS; using namespace js; @@ -423,9 +425,12 @@ WrapperFactory::Rewrap(JSContext *cx, HandleObject existing, HandleObject obj, } // If this is a chrome function being exposed to content, we need to allow - // call (but nothing else). + // call (but nothing else). We allow CPOWs that purport to be function's + // here, but only in the content process. else if (originIsChrome && !targetIsChrome && - IdentifyStandardInstance(obj) == JSProto_Function) + (IdentifyStandardInstance(obj) == JSProto_Function || + (jsipc::IsCPOW(obj) && JS::IsCallable(obj) && + XRE_GetProcessType() == GeckoProcessType_Content))) { wrapper = &FilteringWrapper::singleton; }