mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 823348 - Replace security wrapper enumeration with a more rule-based approach. r=mrbkap
This commit is contained in:
parent
4b3c0f19a3
commit
c82ae67593
@ -307,6 +307,41 @@ DEBUG_CheckUnwrapSafety(JSObject *obj, js::Wrapper *handler,
|
||||
#define DEBUG_CheckUnwrapSafety(obj, handler, origin, target) {}
|
||||
#endif
|
||||
|
||||
static Wrapper *
|
||||
SelectWrapper(bool securityWrapper, bool wantXrays, XrayType xrayType,
|
||||
bool waiveXrays)
|
||||
{
|
||||
// Waived Xray uses a modified CCW that has transparent behavior but
|
||||
// transitively waives Xrays on arguments.
|
||||
if (waiveXrays) {
|
||||
MOZ_ASSERT(!securityWrapper);
|
||||
return &WaiveXrayWrapper::singleton;
|
||||
}
|
||||
|
||||
// If we don't want or can't use Xrays, select a wrapper that's either
|
||||
// entirely transparent or entirely opaque.
|
||||
if (!wantXrays || xrayType == NotXray) {
|
||||
if (!securityWrapper)
|
||||
return &CrossCompartmentWrapper::singleton;
|
||||
return &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton;
|
||||
}
|
||||
|
||||
// Ok, we're using Xray. If this isn't a security wrapper, use the permissive
|
||||
// version and skip the filter.
|
||||
if (!securityWrapper) {
|
||||
if (xrayType == XrayForWrappedNative)
|
||||
return &PermissiveXrayXPCWN::singleton;
|
||||
return &PermissiveXrayDOM::singleton;
|
||||
}
|
||||
|
||||
// This is a security wrapper. Use the security versions and filter.
|
||||
if (xrayType == XrayForWrappedNative)
|
||||
return &FilteringWrapper<SecurityXrayXPCWN,
|
||||
CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
return &FilteringWrapper<SecurityXrayDOM,
|
||||
CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
|
||||
JSObject *wrappedProto, JSObject *parent,
|
||||
@ -367,66 +402,33 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
|
||||
//
|
||||
// Now, handle the regular cases.
|
||||
//
|
||||
// These are wrappers we can compute using a rule-based approach. In order
|
||||
// to do so, we need to compute some parameters.
|
||||
//
|
||||
else {
|
||||
|
||||
else if (targetIsChrome) {
|
||||
if (originIsChrome) {
|
||||
wrapper = &CrossCompartmentWrapper::singleton;
|
||||
} else {
|
||||
if (flags & WAIVE_XRAY_WRAPPER_FLAG) {
|
||||
// If we waived the X-ray wrapper for this object, wrap it into a
|
||||
// special wrapper to transitively maintain the X-ray waiver.
|
||||
wrapper = &WaiveXrayWrapper::singleton;
|
||||
} else {
|
||||
// Native objects must be wrapped into an X-ray wrapper.
|
||||
if (xrayType == XrayForDOMObject) {
|
||||
wrapper = &PermissiveXrayDOM::singleton;
|
||||
} else if (xrayType == XrayForWrappedNative) {
|
||||
wrapper = &PermissiveXrayXPCWN::singleton;
|
||||
} else {
|
||||
wrapper = &CrossCompartmentWrapper::singleton;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (originIsChrome) {
|
||||
// The wrapper is a security wrapper (protecting the wrappee) if and
|
||||
// only if the target does not subsume the origin.
|
||||
bool securityWrapper = !targetSubsumesOrigin;
|
||||
|
||||
if (xrayType == XrayForWrappedNative) {
|
||||
wrapper = &FilteringWrapper<SecurityXrayXPCWN, CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
} else if (xrayType == XrayForDOMObject) {
|
||||
wrapper = &FilteringWrapper<SecurityXrayDOM, CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
} else {
|
||||
MOZ_NOT_REACHED();
|
||||
}
|
||||
} else if (targetSubsumesOrigin) {
|
||||
// For the same-origin case we use a transparent wrapper, unless one
|
||||
// of the following is true:
|
||||
// * The object is flagged as needing a SOW.
|
||||
// * The object is a Components object.
|
||||
// * The context compartment specifically requested Xray vision into
|
||||
// same-origin compartments.
|
||||
// Xrays are warranted if either the target or the origin don't trust
|
||||
// each other. This is generally the case, unless the two are same-origin
|
||||
// and the caller has not requested same-origin Xrays.
|
||||
//
|
||||
// The first two cases always require a security wrapper for non-chrome
|
||||
// access, regardless of the origin of the object.
|
||||
if (!targetdata->wantXrays || xrayType == NotXray) {
|
||||
wrapper = &CrossCompartmentWrapper::singleton;
|
||||
} else if (xrayType == XrayForDOMObject) {
|
||||
wrapper = &PermissiveXrayDOM::singleton;
|
||||
} else {
|
||||
wrapper = &PermissiveXrayXPCWN::singleton;
|
||||
}
|
||||
} else {
|
||||
// Cross origin we want to disallow scripting and limit access to
|
||||
// a predefined set of properties.
|
||||
if (xrayType == NotXray) {
|
||||
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton;
|
||||
} else if (xrayType == XrayForDOMObject) {
|
||||
wrapper = &FilteringWrapper<SecurityXrayDOM,
|
||||
CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
} else {
|
||||
wrapper = &FilteringWrapper<SecurityXrayXPCWN,
|
||||
CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
}
|
||||
// Xrays are a bidirectional protection, since it affords clarity to the
|
||||
// caller and privacy to the callee.
|
||||
bool wantXrays = !(sameOrigin && !targetdata->wantXrays);
|
||||
|
||||
// If Xrays are warranted, the caller may waive them for non-security
|
||||
// wrappers.
|
||||
bool waiveXrays = wantXrays && !securityWrapper &&
|
||||
(flags & WAIVE_XRAY_WRAPPER_FLAG);
|
||||
|
||||
wrapper = SelectWrapper(securityWrapper, wantXrays, xrayType, waiveXrays);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// If the prototype of a chrome object being wrapped in content is a prototype
|
||||
// for a standard class, use the one from the content compartment so
|
||||
// that we can safely take advantage of things like .forEach().
|
||||
|
Loading…
Reference in New Issue
Block a user