Bug 788914 - Kill the XOW flag. r=mrbkap

There are really two questions to be asked: is the caller chrome, and does the
caller subsume the callee. We have other, more precise ways of asking both of
these questions.
This commit is contained in:
Bobby Holley 2012-09-11 01:05:10 -07:00
Родитель e5ff464782
Коммит ecaa32c106
7 изменённых файлов: 34 добавлений и 23 удалений

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

@ -2170,7 +2170,7 @@ bool
nsDOMClassInfo::ObjectIsNativeWrapper(JSContext* cx, JSObject* obj)
{
return xpc::WrapperFactory::IsXrayWrapper(obj) &&
!xpc::WrapperFactory::IsXOW(obj);
xpc::AccessCheck::wrapperSubsumes(obj);
}
nsDOMClassInfo::nsDOMClassInfo(nsDOMClassInfoData* aData) : mData(aData)

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

@ -7,7 +7,9 @@
#include "XPCWrapper.h"
#include "AccessCheck.h"
#include "WrapperFactory.h"
#include "AccessCheck.h"
using namespace xpc;
namespace XPCNativeWrapper {
static inline
@ -37,8 +39,7 @@ UnwrapNW(JSContext *cx, unsigned argc, jsval *vp)
return true;
}
if (xpc::WrapperFactory::IsXrayWrapper(obj) &&
!xpc::WrapperFactory::IsXOW(obj)) {
if (WrapperFactory::IsXrayWrapper(obj) && AccessCheck::isChrome(obj)) {
return JS_GetProperty(cx, obj, "wrappedJSObject", vp);
}

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

@ -52,6 +52,16 @@ AccessCheck::subsumes(JSCompartment *a, JSCompartment *b)
return subsumes;
}
// Does the compartment of the wrapper subsumes the compartment of the wrappee?
bool
AccessCheck::wrapperSubsumes(JSObject *wrapper)
{
MOZ_ASSERT(js::IsWrapper(wrapper));
JSObject *wrapped = js::UnwrapObject(wrapper);
return AccessCheck::subsumes(js::GetObjectCompartment(wrapper),
js::GetObjectCompartment(wrapped));
}
bool
AccessCheck::isLocationObjectSameOrigin(JSContext *cx, JSObject *wrapper)
{
@ -91,6 +101,12 @@ AccessCheck::isChrome(JSCompartment *compartment)
return NS_SUCCEEDED(ssm->IsSystemPrincipal(principal, &privileged)) && privileged;
}
bool
AccessCheck::isChrome(JSObject *obj)
{
return isChrome(js::GetObjectCompartment(obj));
}
bool
AccessCheck::callerIsChrome()
{

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

@ -19,7 +19,9 @@ namespace xpc {
class AccessCheck {
public:
static bool subsumes(JSCompartment *a, JSCompartment *b);
static bool wrapperSubsumes(JSObject *wrapper);
static bool isChrome(JSCompartment *compartment);
static bool isChrome(JSObject *obj);
static bool callerIsChrome();
static nsIPrincipal *getPrincipal(JSCompartment *compartment);
static bool isCrossOriginAccessPermitted(JSContext *cx, JSObject *obj, jsid id,

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

@ -125,14 +125,10 @@ 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<> XOW XOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::XOW_FLAG);
template<> PXOW PXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::XOW_FLAG);
template<> DXOW DXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::XOW_FLAG);
template<> NNXOW NNXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::XOW_FLAG);
template<> XOW XOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG);
template<> PXOW PXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG);
template<> DXOW DXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG);
template<> NNXOW NNXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG);
template<> LW LW::singleton(WrapperFactory::SHADOWING_FORBIDDEN);
template<> XLW XLW::singleton(WrapperFactory::SHADOWING_FORBIDDEN);

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

@ -18,8 +18,7 @@ class WrapperFactory {
enum { WAIVE_XRAY_WRAPPER_FLAG = js::Wrapper::LAST_USED_FLAG << 1,
IS_XRAY_WRAPPER_FLAG = WAIVE_XRAY_WRAPPER_FLAG << 1,
SCRIPT_ACCESS_ONLY_FLAG = IS_XRAY_WRAPPER_FLAG << 1,
XOW_FLAG = SCRIPT_ACCESS_ONLY_FLAG << 1,
SOW_FLAG = XOW_FLAG << 1,
SOW_FLAG = SCRIPT_ACCESS_ONLY_FLAG << 1,
// Prevent scripts from shadowing native properties.
// NB: Applies only to Xray wrappers.
@ -38,10 +37,6 @@ class WrapperFactory {
return HasWrapperFlag(wrapper, IS_XRAY_WRAPPER_FLAG);
}
static bool IsXOW(JSObject *wrapper) {
return HasWrapperFlag(wrapper, XOW_FLAG);
}
static bool HasWaiveXrayFlag(JSObject *wrapper) {
return HasWrapperFlag(wrapper, WAIVE_XRAY_WRAPPER_FLAG);
}

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

@ -919,13 +919,12 @@ XPCWrappedNativeXrayTraits::resolveOwnProperty(JSContext *cx, js::Wrapper &jsWra
// in the wrapper's compartment here, not the wrappee.
MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx));
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
if (!WrapperFactory::IsXOW(wrapper) &&
if (AccessCheck::isChrome(wrapper) &&
(((id == rt->GetStringID(XPCJSRuntime::IDX_BASEURIOBJECT) ||
id == rt->GetStringID(XPCJSRuntime::IDX_NODEPRINCIPAL)) &&
Is<nsINode>(wrapper)) ||
(id == rt->GetStringID(XPCJSRuntime::IDX_DOCUMENTURIOBJECT) &&
Is<nsIDocument>(wrapper))) &&
(AccessCheck::callerIsChrome())) {
Is<nsIDocument>(wrapper)))) {
bool status;
Wrapper::Action action = set ? Wrapper::SET : Wrapper::GET;
desc->obj = NULL; // default value
@ -1388,9 +1387,11 @@ XrayWrapper<Base, Traits>::getPropertyDescriptor(JSContext *cx, JSObject *wrappe
if (!holder)
return false;
// XOWs don't have a .wrappedJSObject property.
// Only chrome wrappers and same-origin xrays (used by jetpack sandboxes)
// get .wrappedJSObject. We can check this by determining if the compartment
// of the wrapper subsumes that of the wrappee.
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
if (!WrapperFactory::IsXOW(wrapper) &&
if (AccessCheck::wrapperSubsumes(wrapper) &&
id == rt->GetStringID(XPCJSRuntime::IDX_WRAPPED_JSOBJECT)) {
bool status;
Wrapper::Action action = set ? Wrapper::SET : Wrapper::GET;
@ -1581,7 +1582,7 @@ XrayWrapper<Base, Traits>::enumerate(JSContext *cx, JSObject *wrapper, unsigned
return js::GetPropertyNames(cx, obj, flags, &props);
}
if (WrapperFactory::IsXOW(wrapper)) {
if (!AccessCheck::wrapperSubsumes(wrapper)) {
JS_ReportError(cx, "Not allowed to enumerate cross origin objects");
return false;
}