8189193: FindClass should only see classes from the boot loader called from its associated native library

Reviewed-by: coleenp, dholmes
This commit is contained in:
Mandy Chung 2017-10-19 17:27:34 -07:00
parent e4cf0cb437
commit 7344b46c71
6 changed files with 180 additions and 6 deletions
make/test
src/hotspot/share/prims
test/hotspot/jtreg/runtime/jni/FindClass

@ -50,6 +50,7 @@ BUILD_HOTSPOT_JTREG_NATIVE_SRC += \
$(TOPDIR)/test/hotspot/jtreg/runtime/jni/8025979 \
$(TOPDIR)/test/hotspot/jtreg/runtime/jni/8033445 \
$(TOPDIR)/test/hotspot/jtreg/runtime/jni/checked \
$(TOPDIR)/test/hotspot/jtreg/runtime/jni/FindClass \
$(TOPDIR)/test/hotspot/jtreg/runtime/jni/PrivateInterfaceMethods \
$(TOPDIR)/test/hotspot/jtreg/runtime/jni/ToStringInInterfaceTest \
$(TOPDIR)/test/hotspot/jtreg/runtime/jni/CalleeSavedRegisters \

@ -396,10 +396,11 @@ JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))
}
//%note jni_3
Handle loader;
Handle protection_domain;
// Find calling class
Klass* k = thread->security_get_caller_class(0);
// default to the system loader when no context
Handle loader(THREAD, SystemDictionary::java_system_loader());
if (k != NULL) {
// Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed
// in the correct class context.
@ -424,11 +425,6 @@ JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))
}
}
if (loader.is_null()) {
// No context and use the system class loader
loader = Handle(THREAD, SystemDictionary::java_system_loader());
}
TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL);
result = find_class_from_class_loader(env, sym, true, loader,
protection_domain, true, thread);

@ -0,0 +1,46 @@
/*
* Copyright (c) 2017, 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.
*/
import java.lang.BootNativeLibrary;
/*
* This is called from FindClassFromBoot class.
*/
public class BootLoaderTest {
public static void main(String... args) throws Exception {
testJNIFindClass("java/lang/String", String.class);
testJNIFindClass("java/lang/BootNativeLibrary", BootNativeLibrary.class);
testJNIFindClass("BootLoaderTest", null);
}
/*
* Call JNI FindClass with null loader as the context
*/
static void testJNIFindClass(String name, Class<?> expected) {
Class<?> c = BootNativeLibrary.findClass(name);
if (c != expected) {
throw new RuntimeException("FindClass " + c + " expected: " + expected);
}
}
}

@ -0,0 +1,50 @@
/*
* Copyright (c) 2017, 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 8189193
* @library /test/lib
* @build jdk.test.lib.process.ProcessTools
* @build java.base/java.lang.BootNativeLibrary BootLoaderTest FindClassFromBoot
* @run main/othervm/native -Xcheck:jni FindClassFromBoot
* @summary verify if the native library loaded by the boot loader
* can only find classes visible to the boot loader
*/
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import jdk.test.lib.process.ProcessTools;
public class FindClassFromBoot {
public static void main(String... args) throws Exception {
Path patches = Paths.get(System.getProperty("test.classes"), "patches", "java.base");
String syspaths = System.getProperty("sun.boot.library.path") +
File.pathSeparator + System.getProperty("java.library.path");
ProcessTools.executeTestJvm("-Dsun.boot.library.path=" + syspaths,
"--patch-module", "java.base=" + patches.toString(),
"BootLoaderTest")
.shouldHaveExitValue(0);
}
}

@ -0,0 +1,32 @@
/*
* Copyright (c) 2017, 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.
*/
package java.lang;
public class BootNativeLibrary {
static {
System.loadLibrary("bootLoaderTest");
}
public static native Class<?> findClass(String name);
}

@ -0,0 +1,49 @@
/*
* Copyright (c) 2017, 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include "jni.h"
#include "jni_util.h"
JNIEXPORT jclass JNICALL
Java_java_lang_BootNativeLibrary_findClass
(JNIEnv *env, jclass cls, jstring name) {
jclass ncdfe;
jthrowable t;
const char* classname = (*env)->GetStringUTFChars(env, name, JNI_FALSE);
jclass c = (*env)->FindClass(env, classname);
(*env)->ReleaseStringUTFChars(env, name, classname);
if (c == NULL) {
// clear NCDFE
t = (*env)->ExceptionOccurred(env);
ncdfe = (*env)->FindClass(env, "java/lang/NoClassDefFoundError");
if (t != NULL && (*env)->IsInstanceOf(env, t, ncdfe)) {
(*env)->ExceptionClear(env);
}
}
return c;
}