This commit is contained in:
Rachel Protacio 2016-11-17 21:59:52 +00:00
commit 7246df4cca
6 changed files with 161 additions and 9 deletions

View File

@ -4349,13 +4349,34 @@ static void check_super_class_access(const InstanceKlass* this_klass, TRAPS) {
assert(this_klass != NULL, "invariant"); assert(this_klass != NULL, "invariant");
const Klass* const super = this_klass->super(); const Klass* const super = this_klass->super();
if (super != NULL) { if (super != NULL) {
// If the loader is not the boot loader then throw an exception if its
// superclass is in package jdk.internal.reflect and its loader is not a
// special reflection class loader
if (!this_klass->class_loader_data()->is_the_null_class_loader_data()) {
assert(super->is_instance_klass(), "super is not instance klass");
PackageEntry* super_package = super->package();
if (super_package != NULL &&
super_package->name()->fast_compare(vmSymbols::jdk_internal_reflect()) == 0 &&
!java_lang_ClassLoader::is_reflection_class_loader(this_klass->class_loader())) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_IllegalAccessError(),
"class %s loaded by %s cannot access jdk/internal/reflect superclass %s",
this_klass->external_name(),
this_klass->class_loader_data()->loader_name(),
super->external_name());
return;
}
}
Reflection::VerifyClassAccessResults vca_result = Reflection::VerifyClassAccessResults vca_result =
Reflection::verify_class_access(this_klass, super, false); Reflection::verify_class_access(this_klass, super, false);
if (vca_result != Reflection::ACCESS_OK) { if (vca_result != Reflection::ACCESS_OK) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
char* msg = Reflection::verify_class_access_msg(this_klass, super, vca_result); char* msg = Reflection::verify_class_access_msg(this_klass, super, vca_result);
if (msg == NULL) { if (msg == NULL) {
ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbols::java_lang_IllegalAccessError(), vmSymbols::java_lang_IllegalAccessError(),

View File

@ -3525,17 +3525,24 @@ bool java_lang_ClassLoader::is_trusted_loader(oop loader) {
return false; return false;
} }
oop java_lang_ClassLoader::non_reflection_class_loader(oop loader) { // Return true if this is one of the class loaders associated with
// the generated bytecodes for reflection.
bool java_lang_ClassLoader::is_reflection_class_loader(oop loader) {
if (loader != NULL) { if (loader != NULL) {
// See whether this is one of the class loaders associated with
// the generated bytecodes for reflection, and if so, "magically"
// delegate to its parent to prevent class loading from occurring
// in places where applications using reflection didn't expect it.
Klass* delegating_cl_class = SystemDictionary::reflect_DelegatingClassLoader_klass(); Klass* delegating_cl_class = SystemDictionary::reflect_DelegatingClassLoader_klass();
// This might be null in non-1.4 JDKs // This might be null in non-1.4 JDKs
if (delegating_cl_class != NULL && loader->is_a(delegating_cl_class)) { return (delegating_cl_class != NULL && loader->is_a(delegating_cl_class));
return parent(loader); }
} return false;
}
oop java_lang_ClassLoader::non_reflection_class_loader(oop loader) {
// See whether this is one of the class loaders associated with
// the generated bytecodes for reflection, and if so, "magically"
// delegate to its parent to prevent class loading from occurring
// in places where applications using reflection didn't expect it.
if (is_reflection_class_loader(loader)) {
return parent(loader);
} }
return loader; return loader;
} }

View File

@ -1243,6 +1243,10 @@ class java_lang_ClassLoader : AllStatic {
static bool is_trusted_loader(oop loader); static bool is_trusted_loader(oop loader);
// Return true if this is one of the class loaders associated with
// the generated bytecodes for reflection.
static bool is_reflection_class_loader(oop loader);
// Fix for 4474172 // Fix for 4474172
static oop non_reflection_class_loader(oop loader); static oop non_reflection_class_loader(oop loader);

View File

@ -228,6 +228,7 @@
\ \
/* Support for reflection based on dynamic bytecode generation (JDK 1.4 and above) */ \ /* Support for reflection based on dynamic bytecode generation (JDK 1.4 and above) */ \
\ \
template(jdk_internal_reflect, "jdk/internal/reflect") \
template(reflect_MagicAccessorImpl, "jdk/internal/reflect/MagicAccessorImpl") \ template(reflect_MagicAccessorImpl, "jdk/internal/reflect/MagicAccessorImpl") \
template(reflect_MethodAccessorImpl, "jdk/internal/reflect/MethodAccessorImpl") \ template(reflect_MethodAccessorImpl, "jdk/internal/reflect/MethodAccessorImpl") \
template(reflect_ConstructorAccessorImpl, "jdk/internal/reflect/ConstructorAccessorImpl") \ template(reflect_ConstructorAccessorImpl, "jdk/internal/reflect/ConstructorAccessorImpl") \

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8166304
* @summary Skipping access check for classes generated by core reflection
* @compile fakeMethodAccessor.jasm
* @run main FakeMethodAcc
*/
/*
* Test that trying to create a sub-type of a 'magic' jdk.internal.reflect
* class should fail with an IllegalAccessError exception.
*/
public class FakeMethodAcc {
public static void main(String args[]) throws Throwable {
System.out.println("Regression test for bug 8166304");
try {
Class newClass = Class.forName("fakeMethodAccessor");
throw new RuntimeException(
"Missing expected IllegalAccessError exception");
} catch (java.lang.IllegalAccessError e) {
}
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
// This is the Java representation of the below jasm code. The test tries
// to create a sub-type of jdk.internal.reflect.MethodAccessorImpl in order
// to bypass Reflection.getCallerClass. That should fail with an IAE.
//
import java.lang.reflect.Module;
class fakeMethodAccessor extends jdk.internal.reflect.MethodAccessorImpl {
public static void main(String[] a) throws Exception {
fakeMethodAccessor f = new fakeMethodAccessor();
System.out.println(String.class.getModule()
.isExported("jdk.internal.misc", fakeMethodAccessor.class.getModule()));
}
}
*/
super class fakeMethodAccessor
extends jdk/internal/reflect/MethodAccessorImpl
version 53:0
{
Method "<init>":"()V"
stack 1 locals 1
{
aload_0;
invokespecial Method jdk/internal/reflect/MethodAccessorImpl."<init>":"()V";
return;
}
public static Method main:"([Ljava/lang/String;)V"
throws java/lang/Exception
stack 4 locals 2
{
new class FakeMethodAccessor;
dup;
invokespecial Method "<init>":"()V";
astore_1;
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc class java/lang/String;
invokevirtual Method java/lang/Class.getModule:"()Ljava/lang/reflect/Module;";
ldc String "jdk.internal.misc";
ldc class FakeMethodAccessor;
invokevirtual Method java/lang/Class.getModule:"()Ljava/lang/reflect/Module;";
invokevirtual Method java/lang/reflect/Module.isExported:"(Ljava/lang/String;Ljava/lang/reflect/Module;)Z";
invokevirtual Method java/io/PrintStream.println:"(Z)V";
return;
}
} // end Class FakeMethodAccessor