Bug 800915 - Clarify and refine the semantics of SecurityWrapper so that it is used if and only if unwrapping is unsafe. r=mrbkap

The naming scheme for Xray typedefs is the concatenation of the tuple:
({SC,}, {Security,Permissive}, Xray, {XPCWN,DOM}). This is admittedly a bit
much, but I think it's still better than explicitly doing the "typdef Foo Xray"
everywhere. Moreover, once the new DOM bindings are done, the last component
in the tuple will go away.
This commit is contained in:
Bobby Holley 2012-11-12 17:35:31 -08:00
Родитель 05ff1bb2bb
Коммит b892d5b7f5
4 изменённых файлов: 50 добавлений и 69 удалений

Просмотреть файл

@ -133,20 +133,13 @@ FilteringWrapper<Base, Policy>::enter(JSContext *cx, JSObject *wrapper, jsid id,
#define SOW FilteringWrapper<CrossCompartmentSecurityWrapper, OnlyIfSubjectIsSystem>
#define SCSOW FilteringWrapper<SameCompartmentSecurityWrapper, OnlyIfSubjectIsSystem>
#define XOW FilteringWrapper<XrayWrapper<CrossCompartmentSecurityWrapper>, \
CrossOriginAccessiblePropertiesOnly>
#define DXOW FilteringWrapper<XrayDOM, \
CrossOriginAccessiblePropertiesOnly>
#define NNXOW FilteringWrapper<CrossCompartmentSecurityWrapper, \
CrossOriginAccessiblePropertiesOnly>
#define LW FilteringWrapper<XrayWrapper<SameCompartmentSecurityWrapper>, \
LocationPolicy>
#define XLW FilteringWrapper<XrayWrapper<CrossCompartmentSecurityWrapper>, \
LocationPolicy>
#define CW FilteringWrapper<SameCompartmentSecurityWrapper, \
ComponentsObjectPolicy>
#define XCW FilteringWrapper<CrossCompartmentSecurityWrapper, \
ComponentsObjectPolicy>
#define XOW FilteringWrapper<SecurityXrayXPCWN, CrossOriginAccessiblePropertiesOnly>
#define DXOW FilteringWrapper<SecurityXrayDOM, CrossOriginAccessiblePropertiesOnly>
#define NNXOW FilteringWrapper<CrossCompartmentSecurityWrapper, CrossOriginAccessiblePropertiesOnly>
#define LW FilteringWrapper<SCSecurityXrayXPCWN, LocationPolicy>
#define XLW FilteringWrapper<SecurityXrayXPCWN, LocationPolicy>
#define CW FilteringWrapper<SameCompartmentSecurityWrapper, ComponentsObjectPolicy>
#define XCW FilteringWrapper<CrossCompartmentSecurityWrapper, ComponentsObjectPolicy>
template<> SOW SOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::SOW_FLAG);
template<> SCSOW SCSOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |

Просмотреть файл

