r=norris. Fix for bug 18702. Adds code to track whether caller to xpconnect is native or JS. This allows xpconnect to decide to not call security manager to filter calls originating from native code

This commit is contained in:
jband%netscape.com 1999-11-15 22:11:21 +00:00
parent 51615a8567
commit 01e9711a8e
9 changed files with 142 additions and 8 deletions

View File

@ -444,12 +444,18 @@ nsXPConnect::InitJSContext(JSContext* aJSContext,
if(!aGlobalJSObj)
aGlobalJSObj = JS_GetGlobalObject(aJSContext);
if(aGlobalJSObj &&
!mContextMap->Find(aJSContext) &&
NewContext(aJSContext, aGlobalJSObj)&&
(!AddComponentsObject ||
NS_SUCCEEDED(AddNewComponentsObject(aJSContext, aGlobalJSObj))))
!mContextMap->Find(aJSContext))
{
return NS_OK;
XPCContext* xpcc;
if(nsnull != (xpcc = NewContext(aJSContext, aGlobalJSObj)))
{
SET_CALLER_NATIVE(xpcc);
if(!AddComponentsObject ||
NS_SUCCEEDED(AddNewComponentsObject(aJSContext, aGlobalJSObj)))
{
return NS_OK;
}
}
}
XPC_LOG_ERROR(("nsXPConnect::InitJSContext failed"));
return NS_ERROR_FAILURE;
@ -468,6 +474,7 @@ nsXPConnect::InitJSContextWithNewWrappedGlobal(JSContext* aJSContext,
if(!mContextMap->Find(aJSContext) &&
nsnull != (xpcc = NewContext(aJSContext, nsnull, JS_FALSE)))
{
SET_CALLER_NATIVE(xpcc);
wrapper = nsXPCWrappedNative::GetNewOrUsedWrapper(xpcc, aCOMObj,
aIID, nsnull);
if(wrapper)
@ -499,6 +506,7 @@ nsXPConnect::AddNewComponentsObject(JSContext* aJSContext,
JSObject* aGlobalJSObj)
{
AUTO_PUSH_JSCONTEXT2(aJSContext, this);
SET_CALLER_NATIVE(aJSContext);
JSBool success;
nsresult rv;
@ -590,6 +598,7 @@ nsXPConnect::WrapNative(JSContext* aJSContext,
XPCContext* xpcc = nsXPConnect::GetContext(aJSContext, this);
if(xpcc)
{
SET_CALLER_NATIVE(xpcc);
nsXPCWrappedNative* wrapper =
nsXPCWrappedNative::GetNewOrUsedWrapper(xpcc, aCOMObj,
aIID, nsnull);
@ -618,6 +627,7 @@ nsXPConnect::WrapJS(JSContext* aJSContext,
XPCContext* xpcc = nsXPConnect::GetContext(aJSContext, this);
if(xpcc)
{
SET_CALLER_NATIVE(xpcc);
nsXPCWrappedJS* wrapper =
nsXPCWrappedJS::GetNewOrUsedWrapper(xpcc, aJSObj, aIID);
if(wrapper)
@ -639,6 +649,7 @@ nsXPConnect::GetWrappedNativeOfJSObject(JSContext* aJSContext,
NS_PRECONDITION(aJSContext,"bad param");
NS_PRECONDITION(aJSObj,"bad param");
NS_PRECONDITION(aWrapper,"bad param");
SET_CALLER_NATIVE(aJSContext);
if(!(*aWrapper = nsXPCWrappedNativeClass::GetWrappedNativeOfJSObject(aJSContext,aJSObj)))
return NS_ERROR_UNEXPECTED;
@ -656,6 +667,7 @@ nsXPConnect::AbandonJSContext(JSContext* aJSContext)
XPCContext* xpcc = mContextMap->Find(aJSContext);
if(!xpcc)
{
SET_CALLER_NATIVE(xpcc);
NS_ASSERTION(0,"called AbandonJSContext for context that's not init'd");
return NS_OK;
}

View File

@ -45,6 +45,38 @@ const char* XPCContext::mStrings[] = {
XPC_QUERY_INTERFACE_STR // IDX_QUERY_INTERFACE_STRING
};
/***************************************************************************/
AutoPushCallingLangType::AutoPushCallingLangType(JSContext* cx,
XPCContext::LangType type)
: mXPCContext(nsXPConnect::GetContext(cx))
{
ctorCommon(type);
}
AutoPushCallingLangType::AutoPushCallingLangType(XPCContext* xpcc,
XPCContext::LangType type)
: mXPCContext(xpcc)
{
ctorCommon(type);
}
AutoPushCallingLangType::~AutoPushCallingLangType()
{
if(mXPCContext)
{
#ifdef DEBUG
XPCContext::LangType type;
type = mXPCContext->SetCallingLangType(mOldCallingLangType);
NS_ASSERTION(type == mDebugPushedCallingLangType,"call type mismatch");
#else
mXPCContext->SetCallingLangType(mOldCallingLangType);
#endif
}
}
/***************************************************************************/
// static
XPCContext*
XPCContext::newXPCContext(JSContext* aJSContext,
@ -112,6 +144,7 @@ XPCContext::XPCContext(JSContext* aJSContext,
mSecurityManager = nsnull;
mSecurityManagerFlags = 0;
mException = nsnull;
mCallingLangType = LANG_UNKNOWN;
}
JS_STATIC_DLL_CALLBACK(intN)

View File

@ -934,6 +934,8 @@ JSBool JS_DLL_CALLBACK
XPC_JSArgumentFormatter(JSContext *cx, const char *format,
JSBool fromJS, jsval **vpp, va_list *app)
{
SET_CALLER_NATIVE(cx);
jsval *vp;
va_list ap;

View File

@ -633,7 +633,9 @@ CIDCreateInstance::Call(JSContext *cx, JSObject *obj,
if(nsnull != (xpcc = nsXPConnect::GetContext(cx)))
{
nsIXPCSecurityManager* sm;
if(nsnull != (sm = xpcc->GetSecurityManager()) &&
NS_WARN_IF_FALSE(xpcc->CallerTypeIsKnown(),"missing caller type set somewhere");
if(xpcc->CallerTypeIsJavaScript() &&
nsnull != (sm = xpcc->GetSecurityManager()) &&
(xpcc->GetSecurityManagerFlags() &
nsIXPCSecurityManager::HOOK_CREATE_INSTANCE) &&
NS_OK != sm->CanCreateInstance(cx, *cid))
@ -834,7 +836,9 @@ CIDGetService::Call(JSContext *cx, JSObject *obj,
if(nsnull != (xpcc = nsXPConnect::GetContext(cx)))
{
nsIXPCSecurityManager* sm;
if(nsnull != (sm = xpcc->GetSecurityManager()) &&
NS_WARN_IF_FALSE(xpcc->CallerTypeIsKnown(),"missing caller type set somewhere");
if(xpcc->CallerTypeIsJavaScript() &&
nsnull != (sm = xpcc->GetSecurityManager()) &&
(xpcc->GetSecurityManagerFlags() &
nsIXPCSecurityManager::HOOK_GET_SERVICE) &&
NS_OK != sm->CanGetService(cx, *cid))

View File

@ -306,6 +306,16 @@ public:
return mStrings[index];
}
enum LangType {LANG_UNKNOWN, LANG_JS, LANG_NATIVE};
LangType GetCallingLangType() const
{return mCallingLangType;}
LangType SetCallingLangType(LangType lt)
{LangType tmp = mCallingLangType; mCallingLangType = lt; return tmp;}
JSBool CallerTypeIsJavaScript() const {return LANG_JS == mCallingLangType;}
JSBool CallerTypeIsNative() const {return LANG_NATIVE == mCallingLangType;}
JSBool CallerTypeIsKnown() const {return LANG_UNKNOWN != mCallingLangType;}
nsIXPCException* GetException()
{
NS_IF_ADDREF(mException);
@ -365,6 +375,7 @@ private:
PRUint16 mSecurityManagerFlags;
nsIXPCException* mException;
nsXPCNativeCallContext mNativeCallContext;
LangType mCallingLangType;
};
/***************************************************************************/
@ -1127,6 +1138,53 @@ private:
JSContext* mCX;
};
/***************************************************************************/
// This class is used to track whether xpconnect was entered from JavaScCript
// or native code. This information is used to determine whther or not to call
// security hooks; i.e. the nsIXPCSecurityManager need not be called to protect
// xpconnect activities initiated by native code. Instances of this class are
// instatiated as auto objects at the various critical entry points of
// xpconnect. On entry they set a variable in the XPCContext to track the
// caller type and then restore the previous value upon destruction (when the
// scope is exited).
class AutoPushCallingLangType
{
public:
AutoPushCallingLangType(JSContext* cx, XPCContext::LangType type);
AutoPushCallingLangType(XPCContext* xpcc, XPCContext::LangType type);
~AutoPushCallingLangType();
XPCContext* GetXPCContext() const
{return mXPCContext;}
JSContext* GetJSContext() const
{return mXPCContext ? nsnull : mXPCContext->GetJSContext();}
private:
void ctorCommon(XPCContext::LangType type)
{
NS_WARN_IF_FALSE(mXPCContext,"bad context in AutoPushCallingLangType");
if(mXPCContext)
mOldCallingLangType = mXPCContext->SetCallingLangType(type);
#ifdef DEBUG
mDebugPushedCallingLangType = type;
#endif
}
private:
XPCContext* mXPCContext;
XPCContext::LangType mOldCallingLangType;
#ifdef DEBUG
XPCContext::LangType mDebugPushedCallingLangType;
#endif
};
#define SET_CALLER_JAVASCRIPT(_context) \
AutoPushCallingLangType _APCLT(_context, XPCContext::LANG_JS)
#define SET_CALLER_NATIVE(_context) \
AutoPushCallingLangType _APCLT(_context, XPCContext::LANG_NATIVE)
/***************************************************************************/
#define NS_JS_RUNTIME_SERVICE_CID \
{0xb5e65b52, 0x1dd1, 0x11b2, \

View File

@ -292,6 +292,7 @@ nsXPCWrappedJS::CallMethod(PRUint16 methodIndex,
const nsXPTMethodInfo* info,
nsXPTCMiniVariant* params)
{
SET_CALLER_NATIVE(GetClass()->GetXPCContext());
return GetClass()->CallMethod(this, methodIndex, info, params);
}

View File

@ -148,7 +148,9 @@ nsXPCWrappedNative::GetNewOrUsedWrapper(XPCContext* xpcc,
// do the security check if necessary
nsIXPCSecurityManager* sm;
if(nsnull != (sm = xpcc->GetSecurityManager()) &&
NS_WARN_IF_FALSE(xpcc->CallerTypeIsKnown(),"missing caller type set somewhere");
if(xpcc->CallerTypeIsJavaScript() &&
nsnull != (sm = xpcc->GetSecurityManager()) &&
(xpcc->GetSecurityManagerFlags() &
nsIXPCSecurityManager::HOOK_CREATE_WRAPPER) &&
NS_OK != sm->CanCreateWrapper(xpcc->GetJSContext(), aIID, realObj))

View File

@ -552,6 +552,7 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
// make sure we have what we need...
// set up the method index and do the security check if needed
NS_WARN_IF_FALSE(xpcc->CallerTypeIsKnown(),"missing caller type set somewhere");
securityManager = xpcc->GetSecurityManager();
switch(callMode)
{
@ -561,6 +562,7 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
if(securityManager &&
(xpcc->GetSecurityManagerFlags() &
nsIXPCSecurityManager::HOOK_CALL_METHOD) &&
xpcc->CallerTypeIsJavaScript() &&
NS_OK !=
securityManager->CanCallMethod(cx, mIID, callee,
mInfo, vtblIndex, desc->id))
@ -576,6 +578,7 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
if(securityManager &&
(xpcc->GetSecurityManagerFlags() &
nsIXPCSecurityManager::HOOK_GET_PROPERTY) &&
xpcc->CallerTypeIsJavaScript() &&
NS_OK !=
securityManager->CanGetProperty(cx, mIID, callee,
mInfo, vtblIndex, desc->id))
@ -594,6 +597,7 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
if(securityManager &&
(xpcc->GetSecurityManagerFlags() &
nsIXPCSecurityManager::HOOK_SET_PROPERTY) &&
xpcc->CallerTypeIsJavaScript() &&
NS_OK !=
securityManager->CanSetProperty(cx, mIID, callee,
mInfo, vtblIndex, desc->id))

View File

@ -82,6 +82,7 @@ JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
if (!wrapper) {
@ -160,6 +161,7 @@ WrappedNative_CallMethod(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *vp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
JSFunction *fun;
jsid id;
jsval idval;
@ -193,6 +195,7 @@ JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
nsXPCWrappedNative* wrapper;
wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
@ -264,6 +267,7 @@ JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
nsXPCWrappedNative* wrapper;
wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
@ -311,6 +315,7 @@ WrappedNative_LookupProperty(JSContext *cx, JSObject *obj, jsid id,
)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
nsIXPCScriptable* ds;
nsIXPCScriptable* as;
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
@ -349,6 +354,7 @@ WrappedNative_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
uintN attrs, JSProperty **propp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
nsIXPCScriptable* ds;
nsIXPCScriptable* as;
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
@ -377,6 +383,7 @@ WrappedNative_GetAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
nsIXPCScriptable* ds;
nsIXPCScriptable* as;
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
@ -404,6 +411,7 @@ WrappedNative_SetAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
nsIXPCScriptable* ds;
nsIXPCScriptable* as;
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
@ -429,6 +437,7 @@ JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
nsIXPCScriptable* ds;
nsIXPCScriptable* as;
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
@ -456,6 +465,7 @@ JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_DefaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
nsIXPCScriptable* ds;
nsIXPCScriptable* as;
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
@ -476,6 +486,7 @@ WrappedNative_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
jsval *statep, jsid *idp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
nsXPCWrappedNative* wrapper;
nsIXPCScriptable* ds;
nsIXPCScriptable* as;
@ -504,6 +515,7 @@ WrappedNative_CheckAccess(JSContext *cx, JSObject *obj, jsid id,
JSAccessMode mode, jsval *vp, uintN *attrsp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
nsIXPCScriptable* ds;
nsIXPCScriptable* as;
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
@ -542,6 +554,7 @@ WrappedNative_Call(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *rval)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
// this is a hack to get the obj of the actual object not the object
// that JS thinks is the 'this' (which it passes as 'obj').
if(!(obj = (JSObject*)argv[-2]))
@ -570,6 +583,7 @@ WrappedNative_Construct(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *rval)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
// this is a hack to get the obj of the actual object not the object
// that JS thinks is the 'this' (which it passes as 'obj').
if(!(obj = (JSObject*)argv[-2]))
@ -598,6 +612,7 @@ JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_ClassHasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
//XXX our default policy is to just say no. Is this right?
*bp = JS_FALSE;
return JS_TRUE;
@ -608,6 +623,7 @@ JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
{
AUTO_PUSH_JSCONTEXT(cx);
SET_CALLER_JAVASCRIPT(cx);
nsIXPCScriptable* ds;
nsIXPCScriptable* as;
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx,obj);
@ -627,6 +643,8 @@ JS_STATIC_DLL_CALLBACK(void)
WrappedNative_Finalize(JSContext *cx, JSObject *obj)
{
AUTO_PUSH_JSCONTEXT(cx);
// we don't want to be setting this in finalization.
// SET_CALLER_JAVASCRIPT(cx);
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx,obj);
if(!wrapper)
return;