8263974: Move SystemDictionary::verify_protection_domain

Reviewed-by: hseigel, lfoltan, dholmes
This commit is contained in:
Coleen Phillimore 2021-03-23 11:35:55 +00:00
parent 9dad857ede
commit de2ff25687
8 changed files with 90 additions and 95 deletions

View File

@ -30,7 +30,6 @@
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/classLoadInfo.hpp"
#include "classfile/defaultMethods.hpp"
#include "classfile/dictionary.hpp"
#include "classfile/fieldLayoutBuilder.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/moduleEntry.hpp"

View File

@ -25,7 +25,6 @@
#include "precompiled.hpp"
#include "classfile/classFileStream.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/dictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "memory/resourceArea.hpp"

View File

@ -25,18 +25,23 @@
#include "precompiled.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/dictionary.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/protectionDomainCache.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "memory/iterator.hpp"
#include "memory/metaspaceClosure.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/klass.inline.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oopHandle.inline.hpp"
#include "runtime/arguments.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepointVerifiers.hpp"
#include "utilities/hashtable.inline.hpp"
@ -285,7 +290,7 @@ DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash,
for (DictionaryEntry* entry = bucket(index);
entry != NULL;
entry = entry->next()) {
if (entry->hash() == hash && entry->equals(class_name)) {
if (entry->hash() == hash && entry->instance_klass()->name() == class_name) {
return entry;
}
}
@ -320,8 +325,7 @@ InstanceKlass* Dictionary::find_class(unsigned int hash,
void Dictionary::add_protection_domain(int index, unsigned int hash,
InstanceKlass* klass,
Handle protection_domain,
TRAPS) {
Handle protection_domain) {
assert(java_lang_System::allow_security_manager(), "only needed if security manager allowed");
Symbol* klass_name = klass->name();
DictionaryEntry* entry = get_entry(index, hash, klass_name);
@ -341,7 +345,7 @@ void Dictionary::add_protection_domain(int index, unsigned int hash,
}
bool Dictionary::is_valid_protection_domain(unsigned int hash,
inline bool Dictionary::is_valid_protection_domain(unsigned int hash,
Symbol* name,
Handle protection_domain) {
int index = hash_to_index(hash);
@ -349,6 +353,74 @@ bool Dictionary::is_valid_protection_domain(unsigned int hash,
return entry->is_valid_protection_domain(protection_domain);
}
void Dictionary::validate_protection_domain(unsigned int name_hash,
InstanceKlass* klass,
Handle class_loader,
Handle protection_domain,
TRAPS) {
assert(class_loader() != NULL, "Should not call this");
assert(protection_domain() != NULL, "Should not call this");
if (!java_lang_System::allow_security_manager() ||
is_valid_protection_domain(name_hash, klass->name(), protection_domain)) {
return;
}
// We only have to call checkPackageAccess if there's a security manager installed.
if (java_lang_System::has_security_manager()) {
// This handle and the class_loader handle passed in keeps this class from
// being unloaded through several GC points.
// The class_loader handle passed in is the initiating loader.
Handle mirror(THREAD, klass->java_mirror());
// Now we have to call back to java to check if the initating class has access
InstanceKlass* system_loader = vmClasses::ClassLoader_klass();
JavaValue result(T_VOID);
JavaCalls::call_special(&result,
class_loader,
system_loader,
vmSymbols::checkPackageAccess_name(),
vmSymbols::class_protectiondomain_signature(),
mirror,
protection_domain,
THREAD);
LogTarget(Debug, protectiondomain) lt;
if (lt.is_enabled()) {
ResourceMark rm(THREAD);
// Print out trace information
LogStream ls(lt);
ls.print_cr("Checking package access");
ls.print("class loader: ");
class_loader()->print_value_on(&ls);
ls.print(" protection domain: ");
protection_domain()->print_value_on(&ls);
ls.print(" loading: "); klass->print_value_on(&ls);
if (HAS_PENDING_EXCEPTION) {
ls.print_cr(" DENIED !!!!!!!!!!!!!!!!!!!!!");
} else {
ls.print_cr(" granted");
}
}
if (HAS_PENDING_EXCEPTION) return;
}
// If no exception has been thrown, we have validated the protection domain
// Insert the protection domain of the initiating class into the set.
// We still have to add the protection_domain to the dictionary in case a new
// security manager is installed later. Calls to load the same class with class loader
// and protection domain are expected to succeed.
{
MutexLocker mu(THREAD, SystemDictionary_lock);
int d_index = hash_to_index(name_hash);
add_protection_domain(d_index, name_hash, klass,
protection_domain);
}
}
// During class loading we may have cached a protection domain that has
// since been unreferenced, so this entry should be cleared.
void Dictionary::clean_cached_protection_domains() {

View File

@ -71,12 +71,11 @@ public:
// Protection domains
InstanceKlass* find(unsigned int hash, Symbol* name, Handle protection_domain);
bool is_valid_protection_domain(unsigned int hash,
Symbol* name,
Handle protection_domain);
void add_protection_domain(int index, unsigned int hash,
InstanceKlass* klass,
Handle protection_domain, TRAPS);
void validate_protection_domain(unsigned int name_hash,
InstanceKlass* klass,
Handle class_loader,
Handle protection_domain,
TRAPS);
void print_on(outputStream* st) const;
void verify();
@ -102,6 +101,13 @@ public:
}
void free_entry(DictionaryEntry* entry);
bool is_valid_protection_domain(unsigned int hash,
Symbol* name,
Handle protection_domain);
void add_protection_domain(int index, unsigned int hash,
InstanceKlass* klass,
Handle protection_domain);
};
// An entry in the class loader data dictionaries, this describes a class as
@ -156,11 +162,6 @@ class DictionaryEntry : public HashtableEntry<InstanceKlass*, mtClass> {
inline bool is_valid_protection_domain(Handle protection_domain);
void verify_protection_domain_set();
bool equals(const Symbol* class_name) const {
InstanceKlass* klass = (InstanceKlass*)literal();
return (klass->name() == class_name);
}
void print_count(outputStream *st);
void verify();
};

View File

@ -25,7 +25,6 @@
#include "precompiled.hpp"
#include "classfile/classLoadInfo.hpp"
#include "classfile/classFileStream.hpp"
#include "classfile/dictionary.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/klassFactory.hpp"
#include "classfile/lambdaFormInvokers.hpp"

View File

@ -455,73 +455,6 @@ InstanceKlass* SystemDictionary::resolve_super_or_fail(Symbol* class_name,
return superk;
}
void SystemDictionary::validate_protection_domain(InstanceKlass* klass,
Handle class_loader,
Handle protection_domain,
TRAPS) {
// Now we have to call back to java to check if the initating class has access
assert(class_loader() != NULL, "Should not call this");
assert(protection_domain() != NULL, "Should not call this");
// We only have to call checkPackageAccess if there's a security manager installed.
if (java_lang_System::has_security_manager()) {
// This handle and the class_loader handle passed in keeps this class from
// being unloaded through several GC points.
// The class_loader handle passed in is the initiating loader.
Handle mirror(THREAD, klass->java_mirror());
InstanceKlass* system_loader = vmClasses::ClassLoader_klass();
JavaValue result(T_VOID);
JavaCalls::call_special(&result,
class_loader,
system_loader,
vmSymbols::checkPackageAccess_name(),
vmSymbols::class_protectiondomain_signature(),
mirror,
protection_domain,
THREAD);
LogTarget(Debug, protectiondomain) lt;
if (lt.is_enabled()) {
ResourceMark rm(THREAD);
// Print out trace information
LogStream ls(lt);
ls.print_cr("Checking package access");
ls.print("class loader: ");
class_loader()->print_value_on(&ls);
ls.print(" protection domain: ");
protection_domain()->print_value_on(&ls);
ls.print(" loading: "); klass->print_value_on(&ls);
if (HAS_PENDING_EXCEPTION) {
ls.print_cr(" DENIED !!!!!!!!!!!!!!!!!!!!!");
} else {
ls.print_cr(" granted");
}
}
if (HAS_PENDING_EXCEPTION) return;
}
// If no exception has been thrown, we have validated the protection domain
// Insert the protection domain of the initiating class into the set.
// We still have to add the protection_domain to the dictionary in case a new
// security manager is installed later. Calls to load the same class with class loader
// and protection domain are expected to succeed.
{
ClassLoaderData* loader_data = class_loader_data(class_loader);
Dictionary* dictionary = loader_data->dictionary();
Symbol* kn = klass->name();
unsigned int name_hash = dictionary->compute_hash(kn);
MutexLocker mu(THREAD, SystemDictionary_lock);
int d_index = dictionary->hash_to_index(name_hash);
dictionary->add_protection_domain(d_index, name_hash, klass,
protection_domain, THREAD);
}
}
// We only get here if this thread finds that another thread
// has already claimed the placeholder token for the current operation,
// but that other thread either never owned or gave up the
@ -876,12 +809,9 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
DEBUG_ONLY(verify_dictionary_entry(name, loaded_class));
// Check if the protection domain is present it has the right access
if (protection_domain() != NULL &&
java_lang_System::allow_security_manager() &&
!dictionary->is_valid_protection_domain(name_hash, name,
protection_domain)) {
if (protection_domain() != NULL) {
// Verify protection domain. If it fails an exception is thrown
validate_protection_domain(loaded_class, class_loader, protection_domain, CHECK_NULL);
dictionary->validate_protection_domain(name_hash, loaded_class, class_loader, protection_domain, CHECK_NULL);
}
return loaded_class;

View File

@ -315,10 +315,6 @@ private:
static OopHandle _java_system_loader;
static OopHandle _java_platform_loader;
static void validate_protection_domain(InstanceKlass* klass,
Handle class_loader,
Handle protection_domain, TRAPS);
friend class VM_PopulateDumpSharedSpace;
static LoaderConstraintTable* constraints() { return _loader_constraints; }
static ResolutionErrorTable* resolution_errors() { return _resolution_errors; }

View File

@ -26,7 +26,6 @@
#include "jvm_io.h"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/classLoaderDataGraph.inline.hpp"
#include "classfile/dictionary.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/moduleEntry.hpp"
#include "classfile/systemDictionary.hpp"