mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-06 14:10:36 +00:00
8263974: Move SystemDictionary::verify_protection_domain
Reviewed-by: hseigel, lfoltan, dholmes
This commit is contained in:
parent
9dad857ede
commit
de2ff25687
@ -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"
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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();
|
||||
};
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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; }
|
||||
|
||||
@ -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"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user