From 3c95dcfdc2d82abb353997589f7c9c85e462657f Mon Sep 17 00:00:00 2001 From: Gary Benson Date: Thu, 10 Aug 2006 09:56:03 +0000 Subject: [PATCH 1/1] java-stack.h (GetAccessControlStack): Change return type. 2006-08-10 Gary Benson * include/java-stack.h (GetAccessControlStack): Change return type. * stacktrace.cc (accesscontrol_trace_fn): Record the number of Java frames encountered. (GetAccessControlStack): Return a flag indicating whether a call to doPrivileged was encountered rather than an array of method names. * java/security/natVMAccessController.cc (getStack): Change return type. * java/security/VMAccessController.java (getStack): Likewise. (getContext): Change to reflect the above. From-SVN: r116058 --- libjava/ChangeLog | 13 ++++ libjava/include/java-stack.h | 2 +- libjava/java/security/VMAccessController.java | 37 ++++-------- .../java/security/natVMAccessController.cc | 2 +- libjava/stacktrace.cc | 60 ++++++++++--------- 5 files changed, 59 insertions(+), 55 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index f8c4f5d6f6e..4792cec6e78 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,16 @@ +2006-08-10 Gary Benson + + * include/java-stack.h (GetAccessControlStack): Change return + type. + * stacktrace.cc (accesscontrol_trace_fn): Record the number of + Java frames encountered. + (GetAccessControlStack): Return a flag indicating whether a call to + doPrivileged was encountered rather than an array of method names. + * java/security/natVMAccessController.cc (getStack): Change return + type. + * java/security/VMAccessController.java (getStack): Likewise. + (getContext): Change to reflect the above. + 2006-08-09 Gary Benson * stacktrace.cc (accesscontrol_trace_fn): Skip non-Java frames. diff --git a/libjava/include/java-stack.h b/libjava/include/java-stack.h index 29e4285fa02..f7209512b2c 100644 --- a/libjava/include/java-stack.h +++ b/libjava/include/java-stack.h @@ -125,7 +125,7 @@ public: static void GetCallerInfo (jclass checkClass, jclass *, _Jv_Method **); static JArray *GetClassContext (jclass checkClass); static ClassLoader *GetFirstNonSystemClassLoader (void); - static JArray *GetAccessControlStack (); + static jobjectArray GetAccessControlStack (); }; diff --git a/libjava/java/security/VMAccessController.java b/libjava/java/security/VMAccessController.java index 04c90d2ee78..85d0313b3a3 100644 --- a/libjava/java/security/VMAccessController.java +++ b/libjava/java/security/VMAccessController.java @@ -178,9 +178,9 @@ final class VMAccessController inGetContext.set(Boolean.TRUE); - Object[][] stack = getStack(); + Object[] stack = getStack(); Class[] classes = (Class[]) stack[0]; - String[] methods = (String[]) stack[1]; + boolean privileged = ((Boolean) stack[1]).booleanValue(); if (DEBUG) debug("got trace of length " + classes.length); @@ -188,32 +188,24 @@ final class VMAccessController HashSet domains = new HashSet(); HashSet seenDomains = new HashSet(); AccessControlContext context = null; - int privileged = 0; // We walk down the stack, adding each ProtectionDomain for each // class in the call stack. If we reach a call to doPrivileged, // we don't add any more stack frames. We skip the first three stack // frames, since they comprise the calls to getStack, getContext, // and AccessController.getContext. - for (int i = 3; i < classes.length && privileged < 2; i++) + for (int i = 3; i < classes.length; i++) { Class clazz = classes[i]; - String method = methods[i]; if (DEBUG) { - debug("checking " + clazz + "." + method); + debug("checking " + clazz); // subject to getClassLoader RuntimePermission debug("loader = " + clazz.getClassLoader()); } - // If the previous frame was a call to doPrivileged, then this is - // the last frame we look at. - if (privileged == 1) - privileged = 2; - - if (clazz.equals (AccessController.class) - && method.equals ("doPrivileged")) + if (privileged && i == classes.length - 2) { // If there was a call to doPrivileged with a supplied context, // return that context. If using JAAS doAs*, it should be @@ -221,7 +213,6 @@ final class VMAccessController LinkedList l = (LinkedList) contexts.get(); if (l != null) context = (AccessControlContext) l.getFirst(); - privileged = 1; } // subject to getProtectionDomain RuntimePermission @@ -270,16 +261,14 @@ final class VMAccessController } /** - * Returns a snapshot of the current call stack as a pair of arrays: - * the first an array of classes in the call stack, the second an array - * of strings containing the method names in the call stack. The two - * arrays match up, meaning that method i is declared in class - * i. The arrays are clean; it will only contain Java methods, - * and no element of the list should be null. + * Returns a snapshot of the current call stack as a two-element + * array. The first element is an array of classes in the call + * stack, and the second element is a boolean value indicating + * whether the trace stopped early because a call to doPrivileged + * was encountered. If this boolean value is true then the call to + * doPrivileged will be the second-last frame in the returned trace. * - * @return A pair of arrays describing the current call stack. The first - * element is an array of Class objects, and the second is an array - * of Strings comprising the method names. + * @return A snapshot of the current call stack. */ - private static native Object[][] getStack(); + private static native Object[] getStack(); } diff --git a/libjava/java/security/natVMAccessController.cc b/libjava/java/security/natVMAccessController.cc index 42cfc9cfe68..9a0ae489e80 100644 --- a/libjava/java/security/natVMAccessController.cc +++ b/libjava/java/security/natVMAccessController.cc @@ -16,7 +16,7 @@ details. */ #include -JArray * +jobjectArray java::security::VMAccessController::getStack () { return _Jv_StackTrace::GetAccessControlStack (); diff --git a/libjava/stacktrace.cc b/libjava/stacktrace.cc index bd011d005ce..fe2c2e058f9 100644 --- a/libjava/stacktrace.cc +++ b/libjava/stacktrace.cc @@ -18,6 +18,7 @@ details. */ #include +#include #include #include #include @@ -536,59 +537,58 @@ _Jv_StackTrace::GetFirstNonSystemClassLoader () return NULL; } +struct AccessControlTraceData +{ + jint length; + jboolean privileged; +}; + _Unwind_Reason_Code _Jv_StackTrace::accesscontrol_trace_fn (_Jv_UnwindState *state) { + AccessControlTraceData *trace_data = (AccessControlTraceData *) + state->trace_data; _Jv_StackFrame *frame = &state->frames[state->pos]; FillInFrameInfo (frame); if (!(frame->klass && frame->meth)) return _URC_NO_REASON; - bool *stopping = (bool *) state->trace_data; - if (*stopping) + trace_data->length++; + + // If the previous frame was a call to doPrivileged, then this is + // the last frame we look at. + if (trace_data->privileged) return _URC_NORMAL_STOP; if (frame->klass == &::java::security::AccessController::class$ && strcmp (frame->meth->name->chars(), "doPrivileged") == 0) - *stopping = true; + trace_data->privileged = true; return _URC_NO_REASON; } -JArray * +jobjectArray _Jv_StackTrace::GetAccessControlStack (void) { int trace_size = 100; _Jv_StackFrame frames[trace_size]; _Jv_UnwindState state (trace_size); state.frames = (_Jv_StackFrame *) &frames; + + AccessControlTraceData trace_data; + trace_data.length = 0; + trace_data.privileged = false; + state.trace_function = accesscontrol_trace_fn; - bool stopping = false; - state.trace_data = (void *) &stopping; + state.trace_data = (void *) &trace_data; UpdateNCodeMap(); _Unwind_Backtrace (UnwindTraceFn, &state); - - jint length = 0; - for (int i = 0; i < state.pos; i++) - { - _Jv_StackFrame *frame = &state.frames[i]; - - if (frame->klass && frame->meth) - length++; - } - - jclass array_class = _Jv_GetArrayClass (&::java::lang::Object::class$, NULL); - JArray *result = - (JArray *) _Jv_NewObjectArray (2, array_class, NULL); JArray *classes = (JArray *) - _Jv_NewObjectArray (length, &::java::lang::Class::class$, NULL); - JArray *methods = (JArray *) - _Jv_NewObjectArray (length, &::java::lang::String::class$, NULL); - jclass *c = elements (classes); - jstring *m = elements (methods); + _Jv_NewObjectArray (trace_data.length, &::java::lang::Class::class$, NULL); + jclass *c = elements (classes); for (int i = 0, j = 0; i < state.pos; i++) { @@ -596,13 +596,15 @@ _Jv_StackTrace::GetAccessControlStack (void) if (!frame->klass || !frame->meth) continue; c[j] = frame->klass; - m[j] = JvNewStringUTF (frame->meth->name->chars()); j++; } - jobjectArray *elems = elements (result); - elems[0] = (jobjectArray) classes; - elems[1] = (jobjectArray) methods; - + jobjectArray result = + (jobjectArray) _Jv_NewObjectArray (2, &::java::lang::Object::class$, + NULL); + jobject *r = elements (result); + r[0] = (jobject) classes; + r[1] = (jobject) new Boolean (trace_data.privileged); + return result; } -- 2.30.2