8189193: FindClass should only see classes from the boot loader called from its associated native library
Reviewed-by: coleenp, dholmes
--- a/make/test/JtregNativeHotspot.gmk Thu Oct 19 11:31:52 2017 -0700
+++ b/make/test/JtregNativeHotspot.gmk Thu Oct 19 17:27:34 2017 -0700
@@ -50,6 +50,7 @@
$(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 \
--- a/src/hotspot/share/prims/jni.cpp Thu Oct 19 11:31:52 2017 -0700
+++ b/src/hotspot/share/prims/jni.cpp Thu Oct 19 17:27:34 2017 -0700
@@ -396,10 +396,11 @@
}
//%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 @@
}
}
- 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);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/jni/FindClass/BootLoaderTest.java Thu Oct 19 17:27:34 2017 -0700
@@ -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);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java Thu Oct 19 17:27:34 2017 -0700
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/jni/FindClass/java.base/java/lang/BootNativeLibrary.java Thu Oct 19 17:27:34 2017 -0700
@@ -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);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/jni/FindClass/libbootLoaderTest.c Thu Oct 19 17:27:34 2017 -0700
@@ -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;
+}