# HG changeset patch # User dlong # Date 1541020236 25200 # Wed Oct 31 14:10:36 2018 -0700 # Node ID 1202bd445f6d5297082dd8b40e2b2df9c0306f17 # Parent e38473506688e0995e701fc7f77d5a91b438ef93 8212605: Pure-Java implementation of AccessController.doPrivileged diff --git a/make/hotspot/symbols/symbols-unix b/make/hotspot/symbols/symbols-unix --- a/make/hotspot/symbols/symbols-unix +++ b/make/hotspot/symbols/symbols-unix @@ -52,7 +52,6 @@ JVM_DefineClass JVM_DefineClassWithSource JVM_DesiredAssertionStatus -JVM_DoPrivileged JVM_DumpAllStacks JVM_DumpThreads JVM_FillInStackTrace diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -1066,7 +1066,7 @@ _method_DontInline, _method_InjectedProfile, _method_LambdaForm_Compiled, - _method_LambdaForm_Hidden, + _method_Hidden, _method_HotSpotIntrinsicCandidate, _jdk_internal_vm_annotation_Contended, _field_Stable, @@ -2121,7 +2121,12 @@ case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature): { if (_location != _in_method) break; // only allow for methods if (!privileged) break; // only allow in privileged code - return _method_LambdaForm_Hidden; + return _method_Hidden; + } + case vmSymbols::VM_SYMBOL_ENUM_NAME(java_security_AccessController_Hidden_signature): { + if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code + return _method_Hidden; } case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_HotSpotIntrinsicCandidate_signature): { if (_location != _in_method) break; // only allow for methods @@ -2178,7 +2183,7 @@ m->set_has_injected_profile(true); if (has_annotation(_method_LambdaForm_Compiled) && m->intrinsic_id() == vmIntrinsics::_none) m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm); - if (has_annotation(_method_LambdaForm_Hidden)) + if (has_annotation(_method_Hidden)) m->set_hidden(true); if (has_annotation(_method_HotSpotIntrinsicCandidate) && !m->is_synthetic()) m->set_intrinsic_candidate(true); diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -116,6 +116,7 @@ do_klass(SecurityManager_klass, java_lang_SecurityManager ) \ do_klass(ProtectionDomain_klass, java_security_ProtectionDomain ) \ do_klass(AccessControlContext_klass, java_security_AccessControlContext ) \ + do_klass(AccessController_klass, java_security_AccessController ) \ do_klass(SecureClassLoader_klass, java_security_SecureClassLoader ) \ do_klass(ClassNotFoundException_klass, java_lang_ClassNotFoundException ) \ do_klass(NoClassDefFoundError_klass, java_lang_NoClassDefFoundError ) \ diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -99,6 +99,8 @@ template(java_lang_CharSequence, "java/lang/CharSequence") \ template(java_lang_SecurityManager, "java/lang/SecurityManager") \ template(java_security_AccessControlContext, "java/security/AccessControlContext") \ + template(java_security_AccessController, "java/security/AccessController") \ + template(executePrivileged_name, "executePrivileged") \ template(java_security_CodeSource, "java/security/CodeSource") \ template(java_security_ProtectionDomain, "java/security/ProtectionDomain") \ template(java_security_SecureClassLoader, "java/security/SecureClassLoader") \ @@ -303,6 +305,7 @@ template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \ template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \ template(java_lang_invoke_MethodHandleNatives_CallSiteContext_signature, "Ljava/lang/invoke/MethodHandleNatives$CallSiteContext;") \ + template(java_security_AccessController_Hidden_signature, "Ljava/security/AccessController$Hidden;") \ /* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */ \ template(findMethodHandleType_name, "findMethodHandleType") \ template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \ diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -621,10 +621,6 @@ */ JNIEXPORT jobject JNICALL -JVM_DoPrivileged(JNIEnv *env, jclass cls, - jobject action, jobject context, jboolean wrapException); - -JNIEXPORT jobject JNICALL JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls); JNIEXPORT jobject JNICALL diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp @@ -34,7 +34,6 @@ #include "oops/markOop.hpp" #include "oops/oop.hpp" #include "prims/jvmtiThreadState.hpp" -#include "prims/privilegedStack.hpp" #include "runtime/frame.inline.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/threadSMR.inline.hpp" @@ -323,14 +322,6 @@ ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_stack_variable, jt); if (jt->has_last_Java_frame()) { - PrivilegedElement* const pelem = jt->privileged_stack_top(); - if (pelem != NULL) { - pelem->oops_do(&rcl); - if (rcl.complete()) { - return true; - } - } - // traverse the registered growable array gc_array // can't do this as it is not reachable from outside diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -55,7 +55,6 @@ #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" #include "prims/nativeLookup.hpp" -#include "prims/privilegedStack.hpp" #include "prims/stackwalk.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.hpp" @@ -1166,155 +1165,6 @@ JVM_END -static bool is_authorized(Handle context, InstanceKlass* 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 = SystemDictionary::ProtectionDomain_klass(); - // Call constructor ProtectionDomain(null, null); - Handle obj = JavaCalls::construct_new_instance(pd_klass, - vmSymbols::codesource_permissioncollection_signature(), - Handle(), Handle(), CHECK_NULL); - - // new ProtectionDomain[] {pd}; - objArrayOop context = oopFactory::new_objArray(pd_klass, 1, CHECK_NULL); - context->obj_at_put(0, obj()); - - // new AccessControlContext(new ProtectionDomain[] {pd}) - objArrayHandle h_context(THREAD, context); - oop acc = java_security_AccessControlContext::create(h_context, false, Handle(), CHECK_NULL); - return acc; -} - -JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException)) - JVMWrapper("JVM_DoPrivileged"); - - if (action == NULL) { - THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), "Null action"); - } - - // 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(); - InstanceKlass* klass = 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)); - - // get run() method - Method* m_oop = object->klass()->uncached_lookup_method( - vmSymbols::run_method_name(), - vmSymbols::void_object_signature(), - Klass::find_overpass); - - // See if there is a default method for "Object run()". - if (m_oop == NULL && object->klass()->is_instance_klass()) { - InstanceKlass* iklass = InstanceKlass::cast(object->klass()); - m_oop = iklass->lookup_method_in_ordered_interfaces( - vmSymbols::run_method_name(), - vmSymbols::void_object_signature()); - } - - methodHandle m (THREAD, m_oop); - if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static() || m()->is_abstract()) { - THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method"); - } - - // Stack allocated list of privileged stack elements - PrivilegedElement pi; - if (!vfst.at_end()) { - pi.initialize(&vfst, h_context(), thread->privileged_stack_top(), CHECK_NULL); - thread->set_privileged_stack_top(&pi); - } - - - // invoke the Object run() in the action object. We cannot use call_interface here, since the static type - // is not really known - it is either java.security.PrivilegedAction or java.security.PrivilegedExceptionAction - Handle pending_exception; - JavaValue result(T_OBJECT); - JavaCallArguments args(object); - JavaCalls::call(&result, m, &args, THREAD); - - // done with action, remove ourselves from the list - if (!vfst.at_end()) { - assert(thread->privileged_stack_top() != NULL && thread->privileged_stack_top() == &pi, "wrong top element"); - thread->set_privileged_stack_top(thread->privileged_stack_top()->next()); - } - - if (HAS_PENDING_EXCEPTION) { - pending_exception = Handle(THREAD, PENDING_EXCEPTION); - CLEAR_PENDING_EXCEPTION; - // JVMTI has already reported the pending exception - // JVMTI internal flag reset is needed in order to report PrivilegedActionException - if (THREAD->is_Java_thread()) { - JvmtiExport::clear_detected_exception((JavaThread*) THREAD); - } - if ( pending_exception->is_a(SystemDictionary::Exception_klass()) && - !pending_exception->is_a(SystemDictionary::RuntimeException_klass())) { - // Throw a java.security.PrivilegedActionException(Exception e) exception - JavaCallArguments args(pending_exception); - THROW_ARG_0(vmSymbols::java_security_PrivilegedActionException(), - vmSymbols::exception_void_signature(), - &args); - } - } - - if (pending_exception.not_null()) THROW_OOP_0(pending_exception()); - return JNIHandles::make_local(env, (oop) result.get_jobject()); -JVM_END - - // Returns the inherited_access_control_context field of the running thread. JVM_ENTRY(jobject, JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls)) JVMWrapper("JVM_GetInheritedAccessControlContext"); @@ -1349,25 +1199,35 @@ // duplicate consecutive protection domains into a single one, as // well as stopping when we hit a privileged frame. - // Use vframeStream to iterate through Java frames - vframeStream vfst(thread); - oop previous_protection_domain = NULL; Handle privileged_context(thread, NULL); bool is_privileged = false; oop protection_domain = NULL; - for(; !vfst.at_end(); vfst.next()) { + // Iterate through Java frames + RegisterMap reg_map(thread); + javaVFrame *vf = thread->last_java_vframe(®_map); + for (; vf != NULL; vf = vf->java_sender()) { // get method of frame - Method* method = vfst.method(); - intptr_t* frame_id = vfst.frame_id(); - - // check the privileged frames to see if we have a match - if (thread->privileged_stack_top() && thread->privileged_stack_top()->frame_id() == frame_id) { + Method* method = vf->method(); + + // stop at the first privileged frame + if (method->method_holder() == SystemDictionary::AccessController_klass() && + method->name() == vmSymbols::executePrivileged_name()) + { // this frame is privileged is_privileged = true; - privileged_context = Handle(thread, thread->privileged_stack_top()->privileged_context()); - protection_domain = thread->privileged_stack_top()->protection_domain(); + + javaVFrame *priv = vf; // executePrivileged + javaVFrame *caller_fr = priv->java_sender(); // doPrivileged + caller_fr = caller_fr->java_sender(); // caller + + StackValueCollection* locals = priv->locals(); + privileged_context = locals->obj_at(1); + Handle caller = locals->obj_at(2); + + Klass *caller_klass = java_lang_Class::as_Klass(caller()); + protection_domain = caller_klass->protection_domain(); } else { protection_domain = method->method_holder()->protection_domain(); } diff --git a/src/hotspot/share/prims/privilegedStack.cpp b/src/hotspot/share/prims/privilegedStack.cpp deleted file mode 100644 --- a/src/hotspot/share/prims/privilegedStack.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 1997, 2018, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "memory/allocation.inline.hpp" -#include "oops/instanceKlass.hpp" -#include "oops/method.hpp" -#include "oops/oop.inline.hpp" -#include "prims/privilegedStack.hpp" -#include "runtime/thread.inline.hpp" -#include "runtime/vframe.inline.hpp" - -void PrivilegedElement::initialize(vframeStream* vfst, oop context, PrivilegedElement* next, TRAPS) { - Method* method = vfst->method(); - _klass = method->method_holder(); - _privileged_context = context; -#ifdef CHECK_UNHANDLED_OOPS - THREAD->allow_unhandled_oop(&_privileged_context); -#endif // CHECK_UNHANDLED_OOPS - _frame_id = vfst->frame_id(); - _next = next; - assert(oopDesc::is_oop_or_null(_privileged_context), "must be an oop"); - assert(oopDesc::is_oop_or_null(protection_domain()), "must be an oop"); -} - -void PrivilegedElement::oops_do(OopClosure* f) { - PrivilegedElement *cur = this; - do { - f->do_oop((oop*) &cur->_privileged_context); - cur = cur->_next; - } while(cur != NULL); -} - -//------------------------------------------------------------------------------- -#ifndef PRODUCT - -void PrivilegedElement::print_on(outputStream* st) const { - st->print(" " PTR_FORMAT " ", p2i(_frame_id)); - _klass->print_value_on(st); - if (protection_domain() != NULL) { - st->print(" "); - protection_domain()->print_value_on(st); - } - st->cr(); -} - -bool PrivilegedElement::contains(address addr) { - PrivilegedElement *e = (PrivilegedElement *)addr; - if (e >= this && e < this+1) return true; - - if (_next != NULL) { - return _next->contains(addr); - } else { - return false; - } -} - -#endif diff --git a/src/hotspot/share/prims/privilegedStack.hpp b/src/hotspot/share/prims/privilegedStack.hpp deleted file mode 100644 --- a/src/hotspot/share/prims/privilegedStack.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 1997, 2018, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_PRIMS_PRIVILEGEDSTACK_HPP -#define SHARE_VM_PRIMS_PRIVILEGEDSTACK_HPP - -#include "oops/oopsHierarchy.hpp" -#include "runtime/vframe.hpp" -#include "utilities/growableArray.hpp" - -class PrivilegedElement { - private: - Klass* _klass; // klass for method - oop _privileged_context; // context for operation - intptr_t* _frame_id; // location on stack - PrivilegedElement* _next; // Link to next one on stack - public: - void initialize(vframeStream* vf, oop context, PrivilegedElement* next, TRAPS); - void oops_do(OopClosure* f); - intptr_t* frame_id() const { return _frame_id; } - oop privileged_context() const { return _privileged_context; } - oop class_loader() const { return InstanceKlass::cast(_klass)->class_loader(); } - oop protection_domain() const { return InstanceKlass::cast(_klass)->protection_domain(); } - PrivilegedElement *next() const { return _next; } - - // debugging (used for find) - void print_on(outputStream* st) const PRODUCT_RETURN; - bool contains(address addr) PRODUCT_RETURN0; -}; - -#endif // SHARE_VM_PRIMS_PRIVILEGEDSTACK_HPP diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -44,7 +44,6 @@ #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "prims/jvm_misc.hpp" -#include "prims/privilegedStack.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.hpp" #include "runtime/frame.inline.hpp" @@ -1091,14 +1090,6 @@ // Check if addr belongs to a Java thread. for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) { - // Check for privilege stack - if (thread->privileged_stack_top() != NULL && - thread->privileged_stack_top()->contains(addr)) { - st->print_cr(INTPTR_FORMAT " is pointing into the privilege stack " - "for thread: " INTPTR_FORMAT, p2i(addr), p2i(thread)); - if (verbose) thread->print_on(st); - return; - } // If the addr is a java thread print information about that. if (addr == (address)thread) { if (verbose) { diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp --- a/src/hotspot/share/runtime/thread.cpp +++ b/src/hotspot/share/runtime/thread.cpp @@ -61,7 +61,6 @@ #include "prims/jvm_misc.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" -#include "prims/privilegedStack.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" @@ -1558,7 +1557,6 @@ _on_thread_list = false; set_thread_state(_thread_new); _terminated = _not_terminated; - _privileged_stack_top = NULL; _array_for_gc = NULL; _suspend_equivalent = false; _in_deopt_handler = 0; @@ -1990,7 +1988,6 @@ // These things needs to be done while we are still a Java Thread. Make sure that thread // is in a consistent state, in case GC happens - assert(_privileged_stack_top == NULL, "must be NULL when we get here"); if (active_handles() != NULL) { JNIHandleBlock* block = active_handles(); @@ -2840,11 +2837,6 @@ // Record JavaThread to GC thread RememberProcessedThread rpt(this); - // Traverse the privileged stack - if (_privileged_stack_top != NULL) { - _privileged_stack_top->oops_do(f); - } - // traverse the registered growable array if (_array_for_gc != NULL) { for (int index = 0; index < _array_for_gc->length(); index++) { diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -1882,14 +1882,9 @@ void thread_main_inner(); private: - // PRIVILEGED STACK - PrivilegedElement* _privileged_stack_top; GrowableArray* _array_for_gc; public: - // Returns the privileged_stack information. - PrivilegedElement* privileged_stack_top() const { return _privileged_stack_top; } - void set_privileged_stack_top(PrivilegedElement *e) { _privileged_stack_top = e; } void register_array_for_gc(GrowableArray* array) { _array_for_gc = array; } public: diff --git a/src/hotspot/share/utilities/debug.cpp b/src/hotspot/share/utilities/debug.cpp --- a/src/hotspot/share/utilities/debug.cpp +++ b/src/hotspot/share/utilities/debug.cpp @@ -37,7 +37,6 @@ #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/oop.inline.hpp" -#include "prims/privilegedStack.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.hpp" #include "runtime/flags/flagSetting.hpp" diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -925,7 +925,6 @@ class ConstantValue; class IllegalValue; -class PrivilegedElement; class MonitorArray; class MonitorInfo; diff --git a/src/java.base/share/classes/java/security/AccessController.java b/src/java.base/share/classes/java/security/AccessController.java --- a/src/java.base/share/classes/java/security/AccessController.java +++ b/src/java.base/share/classes/java/security/AccessController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -25,9 +25,17 @@ package java.security; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.ref.Reference; import sun.security.util.Debug; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; +import jdk.internal.vm.annotation.DontInline; +import jdk.internal.vm.annotation.ForceInline; +import jdk.internal.vm.annotation.ReservedStackAccess; /** *

