mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Backout 5853df66d488, e8fadd906232, d787279d282c, 8c1ed6327355, 94cfcf5da7c8, 87aa103d7e87 (bug 585922) for failures in test_bug411236.html
This commit is contained in:
parent
dc77cb5f0a
commit
f66e09e47d
@ -2176,7 +2176,7 @@ bool
|
||||
nsDOMClassInfo::ObjectIsNativeWrapper(JSContext* cx, JSObject* obj)
|
||||
{
|
||||
return xpc::WrapperFactory::IsXrayWrapper(obj) &&
|
||||
xpc::AccessCheck::isChrome(obj);
|
||||
!xpc::WrapperFactory::IsPartiallyTransparent(obj);
|
||||
}
|
||||
|
||||
nsDOMClassInfo::nsDOMClassInfo(nsDOMClassInfoData* aData) : mData(aData)
|
||||
|
@ -7,9 +7,7 @@
|
||||
#include "XPCWrapper.h"
|
||||
#include "AccessCheck.h"
|
||||
#include "WrapperFactory.h"
|
||||
#include "AccessCheck.h"
|
||||
|
||||
using namespace xpc;
|
||||
namespace XPCNativeWrapper {
|
||||
|
||||
static inline
|
||||
@ -39,7 +37,8 @@ UnwrapNW(JSContext *cx, unsigned argc, jsval *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (WrapperFactory::IsXrayWrapper(obj) && AccessCheck::isChrome(obj)) {
|
||||
if (xpc::WrapperFactory::IsXrayWrapper(obj) &&
|
||||
!xpc::WrapperFactory::IsPartiallyTransparent(obj)) {
|
||||
return JS_GetProperty(cx, obj, "wrappedJSObject", vp);
|
||||
}
|
||||
|
||||
|
@ -4380,21 +4380,16 @@ GetCompartmentPrivate(JSObject *object)
|
||||
return GetCompartmentPrivate(compartment);
|
||||
}
|
||||
|
||||
inline bool IsUniversalXPConnectEnabled(JSCompartment *compartment)
|
||||
{
|
||||
CompartmentPrivate *priv =
|
||||
static_cast<CompartmentPrivate*>(JS_GetCompartmentPrivate(compartment));
|
||||
if (!priv)
|
||||
return false;
|
||||
return priv->universalXPConnectEnabled;
|
||||
}
|
||||
|
||||
inline bool IsUniversalXPConnectEnabled(JSContext *cx)
|
||||
{
|
||||
JSCompartment *compartment = js::GetContextCompartment(cx);
|
||||
if (!compartment)
|
||||
return false;
|
||||
return IsUniversalXPConnectEnabled(compartment);
|
||||
CompartmentPrivate *priv =
|
||||
static_cast<CompartmentPrivate*>(JS_GetCompartmentPrivate(compartment));
|
||||
if (!priv)
|
||||
return false;
|
||||
return priv->universalXPConnectEnabled;
|
||||
}
|
||||
|
||||
inline void EnableUniversalXPConnect(JSContext *cx)
|
||||
@ -4407,13 +4402,6 @@ inline void EnableUniversalXPConnect(JSContext *cx)
|
||||
if (!priv)
|
||||
return;
|
||||
priv->universalXPConnectEnabled = true;
|
||||
|
||||
// Recompute all the cross-compartment wrappers leaving the newly-privileged
|
||||
// compartment.
|
||||
mozilla::DebugOnly<bool> rv;
|
||||
rv = js::RecomputeWrappers(cx, js::SingleCompartment(compartment),
|
||||
js::AllCompartments());
|
||||
MOZ_ASSERT(rv);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,16 +52,6 @@ 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)
|
||||
{
|
||||
@ -101,12 +91,6 @@ 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()
|
||||
{
|
||||
@ -221,7 +205,7 @@ AccessCheck::isCrossOriginAccessPermitted(JSContext *cx, JSObject *wrapper, jsid
|
||||
|
||||
// PUNCTURE Is always denied for cross-origin access.
|
||||
if (act == Wrapper::PUNCTURE) {
|
||||
return false;
|
||||
return nsContentUtils::CallerHasUniversalXPConnect();
|
||||
}
|
||||
|
||||
const char *name;
|
||||
@ -286,7 +270,7 @@ AccessCheck::isSystemOnlyAccessPermitted(JSContext *cx)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return NS_SUCCEEDED(ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged)) && privileged;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -311,7 +295,18 @@ AccessCheck::isScriptAccessOnly(JSContext *cx, JSObject *wrapper)
|
||||
if (flags & WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG) {
|
||||
if (flags & WrapperFactory::SOW_FLAG)
|
||||
return !isSystemOnlyAccessPermitted(cx);
|
||||
return true;
|
||||
|
||||
if (flags & WrapperFactory::PARTIALLY_TRANSPARENT)
|
||||
return !XrayUtils::IsTransparent(cx, wrapper);
|
||||
|
||||
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
|
||||
if (!ssm)
|
||||
return true;
|
||||
|
||||
// Bypass script-only status if UniversalXPConnect is enabled.
|
||||
bool privileged;
|
||||
return !NS_SUCCEEDED(ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged)) ||
|
||||
!privileged;
|
||||
}
|
||||
|
||||
// In addition, chrome objects can explicitly opt-in by setting .scriptOnly to true.
|
||||
@ -361,6 +356,33 @@ Deny(JSContext *cx, jsid id, Wrapper::Action act)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
PermitIfUniversalXPConnect(JSContext *cx, jsid id, Wrapper::Action act,
|
||||
ExposedPropertiesOnly::Permission &perm)
|
||||
{
|
||||
// If UniversalXPConnect is enabled, allow access even if __exposedProps__ doesn't
|
||||
// exists.
|
||||
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
|
||||
if (!ssm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Double-check that the subject principal according to CAPS is a content
|
||||
// principal rather than the system principal. If it isn't, this check is
|
||||
// meaningless.
|
||||
NS_ASSERTION(!AccessCheck::callerIsChrome(), "About to do a meaningless security check!");
|
||||
|
||||
bool privileged;
|
||||
if (NS_SUCCEEDED(ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged)) &&
|
||||
privileged) {
|
||||
perm = ExposedPropertiesOnly::PermitPropertyAccess;
|
||||
return true; // Allow
|
||||
}
|
||||
|
||||
// Deny
|
||||
return Deny(cx, id, act);
|
||||
}
|
||||
|
||||
static bool
|
||||
IsInSandbox(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
@ -382,12 +404,12 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper:
|
||||
|
||||
perm = DenyAccess;
|
||||
if (act == Wrapper::PUNCTURE)
|
||||
return Deny(cx, id, act);
|
||||
return PermitIfUniversalXPConnect(cx, id, act, perm); // Deny
|
||||
|
||||
jsid exposedPropsId = GetRTIdByIndex(cx, XPCJSRuntime::IDX_EXPOSEDPROPS);
|
||||
|
||||
// We need to enter the wrappee's compartment to look at __exposedProps__,
|
||||
// but we want to be in the wrapper's compartment if we call Deny().
|
||||
// but we need to be in the wrapper's compartment to check UniversalXPConnect.
|
||||
//
|
||||
// Unfortunately, |cx| can be in either compartment when we call ::check. :-(
|
||||
JSAutoCompartment ac(cx, wrappedObject);
|
||||
@ -429,7 +451,7 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper:
|
||||
perm = PermitPropertyAccess;
|
||||
return true;
|
||||
}
|
||||
return Deny(cx, id, act);
|
||||
return PermitIfUniversalXPConnect(cx, id, act, perm); // Deny
|
||||
}
|
||||
|
||||
if (id == JSID_VOID) {
|
||||
@ -444,7 +466,7 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper:
|
||||
|
||||
if (exposedProps.isNullOrUndefined()) {
|
||||
JSAutoCompartment wrapperAC(cx, wrapper);
|
||||
return Deny(cx, id, act);
|
||||
return PermitIfUniversalXPConnect(cx, id, act, perm); // Deny
|
||||
}
|
||||
|
||||
if (!exposedProps.isObject()) {
|
||||
@ -463,7 +485,7 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper:
|
||||
}
|
||||
if (desc.obj == NULL || !(desc.attrs & JSPROP_ENUMERATE)) {
|
||||
JSAutoCompartment wrapperAC(cx, wrapper);
|
||||
return Deny(cx, id, act);
|
||||
return PermitIfUniversalXPConnect(cx, id, act, perm); // Deny
|
||||
}
|
||||
|
||||
if (!JSVAL_IS_STRING(desc.value)) {
|
||||
@ -509,7 +531,7 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper:
|
||||
if ((act == Wrapper::SET && !(access & WRITE)) ||
|
||||
(act != Wrapper::SET && !(access & READ))) {
|
||||
JSAutoCompartment wrapperAC(cx, wrapper);
|
||||
return Deny(cx, id, act);
|
||||
return PermitIfUniversalXPConnect(cx, id, act, perm); // Deny
|
||||
}
|
||||
|
||||
perm = PermitPropertyAccess;
|
||||
@ -536,15 +558,7 @@ ComponentsObjectPolicy::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper
|
||||
}
|
||||
}
|
||||
|
||||
// We don't have any way to recompute same-compartment Components wrappers,
|
||||
// so we need this dynamic check. This can go away when we expose Components
|
||||
// as SpecialPowers.wrap(Components) during automation.
|
||||
if (xpc::IsUniversalXPConnectEnabled(cx)) {
|
||||
perm = PermitPropertyAccess;
|
||||
return true;
|
||||
}
|
||||
|
||||
return Deny(cx, id, act);
|
||||
return PermitIfUniversalXPConnect(cx, id, act, perm); // Deny
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,9 +19,7 @@ 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,10 +125,14 @@ 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);
|
||||
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<> XOW XOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
|
||||
WrapperFactory::PARTIALLY_TRANSPARENT);
|
||||
template<> PXOW PXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
|
||||
WrapperFactory::PARTIALLY_TRANSPARENT);
|
||||
template<> DXOW DXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
|
||||
WrapperFactory::PARTIALLY_TRANSPARENT);
|
||||
template<> NNXOW NNXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
|
||||
WrapperFactory::PARTIALLY_TRANSPARENT);
|
||||
template<> LW LW::singleton(WrapperFactory::SHADOWING_FORBIDDEN);
|
||||
template<> XLW XLW::singleton(WrapperFactory::SHADOWING_FORBIDDEN);
|
||||
|
||||
|
@ -349,8 +349,6 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (xpc::IsUniversalXPConnectEnabled(target)) {
|
||||
wrapper = &CrossCompartmentWrapper::singleton;
|
||||
} else if (AccessCheck::isChrome(origin)) {
|
||||
JSFunction *fun = JS_GetObjectFunction(obj);
|
||||
if (fun) {
|
||||
|
@ -18,7 +18,8 @@ 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,
|
||||
SOW_FLAG = SCRIPT_ACCESS_ONLY_FLAG << 1,
|
||||
PARTIALLY_TRANSPARENT = SCRIPT_ACCESS_ONLY_FLAG << 1,
|
||||
SOW_FLAG = PARTIALLY_TRANSPARENT << 1,
|
||||
|
||||
// Prevent scripts from shadowing native properties.
|
||||
// NB: Applies only to Xray wrappers.
|
||||
@ -37,6 +38,10 @@ class WrapperFactory {
|
||||
return HasWrapperFlag(wrapper, IS_XRAY_WRAPPER_FLAG);
|
||||
}
|
||||
|
||||
static bool IsPartiallyTransparent(JSObject *wrapper) {
|
||||
return HasWrapperFlag(wrapper, PARTIALLY_TRANSPARENT);
|
||||
}
|
||||
|
||||
static bool HasWaiveXrayFlag(JSObject *wrapper) {
|
||||
return HasWrapperFlag(wrapper, WAIVE_XRAY_WRAPPER_FLAG);
|
||||
}
|
||||
|
@ -910,6 +910,23 @@ nodePrincipal_getter(JSContext *cx, JSHandleObject wrapper, JSHandleId id, JSMut
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ContentScriptHasUniversalXPConnect()
|
||||
{
|
||||
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
|
||||
if (ssm) {
|
||||
// Double-check that the subject principal according to CAPS is a content
|
||||
// principal rather than the system principal. If it is, this check is
|
||||
// meaningless.
|
||||
NS_ASSERTION(!AccessCheck::callerIsChrome(), "About to do a meaningless security check!");
|
||||
|
||||
bool privileged;
|
||||
if (NS_SUCCEEDED(ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged)) && privileged)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
XPCWrappedNativeXrayTraits::resolveOwnProperty(JSContext *cx, js::Wrapper &jsWrapper,
|
||||
JSObject *wrapper, JSObject *holder, jsid id,
|
||||
@ -919,12 +936,13 @@ 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 (AccessCheck::isChrome(wrapper) &&
|
||||
if (!WrapperFactory::IsPartiallyTransparent(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)))) {
|
||||
Is<nsIDocument>(wrapper))) &&
|
||||
(AccessCheck::callerIsChrome() || ContentScriptHasUniversalXPConnect())) {
|
||||
bool status;
|
||||
Wrapper::Action action = set ? Wrapper::SET : Wrapper::GET;
|
||||
desc->obj = NULL; // default value
|
||||
@ -1280,7 +1298,16 @@ namespace XrayUtils {
|
||||
bool
|
||||
IsTransparent(JSContext *cx, JSObject *wrapper)
|
||||
{
|
||||
return WrapperFactory::HasWaiveXrayFlag(wrapper);
|
||||
if (WrapperFactory::HasWaiveXrayFlag(wrapper))
|
||||
return true;
|
||||
|
||||
if (!WrapperFactory::IsPartiallyTransparent(wrapper))
|
||||
return false;
|
||||
|
||||
// Redirect access straight to the wrapper if UniversalXPConnect is enabled.
|
||||
// We don't need to check for system principal here, because only content
|
||||
// scripts have Partially Transparent wrappers.
|
||||
return ContentScriptHasUniversalXPConnect();
|
||||
}
|
||||
|
||||
JSObject *
|
||||
@ -1387,11 +1414,10 @@ XrayWrapper<Base, Traits>::getPropertyDescriptor(JSContext *cx, JSObject *wrappe
|
||||
if (!holder)
|
||||
return false;
|
||||
|
||||
// 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.
|
||||
// Partially transparent wrappers (which used to be known as XOWs) don't
|
||||
// have a .wrappedJSObject property.
|
||||
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
|
||||
if (AccessCheck::wrapperSubsumes(wrapper) &&
|
||||
if (!WrapperFactory::IsPartiallyTransparent(wrapper) &&
|
||||
id == rt->GetStringID(XPCJSRuntime::IDX_WRAPPED_JSOBJECT)) {
|
||||
bool status;
|
||||
Wrapper::Action action = set ? Wrapper::SET : Wrapper::GET;
|
||||
@ -1582,7 +1608,7 @@ XrayWrapper<Base, Traits>::enumerate(JSContext *cx, JSObject *wrapper, unsigned
|
||||
return js::GetPropertyNames(cx, obj, flags, &props);
|
||||
}
|
||||
|
||||
if (!AccessCheck::isChrome(wrapper)) {
|
||||
if (WrapperFactory::IsPartiallyTransparent(wrapper)) {
|
||||
JS_ReportError(cx, "Not allowed to enumerate cross origin objects");
|
||||
return false;
|
||||
}
|
||||
|
@ -7,10 +7,13 @@
|
||||
<input type=text>
|
||||
<script>
|
||||
function doTest() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege(
|
||||
"UniversalXPConnect");
|
||||
|
||||
var d = document.querySelector("input");
|
||||
d.value = "b";
|
||||
d.focus();
|
||||
var editor = SpecialPowers.wrap(d).QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor;
|
||||
var editor = d.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor;
|
||||
var sel = editor.selection;
|
||||
var t = editor.rootElement.firstChild;
|
||||
sel.collapse(t, 1); // put the caret at the end of the textbox
|
||||
|
@ -7,6 +7,8 @@
|
||||
<input type=text>
|
||||
<script>
|
||||
function doTest() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege(
|
||||
"UniversalXPConnect");
|
||||
function enableCaret(aEnable) {
|
||||
var selCon = editor.selectionController;
|
||||
selCon.setCaretEnabled(aEnable);
|
||||
@ -15,11 +17,13 @@
|
||||
var d = document.querySelector("input");
|
||||
d.value = "a";
|
||||
d.focus();
|
||||
var editor = SpecialPowers.wrap(d).QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor;
|
||||
var editor = d.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor;
|
||||
var sel = editor.selection;
|
||||
var t = editor.rootElement.firstChild;
|
||||
sel.collapse(t, 1); // put the caret at the end of the div
|
||||
setTimeout(function() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege(
|
||||
"UniversalXPConnect");
|
||||
enableCaret(false);enableCaret(true);// force a caret display
|
||||
enableCaret(false); // hide the caret
|
||||
t.replaceData(0, 1, "b"); // replace the text node data
|
||||
|
Loading…
Reference in New Issue
Block a user