changeset 7206:e232b716ad69

8015256: Better class accessibility Summary: Improve protection domain check in forName() Reviewed-by: mchung, acorn, jdn
author coleenp
date Tue, 14 Oct 2014 13:10:50 -0700
parents f23dc1b5dd8f
children 7f6c5c14791d
files make/aix/makefiles/mapfile-vers-debug make/aix/makefiles/mapfile-vers-product make/bsd/makefiles/mapfile-vers-darwin-debug make/bsd/makefiles/mapfile-vers-darwin-product make/bsd/makefiles/mapfile-vers-debug make/bsd/makefiles/mapfile-vers-product make/linux/makefiles/mapfile-vers-debug make/linux/makefiles/mapfile-vers-product make/solaris/makefiles/mapfile-vers src/share/vm/prims/jvm.cpp src/share/vm/prims/jvm.h
diffstat 11 files changed, 66 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/make/aix/makefiles/mapfile-vers-debug	Wed May 07 19:38:22 2014 +0400
+++ b/make/aix/makefiles/mapfile-vers-debug	Tue Oct 14 13:10:50 2014 -0700
@@ -84,6 +84,7 @@
                 JVM_EnableCompiler;
                 JVM_Exit;
                 JVM_FillInStackTrace;
+                JVM_FindClassFromCaller;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromClassLoader;
                 JVM_FindClassFromBootLoader;
--- a/make/aix/makefiles/mapfile-vers-product	Wed May 07 19:38:22 2014 +0400
+++ b/make/aix/makefiles/mapfile-vers-product	Tue Oct 14 13:10:50 2014 -0700
@@ -84,6 +84,7 @@
                 JVM_EnableCompiler;
                 JVM_Exit;
                 JVM_FillInStackTrace;
+                JVM_FindClassFromCaller;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromClassLoader;
                 JVM_FindClassFromBootLoader;
--- a/make/bsd/makefiles/mapfile-vers-darwin-debug	Wed May 07 19:38:22 2014 +0400
+++ b/make/bsd/makefiles/mapfile-vers-darwin-debug	Tue Oct 14 13:10:50 2014 -0700
@@ -82,6 +82,7 @@
                 _JVM_EnableCompiler
                 _JVM_Exit
                 _JVM_FillInStackTrace
+                _JVM_FindClassFromCaller
                 _JVM_FindClassFromClass
                 _JVM_FindClassFromClassLoader
                 _JVM_FindClassFromBootLoader
--- a/make/bsd/makefiles/mapfile-vers-darwin-product	Wed May 07 19:38:22 2014 +0400
+++ b/make/bsd/makefiles/mapfile-vers-darwin-product	Tue Oct 14 13:10:50 2014 -0700
@@ -82,6 +82,7 @@
                 _JVM_EnableCompiler
                 _JVM_Exit
                 _JVM_FillInStackTrace
+                _JVM_FindClassFromCaller
                 _JVM_FindClassFromClass
                 _JVM_FindClassFromClassLoader
                 _JVM_FindClassFromBootLoader
--- a/make/bsd/makefiles/mapfile-vers-debug	Wed May 07 19:38:22 2014 +0400
+++ b/make/bsd/makefiles/mapfile-vers-debug	Tue Oct 14 13:10:50 2014 -0700
@@ -84,6 +84,7 @@
                 JVM_EnableCompiler;
                 JVM_Exit;
                 JVM_FillInStackTrace;
+                JVM_FindClassFromCaller;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromClassLoader;
                 JVM_FindClassFromBootLoader;
--- a/make/bsd/makefiles/mapfile-vers-product	Wed May 07 19:38:22 2014 +0400
+++ b/make/bsd/makefiles/mapfile-vers-product	Tue Oct 14 13:10:50 2014 -0700
@@ -84,6 +84,7 @@
                 JVM_EnableCompiler;
                 JVM_Exit;
                 JVM_FillInStackTrace;
+                JVM_FindClassFromCaller;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromClassLoader;
                 JVM_FindClassFromBootLoader;
--- a/make/linux/makefiles/mapfile-vers-debug	Wed May 07 19:38:22 2014 +0400
+++ b/make/linux/makefiles/mapfile-vers-debug	Tue Oct 14 13:10:50 2014 -0700
@@ -84,6 +84,7 @@
                 JVM_EnableCompiler;
                 JVM_Exit;
                 JVM_FillInStackTrace;
+                JVM_FindClassFromCaller;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromClassLoader;
                 JVM_FindClassFromBootLoader;
