bug 580128 - Create SOWs same and cross compartment. r=jst

This commit is contained in:
Blake Kaplan 2010-10-10 15:48:55 -07:00
Родитель 6c9d0884d7
Коммит 25fc5d0395
5 изменённых файлов: 51 добавлений и 15 удалений

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

@ -49,6 +49,7 @@
#include "nsJSPrincipals.h"
#include "nsWrapperCache.h"
#include "WrapperFactory.h"
#include "AccessCheck.h"
//#define STRICT_CHECK_OF_UNICODE
#ifdef STRICT_CHECK_OF_UNICODE
@ -1383,6 +1384,23 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
flat = locationWrapper;
}
else if(wrapper->NeedsSOW() &&
!xpc::AccessCheck::isChrome(cx->compartment))
{
JSObject *sowWrapper = wrapper->GetWrapper();
if(!sowWrapper)
{
sowWrapper = xpc::WrapperFactory::WrapSOWObject(cx, flat);
if(!sowWrapper)
return JS_FALSE;
// Cache the sow wrapper to ensure that we maintain
// the identity of this node.
wrapper->SetWrapper(sowWrapper);
}
flat = sowWrapper;
}
else
{
OBJ_TO_OUTER_OBJECT(cx, flat);

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

@ -329,6 +329,9 @@ AccessCheck::isScriptAccessOnly(JSContext *cx, JSObject *wrapper)
// If the wrapper indicates script-only access, we are done.
if (flags & WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG) {
if (flags & WrapperFactory::SOW_FLAG)
return !isSystemOnlyAccessPermitted(cx);
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
if (!ssm)
return true;

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

@ -150,6 +150,7 @@ FilteringWrapper<Base, Policy>::enter(JSContext *cx, JSObject *wrapper, jsid id,
}
#define SOW FilteringWrapper<JSCrossCompartmentWrapper, OnlyIfSubjectIsSystem>
#define SCSOW FilteringWrapper<JSWrapper, OnlyIfSubjectIsSystem>
#define COW FilteringWrapper<JSCrossCompartmentWrapper, ExposedPropertiesOnly>
#define XOW FilteringWrapper<XrayWrapper<JSCrossCompartmentWrapper, CrossCompartmentXray>, \
CrossOriginAccessiblePropertiesOnly>
@ -159,7 +160,10 @@ FilteringWrapper<Base, Policy>::enter(JSContext *cx, JSObject *wrapper, jsid id,
#define XLW FilteringWrapper<XrayWrapper<JSCrossCompartmentWrapper, CrossCompartmentXray>, \
SameOriginOrCrossOriginAccessiblePropertiesOnly>
template<> SOW SOW::singleton(0);
template<> SOW SOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::SOW_FLAG);
template<> SCSOW SCSOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::SOW_FLAG);
template<> COW COW::singleton(0);
template<> XOW XOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::PARTIALLY_TRANSPARENT);

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

@ -198,22 +198,16 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO
}
}
} else if (AccessCheck::isChrome(origin)) {
// If an object that needs a system only wrapper crosses into content
// from chrome, we have to wrap it into a system only wrapper on the
// fly. In this case we don't need to restrict to exposed properties
// since only privileged content will be allowed to touch it anyway.
wrapper = &FilteringWrapper<JSCrossCompartmentWrapper,
ExposedPropertiesOnly>::singleton;
} else if (AccessCheck::isSameOrigin(origin, target)) {
// Same origin we use a transparent wrapper, unless the compartment asks
// for an Xray or the wrapper needs a SOW.
if (AccessCheck::needsSystemOnlyWrapper(obj)) {
wrapper = &FilteringWrapper<JSCrossCompartmentWrapper,
OnlyIfSubjectIsSystem>::singleton;
} else {
wrapper = &FilteringWrapper<JSCrossCompartmentWrapper,
ExposedPropertiesOnly>::singleton;
}
} else if (AccessCheck::isSameOrigin(origin, target)) {
// Same origin we use a transparent wrapper, unless the compartment asks
// for an Xray.
if (static_cast<xpc::CompartmentPrivate*>(target->data)->preferXrays &&
IS_WN_WRAPPER(obj)) {
} else if (static_cast<xpc::CompartmentPrivate*>(target->data)->preferXrays &&
IS_WN_WRAPPER(obj)) {
typedef XrayWrapper<JSCrossCompartmentWrapper, CrossCompartmentXray> Xray;
wrapper = &Xray::singleton;
xrayHolder = Xray::createHolder(cx, obj, parent);
@ -223,6 +217,9 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO
wrapper = &JSCrossCompartmentWrapper::singleton;
}
} else {
NS_ASSERTION(!AccessCheck::needsSystemOnlyWrapper(obj),
"bad object exposed across origins");
// Cross origin we want to disallow scripting and limit access to
// a predefined set of properties. XrayWrapper adds a property
// (.wrappedJSObject) which allows bypassing the XrayWrapper, but
@ -307,4 +304,14 @@ WrapperFactory::WaiveXrayAndWrap(JSContext *cx, jsval *vp)
return JS_WrapValue(cx, vp);
}
JSObject *
WrapperFactory::WrapSOWObject(JSContext *cx, JSObject *obj)
{
JSObject *wrapperObj =
JSWrapper::New(cx, obj, obj->getProto(), NULL,
&FilteringWrapper<JSWrapper,
OnlyIfSubjectIsSystem>::singleton);
return wrapperObj;
}
}

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

@ -47,7 +47,8 @@ class WrapperFactory {
enum { WAIVE_XRAY_WRAPPER_FLAG = (1<<0),
IS_XRAY_WRAPPER_FLAG = (1<<1),
SCRIPT_ACCESS_ONLY_FLAG = (1<<2),
PARTIALLY_TRANSPARENT = (1<<3) };
PARTIALLY_TRANSPARENT = (1<<3),
SOW_FLAG = (1<<4) };
// Return true if any of any of the nested wrappers have the flag set.
static bool HasWrapperFlag(JSObject *wrapper, uintN flag) {
@ -89,6 +90,9 @@ class WrapperFactory {
// Wrap wrapped object into a waiver wrapper and then re-wrap it.
static bool WaiveXrayAndWrap(JSContext *cx, jsval *vp);
// Wrap a (same compartment) object in a SOW.
static JSObject *WrapSOWObject(JSContext *cx, JSObject *obj);
};
extern JSWrapper WaiveXrayWrapperWrapper;