src/hotspot/share/prims/jniCheck.cpp
changeset 58479 35ce0ad5870a
parent 57829 58891103f9cc
child 58562 e43ac61b89ab
--- a/src/hotspot/share/prims/jniCheck.cpp	Mon Oct 07 15:58:04 2019 +0200
+++ b/src/hotspot/share/prims/jniCheck.cpp	Mon Oct 07 10:04:01 2019 -0400
@@ -448,16 +448,16 @@
 Method* jniCheck::validate_jmethod_id(JavaThread* thr, jmethodID method_id) {
   ASSERT_OOPS_ALLOWED;
   // do the fast jmethodID check first
-  Method* moop = Method::checked_resolve_jmethod_id(method_id);
-  if (moop == NULL) {
+  Method* m = Method::checked_resolve_jmethod_id(method_id);
+  if (m == NULL) {
     ReportJNIFatalError(thr, fatal_wrong_class_or_method);
   }
-  // jmethodIDs are supposed to be weak handles in the class loader data,
+  // jmethodIDs are handles in the class loader data,
   // but that can be expensive so check it last
   else if (!Method::is_method_id(method_id)) {
     ReportJNIFatalError(thr, fatal_non_weak_method);
   }
-  return moop;
+  return m;
 }
 
 
@@ -518,18 +518,29 @@
   }
 }
 
-void jniCheck::validate_call_object(JavaThread* thr, jobject obj, jmethodID method_id) {
-  /* validate the object being passed */
+void jniCheck::validate_call(JavaThread* thr, jclass clazz, jmethodID method_id, jobject obj) {
   ASSERT_OOPS_ALLOWED;
-  jniCheck::validate_jmethod_id(thr, method_id);
-  jniCheck::validate_object(thr, obj);
-}
+  Method* m = jniCheck::validate_jmethod_id(thr, method_id);
+  InstanceKlass* holder = m->method_holder();
+
+  if (clazz != NULL) {
+    Klass* k = jniCheck::validate_class(thr, clazz, false);
+    // Check that method is in the class, must be InstanceKlass
+    if (!InstanceKlass::cast(k)->is_subtype_of(holder)) {
+      ReportJNIFatalError(thr, fatal_wrong_class_or_method);
+    }
+  }
 
-void jniCheck::validate_call_class(JavaThread* thr, jclass clazz, jmethodID method_id) {
-  /* validate the class being passed */
-  ASSERT_OOPS_ALLOWED;
-  jniCheck::validate_jmethod_id(thr, method_id);
-  jniCheck::validate_class(thr, clazz, false);
+  if (obj != NULL) {
+    oop recv = jniCheck::validate_object(thr, obj);
+    assert(recv != NULL, "validate_object checks that");
+    Klass* ik = recv->klass();
+
+    // Check that the object is a subtype of method holder too.
+    if (!InstanceKlass::cast(ik)->is_subtype_of(holder)) {
+      ReportJNIFatalError(thr, fatal_wrong_class_or_method);
+    }
+  }
 }
 
 
@@ -595,8 +606,7 @@
                                 jboolean isStatic))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_class(thr, cls, false);
-      jniCheck::validate_jmethod_id(thr, methodID);
+      jniCheck::validate_call(thr, cls, methodID);
     )
     jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID,
                                                     isStatic);
@@ -852,8 +862,7 @@
     functionEnter(thr);
     va_list args;
     IN_VM(
-      jniCheck::validate_class(thr, clazz, false);
-      jniCheck::validate_jmethod_id(thr, methodID);
+      jniCheck::validate_call(thr, clazz, methodID);
     )
     va_start(args, methodID);
     jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
@@ -869,8 +878,7 @@
                          va_list args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_class(thr, clazz, false);
-      jniCheck::validate_jmethod_id(thr, methodID);
+      jniCheck::validate_call(thr, clazz, methodID);
     )
     jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
     functionExit(thr);
@@ -884,8 +892,7 @@
                          const jvalue *args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_class(thr, clazz, false);
-      jniCheck::validate_jmethod_id(thr, methodID);
+      jniCheck::validate_call(thr, clazz, methodID);
     )
     jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args);
     functionExit(thr);
@@ -941,7 +948,7 @@
     functionEnter(thr); \
     va_list args; \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
+      jniCheck::validate_call(thr, NULL, methodID, obj); \
     ) \
     va_start(args,methodID); \
     ResultType result =UNCHECKED()->Call##Result##MethodV(env, obj, methodID, \
@@ -959,7 +966,7 @@
                                     va_list args)) \
     functionEnter(thr); \
     IN_VM(\
-      jniCheck::validate_call_object(thr, obj, methodID); \
+      jniCheck::validate_call(thr, NULL, methodID, obj); \
     ) \
     ResultType result = UNCHECKED()->Call##Result##MethodV(env, obj, methodID,\
                                                            args); \