The AccessController class is used for access control operations @@ -296,7 +304,10 @@ */ @CallerSensitive - public static native T doPrivileged(PrivilegedAction action); + public static T doPrivileged(PrivilegedAction action) + { + return executePrivileged(action, null, Reflection.getCallerClass()); + } /** * Performs the specified {@code PrivilegedAction} with privileges @@ -369,8 +380,13 @@ * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) */ @CallerSensitive - public static native T doPrivileged(PrivilegedAction action, - AccessControlContext context); + public static T doPrivileged(PrivilegedAction action, + AccessControlContext context) + { + Class caller = Reflection.getCallerClass(); + context = checkContext(context, caller); + return executePrivileged(action, context, caller); + } /** @@ -524,10 +540,20 @@ * @see java.security.DomainCombiner */ @CallerSensitive - public static native T + public static T doPrivileged(PrivilegedExceptionAction action) - throws PrivilegedActionException; - + throws PrivilegedActionException + { + AccessControlContext context = null; + Class caller = Reflection.getCallerClass(); + try { + return executePrivileged(action, context, caller); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw wrapException(e); + } + } /** * Performs the specified {@code PrivilegedExceptionAction} with @@ -611,6 +637,8 @@ return AccHolder.innocuousAcc; } + private static native ProtectionDomain getProtectionDomain(final Class caller); + private static ProtectionDomain getCallerPD(final Class caller) { ProtectionDomain callerPd = doPrivileged (new PrivilegedAction<>() { @@ -659,11 +687,101 @@ * @see #doPrivileged(PrivilegedAction,AccessControlContext) */ @CallerSensitive - public static native T + public static T doPrivileged(PrivilegedExceptionAction action, AccessControlContext context) - throws PrivilegedActionException; + throws PrivilegedActionException + { + Class caller = Reflection.getCallerClass(); + context = checkContext(context, caller); + try { + return executePrivileged(action, context, caller); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw wrapException(e); + } + } + private static AccessControlContext checkContext(AccessControlContext context, + Class caller) + { + // check if caller is authorized to create context + if (context != null && !context.isAuthorized() && + context != getInnocuousAcc() && + System.getSecurityManager() != null) + { + ProtectionDomain callerPD = getProtectionDomain(caller); + if (callerPD != null && !callerPD.impliesCreateAccessControlContext()) { + return getInnocuousAcc(); + } + } + return context; + } + + private static boolean isPrivileged() { + AccessControlContext ctx = getStackAccessControlContext(); + return ctx == null || ctx.isPrivileged(); + } + + @Hidden + @ForceInline + private static T + executePrivileged(PrivilegedAction action, + AccessControlContext context, + Class caller) + { + assert isPrivileged(); + T result = action.run(); + assert isPrivileged(); + + // Keep these alive across the run() call so they can be + // retrieved by getStackAccessControlContext(). + Reference.reachabilityFence(context); + Reference.reachabilityFence(caller); + Reference.reachabilityFence(action); + return result; + } + + @Hidden + @ForceInline + private static T + executePrivileged(PrivilegedExceptionAction action, + AccessControlContext context, + Class caller) + throws Exception + { + assert isPrivileged(); + T result = action.run(); + assert isPrivileged(); + + // Keep these alive across the run() call so they can be + // retrieved by getStackAccessControlContext(). + Reference.reachabilityFence(context); + Reference.reachabilityFence(caller); + Reference.reachabilityFence(action); + return result; + } + + + /** + * Internal marker for hidden implementation frames. + */ + /*non-public*/ + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + @interface Hidden { + } + + + @Hidden + @ForceInline + @ReservedStackAccess + private static PrivilegedActionException wrapException(Exception e) { + // Nice place for tail-call elimination, if only there was a + // version of that returned "this" instead of "void". + return new PrivilegedActionException(e); + } /** * Performs the specified {@code PrivilegedExceptionAction} with diff --git a/src/java.base/share/native/libjava/AccessController.c b/src/java.base/share/native/libjava/AccessController.c --- a/src/java.base/share/native/libjava/AccessController.c +++ b/src/java.base/share/native/libjava/AccessController.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -34,48 +34,13 @@ #include "jvm.h" #include "java_security_AccessController.h" -/* - * Class: java_security_AccessController - * Method: doPrivileged - * Signature: (Ljava/security/PrivilegedAction;)Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2 - (JNIEnv *env, jclass cls, jobject action) +JNIEXPORT jobject JNICALL +Java_java_security_AccessController_getProtectionDomain( + JNIEnv *env, + jclass cls, + jclass caller) { - return JVM_DoPrivileged(env, cls, action, NULL, JNI_FALSE); -} - -/* - * Class: java_security_AccessController - * Method: doPrivileged - * Signature: (Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;)Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2 - (JNIEnv *env, jclass cls, jobject action, jobject context) -{ - return JVM_DoPrivileged(env, cls, action, context, JNI_FALSE); -} - -/* - * Class: java_security_AccessController - * Method: doPrivileged - * Signature: (Ljava/security/PrivilegedExceptionAction;)Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2 - (JNIEnv *env, jclass cls, jobject action) -{ - return JVM_DoPrivileged(env, cls, action, NULL, JNI_TRUE); -} - -/* - * Class: java_security_AccessController - * Method: doPrivileged - * Signature: (Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2 - (JNIEnv *env, jclass cls, jobject action, jobject context) -{ - return JVM_DoPrivileged(env, cls, action, context, JNI_TRUE); + return JVM_GetProtectionDomain(env, caller); } JNIEXPORT jobject JNICALL diff --git a/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivRunAbstract.jasm b/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivRunAbstract.jasm --- a/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivRunAbstract.jasm +++ b/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivRunAbstract.jasm @@ -23,7 +23,7 @@ /* * @test - * @summary Test that JVM_DoPrivilege throws java.lang.InternalError for an + * @summary Test that JVM_DoPrivilege throws java.lang.AbstractMethodError for an * abstract run() method. * @bug 8183962 * @compile DoPrivRunAbstract.jasm @@ -56,8 +56,8 @@ // public static void main(String[] args) throws Exception { // try { // doPrivileged(() -> System.out.println(System.getProperty("java.home"))); -// throw new RuntimeException("Expected InternalError not throw"); -// } catch (java.lang.InternalError e) { } +// throw new RuntimeException("Expected AbstractMethodError not throw"); +// } catch (java.lang.AbstractMethodError e) { } // } //} @@ -82,13 +82,13 @@ invokestatic Method doPrivileged:"(LDoPrivRunAbstract$VoidPrivActRunAbstract;)V"; new class java/lang/RuntimeException; dup; - ldc String "Expected InternalError not throw"; + ldc String "Expected AbstractMethodError not throw"; invokespecial Method java/lang/RuntimeException."":"(Ljava/lang/String;)V"; athrow; endtry t0; - catch t0 java/lang/InternalError; + catch t0 java/lang/AbstractMethodError; stack_frame_type stack1; - stack_map class java/lang/InternalError; + stack_map class java/lang/AbstractMethodError; astore_1; return; } diff --git a/test/jdk/java/lang/StackWalker/VerifyStackTrace.java b/test/jdk/java/lang/StackWalker/VerifyStackTrace.java --- a/test/jdk/java/lang/StackWalker/VerifyStackTrace.java +++ b/test/jdk/java/lang/StackWalker/VerifyStackTrace.java @@ -71,7 +71,7 @@ "3: VerifyStackTrace$Handle.run(VerifyStackTrace.java:158)\n" + "4: VerifyStackTrace.invoke(VerifyStackTrace.java:188)\n" + "5: VerifyStackTrace$1.run(VerifyStackTrace.java:218)\n" + - "6: java.base/java.security.AccessController.doPrivileged(Native Method)\n" + + "6: java.base/java.security.AccessController.doPrivileged(AccessController.java:310)\n" + "7: VerifyStackTrace.test(VerifyStackTrace.java:227)\n" + "8: VerifyStackTrace.main(VerifyStackTrace.java:182)\n"; @@ -105,7 +105,7 @@ "7: java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n" + "8: java.base/java.lang.reflect.Method.invoke(Method.java:520)\n" + "9: VerifyStackTrace$1.run(VerifyStackTrace.java:220)\n" + - "10: java.base/java.security.AccessController.doPrivileged(Native Method)\n" + + "10: java.base/java.security.AccessController.doPrivileged(AccessController.java:310)\n" + "11: VerifyStackTrace.test(VerifyStackTrace.java:229)\n" + "12: VerifyStackTrace.main(VerifyStackTrace.java:185)\n"; @@ -142,9 +142,10 @@ "10: java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n" + "11: java.base/java.lang.reflect.Method.invoke(Method.java:520)\n" + "12: VerifyStackTrace$1.run(VerifyStackTrace.java:222)\n" + - "13: java.base/java.security.AccessController.doPrivileged(Native Method)\n" + - "14: VerifyStackTrace.test(VerifyStackTrace.java:231)\n" + - "15: VerifyStackTrace.main(VerifyStackTrace.java:188)\n"; + "13: java.base/java.security.AccessController.executePrivileged(AccessController.java:759)\n" + + "14: java.base/java.security.AccessController.doPrivileged(AccessController.java:310)\n" + + "15: VerifyStackTrace.test(VerifyStackTrace.java:231)\n" + + "16: VerifyStackTrace.main(VerifyStackTrace.java:188)\n"; @Override public StackWalker walker() { return walker;} @Override public String description() { return description;} # HG changeset patch # User dlong # Date 1541029979 25200 # Wed Oct 31 16:52:59 2018 -0700 # Node ID 71aaefbe892f506f9fc20e5a67451fbd00188cba # Parent 1202bd445f6d5297082dd8b40e2b2df9c0306f17 [mq]: webrev.2.incr diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -3786,12 +3786,6 @@ } #endif -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 @@ -3975,13 +3969,6 @@ int java_lang_System::out_offset_in_bytes() { return static_out_offset; } int java_lang_System::err_offset_in_bytes() { return static_err_offset; } - -bool java_lang_System::has_security_manager() { - InstanceKlass* ik = SystemDictionary::System_klass(); - oop base = ik->static_field_base_raw(); - return base->obj_field(static_security_offset) != NULL; -} - int java_lang_Class::_klass_offset; int java_lang_Class::_array_klass_offset; int java_lang_Class::_oop_size_offset; diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -1240,8 +1240,6 @@ static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN; static oop create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS); - static bool is_authorized(Handle context); - // Debugging/initialization friend class JavaClasses; }; @@ -1315,8 +1313,6 @@ static int out_offset_in_bytes(); static int err_offset_in_bytes(); - static bool has_security_manager(); - static void compute_offsets(); static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN; diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -549,7 +549,6 @@ template(char_StringBuffer_signature, "(C)Ljava/lang/StringBuffer;") \ template(int_String_signature, "(I)Ljava/lang/String;") \ template(boolean_boolean_int_signature, "(ZZ)I") \ - template(codesource_permissioncollection_signature, "(Ljava/security/CodeSource;Ljava/security/PermissionCollection;)V") \ /* signature symbols needed by intrinsics */ \ VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, template, VM_ALIAS_IGNORE) \ \ diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp --- a/src/hotspot/share/memory/universe.cpp +++ b/src/hotspot/share/memory/universe.cpp @@ -105,7 +105,6 @@ oop Universe::_the_min_jint_string = NULL; LatestMethodCache* Universe::_finalizer_register_cache = NULL; LatestMethodCache* Universe::_loader_addClass_cache = NULL; -LatestMethodCache* Universe::_pd_implies_cache = NULL; LatestMethodCache* Universe::_throw_illegal_access_error_cache = NULL; LatestMethodCache* Universe::_do_stack_walk_cache = NULL; oop Universe::_out_of_memory_error_java_heap = NULL; @@ -229,7 +228,6 @@ _finalizer_register_cache->metaspace_pointers_do(it); _loader_addClass_cache->metaspace_pointers_do(it); - _pd_implies_cache->metaspace_pointers_do(it); _throw_illegal_access_error_cache->metaspace_pointers_do(it); _do_stack_walk_cache->metaspace_pointers_do(it); } @@ -271,7 +269,6 @@ f->do_ptr((void**)&_the_empty_instance_klass_array); _finalizer_register_cache->serialize(f); _loader_addClass_cache->serialize(f); - _pd_implies_cache->serialize(f); _throw_illegal_access_error_cache->serialize(f); _do_stack_walk_cache->serialize(f); } @@ -680,7 +677,6 @@ // Metaspace::initialize_shared_spaces() tries to populate them. Universe::_finalizer_register_cache = new LatestMethodCache(); Universe::_loader_addClass_cache = new LatestMethodCache(); - Universe::_pd_implies_cache = new LatestMethodCache(); Universe::_throw_illegal_access_error_cache = new LatestMethodCache(); Universe::_do_stack_walk_cache = new LatestMethodCache(); @@ -934,12 +930,6 @@ "addClass", vmSymbols::class_void_signature(), false, CHECK); - // Set up method for checking protection domain - initialize_known_method(_pd_implies_cache, - SystemDictionary::ProtectionDomain_klass(), - "impliesCreateAccessControlContext", - vmSymbols::void_boolean_signature(), false, CHECK); - // Set up method for stack walking initialize_known_method(_do_stack_walk_cache, SystemDictionary::AbstractStackWalker_klass(), diff --git a/src/hotspot/share/memory/universe.hpp b/src/hotspot/share/memory/universe.hpp --- a/src/hotspot/share/memory/universe.hpp +++ b/src/hotspot/share/memory/universe.hpp @@ -137,7 +137,6 @@ static oop _the_min_jint_string; // A cache of "-2147483648" as a Java string static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects static LatestMethodCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector - static LatestMethodCache* _pd_implies_cache; // method for checking protection domain attributes static LatestMethodCache* _throw_illegal_access_error_cache; // Unsafe.throwIllegalAccessError() method static LatestMethodCache* _do_stack_walk_cache; // method for stack walker callback @@ -322,7 +321,6 @@ 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 Method* throw_illegal_access_error() { return _throw_illegal_access_error_cache->get_method(); } static Method* do_stack_walk_method() { return _do_stack_walk_cache->get_method(); } diff --git a/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivRunAbstract.jasm b/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivRunAbstract.jasm --- a/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivRunAbstract.jasm +++ b/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivRunAbstract.jasm @@ -23,7 +23,7 @@ /* * @test - * @summary Test that JVM_DoPrivilege throws java.lang.AbstractMethodError for an + * @summary Test that AccessController.doPrivileged throws java.lang.AbstractMethodError for an * abstract run() method. * @bug 8183962 * @compile DoPrivRunAbstract.jasm diff --git a/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivileged.java b/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivileged.java --- a/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivileged.java +++ b/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivileged.java @@ -23,7 +23,7 @@ /* * @test - * @summary Test that JVM_DoPrivilege() searches default methods when looking + * @summary Test that AccessController.doPrivileged() searches default methods when looking * for the run() method. * @bug 8183962 * @run main DoPrivileged