bug 124053 Fix invalid use of JVMContext TLS to map between threads, JSContexts and JSJavaThreadStates

patch by beard@netscape.com r=bnesse sr=rpotts
This commit is contained in:
cbiesinger%web.de 2003-12-19 14:52:49 +00:00
parent 45514a2b8a
commit 04541c45d5
3 changed files with 10 additions and 284 deletions

View File

@ -42,7 +42,7 @@
#include "ProxyJNI.h"
#include "lcglue.h"
#include "nsCSecurityContext.h"
#include "nsISecurityContext.h"
#include "nsIJSContextStack.h"
static NS_DEFINE_CID(kJVMManagerCID, NS_JVMMANAGER_CID);
static NS_DEFINE_IID(kIJVMConsoleIID, NS_IJVMCONSOLE_IID);
@ -362,157 +362,12 @@ JVM_IsLiveConnectEnabled(void)
}
static
JVMSecurityStack *
findPrevNode(JSStackFrame *pCurrentFrame)
{
JVMContext* context = GetJVMContext();
JVMSecurityStack *pSecInfoBottom = context->securityStack;
if (pSecInfoBottom == NULL)
{
return NULL;
}
JVMSecurityStack *pSecInfoTop = pSecInfoBottom->prev;
if (pCurrentFrame == NULL)
{
return pSecInfoTop;
}
if ( pSecInfoBottom->pJavaToJSFrame == pCurrentFrame )
{
return NULL;
}
JVMSecurityStack *pTempSecNode = pSecInfoTop;
while( pTempSecNode->pJSToJavaFrame != pCurrentFrame )
{
pTempSecNode = pTempSecNode->prev;
if ( pTempSecNode == pSecInfoTop )
{
break;
}
}
if( pTempSecNode->pJSToJavaFrame == pCurrentFrame )
{
return pTempSecNode;
}
return NULL;
}
PR_IMPLEMENT(PRBool)
JVM_NSISecurityContextImplies(JSStackFrame *pCurrentFrame, const char* target, const char* action)
{
JVMSecurityStack *pSecInfo = findPrevNode(pCurrentFrame);
if (pSecInfo == NULL)
{
return PR_FALSE;
}
nsISecurityContext *pNSISecurityContext = (nsISecurityContext *)pSecInfo->pNSISecurityContext;
PRBool bAllowedAccess = PR_FALSE;
if (pNSISecurityContext != NULL)
{
pNSISecurityContext->Implies(target, action, &bAllowedAccess);
}
return bAllowedAccess;
}
PR_IMPLEMENT(void *)
JVM_GetJavaPrincipalsFromStackAsNSVector(JSStackFrame *pCurrentFrame)
{
JVMSecurityStack *pSecInfo = findPrevNode(pCurrentFrame);
if (pSecInfo == NULL)
{
return NULL;
}
JVMContext* context = GetJVMContext();
JSContext *pJSCX = context->js_context;
if (pJSCX == NULL)
{
//TODO: Get to the new context from DOM.
//pJSCX = LM_GetCrippledContext();
}
/*
** TODO: Get raman's help here. I don't know how we are going to give back a nsPrincipals array.
** Tom's new code should now use a different signature and accept a nsIPrincipal vector object
** instead in lm_taint.c and then call into caps. Caps needs to change to accommodate this.
void *pNSPrincipalArray = ConvertNSIPrincipalToNSPrincipalArray(NULL, pJSCX, pSecInfo->pNSIPrincipaArray,
pSecInfo->numPrincipals, pSecInfo->pNSISecurityContext);
if (pNSPrincipalArray != NULL)
{
return pNSPrincipalArray;
}
*/
return NULL;
}
PR_IMPLEMENT(JSPrincipals*)
JVM_GetJavaPrincipalsFromStack(JSStackFrame *pCurrentFrame)
{
JVMSecurityStack *pSecInfo = findPrevNode(pCurrentFrame);
if (pSecInfo == NULL)
{
return NULL;
}
JVMContext* context = GetJVMContext();
JSContext *pJSCX = context->js_context;
if (pJSCX == NULL)
{
//TODO: Get to the new context from DOM.
//pJSCX = LM_GetCrippledContext();
}
/* TODO:
** Get raman's help here. We should not need to convert nsIPrincipal to nsPrincipal anymore.
** But we should convert from nsIPrincipal array to a nsIPrincipal array object represented as
** nsVector. Use this vector to pass into Tom's code to get to the JSPrinciapals
void *pNSPrincipalArray = ConvertNSIPrincipalArrayToObject(NULL, pJSCX, pSecInfo->pNSIPrincipaArray,
pSecInfo->numPrincipals, pSecInfo->pNSISecurityContext);
if (pNSPrincipalArray != NULL)
{
return LM_GetJSPrincipalsFromJavaCaller(pJSCX, pNSPrincipalArray, pSecInfo->pNSISecurityContext);
}
*/
return NULL;
}
PR_IMPLEMENT(JSStackFrame*)
JVM_GetEndJSFrameFromParallelStack(JSStackFrame *pCurrentFrame)
{
JVMSecurityStack *pSecInfo = findPrevNode(pCurrentFrame);
if (pSecInfo == NULL)
{
return NULL;
}
return pSecInfo->pJavaToJSFrame;
}
PR_IMPLEMENT(JSStackFrame**)
JVM_GetStartJSFrameFromParallelStack()
{
JVMContext* context = GetJVMContext();
return &context->js_startframe;
}
PR_IMPLEMENT(nsISecurityContext*)
JVM_GetJSSecurityContext()
{
JVMContext* context = GetJVMContext();
JVMSecurityStack *securityStack = context->securityStack;
JVMSecurityStack *securityStackTop = NULL;
JSContext *cx = context->js_context;
if(securityStack != NULL) {
securityStackTop = securityStack->prev;
JSStackFrame *fp = NULL;
securityStackTop->pJSToJavaFrame = JS_FrameIterator(cx, &fp);
}
JSContext *cx = nsnull;
nsCOMPtr<nsIJSContextStack> stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
if (stack) stack->Peek(&cx);
nsCSecurityContext *securityContext = new nsCSecurityContext(cx);
if (securityContext == nsnull) {

View File

@ -109,11 +109,7 @@ JVMContext* GetJVMContext()
if (context == NULL) {
context = new JVMContext;
context->proxyEnv = NULL;
context->securityStack = NULL;
context->jsj_env = NULL;
context->js_context = NULL;
context->js_startframe = NULL;
context->java_applet_obj = NULL;
localContext.set(context);
}
return context;
@ -130,22 +126,6 @@ JS_BEGIN_EXTERN_C
JS_STATIC_DLL_CALLBACK(JSContext*)
map_jsj_thread_to_js_context_impl(JSJavaThreadState *jsj_env, void* java_applet_obj, JNIEnv *env, char **errp)
{
#if 0
JVMContext* context = GetJVMContext();
JSContext *cx = context->js_context;
/*
** This callback is called for spontaneous calls only. Either create a new JSContext
** or return the crippled context.
** TODO: Get to some kind of script manager via service manager and then get to script context
** and then to get to the native context.
*/
//JSContext *cx = LM_GetCrippledContext();
//JSContext *cx = NULL;
*errp = NULL;
return cx;
#else
// Guess what? This design is totally invalid under Gecko, because there isn't a 1 to 1 mapping
// between NSPR threads and JSContexts. We have to ask the plugin instance peer what JSContext
// it lives in to make any sense of all this.
@ -163,7 +143,6 @@ map_jsj_thread_to_js_context_impl(JSJavaThreadState *jsj_env, void* java_applet_
}
}
return context;
#endif
}
/*
@ -177,21 +156,20 @@ map_js_context_to_jsj_thread_impl(JSContext *cx, char **errp)
{
*errp = NULL;
// FIXME: how do we ever break the association between the jsj_env and the
// JVMContext? This needs to be figured out. Otherwise, we'll end up with the
// same dangling JSContext problem we are trying to weed out.
JVMContext* context = GetJVMContext();
JSJavaThreadState* jsj_env = context->jsj_env;
if (jsj_env != NULL)
return jsj_env;
/*/TODO: Figure out if moja intiailzation went ok.
if (ET_InitMoja(0) != LM_MOJA_OK) {
*errp = strdup("LiveConnect initialization failed.");
return NULL;
}
*/
JSJavaVM* js_jvm = NULL;
nsresult rv;
nsCOMPtr<nsIJVMManager> managerService = do_GetService(kJVMManagerCID, &rv);
if (NS_FAILED(rv)) return NULL;
nsJVMManager* pJVMMgr = (nsJVMManager *)managerService.get();
nsJVMManager* pJVMMgr = (nsJVMManager*) managerService.get();
if (pJVMMgr != NULL) {
js_jvm = pJVMMgr->GetJSJavaVM();
if (js_jvm == NULL) {
@ -202,7 +180,6 @@ map_js_context_to_jsj_thread_impl(JSContext *cx, char **errp)
jsj_env = JSJ_AttachCurrentThreadToJava(js_jvm, NULL, NULL);
context->jsj_env = jsj_env;
context->js_context = cx;
return jsj_env;
}
@ -269,70 +246,6 @@ map_java_object_to_js_object_impl(JNIEnv *env, void *pluginInstancePtr, char* *e
return window;
}
#if 0
// This needs to be modified at least temporarily. Caps is undergoing some rearchitecture
// nsPrincipal doesn't exist anymore, we're trying to move towards using nsIPrincipal and a PrincipalTools.h
// which includes the definitions for arrays.
// TODO: Need raman's help. This needs to convert between C++ [] array data type to a nsVector object.
void*
ConvertNSIPrincipalArrayToObject(JNIEnv *pJNIEnv, JSContext *pJSContext, void **ppNSIPrincipalArrayIN, int numPrincipals, void *pNSISecurityContext)
{
nsIPrincipal **ppNSIPrincipalArray = NS_REINTERPRET_CAST(nsIPrincipal**, ppNSIPrincipalArrayIN);
PRInt32 length = numPrincipals;
nsresult err = NS_OK;
nsCOMPtr<nsIJVMManager> managerService = do_GetService(kJVMManagerCID, &err);
if (NS_FAILED(err)) return NULL;
nsJVMManager* pJVMMgr = (nsJVMManager *)managerService.get();
void *pNSPrincipalArray = NULL;
if (pJVMMgr != NULL) {
if (ppNSIPrincipalArray != NULL) {
nsIPluginManager *pNSIPluginManager = NULL;
NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID);
err = pJVMMgr->QueryInterface(kIPluginManagerIID,
(void**)&pNSIPluginManager);
if( (err == NS_OK)
&& (pNSIPluginManager != NULL )
)
{
nsCCapsManager *pNSCCapsManager = NULL;
NS_DEFINE_IID(kICapsManagerIID, NS_ICAPSMANAGER_IID);
err = pNSIPluginManager->QueryInterface(kICapsManagerIID, (void**)&pNSCCapsManager);
if( (err == NS_OK)
&& (pNSCCapsManager != NULL)
)
{
PRInt32 i=0;
nsPrincipal *pNSPrincipal = NULL;
pNSPrincipalArray = nsCapsNewPrincipalArray(length);
if (pNSPrincipalArray != NULL)
{
while( i<length )
{
err = pNSCCapsManager->GetNSPrincipal(ppNSIPrincipalArray[i], &pNSPrincipal);
nsCapsSetPrincipalArrayElement(pNSPrincipalArray, i, pNSPrincipal);
i++;
}
}
pNSCCapsManager->Release();
}
pNSIPluginManager->Release();
}
}
}
if ( (pNSPrincipalArray != NULL)
&&(length != 0)
)
{
return pNSPrincipalArray;
}
return NULL;
}
#endif //0
JS_STATIC_DLL_CALLBACK(JSPrincipals*)
get_JSPrincipals_from_java_caller_impl(JNIEnv *pJNIEnv, JSContext *pJSContext, void **ppNSIPrincipalArrayIN, int numPrincipals, void *pNSISecurityContext)
{
@ -491,31 +404,6 @@ enter_js_from_java_impl(JNIEnv *jEnv, char **errp,
JS_STATIC_DLL_CALLBACK(void)
exit_js_impl(JNIEnv *jEnv, JSContext *cx)
{
//TODO:
//LM_UnlockJS();
// Pop the security context stack
JVMContext* context = GetJVMContext();
JVMSecurityStack *pSecInfoBottom = context->securityStack;
if (pSecInfoBottom != NULL)
{
if(pSecInfoBottom->next == pSecInfoBottom)
{
context->securityStack = NULL;
pSecInfoBottom->next = NULL;
pSecInfoBottom->prev = NULL;
delete pSecInfoBottom;
}
else
{
JVMSecurityStack *top = pSecInfoBottom->prev;
top->next = NULL;
pSecInfoBottom->prev = top->prev;
top->prev->next = pSecInfoBottom;
top->prev = NULL;
delete top;
}
}
// The main idea is to execute terminate function if have any;
if (cx)
{

View File

@ -46,33 +46,16 @@
#include "nsIThreadManager.h"
#include "nsISecurityContext.h"
struct JVMSecurityStack {
void **pNSIPrincipaArray;
int numPrincipals;
void *pNSISecurityContext;
JSStackFrame *pJavaToJSFrame;
JSStackFrame *pJSToJavaFrame;
JVMSecurityStack *next;
JVMSecurityStack *prev;
};
typedef struct JVMSecurityStack JVMSecurityStack;
/**
* JVMContext is maintained as thread local storage. The current thread's
* context is accessed by calling GetJVMContext().
*/
struct JVMContext {
JNIEnv *proxyEnv; /* thread local proxy JNI */
JVMSecurityStack *securityStack; /* thread local security stack. */
JSJavaThreadState *jsj_env; /* thread local JavaScript execution env. */
JSContext *js_context; /* thread local JavaScript context. */
JSStackFrame *js_startframe; /* thread local JavaScript stack frame. */
void *java_applet_obj;
};
JVMContext* GetJVMContext();
void JVM_InitLCGlue(void); // in lcglue.cpp
extern "C" void*
ConvertNSIPrincipalToNSPrincipalArray(JNIEnv *pJNIEnv, JSContext *pJSContext, void **ppNSIPrincipalArrayIN, int numPrincipals, void *pNSISecurityContext);
#endif /* lcglue_h___ */