       1 /*
       2  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
       3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       4  *
       5  * This code is free software; you can redistribute it and/or modify it
       6  * under the terms of the GNU General Public License version 2 only, as
       7  * published by the Free Software Foundation.  Oracle designates this
       8  * particular file as subject to the "Classpath" exception as provided
       9  * by Oracle in the LICENSE file that accompanied this code.
      10  *
      11  * This code is distributed in the hope that it will be useful, but WITHOUT
      12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14  * version 2 for more details (a copy is included in the LICENSE file that
      15  * accompanied this code).
      16  *
      17  * You should have received a copy of the GNU General Public License version
      18  * 2 along with this work; if not, write to the Free Software Foundation,
      19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
      20  *
      21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
      22  * or visit www.oracle.com if you need additional information or have any
      23  * questions.
      24  */
      25
      26 package java.security;
      27
      28 import java.lang.annotation.ElementType;
      29 import java.lang.annotation.Retention;
      30 import java.lang.annotation.RetentionPolicy;
      31 import java.lang.annotation.Target;
      32 import java.lang.ref.Reference;
      33
      34 import jdk.internal.vm.annotation.Hidden;
      35 import sun.security.util.Debug;
      36 import sun.security.util.SecurityConstants;
      37 import jdk.internal.reflect.CallerSensitive;
      38 import jdk.internal.reflect.Reflection;
      39 import jdk.internal.vm.annotation.DontInline;
      40 import jdk.internal.vm.annotation.ForceInline;
      41 import jdk.internal.vm.annotation.ReservedStackAccess;
      42
      43 /**
      44  * <p> The AccessController class is used for access control operations
      45  * and decisions.
      46  *
      47  * <p> More specifically, the AccessController class is used for
      48  * three purposes:
      49  *
      50  * <ul>
      51  * <li> to decide whether an access to a critical system
      52  * resource is to be allowed or denied, based on the security policy
      53  * currently in effect,
      54  * <li>to mark code as being "privileged", thus affecting subsequent
      55  * access determinations, and
      56  * <li>to obtain a "snapshot" of the current calling context so
      57  * access-control decisions from a different context can be made with
      58  * respect to the saved context. </ul>
      59  *
      60  * <p> The {@link #checkPermission(Permission) checkPermission} method
      61  * determines whether the access request indicated by a specified
      62  * permission should be granted or denied. A sample call appears
      63  * below. In this example, {@code checkPermission} will determine
      64  * whether or not to grant "read" access to the file named "testFile" in
      65  * the "/temp" directory.
      66  *
      67  * <pre>
      68  *
      69  * FilePermission perm = new FilePermission("/temp/testFile", "read");
      70  * AccessController.checkPermission(perm);
      71  *
      72  * </pre>
      73  *
      74  * <p> If a requested access is allowed,
      75  * {@code checkPermission} returns quietly. If denied, an
      76  * AccessControlException is
      77  * thrown. AccessControlException can also be thrown if the requested
      78  * permission is of an incorrect type or contains an invalid value.
      79  * Such information is given whenever possible.
      80  *
      81  * Suppose the current thread traversed m callers, in the order of caller 1
      82  * to caller 2 to caller m. Then caller m invoked the
      83  * {@code checkPermission} method.
      84  * The {@code checkPermission} method determines whether access
      85  * is granted or denied based on the following algorithm:
      86  *
      87  *  <pre> {@code
      88  * for (int i = m; i > 0; i--) {
      89  *
      90  *     if (caller i's domain does not have the permission)
      91  *         throw AccessControlException
      92  *
      93  *     else if (caller i is marked as privileged) {
      94  *         if (a context was specified in the call to doPrivileged)
      95  *             context.checkPermission(permission)
      96  *         if (limited permissions were specified in the call to doPrivileged) {
      97  *             for (each limited permission) {
      98  *                 if (the limited permission implies the requested permission)
      99  *                     return;
     100  *             }
     101  *         } else
     102  *             return;
     103  *     }
     104  * }
     105  *
     106  * // Next, check the context inherited when the thread was created.
     107  * // Whenever a new thread is created, the AccessControlContext at
     108  * // that time is stored and associated with the new thread, as the
     109  * // "inherited" context.
     110  *
     111  * inheritedContext.checkPermission(permission);
     112  * }</pre>
     113  *
     114  * <p> A caller can be marked as being "privileged"
     115  * (see {@link #doPrivileged(PrivilegedAction) doPrivileged} and below).
     116  * When making access control decisions, the {@code checkPermission}
     117  * method stops checking if it reaches a caller that
     118  * was marked as "privileged" via a {@code doPrivileged}
     119  * call without a context argument (see below for information about a
     120  * context argument). If that caller's domain has the
     121  * specified permission and at least one limiting permission argument (if any)
     122  * implies the requested permission, no further checking is done and
     123  * {@code checkPermission}
     124  * returns quietly, indicating that the requested access is allowed.
     125  * If that domain does not have the specified permission, an exception
     126  * is thrown, as usual. If the caller's domain had the specified permission
     127  * but it was not implied by any limiting permission arguments given in the call
     128  * to {@code doPrivileged} then the permission checking continues
     129  * until there are no more callers or another {@code doPrivileged}
     130  * call matches the requested permission and returns normally.
     131  *
     132  * <p> The normal use of the "privileged" feature is as follows. If you
     133  * don't need to return a value from within the "privileged" block, do
     134  * the following:
     135  *
     136  *  <pre> {@code
     137  * somemethod() {
     138  *     ...normal code here...
     139  *     AccessController.doPrivileged(new PrivilegedAction<Void>() {
     140  *         public Void run() {
     141  *             // privileged code goes here, for example:
     142  *             System.loadLibrary("awt");
     143  *             return null; // nothing to return
     144  *         }
     145  *     });
     146  *     ...normal code here...
     147  * }}</pre>
     148  *
     149  * <p>
     150  * PrivilegedAction is an interface with a single method, named
     151  * {@code run}.
     152  * The above example shows creation of an implementation
     153  * of that interface; a concrete implementation of the
     154  * {@code run} method is supplied.
     155  * When the call to {@code doPrivileged} is made, an
     156  * instance of the PrivilegedAction implementation is passed
     157  * to it. The {@code doPrivileged} method calls the
     158  * {@code run} method from the PrivilegedAction
     159  * implementation after enabling privileges, and returns the
     160  * {@code run} method's return value as the
     161  * {@code doPrivileged} return value (which is
     162  * ignored in this example).
     163  *
     164  * <p> If you need to return a value, you can do something like the following:
     165  *
     166  *  <pre> {@code
     167  * somemethod() {
     168  *     ...normal code here...
     169  *     String user = AccessController.doPrivileged(
     170  *         new PrivilegedAction<String>() {
     171  *         public String run() {
     172  *             return System.getProperty("user.name");
     173  *             }
     174  *         });
     175  *     ...normal code here...
     176  * }}</pre>
     177  *
     178  * <p>If the action performed in your {@code run} method could
     179  * throw a "checked" exception (those listed in the {@code throws} clause
     180  * of a method), then you need to use the
     181  * {@code PrivilegedExceptionAction} interface instead of the
     182  * {@code PrivilegedAction} interface:
     183  *
     184  *  <pre> {@code
     185  * somemethod() throws FileNotFoundException {
     186  *     ...normal code here...
     187  *     try {
     188  *         FileInputStream fis = AccessController.doPrivileged(
     189  *         new PrivilegedExceptionAction<FileInputStream>() {
     190  *             public FileInputStream run() throws FileNotFoundException {
     191  *                 return new FileInputStream("someFile");
     192  *             }
     193  *         });
     194  *     } catch (PrivilegedActionException e) {
     195  *         // e.getException() should be an instance of FileNotFoundException,
     196  *         // as only "checked" exceptions will be "wrapped" in a
     197  *         // PrivilegedActionException.
     198  *         throw (FileNotFoundException) e.getException();
     199  *     }
     200  *     ...normal code here...
     201  *  }}</pre>
     202  *
     203  * <p> Be *very* careful in your use of the "privileged" construct, and
     204  * always remember to make the privileged code section as small as possible.
     205  * You can pass {@code Permission} arguments to further limit the
     206  * scope of the "privilege" (see below).
     207  *
     208  *
     209  * <p> Note that {@code checkPermission} always performs security checks
     210  * within the context of the currently executing thread.
     211  * Sometimes a security check that should be made within a given context
     212  * will actually need to be done from within a
     213  * <i>different</i> context (for example, from within a worker thread).
     214  * The {@link #getContext() getContext} method and
     215  * AccessControlContext class are provided
     216  * for this situation. The {@code getContext} method takes a "snapshot"
     217  * of the current calling context, and places
     218  * it in an AccessControlContext object, which it returns. A sample call is
     219  * the following:
     220  *
     221  * <pre>
     222  *
     223  * AccessControlContext acc = AccessController.getContext()
     224  *
     225  * </pre>
     226  *
     227  * <p>
     228  * AccessControlContext itself has a {@code checkPermission} method
     229  * that makes access decisions based on the context <i>it</i> encapsulates,
     230  * rather than that of the current execution thread.
     231  * Code within a different context can thus call that method on the
     232  * previously-saved AccessControlContext object. A sample call is the
     233  * following:
     234  *
     235  * <pre>
     236  *
     237  * acc.checkPermission(permission)
     238  *
     239  * </pre>
     240  *
     241  * <p> There are also times where you don't know a priori which permissions
     242  * to check the context against. In these cases you can use the
     243  * doPrivileged method that takes a context. You can also limit the scope
     244  * of the privileged code by passing additional {@code Permission}
     245  * parameters.
     246  *
     247  *  <pre> {@code
     248  * somemethod() {
     249  *     AccessController.doPrivileged(new PrivilegedAction<Object>() {
     250  *         public Object run() {
     251  *             // Code goes here. Any permission checks within this
     252  *             // run method will require that the intersection of the
     253  *             // caller's protection domain and the snapshot's
     254  *             // context have the desired permission. If a requested
     255  *             // permission is not implied by the limiting FilePermission
     256  *             // argument then checking of the thread continues beyond the
     257  *             // caller of doPrivileged.
     258  *         }
     259  *     }, acc, new FilePermission("/temp/*", read));
     260  *     ...normal code here...
     261  * }}</pre>
     262  * <p> Passing a limiting {@code Permission} argument of an instance of
     263  * {@code AllPermission} is equivalent to calling the equivalent
     264  * {@code doPrivileged} method without limiting {@code Permission}
     265  * arguments. Passing a zero length array of {@code Permission} disables
     266  * the code privileges so that checking always continues beyond the caller of
     267  * that {@code doPrivileged} method.
     268  *
     269  * @see AccessControlContext
     270  *
     271  * @author Li Gong
     272  * @author Roland Schemers
     273  * @since 1.2
     274  * @deprecated This class is only useful in conjunction with
     275  *       {@linkplain SecurityManager the Security Manager}, which is deprecated
     276  *       and subject to removal in a future release. Consequently, this class
     277  *       is also deprecated and subject to removal. There is no replacement for
     278  *       the Security Manager or this class.
     279  */
     280
     281 @Deprecated(since="17", forRemoval=true)
     282 public final class AccessController {
     283
     284     /**
     285      * Don't allow anyone to instantiate an AccessController
     286      */
     287     private AccessController() { }
     288
     289     /**
     290      * Performs the specified {@code PrivilegedAction} with privileges
     291      * enabled. The action is performed with <i>all</i> of the permissions
     292      * possessed by the caller's protection domain.
     293      *
     294      * <p> If the action's {@code run} method throws an (unchecked)
     295      * exception, it will propagate through this method.
     296      *
     297      * <p> Note that any DomainCombiner associated with the current
     298      * AccessControlContext will be ignored while the action is performed.
     299      *
     300      * @param <T> the type of the value returned by the PrivilegedAction's
     301      *                  {@code run} method.
     302      *
     303      * @param action the action to be performed.
     304      *
     305      * @return the value returned by the action's {@code run} method.
     306      *
     307      * @throws    NullPointerException if the action is {@code null}
     308      *
     309      * @see #doPrivileged(PrivilegedAction,AccessControlContext)
     310      * @see #doPrivileged(PrivilegedExceptionAction)
     311      * @see #doPrivilegedWithCombiner(PrivilegedAction)
     312      * @see java.security.DomainCombiner
     313      */
     314
     315     @CallerSensitive
     316     public static <T> T doPrivileged(PrivilegedAction<T> action)
     317     {
     318         return executePrivileged(action, null, Reflection.getCallerClass());
     319     }
     320
     321     /**
     322      * Performs the specified {@code PrivilegedAction} with privileges
     323      * enabled. The action is performed with <i>all</i> of the permissions
     324      * possessed by the caller's protection domain.
     325      *
     326      * <p> If the action's {@code run} method throws an (unchecked)
     327      * exception, it will propagate through this method.
     328      *
     329      * <p> This method preserves the current AccessControlContext's
     330      * DomainCombiner (which may be null) while the action is performed.
     331      *
     332      * @param <T> the type of the value returned by the PrivilegedAction's
     333      *                  {@code run} method.
     334      *
     335      * @param action the action to be performed.
     336      *
     337      * @return the value returned by the action's {@code run} method.
     338      *
     339      * @throws    NullPointerException if the action is {@code null}
     340      *
     341      * @see #doPrivileged(PrivilegedAction)
     342      * @see java.security.DomainCombiner
     343      *
     344      * @since 1.6
     345      */
     346     @CallerSensitive
     347     public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) {
     348         AccessControlContext acc = getStackAccessControlContext();
     349         if (acc == null) {
     350             return AccessController.doPrivileged(action);
     351         }
     352         DomainCombiner dc = acc.getAssignedCombiner();
     353         return AccessController.doPrivileged(action,
     354                                              preserveCombiner(dc, Reflection.getCallerClass()));
     355     }
     356
     357
     358     /**
     359      * Performs the specified {@code PrivilegedAction} with privileges
     360      * enabled and restricted by the specified {@code AccessControlContext}.
     361      * The action is performed with the intersection of the permissions
     362      * possessed by the caller's protection domain, and those possessed
     363      * by the domains represented by the specified {@code AccessControlContext}.
     364      * <p>
     365      * If the action's {@code run} method throws an (unchecked) exception,
     366      * it will propagate through this method.
     367      * <p>
     368      * If a security manager is installed and the specified
     369      * {@code AccessControlContext} was not created by system code and the
     370      * caller's {@code ProtectionDomain} has not been granted the
     371      * {@literal "createAccessControlContext"}
     372      * {@link java.security.SecurityPermission}, then the action is performed
     373      * with no permissions.
     374      *
     375      * @param <T> the type of the value returned by the PrivilegedAction's
     376      *                  {@code run} method.
     377      * @param action the action to be performed.
     378      * @param context an <i>access control context</i>
     379      *                representing the restriction to be applied to the
     380      *                caller's domain's privileges before performing
     381      *                the specified action.  If the context is
     382      *                {@code null}, then no additional restriction is applied.
     383      *
     384      * @return the value returned by the action's {@code run} method.
     385      *
     386      * @throws    NullPointerException if the action is {@code null}
     387      *
     388      * @see #doPrivileged(PrivilegedAction)
     389      * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
     390      */
     391     @CallerSensitive
     392     public static <T> T doPrivileged(PrivilegedAction<T> action,
     393                                      AccessControlContext context)
     394     {
     395         Class<?> caller = Reflection.getCallerClass();
     396         context = checkContext(context, caller);
     397         return executePrivileged(action, context, caller);
     398     }
     399
     400
     401     /**
     402      * Performs the specified {@code PrivilegedAction} with privileges
     403      * enabled and restricted by the specified
     404      * {@code AccessControlContext} and with a privilege scope limited
     405      * by specified {@code Permission} arguments.
     406      *
     407      * The action is performed with the intersection of the permissions
     408      * possessed by the caller's protection domain, and those possessed
     409      * by the domains represented by the specified
     410      * {@code AccessControlContext}.
     411      * <p>
     412      * If the action's {@code run} method throws an (unchecked) exception,
     413      * it will propagate through this method.
     414      * <p>
     415      * If a security manager is installed and the specified
     416      * {@code AccessControlContext} was not created by system code and the
     417      * caller's {@code ProtectionDomain} has not been granted the
     418      * {@literal "createAccessControlContext"}
     419      * {@link java.security.SecurityPermission}, then the action is performed
     420      * with no permissions.
     421      *
     422      * @param <T> the type of the value returned by the PrivilegedAction's
     423      *                  {@code run} method.
     424      * @param action the action to be performed.
     425      * @param context an <i>access control context</i>
     426      *                representing the restriction to be applied to the
     427      *                caller's domain's privileges before performing
     428      *                the specified action.  If the context is
     429      *                {@code null},
     430      *                then no additional restriction is applied.
     431      * @param perms the {@code Permission} arguments which limit the
     432      *              scope of the caller's privileges. The number of arguments
     433      *              is variable.
     434      *
     435      * @return the value returned by the action's {@code run} method.
     436      *
     437      * @throws NullPointerException if action or perms or any element of
     438      *         perms is {@code null}
     439      *
     440      * @see #doPrivileged(PrivilegedAction)
     441      * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
     442      *
     443      * @since 1.8
     444      */
     445     @CallerSensitive
     446     public static <T> T doPrivileged(PrivilegedAction<T> action,
     447         AccessControlContext context, Permission... perms) {
     448
     449         AccessControlContext parent = getContext();
     450         if (perms == null) {
     451             throw new NullPointerException("null permissions parameter");
     452         }
     453         Class<?> caller = Reflection.getCallerClass();
     454         DomainCombiner dc = (context == null) ? null : context.getCombiner();
     455         return AccessController.doPrivileged(action, createWrapper(dc,
     456             caller, parent, context, perms));
     457     }
     458
     459
     460     /**
     461      * Performs the specified {@code PrivilegedAction} with privileges
     462      * enabled and restricted by the specified
     463      * {@code AccessControlContext} and with a privilege scope limited
     464      * by specified {@code Permission} arguments.
     465      *
     466      * The action is performed with the intersection of the permissions
     467      * possessed by the caller's protection domain, and those possessed
     468      * by the domains represented by the specified
     469      * {@code AccessControlContext}.
     470      * <p>
     471      * If the action's {@code run} method throws an (unchecked) exception,
     472      * it will propagate through this method.
     473      *
     474      * <p> This method preserves the current AccessControlContext's
     475      * DomainCombiner (which may be null) while the action is performed.
     476      * <p>
     477      * If a security manager is installed and the specified
     478      * {@code AccessControlContext} was not created by system code and the
     479      * caller's {@code ProtectionDomain} has not been granted the
     480      * {@literal "createAccessControlContext"}
     481      * {@link java.security.SecurityPermission}, then the action is performed
     482      * with no permissions.
     483      *
     484      * @param <T> the type of the value returned by the PrivilegedAction's
     485      *                  {@code run} method.
     486      * @param action the action to be performed.
     487      * @param context an <i>access control context</i>
     488      *                representing the restriction to be applied to the
     489      *                caller's domain's privileges before performing
     490      *                the specified action.  If the context is
     491      *                {@code null},
     492      *                then no additional restriction is applied.
     493      * @param perms the {@code Permission} arguments which limit the
     494      *              scope of the caller's privileges. The number of arguments
     495      *              is variable.
     496      *
     497      * @return the value returned by the action's {@code run} method.
     498      *
     499      * @throws NullPointerException if action or perms or any element of
     500      *         perms is {@code null}
     501      *
     502      * @see #doPrivileged(PrivilegedAction)
     503      * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
     504      * @see java.security.DomainCombiner
     505      *
     506      * @since 1.8
     507      */
     508     @CallerSensitive
     509     public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action,
     510         AccessControlContext context, Permission... perms) {
     511
     512         AccessControlContext parent = getContext();
     513         DomainCombiner dc = parent.getCombiner();
     514         if (dc == null && context != null) {
     515             dc = context.getCombiner();
     516         }
     517         if (perms == null) {
     518             throw new NullPointerException("null permissions parameter");
     519         }
     520         Class<?> caller = Reflection.getCallerClass();
     521         return AccessController.doPrivileged(action, createWrapper(dc, caller,
     522             parent, context, perms));
     523     }
     524
     525     /**
     526      * Performs the specified {@code PrivilegedExceptionAction} with
     527      * privileges enabled.  The action is performed with <i>all</i> of the
     528      * permissions possessed by the caller's protection domain.
     529      *
     530      * <p> If the action's {@code run} method throws an <i>unchecked</i>
     531      * exception, it will propagate through this method.
     532      *
     533      * <p> Note that any DomainCombiner associated with the current
     534      * AccessControlContext will be ignored while the action is performed.
     535      *
     536      * @param <T> the type of the value returned by the
     537      *                  PrivilegedExceptionAction's {@code run} method.
     538      *
     539      * @param action the action to be performed
     540      *
     541      * @return the value returned by the action's {@code run} method
     542      *
     543      * @throws    PrivilegedActionException if the specified action's
     544      *         {@code run} method threw a <i>checked</i> exception
     545      * @throws    NullPointerException if the action is {@code null}
     546      *
     547      * @see #doPrivileged(PrivilegedAction)
     548      * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
     549      * @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)
     550      * @see java.security.DomainCombiner
     551      */
     552     @CallerSensitive
     553     public static <T> T
     554         doPrivileged(PrivilegedExceptionAction<T> action)
     555         throws PrivilegedActionException
     556     {
     557         AccessControlContext context = null;
     558         Class<?> caller = Reflection.getCallerClass();
     559         try {
     560             return executePrivileged(action, context, caller);
     561         } catch (RuntimeException e) {
     562             throw e;
     563         } catch (Exception e) {
     564             throw wrapException(e);
     565         }
     566     }
     567
     568     /**
     569      * Performs the specified {@code PrivilegedExceptionAction} with
     570      * privileges enabled.  The action is performed with <i>all</i> of the
     571      * permissions possessed by the caller's protection domain.
     572      *
     573      * <p> If the action's {@code run} method throws an <i>unchecked</i>
     574      * exception, it will propagate through this method.
     575      *
     576      * <p> This method preserves the current AccessControlContext's
     577      * DomainCombiner (which may be null) while the action is performed.
     578      *
     579      * @param <T> the type of the value returned by the
     580      *                  PrivilegedExceptionAction's {@code run} method.
     581      *
     582      * @param action the action to be performed.
     583      *
     584      * @return the value returned by the action's {@code run} method
     585      *
     586      * @throws    PrivilegedActionException if the specified action's
     587      *         {@code run} method threw a <i>checked</i> exception
     588      * @throws    NullPointerException if the action is {@code null}
     589      *
     590      * @see #doPrivileged(PrivilegedAction)
     591      * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
     592      * @see java.security.DomainCombiner
     593      *
     594      * @since 1.6
     595      */
     596     @CallerSensitive
     597     public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action)
     598         throws PrivilegedActionException
     599     {
     600         AccessControlContext acc = getStackAccessControlContext();
     601         if (acc == null) {
     602             return AccessController.doPrivileged(action);
     603         }
     604         DomainCombiner dc = acc.getAssignedCombiner();
     605         return AccessController.doPrivileged(action,
     606                                              preserveCombiner(dc, Reflection.getCallerClass()));
     607     }
     608
     609     /**
     610      * preserve the combiner across the doPrivileged call
     611      */
     612     private static AccessControlContext preserveCombiner(DomainCombiner combiner,
     613                                                          Class<?> caller)
     614     {
     615         return createWrapper(combiner, caller, null, null, null);
     616     }
     617
     618     /**
     619      * Create a wrapper to contain the limited privilege scope data.
     620      */
     621     private static AccessControlContext
     622         createWrapper(DomainCombiner combiner, Class<?> caller,
     623                       AccessControlContext parent, AccessControlContext context,
     624                       Permission[] perms)
     625     {
     626         ProtectionDomain callerPD = getProtectionDomain(caller);
     627         // check if caller is authorized to create context
     628         if (System.getSecurityManager() != null &&
     629             context != null && !context.isAuthorized() &&
     630             !callerPD.implies(SecurityConstants.CREATE_ACC_PERMISSION))
     631         {
     632             return getInnocuousAcc();
     633         } else {
     634             return new AccessControlContext(callerPD, combiner, parent,
     635                                             context, perms);
     636         }
     637     }
     638
     639     private static class AccHolder {
     640         // An AccessControlContext with no granted permissions.
     641         // Only initialized on demand when getInnocuousAcc() is called.
     642         static final AccessControlContext innocuousAcc =
     643             new AccessControlContext(new ProtectionDomain[] {
     644                                      new ProtectionDomain(null, null) });
     645     }
     646     private static AccessControlContext getInnocuousAcc() {
     647         return AccHolder.innocuousAcc;
     648     }
     649
     650     private static native ProtectionDomain getProtectionDomain(final Class<?> caller);
     651
     652     /**
     653      * Performs the specified {@code PrivilegedExceptionAction} with
     654      * privileges enabled and restricted by the specified
     655      * {@code AccessControlContext}.  The action is performed with the
     656      * intersection of the permissions possessed by the caller's
     657      * protection domain, and those possessed by the domains represented by the
     658      * specified {@code AccessControlContext}.
     659      * <p>
     660      * If the action's {@code run} method throws an <i>unchecked</i>
     661      * exception, it will propagate through this method.
     662      * <p>
     663      * If a security manager is installed and the specified
     664      * {@code AccessControlContext} was not created by system code and the
     665      * caller's {@code ProtectionDomain} has not been granted the
     666      * {@literal "createAccessControlContext"}
     667      * {@link java.security.SecurityPermission}, then the action is performed
     668      * with no permissions.
     669      *
     670      * @param <T> the type of the value returned by the
     671      *                  PrivilegedExceptionAction's {@code run} method.
     672      * @param action the action to be performed
     673      * @param context an <i>access control context</i>
     674      *                representing the restriction to be applied to the
     675      *                caller's domain's privileges before performing
     676      *                the specified action.  If the context is
     677      *                {@code null}, then no additional restriction is applied.
     678      *
     679      * @return the value returned by the action's {@code run} method
     680      *
     681      * @throws    PrivilegedActionException if the specified action's
     682      *         {@code run} method threw a <i>checked</i> exception
     683      * @throws    NullPointerException if the action is {@code null}
     684      *
     685      * @see #doPrivileged(PrivilegedAction)
     686      * @see #doPrivileged(PrivilegedAction,AccessControlContext)
     687      */
     688     @CallerSensitive
     689     public static <T> T
     690         doPrivileged(PrivilegedExceptionAction<T> action,
     691                      AccessControlContext context)
     692         throws PrivilegedActionException
     693     {
     694         Class<?> caller = Reflection.getCallerClass();
     695         context = checkContext(context, caller);
     696         try {
     697             return executePrivileged(action, context, caller);
     698         } catch (RuntimeException e) {
     699             throw e;
     700         } catch (Exception e) {
     701             throw wrapException(e);
     702         }
     703     }
     704
     705     private static AccessControlContext checkContext(AccessControlContext context,
     706         Class<?> caller)
     707     {
     708         // check if caller is authorized to create context
     709         if (System.getSecurityManager() != null &&
     710             context != null && !context.isAuthorized() &&
     711             context != getInnocuousAcc())
     712         {
     713             ProtectionDomain callerPD = getProtectionDomain(caller);
     714             if (callerPD != null && !callerPD.implies(SecurityConstants.CREATE_ACC_PERMISSION)) {
     715                 return getInnocuousAcc();
     716             }
     717         }
     718         return context;
     719     }
     720
     721     /**
     722      * The value needs to be physically located in the frame, so that it
     723      * can be found by a stack walk.
     724      */
     725     @Hidden
     726     private static native void ensureMaterializedForStackWalk(Object o);
     727
     728     /**
     729      * Sanity check that the caller context is indeed privileged.
     730      *
     731      * Used by executePrivileged to make sure the frame is properly
     732      * recognized by the VM.
     733      */
     734     private static boolean isPrivileged() {
     735         AccessControlContext ctx = getStackAccessControlContext();
     736         return ctx == null || ctx.isPrivileged();
     737     }
     738
     739     /**
     740      * Execute the action as privileged.
     741      *
     742      * The VM recognizes this method as special, so any changes to the
     743      * name or signature require corresponding changes in
     744      * getStackAccessControlContext().
     745      */
     746     @Hidden
     747     @ForceInline
     748     private static <T> T
     749         executePrivileged(PrivilegedAction<T> action,
     750                           AccessControlContext context,
     751                           Class<?> caller)
     752     {
     753         // Ensure context has a physical value in the frame
     754         if (context != null) {
     755             ensureMaterializedForStackWalk(context);
     756         }
     757
     758         assert isPrivileged(); // sanity check invariant
     759         T result = action.run();
     760         assert isPrivileged(); // sanity check invariant
     761
     762         // Keep these alive across the run() call so they can be
     763         // retrieved by getStackAccessControlContext().
     764         Reference.reachabilityFence(context);
     765         Reference.reachabilityFence(caller);
     766         return result;
     767     }
     768
     769     /**
     770      * Execute the action as privileged.
     771      *
     772      * The VM recognizes this method as special, so any changes to the
     773      * name or signature require corresponding changes in
     774      * getStackAccessControlContext().
     775      */
     776     @Hidden
     777     @ForceInline
     778     private static <T> T
     779         executePrivileged(PrivilegedExceptionAction<T> action,
     780                           AccessControlContext context,
     781                           Class<?> caller)
     782         throws Exception
     783     {
     784         // Ensure context has a physical value in the frame
     785         if (context != null) {
     786             ensureMaterializedForStackWalk(context);
     787         }
     788
     789         assert isPrivileged(); // sanity check invariant
     790         T result = action.run();
     791         assert isPrivileged(); // sanity check invariant
     792
     793         // Keep these alive across the run() call so they can be
     794         // retrieved by getStackAccessControlContext().
     795         Reference.reachabilityFence(context);
     796         Reference.reachabilityFence(caller);
     797         return result;
     798     }
     799
     800
     801     /**
     802      * Wrap an exception.  The annotations are used in a best effort to
     803      * avoid StackOverflowError in the caller.  Inlining the callees as
     804      * well and tail-call elimination could also help here, but are not
     805      * needed for correctness, only quality of implementation.
     806      */
     807     @Hidden
     808     @ForceInline
     809     @ReservedStackAccess
     810     private static PrivilegedActionException wrapException(Exception e) {
     811         return new PrivilegedActionException(e);
     812     }
     813
     814     /**
     815      * Performs the specified {@code PrivilegedExceptionAction} with
     816      * privileges enabled and restricted by the specified
     817      * {@code AccessControlContext} and with a privilege scope limited by
     818      * specified {@code Permission} arguments.
     819      *
     820      * The action is performed with the intersection of the permissions
     821      * possessed by the caller's protection domain, and those possessed
     822      * by the domains represented by the specified
     823      * {@code AccessControlContext}.
     824      * <p>
     825      * If the action's {@code run} method throws an (unchecked) exception,
     826      * it will propagate through this method.
     827      * <p>
     828      * If a security manager is installed and the specified
     829      * {@code AccessControlContext} was not created by system code and the
     830      * caller's {@code ProtectionDomain} has not been granted the
     831      * {@literal "createAccessControlContext"}
     832      * {@link java.security.SecurityPermission}, then the action is performed
     833      * with no permissions.
     834      *
     835      * @param <T> the type of the value returned by the
     836      *                  PrivilegedExceptionAction's {@code run} method.
     837      * @param action the action to be performed.
     838      * @param context an <i>access control context</i>
     839      *                representing the restriction to be applied to the
     840      *                caller's domain's privileges before performing
     841      *                the specified action.  If the context is
     842      *                {@code null},
     843      *                then no additional restriction is applied.
     844      * @param perms the {@code Permission} arguments which limit the
     845      *              scope of the caller's privileges. The number of arguments
     846      *              is variable.
     847      *
     848      * @return the value returned by the action's {@code run} method.
     849      *
     850      * @throws PrivilegedActionException if the specified action's
     851      *         {@code run} method threw a <i>checked</i> exception
     852      * @throws NullPointerException if action or perms or any element of
     853      *         perms is {@code null}
     854      *
     855      * @see #doPrivileged(PrivilegedAction)
     856      * @see #doPrivileged(PrivilegedAction,AccessControlContext)
     857      *
     858      * @since 1.8
     859      */
     860     @CallerSensitive
     861     public static <T> T doPrivileged(PrivilegedExceptionAction<T> action,
     862                                      AccessControlContext context, Permission... perms)
     863         throws PrivilegedActionException
     864     {
     865         AccessControlContext parent = getContext();
     866         if (perms == null) {
     867             throw new NullPointerException("null permissions parameter");
     868         }
     869         Class<?> caller = Reflection.getCallerClass();
     870         DomainCombiner dc = (context == null) ? null : context.getCombiner();
     871         return AccessController.doPrivileged(action, createWrapper(dc, caller, parent, context, perms));
     872     }
     873
     874
     875     /**
     876      * Performs the specified {@code PrivilegedExceptionAction} with
     877      * privileges enabled and restricted by the specified
     878      * {@code AccessControlContext} and with a privilege scope limited by
     879      * specified {@code Permission} arguments.
     880      *
     881      * The action is performed with the intersection of the permissions
     882      * possessed by the caller's protection domain, and those possessed
     883      * by the domains represented by the specified
     884      * {@code AccessControlContext}.
     885      * <p>
     886      * If the action's {@code run} method throws an (unchecked) exception,
     887      * it will propagate through this method.
     888      *
     889      * <p> This method preserves the current AccessControlContext's
     890      * DomainCombiner (which may be null) while the action is performed.
     891      * <p>
     892      * If a security manager is installed and the specified
     893      * {@code AccessControlContext} was not created by system code and the
     894      * caller's {@code ProtectionDomain} has not been granted the
     895      * {@literal "createAccessControlContext"}
     896      * {@link java.security.SecurityPermission}, then the action is performed
     897      * with no permissions.
     898      *
     899      * @param <T> the type of the value returned by the
     900      *                  PrivilegedExceptionAction's {@code run} method.
     901      * @param action the action to be performed.
     902      * @param context an <i>access control context</i>
     903      *                representing the restriction to be applied to the
     904      *                caller's domain's privileges before performing
     905      *                the specified action.  If the context is
     906      *                {@code null},
     907      *                then no additional restriction is applied.
     908      * @param perms the {@code Permission} arguments which limit the
     909      *              scope of the caller's privileges. The number of arguments
     910      *              is variable.
     911      *
     912      * @return the value returned by the action's {@code run} method.
     913      *
     914      * @throws PrivilegedActionException if the specified action's
     915      *         {@code run} method threw a <i>checked</i> exception
     916      * @throws NullPointerException if action or perms or any element of
     917      *         perms is {@code null}
     918      *
     919      * @see #doPrivileged(PrivilegedAction)
     920      * @see #doPrivileged(PrivilegedAction,AccessControlContext)
     921      * @see java.security.DomainCombiner
     922      *
     923      * @since 1.8
     924      */
     925     @CallerSensitive
     926     public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action,
     927                                                  AccessControlContext context,
     928                                                  Permission... perms)
     929         throws PrivilegedActionException
     930     {
     931         AccessControlContext parent = getContext();
     932         DomainCombiner dc = parent.getCombiner();
     933         if (dc == null && context != null) {
     934             dc = context.getCombiner();
     935         }
     936         if (perms == null) {
     937             throw new NullPointerException("null permissions parameter");
     938         }
     939         Class<?> caller = Reflection.getCallerClass();
     940         return AccessController.doPrivileged(action, createWrapper(dc, caller,
     941             parent, context, perms));
     942     }
     943
     944     /**
     945      * Returns the AccessControl context. i.e., it gets
     946      * the protection domains of all the callers on the stack,
     947      * starting at the first class with a non-null
     948      * ProtectionDomain.
     949      *
     950      * @return the access control context based on the current stack or
     951      *         null if there was only privileged system code.
     952      */
     953
     954     private static native AccessControlContext getStackAccessControlContext();
     955
     956
     957     /**
     958      * Returns the "inherited" AccessControl context. This is the context
     959      * that existed when the thread was created. Package private so
     960      * AccessControlContext can use it.
     961      */
     962
     963     static native AccessControlContext getInheritedAccessControlContext();
     964
     965     /**
     966      * This method takes a "snapshot" of the current calling context, which
     967      * includes the current Thread's inherited AccessControlContext and any
     968      * limited privilege scope, and places it in an AccessControlContext object.
     969      * This context may then be checked at a later point, possibly in another thread.
     970      *
     971      * @see AccessControlContext
     972      *
     973      * @return the AccessControlContext based on the current context.
     974      */
     975
     976     public static AccessControlContext getContext()
     977     {
     978         AccessControlContext acc = getStackAccessControlContext();
     979         if (acc == null) {
     980             // all we had was privileged system code. We don't want
     981             // to return null though, so we construct a real ACC.
     982             return new AccessControlContext(null, true);
     983         } else {
     984             return acc.optimize();
     985         }
     986     }
     987
     988     /**
     989      * Determines whether the access request indicated by the
     990      * specified permission should be allowed or denied, based on
     991      * the current AccessControlContext and security policy.
     992      * This method quietly returns if the access request
     993      * is permitted, or throws an AccessControlException otherwise. The
     994      * getPermission method of the AccessControlException returns the
     995      * {@code perm} Permission object instance.
     996      *
     997      * @param perm the requested permission.
     998      *
     999      * @throws    AccessControlException if the specified permission
    1000      *            is not permitted, based on the current security policy.
    1001      * @throws    NullPointerException if the specified permission
    1002      *            is {@code null} and is checked based on the
    1003      *            security policy currently in effect.
    1004      */
    1005
    1006     public static void checkPermission(Permission perm)
    1007         throws AccessControlException
    1008     {
    1009         //System.err.println("checkPermission "+perm);
    1010         //Thread.currentThread().dumpStack();
    1011
    1012         if (perm == null) {
    1013             throw new NullPointerException("permission can't be null");
    1014         }
    1015
    1016         AccessControlContext stack = getStackAccessControlContext();
    1017         // if context is null, we had privileged system code on the stack.
    1018         if (stack == null) {
    1019             Debug debug = AccessControlContext.getDebug();
    1020             boolean dumpDebug = false;
    1021             if (debug != null) {
    1022                 dumpDebug = !Debug.isOn("codebase=");
    1023                 dumpDebug &= !Debug.isOn("permission=") ||
    1024                     Debug.isOn("permission=" + perm.getClass().getCanonicalName());
    1025             }
    1026
    1027             if (dumpDebug && Debug.isOn("stack")) {
    1028                 Thread.dumpStack();
    1029             }
    1030
    1031             if (dumpDebug && Debug.isOn("domain")) {
    1032                 debug.println("domain (context is null)");
    1033             }
    1034
    1035             if (dumpDebug) {
    1036                 debug.println("access allowed "+perm);
    1037             }
    1038             return;
    1039         }
    1040
    1041         AccessControlContext acc = stack.optimize();
    1042         acc.checkPermission(perm);
    1043     }
    1044 }