[go: nahoru, domu]

Skip to content

Commit

Permalink
Bug 1481467 part 2 - Use JSAutoRealm instead of JSAutoRealmAllowCCW i…
Browse files Browse the repository at this point in the history
…n JSXrayTraits::getOwnPropertyFromTargetIfSafe. r=bz

Because getOwnPropertyFromTargetIfSafe operates in the Xray target realm/compartment and we cannot use the Xray wrapper with JSAutoRealm, we pass the caller's global as wrapperGlobal and use that.
  • Loading branch information
jandem committed Aug 8, 2018
1 parent d5afdc8 commit d66831e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
29 changes: 21 additions & 8 deletions js/xpconnect/wrappers/XrayWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,11 @@ bool JSXrayTraits::getOwnPropertyFromWrapperIfSafe(JSContext* cx,
{
MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx));
RootedObject target(cx, getTargetObject(wrapper));
RootedObject wrapperGlobal(cx, JS::CurrentGlobalOrNull(cx));
{
JSAutoRealm ar(cx, target);
JS_MarkCrossZoneId(cx, id);
if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, outDesc))
if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, wrapperGlobal, id, outDesc))
return false;
}
return JS_WrapPropertyDescriptor(cx, outDesc);
Expand All @@ -289,6 +290,7 @@ bool JSXrayTraits::getOwnPropertyFromWrapperIfSafe(JSContext* cx,
bool JSXrayTraits::getOwnPropertyFromTargetIfSafe(JSContext* cx,
HandleObject target,
HandleObject wrapper,
HandleObject wrapperGlobal,
HandleId id,
MutableHandle<PropertyDescriptor> outDesc)
{
Expand All @@ -297,6 +299,8 @@ bool JSXrayTraits::getOwnPropertyFromTargetIfSafe(JSContext* cx,
MOZ_ASSERT(getTargetObject(wrapper) == target);
MOZ_ASSERT(js::IsObjectInContextCompartment(target, cx));
MOZ_ASSERT(WrapperFactory::IsXrayWrapper(wrapper));
MOZ_ASSERT(JS_IsGlobalObject(wrapperGlobal));
js::AssertSameCompartment(wrapper, wrapperGlobal);
MOZ_ASSERT(outDesc.object() == nullptr);

Rooted<PropertyDescriptor> desc(cx);
Expand All @@ -309,7 +313,7 @@ bool JSXrayTraits::getOwnPropertyFromTargetIfSafe(JSContext* cx,

// Disallow accessor properties.
if (desc.hasGetterOrSetter()) {
JSAutoRealmAllowCCW ar(cx, wrapper);
JSAutoRealm ar(cx, wrapperGlobal);
JS_MarkCrossZoneId(cx, id);
return ReportWrapperDenial(cx, id, WrapperDenialForXray, "property has accessor");
}
Expand All @@ -321,30 +325,30 @@ bool JSXrayTraits::getOwnPropertyFromTargetIfSafe(JSContext* cx,

// Disallow non-subsumed objects.
if (!AccessCheck::subsumes(target, propObj)) {
JSAutoRealmAllowCCW ar(cx, wrapper);
JSAutoRealm ar(cx, wrapperGlobal);
JS_MarkCrossZoneId(cx, id);
return ReportWrapperDenial(cx, id, WrapperDenialForXray, "value not same-origin with target");
}

// Disallow non-Xrayable objects.
XrayType xrayType = GetXrayType(propObj);
if (xrayType == NotXray || xrayType == XrayForOpaqueObject) {
JSAutoRealmAllowCCW ar(cx, wrapper);
JSAutoRealm ar(cx, wrapperGlobal);
JS_MarkCrossZoneId(cx, id);
return ReportWrapperDenial(cx, id, WrapperDenialForXray, "value not Xrayable");
}

// Disallow callables.
if (JS::IsCallable(propObj)) {
JSAutoRealmAllowCCW ar(cx, wrapper);
JSAutoRealm ar(cx, wrapperGlobal);
JS_MarkCrossZoneId(cx, id);
return ReportWrapperDenial(cx, id, WrapperDenialForXray, "value is callable");
}
}

// Disallow any property that shadows something on its (Xrayed)
// prototype chain.
JSAutoRealmAllowCCW ar2(cx, wrapper);
JSAutoRealm ar2(cx, wrapperGlobal);
JS_MarkCrossZoneId(cx, id);
RootedObject proto(cx);
bool foundOnProto = false;
Expand Down Expand Up @@ -659,6 +663,8 @@ JSXrayTraits::resolveOwnProperty(JSContext* cx, HandleObject wrapper,
bool
JSXrayTraits::delete_(JSContext* cx, HandleObject wrapper, HandleId id, ObjectOpResult& result)
{
MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx));

RootedObject holder(cx, ensureHolder(cx, wrapper));
if (!holder)
return false;
Expand All @@ -670,11 +676,12 @@ JSXrayTraits::delete_(JSContext* cx, HandleObject wrapper, HandleId id, ObjectOp
bool isObjectOrArrayInstance = (key == JSProto_Object || key == JSProto_Array) &&
!isPrototype(holder);
if (isObjectOrArrayInstance) {
RootedObject wrapperGlobal(cx, JS::CurrentGlobalOrNull(cx));
RootedObject target(cx, getTargetObject(wrapper));
JSAutoRealm ar(cx, target);
JS_MarkCrossZoneId(cx, id);
Rooted<PropertyDescriptor> desc(cx);
if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, &desc))
if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, wrapperGlobal, id, &desc))
return false;
if (desc.object())
return JS_DeletePropertyById(cx, target, id, result);
Expand Down Expand Up @@ -799,6 +806,8 @@ bool
JSXrayTraits::enumerateNames(JSContext* cx, HandleObject wrapper, unsigned flags,
AutoIdVector& props)
{
MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx));

RootedObject target(cx, getTargetObject(wrapper));
RootedObject holder(cx, ensureHolder(cx, wrapper));
if (!holder)
Expand All @@ -810,6 +819,7 @@ JSXrayTraits::enumerateNames(JSContext* cx, HandleObject wrapper, unsigned flags
// object, but only after filtering them carefully.
if (key == JSProto_Object || key == JSProto_Array) {
MOZ_ASSERT(props.empty());
RootedObject wrapperGlobal(cx, JS::CurrentGlobalOrNull(cx));
{
JSAutoRealm ar(cx, target);
AutoIdVector targetProps(cx);
Expand All @@ -822,8 +832,11 @@ JSXrayTraits::enumerateNames(JSContext* cx, HandleObject wrapper, unsigned flags
for (size_t i = 0; i < targetProps.length(); ++i) {
Rooted<PropertyDescriptor> desc(cx);
RootedId id(cx, targetProps[i]);
if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, &desc))
if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, wrapperGlobal, id,
&desc))
{
return false;
}
if (desc.object())
props.infallibleAppend(id);
}
Expand Down
4 changes: 3 additions & 1 deletion js/xpconnect/wrappers/XrayWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,10 +267,12 @@ class JSXrayTraits : public XrayTraits
JS::HandleId id,
JS::MutableHandle<JS::PropertyDescriptor> desc);

// Like the above, but operates in the target compartment.
// Like the above, but operates in the target compartment. wrapperGlobal is
// the caller's global (must be in the wrapper compartment).
static bool getOwnPropertyFromTargetIfSafe(JSContext* cx,
JS::HandleObject target,
JS::HandleObject wrapper,
JS::HandleObject wrapperGlobal,
JS::HandleId id,
JS::MutableHandle<JS::PropertyDescriptor> desc);

Expand Down

0 comments on commit d66831e

Please sign in to comment.