Bug 965094. Reconcile the behavior of the JSObject* argument for Func on interfaces and on interface members. r=bholley

This commit is contained in:
Boris Zbarsky 2014-02-05 13:38:18 -05:00
parent 67076fac17
commit 8367dee14d
7 changed files with 22 additions and 46 deletions

View File

@ -12,7 +12,8 @@
using namespace mozilla::dom;
/* static */ bool
InterAppComm::EnabledForScope(JSContext* /* unused */, JS::Handle<JSObject*> aObj)
InterAppComm::EnabledForScope(JSContext* /* unused */,
JS::Handle<JSObject*> /* unused */)
{
// Disable the constructors if they're disabled by the preference for sure.
if (!Preferences::GetBool("dom.inter-app-communication-api.enabled", false)) {
@ -21,5 +22,5 @@ InterAppComm::EnabledForScope(JSContext* /* unused */, JS::Handle<JSObject*> aOb
// Only expose the constructors to the chrome codes for Gecko internal uses.
// The content pages shouldn't be aware of the constructors.
return xpc::AccessCheck::isChrome(aObj);
return nsContentUtils::ThreadsafeIsCallerChrome();
}

View File

@ -17,7 +17,8 @@ namespace dom {
class InterAppComm
{
public:
static bool EnabledForScope(JSContext* /* unused */, JS::Handle<JSObject*> aObj);
static bool EnabledForScope(JSContext* /* unused */,
JS::Handle<JSObject*> /* unused */);
};
} // namespace dom

View File

@ -1960,17 +1960,7 @@ Navigator::HasDataStoreSupport(JSContext* cx, JSObject* aGlobal)
bool
Navigator::HasDownloadsSupport(JSContext* aCx, JSObject* aGlobal)
{
// We'll need a rooted object so that GC doesn't make it go away while
// we're calling CheckIsChrome.
JS::Rooted<JSObject*> global(aCx, aGlobal);
// Because of the way this API must be implemented, it will interact with
// objects attached to a chrome window. We always want to allow this.
if (ThreadsafeCheckIsChrome(aCx, global)) {
return true;
}
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(global);
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
return win &&
CheckPermission(win, "downloads") &&

View File

@ -2856,7 +2856,16 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
}
ConstructorEnabled* checkEnabledForScope = name_struct->mConstructorEnabled;
if (checkEnabledForScope && !checkEnabledForScope(cx, obj)) {
// We do the enabled check on the current compartment of cx, but for the
// actual object we pass in the underlying object in the Xray case. That
// way the callee can decide whether to allow access based on the caller
// or the window being touched.
JS::Rooted<JSObject*> global(cx,
js::CheckedUnwrap(obj, /* stopAtOuter = */ false));
if (!global) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if (checkEnabledForScope && !checkEnabledForScope(cx, global)) {
return NS_OK;
}
@ -2895,11 +2904,6 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
// This all could use some grand refactoring, but for now we just limp
// along.
if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
JS::Rooted<JSObject*> global(cx,
js::CheckedUnwrap(obj, /* stopAtOuter = */ false));
if (!global) {
return NS_ERROR_DOM_SECURITY_ERR;
}
JS::Rooted<JSObject*> interfaceObject(cx);
{
JSAutoCompartment ac(cx, global);

View File

@ -2142,14 +2142,6 @@ ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
return true;
}
bool
ThreadsafeCheckIsChrome(JSContext* aCx, JSObject* aObj)
{
using mozilla::dom::workers::GetWorkerPrivateFromContext;
return NS_IsMainThread() ? xpc::AccessCheck::isChrome(aObj):
GetWorkerPrivateFromContext(aCx)->UsesSystemPrincipal();
}
bool
IsInPrivilegedApp(JSContext* aCx, JSObject* aObj)
{

View File

@ -2351,9 +2351,6 @@ public:
}
};
bool
ThreadsafeCheckIsChrome(JSContext* aCx, JSObject* aObj);
/*
* Helper function for testing whether the given object comes from a
* privileged app.

View File

@ -1125,10 +1125,10 @@ class CGClassConstructor(CGAbstractStaticMethod):
JS::Rooted<JSObject*> obj(cx, &args.callee());
"""
if isChromeOnly(self._ctor):
preamble += """ if (!%s) {
preamble += """ if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
return ThrowingConstructor(cx, argc, vp);
}
""" % GetAccessCheck(self.descriptor, "cx", "obj")
"""
name = self._ctor.identifier.name
nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
callGenerator = CGMethodCall(nativeName, True, self.descriptor,
@ -1975,7 +1975,7 @@ if (!unforgeableHolder) {
else:
properties = "nullptr"
if self.properties.hasChromeOnly():
accessCheck = GetAccessCheck(self.descriptor, "aCx", "aGlobal")
accessCheck = "nsContentUtils::ThreadsafeIsCallerChrome()"
chromeProperties = accessCheck + " ? &sChromeOnlyNativeProperties : nullptr"
else:
chromeProperties = "nullptr"
@ -2130,7 +2130,7 @@ class CGConstructorEnabled(CGAbstractMethod):
assert isinstance(pref, list) and len(pref) == 1
conditions.append('Preferences::GetBool("%s")' % pref[0])
if iface.getExtendedAttribute("ChromeOnly"):
conditions.append(GetAccessCheck(self.descriptor, "aCx", "aObj"))
conditions.append("nsContentUtils::ThreadsafeIsCallerChrome()")
func = iface.getExtendedAttribute("Func")
if func:
assert isinstance(func, list) and len(func) == 1
@ -2193,15 +2193,6 @@ def CreateBindingJSObject(descriptor, properties, parent):
"""
return create % parent
def GetAccessCheck(descriptor, context, object):
"""
context is the name of a JSContext*
object is the name of a JSObject*
returns a string
"""
return "ThreadsafeCheckIsChrome(%s, %s)" % (context, object)
def InitUnforgeablePropertiesOnObject(descriptor, obj, properties, failureReturnValue=""):
"""
properties is a PropertyArrays instance
@ -2224,7 +2215,7 @@ def InitUnforgeablePropertiesOnObject(descriptor, obj, properties, failureReturn
unforgeables.append(
CGIfWrapper(CGGeneric(defineUnforgeables %
unforgeableAttrs.variableName(True)),
GetAccessCheck(descriptor, "aCx", obj)))
"nsContentUtils::ThreadsafeIsCallerChrome()"))
return CGList(unforgeables, "\n")
def InitUnforgeableProperties(descriptor, properties):
@ -9748,7 +9739,7 @@ class CGBindingRoot(CGThing):
# chromeonly _create method.
(desc.interface.isJSImplemented() and
desc.interface.hasInterfaceObject()))
bindingHeaders["AccessCheck.h"] = any(
bindingHeaders["nsContentUtils.h"] = any(
descriptorHasChromeOnly(d) for d in descriptors)
# XXXkhuey ugly hack but this is going away soon.
bindingHeaders['xpcprivate.h'] = webIDLFile.endswith("EventTarget.webidl")