--- old/src/hotspot/share/prims/jniCheck.cpp 2019-10-01 09:37:37.088444780 -0400 +++ new/src/hotspot/share/prims/jniCheck.cpp 2019-10-01 09:37:36.788436920 -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; } @@ -525,11 +525,18 @@ jniCheck::validate_object(thr, obj); } -void jniCheck::validate_call_class(JavaThread* thr, jclass clazz, jmethodID method_id) { - /* validate the class being passed */ +void jniCheck::validate_call_class(JavaThread* thr, jclass clazz, jmethodID method_id, jobject obj) { ASSERT_OOPS_ALLOWED; - jniCheck::validate_jmethod_id(thr, method_id); - jniCheck::validate_class(thr, clazz, false); + Method* m = jniCheck::validate_jmethod_id(thr, method_id); + Klass* k = jniCheck::validate_class(thr, clazz, false); + if (obj != NULL) { + jniCheck::validate_object(thr, obj); + } + + // Check that method is in the class, must be InstanceKlass + if (!InstanceKlass::cast(k)->is_subtype_of(m->method_holder())) { + ReportJNIFatalError(thr, fatal_wrong_class_or_method); + } } @@ -595,8 +602,7 @@ jboolean isStatic)) functionEnter(thr); IN_VM( - jniCheck::validate_class(thr, cls, false); - jniCheck::validate_jmethod_id(thr, methodID); + jniCheck::validate_call_class(thr, cls, methodID); ) jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID, isStatic); @@ -852,8 +858,7 @@ functionEnter(thr); va_list args; IN_VM( - jniCheck::validate_class(thr, clazz, false); - jniCheck::validate_jmethod_id(thr, methodID); + jniCheck::validate_call_class(thr, clazz, methodID); ) va_start(args, methodID); jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args); @@ -869,8 +874,7 @@ va_list args)) functionEnter(thr); IN_VM( - jniCheck::validate_class(thr, clazz, false); - jniCheck::validate_jmethod_id(thr, methodID); + jniCheck::validate_call_class(thr, clazz, methodID); ) jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args); functionExit(thr); @@ -884,8 +888,7 @@ const jvalue *args)) functionEnter(thr); IN_VM( - jniCheck::validate_class(thr, clazz, false); - jniCheck::validate_jmethod_id(thr, methodID); + jniCheck::validate_call_class(thr, clazz, methodID); ) jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args); functionExit(thr); @@ -1049,8 +1052,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_class(thr, clazz, methodID, obj); \ ) \ va_start(args,methodID); \ ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \ @@ -1072,8 +1074,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_class(thr, clazz, methodID, obj); \ ) \ ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \ obj, \ @@ -1093,8 +1094,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_class(thr, clazz, methodID, obj); \ ) \ ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodA(env, \ obj, \ @@ -1125,8 +1125,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_class(thr, clazz, methodID, obj); ) va_start(args,methodID); UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args); @@ -1143,8 +1142,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_class(thr, clazz, methodID, obj); ) UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args); thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodV"); @@ -1159,8 +1157,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_class(thr, clazz, methodID, obj); ) UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args); thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodA"); @@ -1253,8 +1250,7 @@ functionEnter(thr); \ va_list args; \ IN_VM( \ - jniCheck::validate_jmethod_id(thr, methodID); \ - jniCheck::validate_class(thr, clazz, false); \ + jniCheck::validate_call_class(thr, clazz, methodID); \ ) \ va_start(args,methodID); \ ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \ @@ -1274,8 +1270,7 @@ va_list args)) \ functionEnter(thr); \ IN_VM( \ - jniCheck::validate_jmethod_id(thr, methodID); \ - jniCheck::validate_class(thr, clazz, false); \ + jniCheck::validate_call_class(thr, clazz, methodID); \ ) \ ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \ clazz, \ @@ -1293,8 +1288,7 @@ const jvalue *args)) \ functionEnter(thr); \ IN_VM( \ - jniCheck::validate_jmethod_id(thr, methodID); \ - jniCheck::validate_class(thr, clazz, false); \ + jniCheck::validate_call_class(thr, clazz, methodID); \ ) \ ReturnType result = UNCHECKED()->CallStatic##Result##MethodA(env, \ clazz, \ @@ -1323,8 +1317,7 @@ functionEnter(thr); va_list args; IN_VM( - jniCheck::validate_jmethod_id(thr, methodID); - jniCheck::validate_class(thr, cls, false); + jniCheck::validate_call_class(thr, cls, methodID); ) va_start(args,methodID); UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args); @@ -1340,8 +1333,7 @@ va_list args)) functionEnter(thr); IN_VM( - jniCheck::validate_jmethod_id(thr, methodID); - jniCheck::validate_class(thr, cls, false); + jniCheck::validate_call_class(thr, cls, methodID); ) UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args); thr->set_pending_jni_exception_check("CallStaticVoidMethodV"); @@ -1355,8 +1347,7 @@ const jvalue * args)) functionEnter(thr); IN_VM( - jniCheck::validate_jmethod_id(thr, methodID); - jniCheck::validate_class(thr, cls, false); + jniCheck::validate_call_class(thr, cls, methodID); ) UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args); thr->set_pending_jni_exception_check("CallStaticVoidMethodA");