зеркало из https://github.com/mozilla/pjs.git
Ensure that accesses to implicit XPCNativeWrappers are actually legal. bug 384750, r+sr=jst
This commit is contained in:
Родитель
8e09a05e8f
Коммит
0609e26629
|
@ -216,6 +216,32 @@ ThrowException(nsresult ex, JSContext *cx)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
JSBool
|
||||||
|
EnsureLegalActivity(JSContext *cx, JSObject *obj)
|
||||||
|
{
|
||||||
|
jsval flags;
|
||||||
|
|
||||||
|
::JS_GetReservedSlot(cx, obj, 0, &flags);
|
||||||
|
if (HAS_FLAGS(flags, FLAG_EXPLICIT)) {
|
||||||
|
// Can't make any assertions about the owner of this wrapper.
|
||||||
|
return JS_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSStackFrame *frame = nsnull;
|
||||||
|
uint32 fileFlags = JS_GetTopScriptFilenameFlags(cx, NULL);
|
||||||
|
if (!JS_FrameIterator(cx, &frame) ||
|
||||||
|
fileFlags == JSFILENAME_NULL ||
|
||||||
|
(fileFlags & JSFILENAME_SYSTEM)) {
|
||||||
|
// We expect implicit native wrappers in system files.
|
||||||
|
return JS_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, we're looking at a non-system file with a handle on an
|
||||||
|
// implcit wrapper. This is a bug! Deny access.
|
||||||
|
return ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx);
|
||||||
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
WrapFunction(JSContext* cx, JSObject* funobj, jsval *rval)
|
WrapFunction(JSContext* cx, JSObject* funobj, jsval *rval)
|
||||||
{
|
{
|
||||||
|
@ -265,12 +291,17 @@ XPC_NW_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||||
|
|
||||||
// Note: no need to protect *vp from GC here, since it's already in the slot
|
// Note: no need to protect *vp from GC here, since it's already in the slot
|
||||||
// on |obj|.
|
// on |obj|.
|
||||||
return RewrapIfDeepWrapper(cx, obj, *vp, vp);
|
return EnsureLegalActivity(cx, obj) &&
|
||||||
|
RewrapIfDeepWrapper(cx, obj, *vp, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||||
XPC_NW_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
XPC_NW_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||||
{
|
{
|
||||||
|
if (!EnsureLegalActivity(cx, obj)) {
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
XPC_NW_BYPASS_BASE(cx, obj,
|
XPC_NW_BYPASS_BASE(cx, obj,
|
||||||
// We're being notified of a delete operation on id in this
|
// We're being notified of a delete operation on id in this
|
||||||
// XPCNativeWrapper, so forward to the right high-level hook,
|
// XPCNativeWrapper, so forward to the right high-level hook,
|
||||||
|
@ -414,6 +445,10 @@ XPC_NW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!EnsureLegalActivity(cx, obj)) {
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
XPCWrappedNative *wrappedNative =
|
XPCWrappedNative *wrappedNative =
|
||||||
XPCNativeWrapper::GetWrappedNative(cx, obj);
|
XPCNativeWrapper::GetWrappedNative(cx, obj);
|
||||||
|
|
||||||
|
@ -623,6 +658,10 @@ XPC_NW_Enumerate(JSContext *cx, JSObject *obj)
|
||||||
// JS_Enumerate API. Then reflect properties named by the enumerated
|
// JS_Enumerate API. Then reflect properties named by the enumerated
|
||||||
// identifiers from the wrapped native to the native wrapper.
|
// identifiers from the wrapped native to the native wrapper.
|
||||||
|
|
||||||
|
if (!EnsureLegalActivity(cx, obj)) {
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
XPCWrappedNative *wn = XPCNativeWrapper::GetWrappedNative(cx, obj);
|
XPCWrappedNative *wn = XPCNativeWrapper::GetWrappedNative(cx, obj);
|
||||||
if (!wn) {
|
if (!wn) {
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
|
@ -682,6 +721,10 @@ XPC_NW_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!EnsureLegalActivity(cx, obj)) {
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// We can't use XPC_NW_BYPASS here, because we need to do a full
|
// We can't use XPC_NW_BYPASS here, because we need to do a full
|
||||||
// OBJ_LOOKUP_PROPERTY on the wrapped native's object, in order to
|
// OBJ_LOOKUP_PROPERTY on the wrapped native's object, in order to
|
||||||
// trigger reflection along the wrapped native prototype chain.
|
// trigger reflection along the wrapped native prototype chain.
|
||||||
|
@ -893,8 +936,11 @@ XPC_NW_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
||||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||||
XPC_NW_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
XPC_NW_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
||||||
{
|
{
|
||||||
XPC_NW_BYPASS(cx, obj, convert, (cx, obj, type, vp));
|
if (!EnsureLegalActivity(cx, obj)) {
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
XPC_NW_BYPASS(cx, obj, convert, (cx, obj, type, vp));
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1256,6 +1302,10 @@ XPC_NW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!EnsureLegalActivity(cx, obj)) {
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether toString was overridden in any object along
|
// Check whether toString was overridden in any object along
|
||||||
// the wrapped native's object's prototype chain.
|
// the wrapped native's object's prototype chain.
|
||||||
XPCJSRuntime *rt = nsXPConnect::GetRuntime();
|
XPCJSRuntime *rt = nsXPConnect::GetRuntime();
|
||||||
|
|
|
@ -836,6 +836,23 @@ inline nsresult UnexpectedFailure(nsresult rv)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SaveFrame
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SaveFrame(JSContext *cx)
|
||||||
|
: mJSContext(cx) {
|
||||||
|
mFrame = JS_SaveFrameChain(mJSContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
~SaveFrame() {
|
||||||
|
JS_RestoreFrameChain(mJSContext, mFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
JSContext *mJSContext;
|
||||||
|
JSStackFrame *mFrame;
|
||||||
|
};
|
||||||
|
|
||||||
/* void initClasses (in JSContextPtr aJSContext, in JSObjectPtr aGlobalJSObj); */
|
/* void initClasses (in JSContextPtr aJSContext, in JSObjectPtr aGlobalJSObj); */
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXPConnect::InitClasses(JSContext * aJSContext, JSObject * aGlobalJSObj)
|
nsXPConnect::InitClasses(JSContext * aJSContext, JSObject * aGlobalJSObj)
|
||||||
|
@ -843,6 +860,7 @@ nsXPConnect::InitClasses(JSContext * aJSContext, JSObject * aGlobalJSObj)
|
||||||
NS_ASSERTION(aJSContext, "bad param");
|
NS_ASSERTION(aJSContext, "bad param");
|
||||||
NS_ASSERTION(aGlobalJSObj, "bad param");
|
NS_ASSERTION(aGlobalJSObj, "bad param");
|
||||||
|
|
||||||
|
SaveFrame sf(aJSContext);
|
||||||
XPCCallContext ccx(NATIVE_CALLER, aJSContext);
|
XPCCallContext ccx(NATIVE_CALLER, aJSContext);
|
||||||
if(!ccx.IsValid())
|
if(!ccx.IsValid())
|
||||||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||||
|
@ -980,6 +998,7 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext,
|
||||||
JS_SetPrototype(aJSContext, protoJSObject, scope->GetPrototypeJSObject());
|
JS_SetPrototype(aJSContext, protoJSObject, scope->GetPrototypeJSObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SaveFrame sf(ccx);
|
||||||
if(!nsXPCComponents::AttachNewComponentsObject(ccx, scope, globalJSObj))
|
if(!nsXPCComponents::AttachNewComponentsObject(ccx, scope, globalJSObj))
|
||||||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче