Commit 3c95dcfd by Gary Benson Committed by Gary Benson

java-stack.h (GetAccessControlStack): Change return type.

2006-08-10  Gary Benson  <gbenson@redhat.com>

	* 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
parent 9f6b5d59
2006-08-10 Gary Benson <gbenson@redhat.com>
* 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 <gbenson@redhat.com> 2006-08-09 Gary Benson <gbenson@redhat.com>
* stacktrace.cc (accesscontrol_trace_fn): Skip non-Java frames. * stacktrace.cc (accesscontrol_trace_fn): Skip non-Java frames.
......
...@@ -125,7 +125,7 @@ public: ...@@ -125,7 +125,7 @@ public:
static void GetCallerInfo (jclass checkClass, jclass *, _Jv_Method **); static void GetCallerInfo (jclass checkClass, jclass *, _Jv_Method **);
static JArray<jclass> *GetClassContext (jclass checkClass); static JArray<jclass> *GetClassContext (jclass checkClass);
static ClassLoader *GetFirstNonSystemClassLoader (void); static ClassLoader *GetFirstNonSystemClassLoader (void);
static JArray<jobjectArray> *GetAccessControlStack (); static jobjectArray GetAccessControlStack ();
}; };
......
...@@ -178,9 +178,9 @@ final class VMAccessController ...@@ -178,9 +178,9 @@ final class VMAccessController
inGetContext.set(Boolean.TRUE); inGetContext.set(Boolean.TRUE);
Object[][] stack = getStack(); Object[] stack = getStack();
Class[] classes = (Class[]) stack[0]; Class[] classes = (Class[]) stack[0];
String[] methods = (String[]) stack[1]; boolean privileged = ((Boolean) stack[1]).booleanValue();
if (DEBUG) if (DEBUG)
debug("got trace of length " + classes.length); debug("got trace of length " + classes.length);
...@@ -188,32 +188,24 @@ final class VMAccessController ...@@ -188,32 +188,24 @@ final class VMAccessController
HashSet domains = new HashSet(); HashSet domains = new HashSet();
HashSet seenDomains = new HashSet(); HashSet seenDomains = new HashSet();
AccessControlContext context = null; AccessControlContext context = null;
int privileged = 0;
// We walk down the stack, adding each ProtectionDomain for each // We walk down the stack, adding each ProtectionDomain for each
// class in the call stack. If we reach a call to doPrivileged, // 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 // we don't add any more stack frames. We skip the first three stack
// frames, since they comprise the calls to getStack, getContext, // frames, since they comprise the calls to getStack, getContext,
// and AccessController.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]; Class clazz = classes[i];
String method = methods[i];
if (DEBUG) if (DEBUG)
{ {
debug("checking " + clazz + "." + method); debug("checking " + clazz);
// subject to getClassLoader RuntimePermission // subject to getClassLoader RuntimePermission
debug("loader = " + clazz.getClassLoader()); debug("loader = " + clazz.getClassLoader());
} }
// If the previous frame was a call to doPrivileged, then this is if (privileged && i == classes.length - 2)
// the last frame we look at.
if (privileged == 1)
privileged = 2;
if (clazz.equals (AccessController.class)
&& method.equals ("doPrivileged"))
{ {
// If there was a call to doPrivileged with a supplied context, // If there was a call to doPrivileged with a supplied context,
// return that context. If using JAAS doAs*, it should be // return that context. If using JAAS doAs*, it should be
...@@ -221,7 +213,6 @@ final class VMAccessController ...@@ -221,7 +213,6 @@ final class VMAccessController
LinkedList l = (LinkedList) contexts.get(); LinkedList l = (LinkedList) contexts.get();
if (l != null) if (l != null)
context = (AccessControlContext) l.getFirst(); context = (AccessControlContext) l.getFirst();
privileged = 1;
} }
// subject to getProtectionDomain RuntimePermission // subject to getProtectionDomain RuntimePermission
...@@ -270,16 +261,14 @@ final class VMAccessController ...@@ -270,16 +261,14 @@ final class VMAccessController
} }
/** /**
* Returns a snapshot of the current call stack as a pair of arrays: * Returns a snapshot of the current call stack as a two-element
* the first an array of classes in the call stack, the second an array * array. The first element is an array of classes in the call
* of strings containing the method names in the call stack. The two * stack, and the second element is a boolean value indicating
* arrays match up, meaning that method <i>i</i> is declared in class * whether the trace stopped early because a call to doPrivileged
* <i>i</i>. The arrays are clean; it will only contain Java methods, * was encountered. If this boolean value is true then the call to
* and no element of the list should be null. * doPrivileged will be the second-last frame in the returned trace.
* *
* @return A pair of arrays describing the current call stack. The first * @return A snapshot of the current call stack.
* element is an array of Class objects, and the second is an array
* of Strings comprising the method names.
*/ */
private static native Object[][] getStack(); private static native Object[] getStack();
} }
...@@ -16,7 +16,7 @@ details. */ ...@@ -16,7 +16,7 @@ details. */
#include <java/security/VMAccessController.h> #include <java/security/VMAccessController.h>
JArray<jobjectArray> * jobjectArray
java::security::VMAccessController::getStack () java::security::VMAccessController::getStack ()
{ {
return _Jv_StackTrace::GetAccessControlStack (); return _Jv_StackTrace::GetAccessControlStack ();
......
...@@ -18,6 +18,7 @@ details. */ ...@@ -18,6 +18,7 @@ details. */
#include <stdio.h> #include <stdio.h>
#include <java/lang/Boolean.h>
#include <java/lang/Class.h> #include <java/lang/Class.h>
#include <java/lang/Long.h> #include <java/lang/Long.h>
#include <java/security/AccessController.h> #include <java/security/AccessController.h>
...@@ -536,59 +537,58 @@ _Jv_StackTrace::GetFirstNonSystemClassLoader () ...@@ -536,59 +537,58 @@ _Jv_StackTrace::GetFirstNonSystemClassLoader ()
return NULL; return NULL;
} }
struct AccessControlTraceData
{
jint length;
jboolean privileged;
};
_Unwind_Reason_Code _Unwind_Reason_Code
_Jv_StackTrace::accesscontrol_trace_fn (_Jv_UnwindState *state) _Jv_StackTrace::accesscontrol_trace_fn (_Jv_UnwindState *state)
{ {
AccessControlTraceData *trace_data = (AccessControlTraceData *)
state->trace_data;
_Jv_StackFrame *frame = &state->frames[state->pos]; _Jv_StackFrame *frame = &state->frames[state->pos];
FillInFrameInfo (frame); FillInFrameInfo (frame);
if (!(frame->klass && frame->meth)) if (!(frame->klass && frame->meth))
return _URC_NO_REASON; return _URC_NO_REASON;
bool *stopping = (bool *) state->trace_data; trace_data->length++;
if (*stopping)
// 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; return _URC_NORMAL_STOP;
if (frame->klass == &::java::security::AccessController::class$ if (frame->klass == &::java::security::AccessController::class$
&& strcmp (frame->meth->name->chars(), "doPrivileged") == 0) && strcmp (frame->meth->name->chars(), "doPrivileged") == 0)
*stopping = true; trace_data->privileged = true;
return _URC_NO_REASON; return _URC_NO_REASON;
} }
JArray<jobjectArray> * jobjectArray
_Jv_StackTrace::GetAccessControlStack (void) _Jv_StackTrace::GetAccessControlStack (void)
{ {
int trace_size = 100; int trace_size = 100;
_Jv_StackFrame frames[trace_size]; _Jv_StackFrame frames[trace_size];
_Jv_UnwindState state (trace_size); _Jv_UnwindState state (trace_size);
state.frames = (_Jv_StackFrame *) &frames; state.frames = (_Jv_StackFrame *) &frames;
AccessControlTraceData trace_data;
trace_data.length = 0;
trace_data.privileged = false;
state.trace_function = accesscontrol_trace_fn; state.trace_function = accesscontrol_trace_fn;
bool stopping = false; state.trace_data = (void *) &trace_data;
state.trace_data = (void *) &stopping;
UpdateNCodeMap(); UpdateNCodeMap();
_Unwind_Backtrace (UnwindTraceFn, &state); _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<jobjectArray> *result =
(JArray<jobjectArray> *) _Jv_NewObjectArray (2, array_class, NULL);
JArray<jclass> *classes = (JArray<jclass> *) JArray<jclass> *classes = (JArray<jclass> *)
_Jv_NewObjectArray (length, &::java::lang::Class::class$, NULL); _Jv_NewObjectArray (trace_data.length, &::java::lang::Class::class$, NULL);
JArray<jstring> *methods = (JArray<jstring> *) jclass *c = elements (classes);
_Jv_NewObjectArray (length, &::java::lang::String::class$, NULL);
jclass *c = elements (classes);
jstring *m = elements (methods);
for (int i = 0, j = 0; i < state.pos; i++) for (int i = 0, j = 0; i < state.pos; i++)
{ {
...@@ -596,13 +596,15 @@ _Jv_StackTrace::GetAccessControlStack (void) ...@@ -596,13 +596,15 @@ _Jv_StackTrace::GetAccessControlStack (void)
if (!frame->klass || !frame->meth) if (!frame->klass || !frame->meth)
continue; continue;
c[j] = frame->klass; c[j] = frame->klass;
m[j] = JvNewStringUTF (frame->meth->name->chars());
j++; j++;
} }
jobjectArray *elems = elements (result); jobjectArray result =
elems[0] = (jobjectArray) classes; (jobjectArray) _Jv_NewObjectArray (2, &::java::lang::Object::class$,
elems[1] = (jobjectArray) methods; NULL);
jobject *r = elements (result);
r[0] = (jobject) classes;
r[1] = (jobject) new Boolean (trace_data.privileged);
return result; return result;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment