--- 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");