@ -323,10 +323,9 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
// Native objects must be wrapped into an X-ray wrapper.
XrayType type = GetXrayType(obj);
if (type == XrayForDOMObject) {
wrapper = &XrayDOM::singleton;
wrapper = &PermissiveXrayDOM::singleton;
} else if (type == XrayForWrappedNative) {
typedef XrayWrapper<CrossCompartmentWrapper> Xray;
wrapper = &Xray::singleton;
wrapper = &PermissiveXrayXPCWN::singleton;
} else {
wrapper = &CrossCompartmentWrapper::singleton;
}
@ -347,13 +346,12 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
if (targetdata &&
(wn = GetWrappedNative(cx, obj)) &&
wn->HasProto() && wn->GetProto()->ClassIsDOMObject()) {
typedef XrayWrapper<CrossCompartmentSecurityWrapper> Xray;
if (IsLocationObject(obj))
wrapper = &FilteringWrapper<Xray, LocationPolicy>::singleton;
wrapper = &FilteringWrapper<SecurityXrayXPCWN, LocationPolicy>::singleton;
else
wrapper = &FilteringWrapper<Xray, CrossOriginAccessiblePropertiesOnly>::singleton;
wrapper = &FilteringWrapper<SecurityXrayXPCWN, CrossOriginAccessiblePropertiesOnly>::singleton;
} else if (mozilla::dom::UseDOMXray(obj)) {
wrapper = &FilteringWrapper<XrayDOM, CrossOriginAccessiblePropertiesOnly>::singleton;
wrapper = &FilteringWrapper<SecurityXrayDOM, CrossOriginAccessiblePropertiesOnly>::singleton;
} else if (IsComponentsObject(obj)) {
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
ComponentsObjectPolicy>::singleton;
@ -408,8 +406,7 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
OnlyIfSubjectIsSystem>::singleton;
} else if (IsLocationObject(obj)) {
typedef XrayWrapper<CrossCompartmentSecurityWrapper> Xray;
wrapper = &FilteringWrapper<Xray, LocationPolicy>::singleton;
wrapper = &FilteringWrapper<SecurityXrayXPCWN, LocationPolicy>::singleton;
} else if (IsComponentsObject(obj)) {
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
ComponentsObjectPolicy>::singleton;
@ -417,10 +414,9 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
(type = GetXrayType(obj)) == NotXray) {
wrapper = &CrossCompartmentWrapper::singleton;
} else if (type == XrayForDOMObject) {
wrapper = &XrayDOM::singleton;
wrapper = &PermissiveXrayDOM::singleton;
} else {
typedef XrayWrapper<CrossCompartmentWrapper> Xray;
wrapper = &Xray::singleton;
wrapper = &PermissiveXrayXPCWN::singleton;
}
} else {
NS_ASSERTION(!AccessCheck::needsSystemOnlyWrapper(obj),
@ -433,18 +429,16 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
CrossOriginAccessiblePropertiesOnly>::singleton;
} else if (type == XrayForDOMObject) {
wrapper = &FilteringWrapper<XrayDOM,
wrapper = &FilteringWrapper<SecurityXrayDOM,
CrossOriginAccessiblePropertiesOnly>::singleton;
} else {
typedef XrayWrapper<CrossCompartmentSecurityWrapper> Xray;
// Location objects can become same origin after navigation, so we might
// have to grant transparent access later on.
if (IsLocationObject(obj)) {
wrapper = &FilteringWrapper<Xray, LocationPolicy>::singleton;
wrapper = &FilteringWrapper<SecurityXrayXPCWN, LocationPolicy>::singleton;
} else {
wrapper = &FilteringWrapper<Xray,
CrossOriginAccessiblePropertiesOnly>::singleton;
wrapper = &FilteringWrapper<SecurityXrayXPCWN,
CrossOriginAccessiblePropertiesOnly>::singleton;
}
}
}
@ -474,8 +468,6 @@ WrapperFactory::WrapForSameCompartment(JSContext *cx, JSObject *obj)
return wn->GetSameCompartmentSecurityWrapper(cx);
}
typedef FilteringWrapper<XrayWrapper<SameCompartmentSecurityWrapper>, LocationPolicy> LW;
bool
WrapperFactory::IsLocationObject(JSObject *obj)
{
@ -489,7 +481,8 @@ WrapperFactory::WrapLocationObject(JSContext *cx, JSObject *obj)
JSObject *proto;
if (!js::GetObjectProto(cx, obj, &proto))
return nullptr;
return Wrapper::New(cx, obj, proto, js::GetObjectParent(obj), &LW::singleton);
return Wrapper::New(cx, obj, proto, js::GetObjectParent(obj),
&FilteringWrapper<SCSecurityXrayXPCWN, LocationPolicy>::singleton);
}
// Call WaiveXrayAndWrap when you have a JS object that you don't want to be
@ -564,9 +557,9 @@ WrapperFactory::WrapForSameCompartmentXray(JSContext *cx, JSObject *obj)
// Select the appropriate proxy handler.
Wrapper *wrapper = NULL;
if (type == XrayForWrappedNative)
wrapper = &XrayWrapper<Wrapper>::singleton;
wrapper = &SCPermissiveXrayXPCWN::singleton;
else if (type == XrayForDOMObject)
wrapper = &XrayWrapper<Wrapper, DOMXrayTraits>::singleton;
wrapper = &SCPermissiveXrayDOM::singleton;
else
MOZ_NOT_REACHED("Bad Xray type");