@@ -975,7 +982,7 @@
                                     const jvalue * args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
+      jniCheck::validate_call(thr, NULL, methodID, obj); \
     ) \
     ResultType result = UNCHECKED()->Call##Result##MethodA(env, obj, methodID,\
                                                            args); \
@@ -1002,7 +1009,7 @@
     functionEnter(thr);
     va_list args;
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
+      jniCheck::validate_call(thr, NULL, methodID, obj);
     )
     va_start(args,methodID);
     UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
@@ -1018,7 +1025,7 @@
                               va_list args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
+      jniCheck::validate_call(thr, NULL, methodID, obj);
     )
     UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
     thr->set_pending_jni_exception_check("CallVoidMethodV");
@@ -1032,7 +1039,7 @@
                               const jvalue * args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
+      jniCheck::validate_call(thr, NULL, methodID, obj);
     )
     UNCHECKED()->CallVoidMethodA(env,obj,methodID,args);
     thr->set_pending_jni_exception_check("CallVoidMethodA");
@@ -1049,8 +1056,7 @@
     functionEnter(thr); \
     va_list args; \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
-      jniCheck::validate_call_class(thr, clazz, methodID); \
+      jniCheck::validate_call(thr, clazz, methodID, obj); \
     ) \
     va_start(args,methodID); \
     ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \
@@ -1072,8 +1078,7 @@
                                               va_list args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
-      jniCheck::validate_call_class(thr, clazz, methodID); \
+      jniCheck::validate_call(thr, clazz, methodID, obj); \
     ) \
     ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \
                                                                      obj, \
@@ -1093,8 +1098,7 @@
                                               const jvalue * args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
-      jniCheck::validate_call_class(thr, clazz, methodID); \
+      jniCheck::validate_call(thr, clazz, methodID, obj); \
     ) \
     ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodA(env, \
                                                                      obj, \
@@ -1125,8 +1129,7 @@
     functionEnter(thr);
     va_list args;
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
-      jniCheck::validate_call_class(thr, clazz, methodID);
+      jniCheck::validate_call(thr, clazz, methodID, obj);
     )
     va_start(args,methodID);
     UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
@@ -1143,8 +1146,7 @@
                                         va_list args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
-      jniCheck::validate_call_class(thr, clazz, methodID);
+      jniCheck::validate_call(thr, clazz, methodID, obj);
     )
     UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
     thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodV");
@@ -1159,8 +1161,7 @@
                                         const jvalue * args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
-      jniCheck::validate_call_class(thr, clazz, methodID);
+      jniCheck::validate_call(thr, clazz, methodID, obj);
     )
     UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args);
     thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodA");
@@ -1253,8 +1254,7 @@
     functionEnter(thr); \
     va_list args; \
     IN_VM( \
-      jniCheck::validate_jmethod_id(thr, methodID); \
-      jniCheck::validate_class(thr, clazz, false); \
+      jniCheck::validate_call(thr, clazz, methodID); \
     ) \
     va_start(args,methodID); \
     ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \
@@ -1274,8 +1274,7 @@
                                           va_list args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_jmethod_id(thr, methodID); \
-      jniCheck::validate_class(thr, clazz, false); \
+      jniCheck::validate_call(thr, clazz, methodID); \
     ) \
     ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \
                                                                  clazz, \
@@ -1293,8 +1292,7 @@
                                           const jvalue *args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_jmethod_id(thr, methodID); \
-      jniCheck::validate_class(thr, clazz, false); \
+      jniCheck::validate_call(thr, clazz, methodID); \
     ) \
     ReturnType result = UNCHECKED()->CallStatic##Result##MethodA(env, \
                                                                  clazz, \
@@ -1323,8 +1321,7 @@
     functionEnter(thr);
     va_list args;
     IN_VM(
-      jniCheck::validate_jmethod_id(thr, methodID);
-      jniCheck::validate_class(thr, cls, false);
+      jniCheck::validate_call(thr, cls, methodID);
     )
     va_start(args,methodID);
     UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
@@ -1340,8 +1337,7 @@
                                     va_list args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_jmethod_id(thr, methodID);
-      jniCheck::validate_class(thr, cls, false);
+      jniCheck::validate_call(thr, cls, methodID);
     )
     UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
     thr->set_pending_jni_exception_check("CallStaticVoidMethodV");
@@ -1355,8 +1351,7 @@
                                     const jvalue * args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_jmethod_id(thr, methodID);
-      jniCheck::validate_class(thr, cls, false);
+      jniCheck::validate_call(thr, cls, methodID);
     )
     UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args);
     thr->set_pending_jni_exception_check("CallStaticVoidMethodA");