< prev index next >
src/java.base/share/classes/java/security/AccessController.java
Print this page
rev 52360 : 8212605: Pure-Java implementation of AccessController.doPrivileged
@@ -1,7 +1,7 @@
/*
- * 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -23,13 +23,21 @@
* questions.
*/
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;
/**
* <p> The AccessController class is used for access control operations
* and decisions.
*
@@ -294,11 +302,14 @@
* @see #doPrivilegedWithCombiner(PrivilegedAction)
* @see java.security.DomainCombiner
*/
@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
* enabled. The action is performed with <i>all</i> of the permissions
* possessed by the caller's protection domain.
@@ -367,12 +378,17 @@
*
* @see #doPrivileged(PrivilegedAction)
* @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);
+ }
/**
* Performs the specified {@code PrivilegedAction} with privileges
* enabled and restricted by the specified
@@ -522,14 +538,24 @@
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
* @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)
* @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
* privileges enabled. The action is performed with <i>all</i> of the
* permissions possessed by the caller's protection domain.
@@ -609,10 +635,12 @@
}
private static AccessControlContext getInnocuousAcc() {
return AccHolder.innocuousAcc;
}
+ private static native ProtectionDomain getProtectionDomain(final Class <?> caller);
+
private static ProtectionDomain getCallerPD(final Class <?> caller) {
ProtectionDomain callerPd = doPrivileged
(new PrivilegedAction<>() {
public ProtectionDomain run() {
return caller.getProtectionDomain();
@@ -657,15 +685,105 @@
*
* @see #doPrivileged(PrivilegedAction)
* @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;
+ }
+
+ private static boolean isPrivileged() {
+ AccessControlContext ctx = getStackAccessControlContext();
+ return ctx == null || ctx.isPrivileged();
+ }
+ @Hidden
+ @ForceInline
+ private static <T> T
+ executePrivileged(PrivilegedAction<T> 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> T
+ executePrivileged(PrivilegedExceptionAction<T> 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 <init> that returned "this" instead of "void".
+ return new PrivilegedActionException(e);
+ }
/**
* Performs the specified {@code PrivilegedExceptionAction} with
* privileges enabled and restricted by the specified
* {@code AccessControlContext} and with a privilege scope limited by
< prev index next >