--- a/make/hotspot/symbols/symbols-unix Wed Sep 12 10:27:03 2018 -0700
+++ b/make/hotspot/symbols/symbols-unix Wed Sep 19 14:47:37 2018 -0700
@@ -52,7 +52,6 @@
JVM_DefineClass
JVM_DefineClassWithSource
JVM_DesiredAssertionStatus
-JVM_DoPrivileged
JVM_DumpAllStacks
JVM_DumpThreads
JVM_FillInStackTrace
--- a/src/hotspot/share/classfile/vmSymbols.hpp Wed Sep 12 10:27:03 2018 -0700
+++ b/src/hotspot/share/classfile/vmSymbols.hpp Wed Sep 19 14:47:37 2018 -0700
@@ -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") \
--- a/src/hotspot/share/include/jvm.h Wed Sep 12 10:27:03 2018 -0700
+++ b/src/hotspot/share/include/jvm.h Wed Sep 19 14:47:37 2018 -0700
@@ -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
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp Wed Sep 12 10:27:03 2018 -0700
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp Wed Sep 19 14:47:37 2018 -0700
@@ -33,7 +33,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"
@@ -322,14 +321,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
--- a/src/hotspot/share/prims/jvm.cpp Wed Sep 12 10:27:03 2018 -0700
+++ b/src/hotspot/share/prims/jvm.cpp Wed Sep 19 14:47:37 2018 -0700
@@ -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,41 @@
// 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()->name() == vmSymbols::java_security_AccessController() &&
+ 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());
+#if 0
+ // TODO: If we want to get the caller from the stackwalk, rather than
+ // passing it in, we need to mimic Reflection.getCallerClass()
+ // behavior and skip reflection frames.
+ assert(caller_klass == caller_fr->method()->method_holder(), "!");
+#endif
+ protection_domain = caller_klass->protection_domain();
} else {
protection_domain = method->method_holder()->protection_domain();
}
--- a/src/hotspot/share/prims/privilegedStack.cpp Wed Sep 12 10:27:03 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -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
--- a/src/hotspot/share/prims/privilegedStack.hpp Wed Sep 12 10:27:03 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -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
--- a/src/hotspot/share/runtime/os.cpp Wed Sep 12 10:27:03 2018 -0700
+++ b/src/hotspot/share/runtime/os.cpp Wed Sep 19 14:47:37 2018 -0700
@@ -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"
@@ -1132,14 +1131,6 @@
}
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) {
--- a/src/hotspot/share/runtime/thread.cpp Wed Sep 12 10:27:03 2018 -0700
+++ b/src/hotspot/share/runtime/thread.cpp Wed Sep 19 14:47:37 2018 -0700
@@ -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"
@@ -1537,7 +1536,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;
@@ -1971,7 +1969,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();
@@ -2821,11 +2818,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++) {
--- a/src/hotspot/share/runtime/thread.hpp Wed Sep 12 10:27:03 2018 -0700
+++ b/src/hotspot/share/runtime/thread.hpp Wed Sep 19 14:47:37 2018 -0700
@@ -1876,14 +1876,9 @@
void thread_main_inner();
private:
- // PRIVILEGED STACK
- PrivilegedElement* _privileged_stack_top;
GrowableArray<oop>* _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<oop>* array) { _array_for_gc = array; }
public:
--- a/src/hotspot/share/utilities/debug.cpp Wed Sep 12 10:27:03 2018 -0700
+++ b/src/hotspot/share/utilities/debug.cpp Wed Sep 19 14:47:37 2018 -0700
@@ -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"
--- a/src/hotspot/share/utilities/globalDefinitions.hpp Wed Sep 12 10:27:03 2018 -0700
+++ b/src/hotspot/share/utilities/globalDefinitions.hpp Wed Sep 19 14:47:37 2018 -0700
@@ -925,7 +925,6 @@
class ConstantValue;
class IllegalValue;
-class PrivilegedElement;
class MonitorArray;
class MonitorInfo;
--- a/src/java.base/share/classes/java/security/AccessController.java Wed Sep 12 10:27:03 2018 -0700
+++ b/src/java.base/share/classes/java/security/AccessController.java Wed Sep 19 14:47:37 2018 -0700
@@ -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,13 @@
package java.security;
+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;
/**
* <p> The AccessController class is used for access control operations
@@ -296,7 +300,10 @@
*/
@CallerSensitive
- public static native <T> T doPrivileged(PrivilegedAction<T> action);
+ public static <T> T doPrivileged(PrivilegedAction<T> action)
+ {
+ return executePrivileged(action, null, Reflection.getCallerClass());
+ }
/**
* Performs the specified {@code PrivilegedAction} with privileges
@@ -369,8 +376,13 @@
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*/
@CallerSensitive
- public static native <T> T doPrivileged(PrivilegedAction<T> action,
- AccessControlContext context);
+ public static <T> T doPrivileged(PrivilegedAction<T> action,
+ AccessControlContext context)
+ {
+ Class <?> caller = Reflection.getCallerClass();
+ context = checkContext(context, caller);
+ return executePrivileged(action, context, caller);
+ }
/**
@@ -524,10 +536,20 @@
* @see java.security.DomainCombiner
*/
@CallerSensitive
- public static native <T> T
+ public static <T> T
doPrivileged(PrivilegedExceptionAction<T> 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
@@ -603,6 +625,7 @@
private static class AccHolder {
// An AccessControlContext with no granted permissions.
// Only initialized on demand when getInnocuousAcc() is called.
+// TODO: set isAuthorized
static final AccessControlContext innocuousAcc =
new AccessControlContext(new ProtectionDomain[] {
new ProtectionDomain(null, null) });
@@ -611,6 +634,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 +684,86 @@
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
*/
@CallerSensitive
- public static native <T> T
+ public static <T> T
doPrivileged(PrivilegedExceptionAction<T> 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;
+ }
+ @ForceInline
+ private static <T> T
+ executePrivileged(PrivilegedAction<T> action,
+ AccessControlContext context,
+ Class <?> caller)
+ {
+{
+AccessControlContext ctx = getStackAccessControlContext();
+assert ctx == null || ctx.isPrivileged();
+}
+ T result = action.run();
+{
+AccessControlContext ctx = getStackAccessControlContext();
+assert ctx == null || ctx.isPrivileged();
+}
+ Reference.reachabilityFence(context);
+ Reference.reachabilityFence(caller);
+ Reference.reachabilityFence(action); // FIXME: for debugging
+ return result;
+ }
+
+ @ForceInline
+ private static <T> T
+ executePrivileged(PrivilegedExceptionAction<T> action,
+ AccessControlContext context,
+ Class <?> caller)
+ throws Exception
+ {
+{
+AccessControlContext ctx = getStackAccessControlContext();
+assert ctx == null || ctx.isPrivileged();
+}
+ T result = action.run();
+{
+AccessControlContext ctx = getStackAccessControlContext();
+assert ctx == null || ctx.isPrivileged();
+}
+ Reference.reachabilityFence(context);
+ Reference.reachabilityFence(caller);
+ Reference.reachabilityFence(action); // FIXME: for debugging
+ return result;
+ }
+
+ @ForceInline
+ @ReservedStackAccess
+ private static PrivilegedActionException wrapException(Exception e) {
+ return new PrivilegedActionException(e);
+ }
/**
* Performs the specified {@code PrivilegedExceptionAction} with
--- a/src/java.base/share/native/libjava/AccessController.c Wed Sep 12 10:27:03 2018 -0700
+++ b/src/java.base/share/native/libjava/AccessController.c Wed Sep 19 14:47:37 2018 -0700
@@ -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)
-{
- 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)
+JNIEXPORT jobject JNICALL
+Java_java_security_AccessController_getProtectionDomain(
+ JNIEnv *env,
+ jclass cls,
+ jclass caller)
{
- 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
--- a/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivRunAbstract.jasm Wed Sep 12 10:27:03 2018 -0700
+++ b/test/hotspot/jtreg/runtime/JVMDoPrivileged/DoPrivRunAbstract.jasm Wed Sep 19 14:47:37 2018 -0700
@@ -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."<init>":"(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;
}
--- a/test/jdk/java/lang/StackWalker/VerifyStackTrace.java Wed Sep 12 10:27:03 2018 -0700
+++ b/test/jdk/java/lang/StackWalker/VerifyStackTrace.java Wed Sep 19 14:47:37 2018 -0700
@@ -71,9 +71,11 @@
"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" +
- "7: VerifyStackTrace.test(VerifyStackTrace.java:227)\n" +
- "8: VerifyStackTrace.main(VerifyStackTrace.java:182)\n";
+ "6: java.base/java.security.AccessController.executePrivileged(AccessController.java:759)\n" +
+ "7: java.base/java.security.AccessController.doPrivileged(AccessController.java:310)\n" +
+
+ "8: VerifyStackTrace.test(VerifyStackTrace.java:227)\n" +
+ "9: VerifyStackTrace.main(VerifyStackTrace.java:182)\n";
@Override public StackWalker walker() { return walker;}
@Override public String description() { return description;}
@@ -105,9 +107,10 @@
"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" +
- "11: VerifyStackTrace.test(VerifyStackTrace.java:229)\n" +
- "12: VerifyStackTrace.main(VerifyStackTrace.java:185)\n";
+ "10: java.base/java.security.AccessController.executePrivileged(AccessController.java:759)\n" +
+ "11: java.base/java.security.AccessController.doPrivileged(AccessController.java:310)\n" +
+ "12: VerifyStackTrace.test(VerifyStackTrace.java:229)\n" +
+ "13: VerifyStackTrace.main(VerifyStackTrace.java:185)\n";
@Override public StackWalker walker() { return walker;}
@Override public String description() { return description;}
@@ -142,9 +145,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;}