diff -r 943cf01a6b82 -r bf6fcd467a7b hotspot/src/share/vm/oops/instanceKlass.cpp --- 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,