8157464: Disallow StackWalker.getCallerClass() be called by caller-sensitive method
authormchung
Wed, 14 Sep 2016 11:53:20 -0700
changeset 41095 97cca074c2be
parent 41094 4e0c638397c9
child 41096 adaf04f6b651
child 41174 aed0f6434aea
8157464: Disallow StackWalker.getCallerClass() be called by caller-sensitive method Reviewed-by: bchristi, coleenp, dfuchs, sspitsyn
hotspot/src/share/vm/prims/jvm.h
hotspot/src/share/vm/prims/stackwalk.cpp
hotspot/src/share/vm/prims/stackwalk.hpp
--- a/hotspot/src/share/vm/prims/jvm.h	Tue Sep 13 16:18:44 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvm.h	Wed Sep 14 11:53:20 2016 -0700
@@ -196,7 +196,8 @@
  * java.lang.StackWalker
  */
 enum {
-  JVM_STACKWALK_FILL_CLASS_REFS_ONLY       = 0x2,
+  JVM_STACKWALK_FILL_CLASS_REFS_ONLY       = 0x02,
+  JVM_STACKWALK_GET_CALLER_CLASS           = 0x04,
   JVM_STACKWALK_SHOW_HIDDEN_FRAMES         = 0x20,
   JVM_STACKWALK_FILL_LIVE_STACK_FRAMES     = 0x100
 };
--- a/hotspot/src/share/vm/prims/stackwalk.cpp	Tue Sep 13 16:18:44 2016 -0700
+++ b/hotspot/src/share/vm/prims/stackwalk.cpp	Wed Sep 14 11:53:20 2016 -0700
@@ -113,7 +113,10 @@
     int bci = stream.bci();
 
     if (method == NULL) continue;
-    if (!ShowHiddenFrames && StackWalk::skip_hidden_frames(mode)) {
+
+    // skip hidden frames for default StackWalker option (i.e. SHOW_HIDDEN_FRAMES
+    // not set) and when StackWalker::getCallerClass is called
+    if (!ShowHiddenFrames && (skip_hidden_frames(mode) || get_caller_class(mode))) {
       if (method->is_hidden()) {
         if (TraceStackWalk) {
           tty->print("  hidden method: "); method->print_short_name();
@@ -139,7 +142,14 @@
       Handle stackFrame(frames_array->obj_at(index));
       fill_stackframe(stackFrame, method, bci);
     } else {
-      assert (use_frames_array(mode) == false, "Bad mode for get caller class");
+      assert (use_frames_array(mode) == false, "Bad mode for filling in Class object");
+      if (get_caller_class(mode) && index == start_index && method->caller_sensitive()) {
+        ResourceMark rm(THREAD);
+        THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(),
+          err_msg("StackWalker::getCallerClass called from @CallerSensitive %s method",
+                  method->name_and_sig_as_C_string()));
+      }
+
       frames_array->obj_at_put(index, method->method_holder()->java_mirror());
     }
     if (++frames_decoded >= max_nframes)  break;
--- a/hotspot/src/share/vm/prims/stackwalk.hpp	Tue Sep 13 16:18:44 2016 -0700
+++ b/hotspot/src/share/vm/prims/stackwalk.hpp	Wed Sep 14 11:53:20 2016 -0700
@@ -82,6 +82,9 @@
   static void fill_live_stackframe(Handle stackFrame, const methodHandle& method, int bci,
                                    javaVFrame* jvf, TRAPS);
 
+  static inline bool get_caller_class(int mode) {
+    return (mode & JVM_STACKWALK_GET_CALLER_CLASS) != 0;
+  }
   static inline bool skip_hidden_frames(int mode) {
     return (mode & JVM_STACKWALK_SHOW_HIDDEN_FRAMES) == 0;
   }