Просмотреть файл

@ -1702,37 +1702,26 @@ XrayWrapper<Base, Traits>::construct(JSContext *cx, JSObject *wrapper, unsigned
return Traits::construct(cx, wrapper, argc, argv, rval);
}
/*
* The Permissive / Security variants should be used depending on whether the
* compartment of the wrapper is guranteed to subsume the compartment of the
* wrapped object (i.e. - whether it is safe from a security perspective to
* unwrap the wrapper).
*/
#define XRAY XrayWrapper<CrossCompartmentSecurityWrapper, XPCWrappedNativeXrayTraits >
template <> XRAY XRAY::singleton(0);
template class XRAY;
#undef XRAY
#define XRAY XrayWrapper<SameCompartmentSecurityWrapper, XPCWrappedNativeXrayTraits >
template <> XRAY XRAY::singleton(0);
template class XRAY;
#undef XRAY
#define XRAY XrayWrapper<CrossCompartmentWrapper, XPCWrappedNativeXrayTraits >
template <> XRAY XRAY::singleton(0);
template class XRAY;
#undef XRAY
#define XRAY XrayWrapper<CrossCompartmentWrapper, DOMXrayTraits >
template <> XRAY XRAY::singleton(0);
template class XRAY;
#undef XRAY
/* Same-compartment non-filtering versions. */
#define XRAY XrayWrapper<Wrapper, XPCWrappedNativeXrayTraits >
template <> XRAY XRAY::singleton(0);
template class XRAY;
#undef XRAY
#define XRAY XrayWrapper<Wrapper, DOMXrayTraits >
template <> XRAY XRAY::singleton(0);
template class XRAY;
#undef XRAY
template<>
PermissiveXrayXPCWN PermissiveXrayXPCWN::singleton(0);
template<>
SecurityXrayXPCWN SecurityXrayXPCWN::singleton(0);
template<>
PermissiveXrayDOM PermissiveXrayDOM::singleton(0);
template<>
SecurityXrayDOM SecurityXrayDOM::singleton(0);
template<>
SCPermissiveXrayXPCWN SCPermissiveXrayXPCWN::singleton(0);
template<>
SCSecurityXrayXPCWN SCSecurityXrayXPCWN::singleton(0);
template<>
SCPermissiveXrayDOM SCPermissiveXrayDOM::singleton(0);
}

Просмотреть файл

@ -93,7 +93,13 @@ class XrayWrapper : public Base {
JS::AutoIdVector &props);
};
typedef XrayWrapper<js::CrossCompartmentWrapper, DOMXrayTraits > XrayDOM;
typedef XrayWrapper<js::CrossCompartmentWrapper, XPCWrappedNativeXrayTraits > PermissiveXrayXPCWN;
typedef XrayWrapper<js::CrossCompartmentSecurityWrapper, XPCWrappedNativeXrayTraits > SecurityXrayXPCWN;
typedef XrayWrapper<js::CrossCompartmentWrapper, DOMXrayTraits > PermissiveXrayDOM;
typedef XrayWrapper<js::CrossCompartmentSecurityWrapper, DOMXrayTraits > SecurityXrayDOM;
typedef XrayWrapper<js::SameCompartmentSecurityWrapper, XPCWrappedNativeXrayTraits > SCSecurityXrayXPCWN;
typedef XrayWrapper<js::Wrapper, XPCWrappedNativeXrayTraits > SCPermissiveXrayXPCWN;
typedef XrayWrapper<js::Wrapper, DOMXrayTraits > SCPermissiveXrayDOM;
class SandboxProxyHandler : public js::Wrapper {
public: