--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Jul 05 18:53:07 2017 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed May 01 14:11:01 2013 +0100
@@ -2783,6 +2783,7 @@
int java_security_AccessControlContext::_context_offset = 0;
int java_security_AccessControlContext::_privilegedContext_offset = 0;
int java_security_AccessControlContext::_isPrivileged_offset = 0;
+int java_security_AccessControlContext::_isAuthorized_offset = -1;
void java_security_AccessControlContext::compute_offsets() {
assert(_isPrivileged_offset == 0, "offsets should be initialized only once");
@@ -2803,9 +2804,20 @@
fatal("Invalid layout of java.security.AccessControlContext");
}
_isPrivileged_offset = fd.offset();
+
+ // The offset may not be present for bootstrapping with older JDK.
+ if (ik->find_local_field(vmSymbols::isAuthorized_name(), vmSymbols::bool_signature(), &fd)) {
+ _isAuthorized_offset = fd.offset();
+ }
}
+bool java_security_AccessControlContext::is_authorized(Handle context) {
+ assert(context.not_null() && context->klass() == SystemDictionary::AccessControlContext_klass(), "Invalid type");
+ assert(_isAuthorized_offset != -1, "should be set");
+ return context->bool_field(_isAuthorized_offset) != 0;
+}
+
oop java_security_AccessControlContext::create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS) {
assert(_isPrivileged_offset != 0, "offsets should have been initialized");
// Ensure klass is initialized
@@ -2816,6 +2828,10 @@
result->obj_field_put(_context_offset, context());
result->obj_field_put(_privilegedContext_offset, privileged_context());
result->bool_field_put(_isPrivileged_offset, isPrivileged);
+ // whitelist AccessControlContexts created by the JVM if present
+ if (_isAuthorized_offset != -1) {
+ result->bool_field_put(_isAuthorized_offset, true);
+ }
return result;
}
@@ -2925,6 +2941,15 @@
}
+bool java_lang_System::has_security_manager() {
+ InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::System_klass());
+ address addr = ik->static_field_addr(static_security_offset);
+ if (UseCompressedOops) {
+ return oopDesc::load_decode_heap_oop((narrowOop *)addr) != NULL;
+ } else {
+ return oopDesc::load_decode_heap_oop((oop*)addr) != NULL;
+ }
+}
int java_lang_Class::_klass_offset;
int java_lang_Class::_array_klass_offset;
@@ -2985,6 +3010,7 @@
int java_lang_System::static_in_offset;
int java_lang_System::static_out_offset;
int java_lang_System::static_err_offset;
+int java_lang_System::static_security_offset;
int java_lang_StackTraceElement::declaringClass_offset;
int java_lang_StackTraceElement::methodName_offset;
int java_lang_StackTraceElement::fileName_offset;
@@ -3110,6 +3136,7 @@
java_lang_System::static_in_offset = java_lang_System::hc_static_in_offset * x;
java_lang_System::static_out_offset = java_lang_System::hc_static_out_offset * x;
java_lang_System::static_err_offset = java_lang_System::hc_static_err_offset * x;
+ java_lang_System::static_security_offset = java_lang_System::hc_static_security_offset * x;
// java_lang_StackTraceElement
java_lang_StackTraceElement::declaringClass_offset = java_lang_StackTraceElement::hc_declaringClass_offset * x + header;
@@ -3309,6 +3336,7 @@
CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, in, "Ljava/io/InputStream;");
CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, out, "Ljava/io/PrintStream;");
CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, err, "Ljava/io/PrintStream;");
+ CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, security, "Ljava/lang/SecurityManager;");
// java.lang.StackTraceElement
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Jul 05 18:53:07 2017 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Wed May 01 14:11:01 2013 +0100
@@ -1152,11 +1152,14 @@
static int _context_offset;
static int _privilegedContext_offset;
static int _isPrivileged_offset;
+ static int _isAuthorized_offset;
static void compute_offsets();
public:
static oop create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS);
+ static bool is_authorized(Handle context);
+
// Debugging/initialization
friend class JavaClasses;
};
@@ -1216,18 +1219,22 @@
enum {
hc_static_in_offset = 0,
hc_static_out_offset = 1,
- hc_static_err_offset = 2
+ hc_static_err_offset = 2,
+ hc_static_security_offset = 3
};
static int static_in_offset;
static int static_out_offset;
static int static_err_offset;
+ static int static_security_offset;
public:
static int in_offset_in_bytes();
static int out_offset_in_bytes();
static int err_offset_in_bytes();
+ static bool has_security_manager();
+
// Debugging
friend class JavaClasses;
};
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jul 05 18:53:07 2017 +0200
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed May 01 14:11:01 2013 +0100
@@ -94,6 +94,7 @@
template(java_lang_SecurityManager, "java/lang/SecurityManager") \
template(java_security_AccessControlContext, "java/security/AccessControlContext") \
template(java_security_ProtectionDomain, "java/security/ProtectionDomain") \
+ template(impliesCreateAccessControlContext_name, "impliesCreateAccessControlContext") \
template(java_io_OutputStream, "java/io/OutputStream") \
template(java_io_Reader, "java/io/Reader") \
template(java_io_BufferedReader, "java/io/BufferedReader") \
@@ -346,6 +347,7 @@
template(contextClassLoader_name, "contextClassLoader") \
template(inheritedAccessControlContext_name, "inheritedAccessControlContext") \
template(isPrivileged_name, "isPrivileged") \
+ template(isAuthorized_name, "isAuthorized") \
template(getClassContext_name, "getClassContext") \
template(wait_name, "wait") \
template(checkPackageAccess_name, "checkPackageAccess") \
--- a/hotspot/src/share/vm/memory/allocation.cpp Wed Jul 05 18:53:07 2017 +0200
+++ b/hotspot/src/share/vm/memory/allocation.cpp Wed May 01 14:11:01 2013 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -248,7 +248,7 @@
ChunkPool(size_t size) : _size(size) { _first = NULL; _num_chunks = _num_used = 0; }
// Allocate a new chunk from the pool (might expand the pool)
- _NOINLINE_ void* allocate(size_t bytes) {
+ _NOINLINE_ void* allocate(size_t bytes, AllocFailType alloc_failmode) {
assert(bytes == _size, "bad size");
void* p = NULL;
// No VM lock can be taken inside ThreadCritical lock, so os::malloc
@@ -258,9 +258,9 @@
p = get_first();
}
if (p == NULL) p = os::malloc(bytes, mtChunk, CURRENT_PC);
- if (p == NULL)
+ if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) {
vm_exit_out_of_memory(bytes, "ChunkPool::allocate");
-
+ }
return p;
}
@@ -357,7 +357,7 @@
//--------------------------------------------------------------------------------------
// Chunk implementation
-void* Chunk::operator new(size_t requested_size, size_t length) {
+void* Chunk::operator new (size_t requested_size, AllocFailType alloc_failmode, size_t length) {
// requested_size is equal to sizeof(Chunk) but in order for the arena
// allocations to come out aligned as expected the size must be aligned
// to expected arean alignment.
@@ -365,13 +365,14 @@
assert(ARENA_ALIGN(requested_size) == aligned_overhead_size(), "Bad alignment");
size_t bytes = ARENA_ALIGN(requested_size) + length;
switch (length) {
- case Chunk::size: return ChunkPool::large_pool()->allocate(bytes);
- case Chunk::medium_size: return ChunkPool::medium_pool()->allocate(bytes);
- case Chunk::init_size: return ChunkPool::small_pool()->allocate(bytes);
+ case Chunk::size: return ChunkPool::large_pool()->allocate(bytes, alloc_failmode);
+ case Chunk::medium_size: return ChunkPool::medium_pool()->allocate(bytes, alloc_failmode);
+ case Chunk::init_size: return ChunkPool::small_pool()->allocate(bytes, alloc_failmode);
default: {
- void *p = os::malloc(bytes, mtChunk, CALLER_PC);
- if (p == NULL)
+ void* p = os::malloc(bytes, mtChunk, CALLER_PC);
+ if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) {
vm_exit_out_of_memory(bytes, "Chunk::new");
+ }
return p;
}
}
@@ -425,7 +426,7 @@
Arena::Arena(size_t init_size) {
size_t round_size = (sizeof (char *)) - 1;
init_size = (init_size+round_size) & ~round_size;
- _first = _chunk = new (init_size) Chunk(init_size);
+ _first = _chunk = new (AllocFailStrategy::EXIT_OOM, init_size) Chunk(init_size);
_hwm = _chunk->bottom(); // Save the cached hwm, max
_max = _chunk->top();
set_size_in_bytes(init_size);
@@ -433,7 +434,7 @@
}
Arena::Arena() {
- _first = _chunk = new (Chunk::init_size) Chunk(Chunk::init_size);
+ _first = _chunk = new (AllocFailStrategy::EXIT_OOM, Chunk::init_size) Chunk(Chunk::init_size);
_hwm = _chunk->bottom(); // Save the cached hwm, max
_max = _chunk->top();
set_size_in_bytes(Chunk::init_size);
@@ -540,12 +541,9 @@
size_t len = MAX2(x, (size_t) Chunk::size);
Chunk *k = _chunk; // Get filled-up chunk address
- _chunk = new (len) Chunk(len);
+ _chunk = new (alloc_failmode, len) Chunk(len);
if (_chunk == NULL) {
- if (alloc_failmode == AllocFailStrategy::EXIT_OOM) {
- signal_out_of_memory(len * Chunk::aligned_overhead_size(), "Arena::grow");
- }
return NULL;
}
if (k) k->set_next(_chunk); // Append new chunk to end of linked list
--- a/hotspot/src/share/vm/memory/allocation.hpp Wed Jul 05 18:53:07 2017 +0200
+++ b/hotspot/src/share/vm/memory/allocation.hpp Wed May 01 14:11:01 2013 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -274,7 +274,7 @@
Chunk* _next; // Next Chunk in list
const size_t _len; // Size of this Chunk
public:
- void* operator new(size_t size, size_t length);
+ void* operator new(size_t size, AllocFailType alloc_failmode, size_t length);
void operator delete(void* p);
Chunk(size_t length);
@@ -337,10 +337,15 @@
void signal_out_of_memory(size_t request, const char* whence) const;
- void check_for_overflow(size_t request, const char* whence) const {
+ bool check_for_overflow(size_t request, const char* whence,
+ AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) const {
if (UINTPTR_MAX - request < (uintptr_t)_hwm) {
+ if (alloc_failmode == AllocFailStrategy::RETURN_NULL) {
+ return false;
+ }
signal_out_of_memory(request, whence);
}
+ return true;
}
public:
@@ -364,7 +369,8 @@
assert(is_power_of_2(ARENA_AMALLOC_ALIGNMENT) , "should be a power of 2");
x = ARENA_ALIGN(x);
debug_only(if (UseMallocOnly) return malloc(x);)
- check_for_overflow(x, "Arena::Amalloc");
+ if (!check_for_overflow(x, "Arena::Amalloc", alloc_failmode))
+ return NULL;
NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x, alloc_failmode);
@@ -378,7 +384,8 @@
void *Amalloc_4(size_t x, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
debug_only(if (UseMallocOnly) return malloc(x);)
- check_for_overflow(x, "Arena::Amalloc_4");
+ if (!check_for_overflow(x, "Arena::Amalloc_4", alloc_failmode))
+ return NULL;
NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x, alloc_failmode);
@@ -399,7 +406,8 @@
size_t delta = (((size_t)_hwm + DALIGN_M1) & ~DALIGN_M1) - (size_t)_hwm;
x += delta;
#endif
- check_for_overflow(x, "Arena::Amalloc_D");
+ if (!check_for_overflow(x, "Arena::Amalloc_D", alloc_failmode))
+ return NULL;
NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x, alloc_failmode); // grow() returns a result aligned >= 8 bytes.
@@ -539,6 +547,9 @@
#define NEW_RESOURCE_ARRAY(type, size)\
(type*) resource_allocate_bytes((size) * sizeof(type))
+#define NEW_RESOURCE_ARRAY_RETURN_NULL(type, size)\
+ (type*) resource_allocate_bytes((size) * sizeof(type), AllocFailStrategy::RETURN_NULL)
+
#define NEW_RESOURCE_ARRAY_IN_THREAD(thread, type, size)\
(type*) resource_allocate_bytes(thread, (size) * sizeof(type))
--- a/hotspot/src/share/vm/memory/universe.cpp Wed Jul 05 18:53:07 2017 +0200
+++ b/hotspot/src/share/vm/memory/universe.cpp Wed May 01 14:11:01 2013 +0100
@@ -108,6 +108,7 @@
oop Universe::_the_min_jint_string = NULL;
LatestMethodOopCache* Universe::_finalizer_register_cache = NULL;
LatestMethodOopCache* Universe::_loader_addClass_cache = NULL;
+LatestMethodOopCache* Universe::_pd_implies_cache = NULL;
ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL;
oop Universe::_out_of_memory_error_java_heap = NULL;
oop Universe::_out_of_memory_error_perm_gen = NULL;
@@ -224,6 +225,7 @@
_finalizer_register_cache->serialize(f);
_loader_addClass_cache->serialize(f);
_reflect_invoke_cache->serialize(f);
+ _pd_implies_cache->serialize(f);
}
void Universe::check_alignment(uintx size, uintx alignment, const char* name) {
@@ -648,6 +650,7 @@
// Metaspace::initialize_shared_spaces() tries to populate them.
Universe::_finalizer_register_cache = new LatestMethodOopCache();
Universe::_loader_addClass_cache = new LatestMethodOopCache();
+ Universe::_pd_implies_cache = new LatestMethodOopCache();
Universe::_reflect_invoke_cache = new ActiveMethodOopsCache();
if (UseSharedSpaces) {
@@ -1082,6 +1085,23 @@
Universe::_loader_addClass_cache->init(
SystemDictionary::ClassLoader_klass(), m, CHECK_false);
+ // Setup method for checking protection domain
+ InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass())->link_class(CHECK_false);
+ m = InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass())->
+ find_method(vmSymbols::impliesCreateAccessControlContext_name(),
+ vmSymbols::void_boolean_signature());
+ // Allow NULL which should only happen with bootstrapping.
+ if (m != NULL) {
+ if (m->is_static()) {
+ // NoSuchMethodException doesn't actually work because it tries to run the
+ // <init> function before java_lang_Class is linked. Print error and exit.
+ tty->print_cr("ProtectionDomain.impliesCreateAccessControlContext() has the wrong linkage");
+ return false; // initialization failed
+ }
+ Universe::_pd_implies_cache->init(
+ SystemDictionary::ProtectionDomain_klass(), m, CHECK_false);;
+ }
+
// The folowing is initializing converter functions for serialization in
// JVM.cpp. If we clean up the StrictMath code above we may want to find
// a better solution for this as well.
@@ -1497,6 +1517,7 @@
Method* LatestMethodOopCache::get_Method() {
+ if (klass() == NULL) return NULL;
InstanceKlass* ik = InstanceKlass::cast(klass());
Method* m = ik->method_with_idnum(method_idnum());
assert(m != NULL, "sanity check");
--- a/hotspot/src/share/vm/memory/universe.hpp Wed Jul 05 18:53:07 2017 +0200
+++ b/hotspot/src/share/vm/memory/universe.hpp Wed May 01 14:11:01 2013 +0100
@@ -176,6 +176,7 @@
static oop _the_min_jint_string; // A cache of "-2147483648" as a Java string
static LatestMethodOopCache* _finalizer_register_cache; // static method for registering finalizable objects
static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector
+ static LatestMethodOopCache* _pd_implies_cache; // method for checking protection domain attributes
static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks
static oop _out_of_memory_error_java_heap; // preallocated error object (no backtrace)
static oop _out_of_memory_error_perm_gen; // preallocated error object (no backtrace)
@@ -346,7 +347,10 @@
static oop the_min_jint_string() { return _the_min_jint_string; }
static Method* finalizer_register_method() { return _finalizer_register_cache->get_Method(); }
static Method* loader_addClass_method() { return _loader_addClass_cache->get_Method(); }
+
+ static Method* protection_domain_implies_method() { return _pd_implies_cache->get_Method(); }
static ActiveMethodOopsCache* reflect_invoke_cache() { return _reflect_invoke_cache; }
+
static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; }
static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; }
static oop virtual_machine_error_instance() { return _virtual_machine_error_instance; }
--- a/hotspot/src/share/vm/oops/generateOopMap.cpp Wed Jul 05 18:53:07 2017 +0200
+++ b/hotspot/src/share/vm/oops/generateOopMap.cpp Wed May 01 14:11:01 2013 +0100
@@ -642,11 +642,21 @@
// CellType handling methods
//
+// Allocate memory and throw LinkageError if failure.
+#define ALLOC_RESOURCE_ARRAY(var, type, count) \
+ var = NEW_RESOURCE_ARRAY_RETURN_NULL(type, count); \
+ if (var == NULL) { \
+ report_error("Cannot reserve enough memory to analyze this method"); \
+ return; \
+ }
+
+
void GenerateOopMap::init_state() {
_state_len = _max_locals + _max_stack + _max_monitors;
- _state = NEW_RESOURCE_ARRAY(CellTypeState, _state_len);
+ ALLOC_RESOURCE_ARRAY(_state, CellTypeState, _state_len);
memset(_state, 0, _state_len * sizeof(CellTypeState));
- _state_vec_buf = NEW_RESOURCE_ARRAY(char, MAX3(_max_locals, _max_stack, _max_monitors) + 1/*for null terminator char */);
+ int count = MAX3(_max_locals, _max_stack, _max_monitors) + 1/*for null terminator char */;
+ ALLOC_RESOURCE_ARRAY(_state_vec_buf, char, count);
}
void GenerateOopMap::make_context_uninitialized() {
@@ -905,7 +915,7 @@
// But cumbersome since we don't know the stack heights yet. (Nor the
// monitor stack heights...)
- _basic_blocks = NEW_RESOURCE_ARRAY(BasicBlock, _bb_count);
+ ALLOC_RESOURCE_ARRAY(_basic_blocks, BasicBlock, _bb_count);
// Make a pass through the bytecodes. Count the number of monitorenters.
// This can be used an upper bound on the monitor stack depth in programs
@@ -976,8 +986,8 @@
return;
}
- CellTypeState *basicBlockState =
- NEW_RESOURCE_ARRAY(CellTypeState, bbNo * _state_len);
+ CellTypeState *basicBlockState;
+ ALLOC_RESOURCE_ARRAY(basicBlockState, CellTypeState, bbNo * _state_len);
memset(basicBlockState, 0, bbNo * _state_len * sizeof(CellTypeState));
// Make a pass over the basicblocks and assign their state vectors.
--- a/hotspot/src/share/vm/prims/jvm.cpp Wed Jul 05 18:53:07 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvm.cpp Wed May 01 14:11:01 2013 +0100
@@ -1144,6 +1144,56 @@
}
JVM_END
+static bool is_authorized(Handle context, instanceKlassHandle klass, TRAPS) {
+ // If there is a security manager and protection domain, check the access
+ // in the protection domain, otherwise it is authorized.
+ if (java_lang_System::has_security_manager()) {
+
+ // For bootstrapping, if pd implies method isn't in the JDK, allow
+ // this context to revert to older behavior.
+ // In this case the isAuthorized field in AccessControlContext is also not
+ // present.
+ if (Universe::protection_domain_implies_method() == NULL) {
+ return true;
+ }
+
+ // Whitelist certain access control contexts
+ if (java_security_AccessControlContext::is_authorized(context)) {
+ return true;
+ }
+
+ oop prot = klass->protection_domain();
+ if (prot != NULL) {
+ // Call pd.implies(new SecurityPermission("createAccessControlContext"))
+ // in the new wrapper.
+ methodHandle m(THREAD, Universe::protection_domain_implies_method());
+ Handle h_prot(THREAD, prot);
+ JavaValue result(T_BOOLEAN);
+ JavaCallArguments args(h_prot);
+ JavaCalls::call(&result, m, &args, CHECK_false);
+ return (result.get_jboolean() != 0);
+ }
+ }
+ return true;
+}
+
+// Create an AccessControlContext with a protection domain with null codesource
+// and null permissions - which gives no permissions.
+oop create_dummy_access_control_context(TRAPS) {
+ InstanceKlass* pd_klass = InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass());
+ // new ProtectionDomain(null,null);
+ oop null_protection_domain = pd_klass->allocate_instance(CHECK_NULL);
+ Handle null_pd(THREAD, null_protection_domain);
+
+ // new ProtectionDomain[] {pd};
+ objArrayOop context = oopFactory::new_objArray(pd_klass, 1, CHECK_NULL);
+ context->obj_at_put(0, null_pd());
+
+ // new AccessControlContext(new ProtectionDomain[] {pd})
+ objArrayHandle h_context(THREAD, context);
+ oop result = java_security_AccessControlContext::create(h_context, false, Handle(), CHECK_NULL);
+ return result;
+}
JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException))
JVMWrapper("JVM_DoPrivileged");
@@ -1152,8 +1202,29 @@
THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), "Null action");
}
- // Stack allocated list of privileged stack elements
- PrivilegedElement pi;
+ // Compute the frame initiating the do privileged operation and setup the privileged stack
+ vframeStream vfst(thread);
+ vfst.security_get_caller_frame(1);
+
+ if (vfst.at_end()) {
+ THROW_MSG_0(vmSymbols::java_lang_InternalError(), "no caller?");
+ }
+
+ Method* method = vfst.method();
+ instanceKlassHandle klass (THREAD, method->method_holder());
+
+ // Check that action object understands "Object run()"
+ Handle h_context;
+ if (context != NULL) {
+ h_context = Handle(THREAD, JNIHandles::resolve(context));
+ bool authorized = is_authorized(h_context, klass, CHECK_NULL);
+ if (!authorized) {
+ // Create an unprivileged access control object and call it's run function
+ // instead.
+ oop noprivs = create_dummy_access_control_context(CHECK_NULL);
+ h_context = Handle(THREAD, noprivs);
+ }
+ }
// Check that action object understands "Object run()"
Handle object (THREAD, JNIHandles::resolve(action));
@@ -1167,12 +1238,10 @@
THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method");
}
- // Compute the frame initiating the do privileged operation and setup the privileged stack
- vframeStream vfst(thread);
- vfst.security_get_caller_frame(1);
-
+ // Stack allocated list of privileged stack elements
+ PrivilegedElement pi;
if (!vfst.at_end()) {
- pi.initialize(&vfst, JNIHandles::resolve(context), thread->privileged_stack_top(), CHECK_NULL);
+ pi.initialize(&vfst, h_context(), thread->privileged_stack_top(), CHECK_NULL);
thread->set_privileged_stack_top(&pi);
}