--- old/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c 2016-09-15 11:14:00.686066347 -0400 +++ new/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c 2016-09-15 11:13:58.882410512 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -343,6 +343,61 @@ debugMonitorExit(invokerLock); } +/* + * Check that method is in the specified clazz or one of its super classes. + * We have to enforce this check at the JDWP layer because the JNI layer + * has different requirements. + */ +static jvmtiError check_methodClass(JNIEnv *env, jclass clazz, jmethodID method) +{ + jfieldID clazz_field; + jclass containing_class; + jclass method_class; + jobject method_object; + jclass super_clazz; + + /* Get the java/lang/reflect/Method class. */ + method_class = JNI_FUNC_PTR(env,FindClass)(env, "java/lang/reflect/Method"); + if (method_class == NULL) { + return JVMTI_ERROR_INTERNAL; + } + + /* Get the field id for the java/lang/reflect/Method/clazz field. */ + clazz_field = JNI_FUNC_PTR(env,GetFieldID)(env, + method_class, + "clazz", + "Ljava/lang/Class;"); + if (clazz_field == NULL) { + return JVMTI_ERROR_INTERNAL; + } + + /* Get the method object from the method's jmethodID. */ + method_object = JNI_FUNC_PTR(env,ToReflectedMethod)(env, + clazz, + method, + JNI_TRUE /* isStatic */); + if (method_object == NULL) { + return JVMTI_ERROR_NONE; /* Bad jmethodID ? This will be handled elsewhere */ + } + + /* Get the value of the java.lang.reflect.Method.clazz field for method. */ + containing_class = JNI_FUNC_PTR(env,GetObjectField)(env, + method_object, + clazz_field); + if (containing_class == NULL) { + return JVMTI_ERROR_INTERNAL; + } + + super_clazz = clazz; + while (super_clazz != NULL) { + if (JNI_FUNC_PTR(env,IsSameObject)(env, super_clazz, containing_class)) { + return JVMTI_ERROR_NONE; + } + super_clazz = JNI_FUNC_PTR(env,GetSuperclass)(env, super_clazz); + } + return JVMTI_ERROR_INVALID_METHODID; +} + jvmtiError invoker_requestInvoke(jbyte invokeType, jbyte options, jint id, jthread thread, jclass clazz, jmethodID method, @@ -353,6 +408,13 @@ InvokeRequest *request; jvmtiError error = JVMTI_ERROR_NONE; + if (invokeType == INVOKE_STATIC) { + error = check_methodClass(env, clazz, method); + if (error != JVMTI_ERROR_NONE) { + return error; + } + } + debugMonitorEnter(invokerLock); request = threadControl_getInvokeRequest(thread); if (request != NULL) {