src/share/vm/prims/jvm.cpp

changeset 4870
cd9ad42dfde0
parent 4818
1916ca1dec2f
parent 4866
16885e702c88
child 5097
92ef81e2f571
child 5242
b295e132102d
     1.1 --- a/src/share/vm/prims/jvm.cpp	Thu Mar 28 19:13:22 2013 -0700
     1.2 +++ b/src/share/vm/prims/jvm.cpp	Fri Mar 29 20:52:01 2013 -0700
     1.3 @@ -30,6 +30,7 @@
     1.4  #include "classfile/systemDictionary.hpp"
     1.5  #include "classfile/vmSymbols.hpp"
     1.6  #include "gc_interface/collectedHeap.inline.hpp"
     1.7 +#include "interpreter/bytecode.hpp"
     1.8  #include "memory/oopFactory.hpp"
     1.9  #include "memory/universe.inline.hpp"
    1.10  #include "oops/fieldStreams.hpp"
    1.11 @@ -665,8 +666,51 @@
    1.12  
    1.13  JVM_ENTRY(jclass, JVM_GetCallerClass(JNIEnv* env, int depth))
    1.14    JVMWrapper("JVM_GetCallerClass");
    1.15 -  Klass* k = thread->security_get_caller_class(depth);
    1.16 -  return (k == NULL) ? NULL : (jclass) JNIHandles::make_local(env, k->java_mirror());
    1.17 +
    1.18 +  // Pre-JDK 8 and early builds of JDK 8 don't have a CallerSensitive annotation.
    1.19 +  if (SystemDictionary::reflect_CallerSensitive_klass() == NULL) {
    1.20 +    Klass* k = thread->security_get_caller_class(depth);
    1.21 +    return (k == NULL) ? NULL : (jclass) JNIHandles::make_local(env, k->java_mirror());
    1.22 +  } else {
    1.23 +    // Basic handshaking with Java_sun_reflect_Reflection_getCallerClass
    1.24 +    assert(depth == -1, "wrong handshake depth");
    1.25 +  }
    1.26 +
    1.27 +  // Getting the class of the caller frame.
    1.28 +  //
    1.29 +  // The call stack at this point looks something like this:
    1.30 +  //
    1.31 +  // [0] [ @CallerSensitive public sun.reflect.Reflection.getCallerClass ]
    1.32 +  // [1] [ @CallerSensitive API.method                                   ]
    1.33 +  // [.] [ (skipped intermediate frames)                                 ]
    1.34 +  // [n] [ caller                                                        ]
    1.35 +  vframeStream vfst(thread);
    1.36 +  // Cf. LibraryCallKit::inline_native_Reflection_getCallerClass
    1.37 +  for (int n = 0; !vfst.at_end(); vfst.security_next(), n++) {
    1.38 +    Method* m = vfst.method();
    1.39 +    assert(m != NULL, "sanity");
    1.40 +    switch (n) {
    1.41 +    case 0:
    1.42 +      // This must only be called from Reflection.getCallerClass
    1.43 +      if (m->intrinsic_id() != vmIntrinsics::_getCallerClass) {
    1.44 +        THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetCallerClass must only be called from Reflection.getCallerClass");
    1.45 +      }
    1.46 +      // fall-through
    1.47 +    case 1:
    1.48 +      // Frame 0 and 1 must be caller sensitive.
    1.49 +      if (!m->caller_sensitive()) {
    1.50 +        THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), err_msg("CallerSensitive annotation expected at frame %d", n));
    1.51 +      }
    1.52 +      break;
    1.53 +    default:
    1.54 +      if (!m->is_ignored_by_security_stack_walk()) {
    1.55 +        // We have reached the desired frame; return the holder class.
    1.56 +        return (jclass) JNIHandles::make_local(env, m->method_holder()->java_mirror());
    1.57 +      }
    1.58 +      break;
    1.59 +    }
    1.60 +  }
    1.61 +  return NULL;
    1.62  JVM_END
    1.63  
    1.64  
    1.65 @@ -3208,11 +3252,24 @@
    1.66    KlassLink* first = NULL;
    1.67    KlassLink* last  = NULL;
    1.68    int depth = 0;
    1.69 -
    1.70 -  for(vframeStream vfst(thread); !vfst.at_end(); vfst.security_get_caller_frame(1)) {
    1.71 +  vframeStream vfst(thread);
    1.72 +
    1.73 +  if (SystemDictionary::reflect_CallerSensitive_klass() != NULL) {
    1.74 +    // This must only be called from SecurityManager.getClassContext
    1.75 +    Method* m = vfst.method();
    1.76 +    if (!(m->method_holder() == SystemDictionary::SecurityManager_klass() &&
    1.77 +          m->name()          == vmSymbols::getClassContext_name() &&
    1.78 +          m->signature()     == vmSymbols::void_class_array_signature())) {
    1.79 +      THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext");
    1.80 +    }
    1.81 +  }
    1.82 +
    1.83 +  // Collect method holders
    1.84 +  for (; !vfst.at_end(); vfst.security_next()) {
    1.85 +    Method* m = vfst.method();
    1.86      // Native frames are not returned
    1.87 -    if (!vfst.method()->is_native()) {
    1.88 -      Klass* holder = vfst.method()->method_holder();
    1.89 +    if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) {
    1.90 +      Klass* holder = m->method_holder();
    1.91        assert(holder->is_klass(), "just checking");
    1.92        depth++;
    1.93        KlassLink* l = new KlassLink(KlassHandle(thread, holder));

mercurial