hotspot/src/share/vm/oops/instanceKlass.cpp
changeset 40016 bf6fcd467a7b
parent 39714 976b97b59d87
child 40102 23ff468d69b4
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Tue Jul 26 10:29:27 2016 -0400
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Jul 27 08:31:48 2016 -0400
@@ -67,6 +67,7 @@
 #include "services/threadService.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/macros.hpp"
+#include "utilities/stringUtils.hpp"
 #include "logging/log.hpp"
 #ifdef COMPILER1
 #include "c1/c1_Compiler.hpp"
@@ -2225,9 +2226,14 @@
 }
 
 void InstanceKlass::set_package(ClassLoaderData* loader_data, TRAPS) {
+
+  // ensure java/ packages only loaded by boot or platform builtin loaders
+  check_prohibited_package(name(), loader_data->class_loader(), CHECK);
+
   TempNewSymbol pkg_name = package_from_name(name(), CHECK);
 
   if (pkg_name != NULL && loader_data != NULL) {
+
     // Find in class loader's package entry table.
     _package_entry = loader_data->packages()->lookup_only(pkg_name);
 
@@ -2376,6 +2382,31 @@
 }
 */
 
+// Only boot and platform class loaders can define classes in "java/" packages.
+void InstanceKlass::check_prohibited_package(Symbol* class_name,
+                                                Handle class_loader,
+                                                TRAPS) {
+  const char* javapkg = "java/";
+  ResourceMark rm(THREAD);
+  if (!class_loader.is_null() &&
+      !SystemDictionary::is_platform_class_loader(class_loader) &&
+      class_name != NULL &&
+      strncmp(class_name->as_C_string(), javapkg, strlen(javapkg)) == 0) {
+    TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK);
+    assert(pkg_name != NULL, "Error in parsing package name starting with 'java/'");
+    char* name = pkg_name->as_C_string();
+    const char* class_loader_name = InstanceKlass::cast(class_loader()->klass())->name()->as_C_string();
+    StringUtils::replace_no_expand(name, "/", ".");
+    const char* msg_text1 = "Class loader (instance of): ";
+    const char* msg_text2 = " tried to load prohibited package name: ";
+    size_t len = strlen(msg_text1) + strlen(class_loader_name) + strlen(msg_text2) + strlen(name) + 1;
+    char* message = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, len);
+    jio_snprintf(message, len, "%s%s%s%s", msg_text1, class_loader_name, msg_text2, name);
+    THROW_MSG(vmSymbols::java_lang_SecurityException(), message);
+  }
+  return;
+}
+
 // tell if two classes have the same enclosing class (at package level)
 bool InstanceKlass::is_same_package_member_impl(const InstanceKlass* class1,
                                                 const Klass* class2,