--- a/make/linux/makefiles/mapfile-vers-product	Wed May 07 19:38:22 2014 +0400
+++ b/make/linux/makefiles/mapfile-vers-product	Tue Oct 14 13:10:50 2014 -0700
@@ -84,6 +84,7 @@
                 JVM_EnableCompiler;
                 JVM_Exit;
                 JVM_FillInStackTrace;
+                JVM_FindClassFromCaller;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromClassLoader;
                 JVM_FindClassFromBootLoader;
--- a/make/solaris/makefiles/mapfile-vers	Wed May 07 19:38:22 2014 +0400
+++ b/make/solaris/makefiles/mapfile-vers	Tue Oct 14 13:10:50 2014 -0700
@@ -84,6 +84,7 @@
                 JVM_EnableCompiler;
                 JVM_Exit;
                 JVM_FillInStackTrace;
+                JVM_FindClassFromCaller;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromClassLoader;
                 JVM_FindClassFromBootLoader;
--- a/src/share/vm/prims/jvm.cpp	Wed May 07 19:38:22 2014 +0400
+++ b/src/share/vm/prims/jvm.cpp	Tue Oct 14 13:10:50 2014 -0700
@@ -805,6 +805,7 @@
   return (jclass) JNIHandles::make_local(env, k->java_mirror());
 JVM_END
 
+// Not used; JVM_FindClassFromCaller replaces this.
 JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
                                                jboolean init, jobject loader,
                                                jboolean throwError))
@@ -831,6 +832,42 @@
   return result;
 JVM_END
 
+// Find a class with this name in this loader, using the caller's protection domain.
+JVM_ENTRY(jclass, JVM_FindClassFromCaller(JNIEnv* env, const char* name,
+                                          jboolean init, jobject loader,
+                                          jclass caller))
+  JVMWrapper2("JVM_FindClassFromCaller %s throws ClassNotFoundException", name);
+  // Java libraries should ensure that name is never null...
+  if (name == NULL || (int)strlen(name) > Symbol::max_length()) {
+    // It's impossible to create this class;  the name cannot fit
+    // into the constant pool.
+    THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);
+  }
+
+  TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL);
+
+  oop loader_oop = JNIHandles::resolve(loader);
+  oop from_class = JNIHandles::resolve(caller);
+  oop protection_domain = NULL;
+  // If loader is null, shouldn't call ClassLoader.checkPackageAccess; otherwise get
+  // NPE. Put it in another way, the bootstrap class loader has all permission and
+  // thus no checkPackageAccess equivalence in the VM class loader.
+  // The caller is also passed as NULL by the java code if there is no security
+  // manager to avoid the performance cost of getting the calling class.
+  if (from_class != NULL && loader_oop != NULL) {
+    protection_domain = java_lang_Class::as_Klass(from_class)->protection_domain();
+  }
+
+  Handle h_loader(THREAD, loader_oop);
+  Handle h_prot(THREAD, protection_domain);
+  jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
+                                               h_prot, false, THREAD);
+
+  if (TraceClassResolution && result != NULL) {
+    trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
+  }
+  return result;
+JVM_END
 
 JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,
                                          jboolean init, jclass from))
@@ -3921,10 +3958,15 @@
 
 // Shared JNI/JVM entry points //////////////////////////////////////////////////////////////
 
-jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS) {
+jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init,
+                                    Handle loader, Handle protection_domain,
+                                    jboolean throwError, TRAPS) {
   // Security Note:
   //   The Java level wrapper will perform the necessary security check allowing
-  //   us to pass the NULL as the initiating class loader.
+  //   us to pass the NULL as the initiating class loader.  The VM is responsible for
+  //   the checkPackageAccess relative to the initiating class loader via the
+  //   protection_domain. The protection_domain is passed as NULL by the java code
+  //   if there is no security manager in 3-arg Class.forName().
   Klass* klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL);
 
   KlassHandle klass_handle(THREAD, klass);
--- a/src/share/vm/prims/jvm.h	Wed May 07 19:38:22 2014 +0400
+++ b/src/share/vm/prims/jvm.h	Tue Oct 14 13:10:50 2014 -0700
@@ -420,6 +420,19 @@
 JVM_FindClassFromBootLoader(JNIEnv *env, const char *name);
 
 /*
+ * Find a class from a given class loader.  Throws ClassNotFoundException.
+ *  name:   name of class
+ *  init:   whether initialization is done
+ *  loader: class loader to look up the class. This may not be the same as the caller's
+ *          class loader.
+ *  caller: initiating class. The initiating class may be null when a security
+ *          manager is not installed.
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init,
+                        jobject loader, jclass caller);
+
+/*
  * Find a class from a given class.
  */
 JNIEXPORT jclass JNICALL