       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  */
     275
     276 public final class AccessController {
     277
     278     /**
     279      * Don't allow anyone to instantiate an AccessController
     280      */
     281     private AccessController() { }
     282
     283     /**
     284      * Performs the specified {@code PrivilegedAction} with privileges
     285      * enabled. The action is performed with <i>all</i> of the permissions
     286      * possessed by the caller's protection domain.
     287      *
     288      * <p> If the action's {@code run} method throws an (unchecked)
     289      * exception, it will propagate through this method.
     290      *
     291      * <p> Note that any DomainCombiner associated with the current
     292      * AccessControlContext will be ignored while the action is performed.
     293      *
     294      * @param <T> the type of the value returned by the PrivilegedAction's
     295      *                  {@code run} method.
     296      *
     297      * @param action the action to be performed.
     298      *
     299      * @return the value returned by the action's {@code run} method.
     300      *
     301      * @throws    NullPointerException if the action is {@code null}
     302      *
     303      * @see #doPrivileged(PrivilegedAction,AccessControlContext)
     304      * @see #doPrivileged(PrivilegedExceptionAction)
     305      * @see #doPrivilegedWithCombiner(PrivilegedAction)
     306      * @see java.security.DomainCombiner
     307      */
     308
     309     @CallerSensitive
     310     public static <T> T doPrivileged(PrivilegedAction<T> action)
     311     {
     312         return executePrivileged(action, null, Reflection.getCallerClass());
     313     }
     314
     315     /**
     316      * Performs the specified {@code PrivilegedAction} with privileges
     317      * enabled. The action is performed with <i>all</i> of the permissions
     318      * possessed by the caller's protection domain.
     319      *
     320      * <p> If the action's {@code run} method throws an (unchecked)
     321      * exception, it will propagate through this method.
     322      *
     323      * <p> This method preserves the current AccessControlContext's
     324      * DomainCombiner (which may be null) while the action is performed.
     325      *
     326      * @param <T> the type of the value returned by the PrivilegedAction's
     327      *                  {@code run} method.
     328      *
     329      * @param action the action to be performed.
     330      *
     331      * @return the value returned by the action's {@code run} method.
     332      *
     333      * @throws    NullPointerException if the action is {@code null}
     334      *
     335      * @see #doPrivileged(PrivilegedAction)
     336      * @see java.security.DomainCombiner
     337      *
     338      * @since 1.6
     339      */
     340     @CallerSensitive
     341     public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) {
     342         AccessControlContext acc = getStackAccessControlContext();
     343         if (acc == null) {
     344             return AccessController.doPrivileged(action);
     345         }
     346         DomainCombiner dc = acc.getAssignedCombiner();
     347         return AccessController.doPrivileged(action,
     348                                              preserveCombiner(dc, Reflection.getCallerClass()));
     349     }
     350
     351
     352     /**
     353      * Performs the specified {@code PrivilegedAction} with privileges
     354      * enabled and restricted by the specified {@code AccessControlContext}.
     355      * The action is performed with the intersection of the permissions
     356      * possessed by the caller's protection domain, and those possessed
     357      * by the domains represented by the specified {@code AccessControlContext}.
     358      * <p>
     359      * If the action's {@code run} method throws an (unchecked) exception,
     360      * it will propagate through this method.
     361      * <p>
     362      * If a security manager is installed and the specified
     363      * {@code AccessControlContext} was not created by system code and the
     364      * caller's {@code ProtectionDomain} has not been granted the
     365      * {@literal "createAccessControlContext"}
     366      * {@link java.security.SecurityPermission}, then the action is performed
     367      * with no permissions.
     368      *
     369      * @param <T> the type of the value returned by the PrivilegedAction's
     370      *                  {@code run} method.
     371      * @param action the action to be performed.
     372      * @param context an <i>access control context</i>
     373      *                representing the restriction to be applied to the
     374      *                caller's domain's privileges before performing
     375      *                the specified action.  If the context is
     376      *                {@code null}, then no additional restriction is applied.
     377      *
     378      * @return the value returned by the action's {@code run} method.
     379      *
     380      * @throws    NullPointerException if the action is {@code null}
     381      *
     382      * @see #doPrivileged(PrivilegedAction)
     383      * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
     384      */
     385     @CallerSensitive
     386     public static <T> T doPrivileged(PrivilegedAction<T> action,
     387                                      AccessControlContext context)
     388     {
     389         Class<?> caller = Reflection.getCallerClass();
     390         context = checkContext(context, caller);
     391         return executePrivileged(action, context, caller);
     392     }
     393
     394
     395     /**
     396      * Performs the specified {@code PrivilegedAction} with privileges
     397      * enabled and restricted by the specified
     398      * {@code AccessControlContext} and with a privilege scope limited
     399      * by specified {@code Permission} arguments.
     400      *
     401      * The action is performed with the intersection of the permissions
     402      * possessed by the caller's protection domain, and those possessed
     403      * by the domains represented by the specified
     404      * {@code AccessControlContext}.
     405      * <p>
     406      * If the action's {@code run} method throws an (unchecked) exception,
     407      * it will propagate through this method.
     408      * <p>
     409      * If a security manager is installed and the specified
     410      * {@code AccessControlContext} was not created by system code and the
     411      * caller's {@code ProtectionDomain} has not been granted the
     412      * {@literal "createAccessControlContext"}
     413      * {@link java.security.SecurityPermission}, then the action is performed
     414      * with no permissions.
     415      *
     416      * @param <T> the type of the value returned by the PrivilegedAction's
     417      *                  {@code run} method.
     418      * @param action the action to be performed.
     419      * @param context an <i>access control context</i>
     420      *                representing the restriction to be applied to the
     421      *                caller's domain's privileges before performing
     422      *                the specified action.  If the context is
     423      *                {@code null},
     424      *                then no additional restriction is applied.
     425      * @param perms the {@code Permission} arguments which limit the
     426      *              scope of the caller's privileges. The number of arguments
     427      *              is variable.
     428      *
     429      * @return the value returned by the action's {@code run} method.
     430      *
     431      * @throws NullPointerException if action or perms or any element of
     432      *         perms is {@code null}
     433      *
     434      * @see #doPrivileged(PrivilegedAction)
     435      * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
     436      *
     437      * @since 1.8
     438      */
     439     @CallerSensitive
     440     public static <T> T doPrivileged(PrivilegedAction<T> action,
     441         AccessControlContext context, Permission... perms) {
     442
     443         AccessControlContext parent = getContext();
     444         if (perms == null) {
     445             throw new NullPointerException("null permissions parameter");
     446         }
     447         Class<?> caller = Reflection.getCallerClass();
     448         DomainCombiner dc = (context == null) ? null : context.getCombiner();
     449         return AccessController.doPrivileged(action, createWrapper(dc,
     450             caller, parent, context, perms));
     451     }
     452
     453
     454     /**
     455      * Performs the specified {@code PrivilegedAction} with privileges
     456      * enabled and restricted by the specified
     457      * {@code AccessControlContext} and with a privilege scope limited
     458      * by specified {@code Permission} arguments.
     459      *
     460      * The action is performed with the intersection of the permissions
     461      * possessed by the caller's protection domain, and those possessed
     462      * by the domains represented by the specified
     463      * {@code AccessControlContext}.
     464      * <p>
     465      * If the action's {@code run} method throws an (unchecked) exception,
     466      * it will propagate through this method.
     467      *
     468      * <p> This method preserves the current AccessControlContext's
     469      * DomainCombiner (which may be null) while the action is performed.
     470      * <p>
     471      * If a security manager is installed and the specified
     472      * {@code AccessControlContext} was not created by system code and the
     473      * caller's {@code ProtectionDomain} has not been granted the
     474      * {@literal "createAccessControlContext"}
     475      * {@link java.security.SecurityPermission}, then the action is performed
     476      * with no permissions.
     477      *
     478      * @param <T> the type of the value returned by the PrivilegedAction's
     479      *                  {@code run} method.
     480      * @param action the action to be performed.
     481      * @param context an <i>access control context</i>
     482      *                representing the restriction to be applied to the
     483      *                caller's domain's privileges before performing
     484      *                the specified action.  If the context is
     485      *                {@code null},
     486      *                then no additional restriction is applied.
     487      * @param perms the {@code Permission} arguments which limit the
     488      *              scope of the caller's privileges. The number of arguments
     489      *              is variable.
     490      *
     491      * @return the value returned by the action's {@code run} method.
     492      *
     493      * @throws NullPointerException if action or perms or any element of
     494      *         perms is {@code null}
     495      *
     496      * @see #doPrivileged(PrivilegedAction)
     497      * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
     498      * @see java.security.DomainCombiner
     499      *
     500      * @since 1.8
     501      */
     502     @CallerSensitive
     503     public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action,
     504         AccessControlContext context, Permission... perms) {
     505
     506         AccessControlContext parent = getContext();
     507         DomainCombiner dc = parent.getCombiner();
     508         if (dc == null && context != null) {
     509             dc = context.getCombiner();
     510         }
     511         if (perms == null) {
     512             throw new NullPointerException("null permissions parameter");
     513         }
     514         Class<?> caller = Reflection.getCallerClass();
     515         return AccessController.doPrivileged(action, createWrapper(dc, caller,
     516             parent, context, perms));
     517     }
     518
     519     /**
     520      * Performs the specified {@code PrivilegedExceptionAction} with
     521      * privileges enabled.  The action is performed with <i>all</i> of the
     522      * permissions possessed by the caller's protection domain.
     523      *
     524      * <p> If the action's {@code run} method throws an <i>unchecked</i>
     525      * exception, it will propagate through this method.
     526      *
     527      * <p> Note that any DomainCombiner associated with the current
     528      * AccessControlContext will be ignored while the action is performed.
     529      *
     530      * @param <T> the type of the value returned by the
     531      *                  PrivilegedExceptionAction's {@code run} method.
     532      *
     533      * @param action the action to be performed
     534      *
     535      * @return the value returned by the action's {@code run} method
     536      *
     537      * @throws    PrivilegedActionException if the specified action's
     538      *         {@code run} method threw a <i>checked</i> exception
     539      * @throws    NullPointerException if the action is {@code null}
     540      *
     541      * @see #doPrivileged(PrivilegedAction)
     542      * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
     543      * @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)
     544      * @see java.security.DomainCombiner
     545      */
     546     @CallerSensitive
     547     public static <T> T
     548         doPrivileged(PrivilegedExceptionAction<T> action)
     549         throws PrivilegedActionException
     550     {
     551         AccessControlContext context = null;
     552         Class<?> caller = Reflection.getCallerClass();
     553         try {
     554             return executePrivileged(action, context, caller);
     555         } catch (RuntimeException e) {
     556             throw e;
     557         } catch (Exception e) {
     558             throw wrapException(e);
     559         }
     560     }
     561
     562     /**
     563      * Performs the specified {@code PrivilegedExceptionAction} with
     564      * privileges enabled.  The action is performed with <i>all</i> of the
     565      * permissions possessed by the caller's protection domain.
     566      *
     567      * <p> If the action's {@code run} method throws an <i>unchecked</i>
     568      * exception, it will propagate through this method.
     569      *
     570      * <p> This method preserves the current AccessControlContext's
     571      * DomainCombiner (which may be null) while the action is performed.
     572      *
     573      * @param <T> the type of the value returned by the
     574      *                  PrivilegedExceptionAction's {@code run} method.
     575      *
     576      * @param action the action to be performed.
     577      *
     578      * @return the value returned by the action's {@code run} method
     579      *
     580      * @throws    PrivilegedActionException if the specified action's
     581      *         {@code run} method threw a <i>checked</i> exception
     582      * @throws    NullPointerException if the action is {@code null}
     583      *
     584      * @see #doPrivileged(PrivilegedAction)
     585      * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
     586      * @see java.security.DomainCombiner
     587      *
     588      * @since 1.6
     589      */
     590     @CallerSensitive
     591     public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action)
     592         throws PrivilegedActionException
     593     {
     594         AccessControlContext acc = getStackAccessControlContext();
     595         if (acc == null) {
     596             return AccessController.doPrivileged(action);
     597         }
     598         DomainCombiner dc = acc.getAssignedCombiner();
     599         return AccessController.doPrivileged(action,
     600                                              preserveCombiner(dc, Reflection.getCallerClass()));
     601     }
     602
     603     /**
     604      * preserve the combiner across the doPrivileged call
     605      */
     606     private static AccessControlContext preserveCombiner(DomainCombiner combiner,
     607                                                          Class<?> caller)
     608     {
     609         return createWrapper(combiner, caller, null, null, null);
     610     }
     611
     612     /**
     613      * Create a wrapper to contain the limited privilege scope data.
     614      */
     615     private static AccessControlContext
     616         createWrapper(DomainCombiner combiner, Class<?> caller,
     617                       AccessControlContext parent, AccessControlContext context,
     618                       Permission[] perms)
     619     {
     620         ProtectionDomain callerPD = getProtectionDomain(caller);
     621         // check if caller is authorized to create context
     622         if (System.getSecurityManager() != null &&
     623             context != null && !context.isAuthorized() &&
     624             !callerPD.implies(SecurityConstants.CREATE_ACC_PERMISSION))
     625         {
     626             return getInnocuousAcc();
     627         } else {
     628             return new AccessControlContext(callerPD, combiner, parent,
     629                                             context, perms);
     630         }
     631     }
     632
     633     private static class AccHolder {
     634         // An AccessControlContext with no granted permissions.
     635         // Only initialized on demand when getInnocuousAcc() is called.
     636         static final AccessControlContext innocuousAcc =
     637             new AccessControlContext(new ProtectionDomain[] {
     638                                      new ProtectionDomain(null, null) });
     639     }
     640     private static AccessControlContext getInnocuousAcc() {
     641         return AccHolder.innocuousAcc;
     642     }
     643
     644     private static native ProtectionDomain getProtectionDomain(final Class<?> caller);
     645
     646     /**
     647      * Performs the specified {@code PrivilegedExceptionAction} with
     648      * privileges enabled and restricted by the specified
     649      * {@code AccessControlContext}.  The action is performed with the
     650      * intersection of the permissions possessed by the caller's
     651      * protection domain, and those possessed by the domains represented by the
     652      * specified {@code AccessControlContext}.
     653      * <p>
     654      * If the action's {@code run} method throws an <i>unchecked</i>
     655      * exception, it will propagate through this method.
     656      * <p>
     657      * If a security manager is installed and the specified
     658      * {@code AccessControlContext} was not created by system code and the
     659      * caller's {@code ProtectionDomain} has not been granted the
     660      * {@literal "createAccessControlContext"}
     661      * {@link java.security.SecurityPermission}, then the action is performed
     662      * with no permissions.
     663      *
     664      * @param <T> the type of the value returned by the
     665      *                  PrivilegedExceptionAction's {@code run} method.
     666      * @param action the action to be performed
     667      * @param context an <i>access control context</i>
     668      *                representing the restriction to be applied to the
     669      *                caller's domain's privileges before performing
     670      *                the specified action.  If the context is
     671      *                {@code null}, then no additional restriction is applied.
     672      *
     673      * @return the value returned by the action's {@code run} method
     674      *
     675      * @throws    PrivilegedActionException if the specified action's
     676      *         {@code run} method threw a <i>checked</i> exception
     677      * @throws    NullPointerException if the action is {@code null}
     678      *
     679      * @see #doPrivileged(PrivilegedAction)
     680      * @see #doPrivileged(PrivilegedAction,AccessControlContext)
     681      */
     682     @CallerSensitive
     683     public static <T> T
     684         doPrivileged(PrivilegedExceptionAction<T> action,
     685                      AccessControlContext context)
     686         throws PrivilegedActionException
     687     {
     688         Class<?> caller = Reflection.getCallerClass();
     689         context = checkContext(context, caller);
     690         try {
     691             return executePrivileged(action, context, caller);
     692         } catch (RuntimeException e) {
     693             throw e;
     694         } catch (Exception e) {
     695             throw wrapException(e);
     696         }
     697     }
     698
     699     private static AccessControlContext checkContext(AccessControlContext context,
     700         Class<?> caller)
     701     {
     702         // check if caller is authorized to create context
     703         if (System.getSecurityManager() != null &&
     704             context != null && !context.isAuthorized() &&
     705             context != getInnocuousAcc())
     706         {
     707             ProtectionDomain callerPD = getProtectionDomain(caller);
     708             if (callerPD != null && !callerPD.implies(SecurityConstants.CREATE_ACC_PERMISSION)) {
     709                 return getInnocuousAcc();
     710             }
     711         }
     712         return context;
     713     }
     714
     715     /**
     716      * The value needs to be physically located in the frame, so that it
     717      * can be found by a stack walk.
     718      */
     719     @Hidden
     720     private static native void ensureMaterializedForStackWalk(Object o);
     721
     722     /**
     723      * Sanity check that the caller context is indeed privileged.
     724      *
     725      * Used by executePrivileged to make sure the frame is properly
     726      * recognized by the VM.
     727      */
     728     private static boolean isPrivileged() {
     729         AccessControlContext ctx = getStackAccessControlContext();
     730         return ctx == null || ctx.isPrivileged();
     731     }
     732
     733     /**
     734      * Execute the action as privileged.
     735      *
     736      * The VM recognizes this method as special, so any changes to the
     737      * name or signature require corresponding changes in
     738      * getStackAccessControlContext().
     739      */
     740     @Hidden
     741     @ForceInline
     742     private static <T> T
     743         executePrivileged(PrivilegedAction<T> action,
     744                           AccessControlContext context,
     745                           Class<?> caller)
     746     {
     747         // Ensure context has a physical value in the frame
     748         if (context != null) {
     749             ensureMaterializedForStackWalk(context);
     750         }
     751
     752         assert isPrivileged(); // sanity check invariant
     753         T result = action.run();
     754         assert isPrivileged(); // sanity check invariant
     755
     756         // Keep these alive across the run() call so they can be
     757         // retrieved by getStackAccessControlContext().
     758         Reference.reachabilityFence(context);
     759         Reference.reachabilityFence(caller);
     760         return result;
     761     }
     762
     763     /**
     764      * Execute the action as privileged.
     765      *
     766      * The VM recognizes this method as special, so any changes to the
     767      * name or signature require corresponding changes in
     768      * getStackAccessControlContext().
     769      */
     770     @Hidden
     771     @ForceInline
     772     private static <T> T
     773         executePrivileged(PrivilegedExceptionAction<T> action,
     774                           AccessControlContext context,
     775                           Class<?> caller)
     776         throws Exception
     777     {
     778         // Ensure context has a physical value in the frame
     779         if (context != null) {
     780             ensureMaterializedForStackWalk(context);
     781         }
     782
     783         assert isPrivileged(); // sanity check invariant
     784         T result = action.run();
     785         assert isPrivileged(); // sanity check invariant
     786
     787         // Keep these alive across the run() call so they can be
     788         // retrieved by getStackAccessControlContext().
     789         Reference.reachabilityFence(context);
     790         Reference.reachabilityFence(caller);
     791         return result;
     792     }
     793
     794
     795     /**
     796      * Wrap an exception.  The annotations are used in a best effort to
     797      * avoid StackOverflowError in the caller.  Inlining the callees as
     798      * well and tail-call elimination could also help here, but are not
     799      * needed for correctness, only quality of implementation.
     800      */
     801     @Hidden
     802     @ForceInline
     803     @ReservedStackAccess
     804     private static PrivilegedActionException wrapException(Exception e) {
     805         return new PrivilegedActionException(e);
     806     }
     807
     808     /**
     809      * Performs the specified {@code PrivilegedExceptionAction} with
     810      * privileges enabled and restricted by the specified
     811      * {@code AccessControlContext} and with a privilege scope limited by
     812      * specified {@code Permission} arguments.
     813      *
     814      * The action is performed with the intersection of the permissions
     815      * possessed by the caller's protection domain, and those possessed
     816      * by the domains represented by the specified
     817      * {@code AccessControlContext}.
     818      * <p>
     819      * If the action's {@code run} method throws an (unchecked) exception,
     820      * it will propagate through this method.
     821      * <p>
     822      * If a security manager is installed and the specified
     823      * {@code AccessControlContext} was not created by system code and the
     824      * caller's {@code ProtectionDomain} has not been granted the
     825      * {@literal "createAccessControlContext"}
     826      * {@link java.security.SecurityPermission}, then the action is performed
     827      * with no permissions.
     828      *
     829      * @param <T> the type of the value returned by the
     830      *                  PrivilegedExceptionAction's {@code run} method.
     831      * @param action the action to be performed.
     832      * @param context an <i>access control context</i>
     833      *                representing the restriction to be applied to the
     834      *                caller's domain's privileges before performing
     835      *                the specified action.  If the context is
     836      *                {@code null},
     837      *                then no additional restriction is applied.
     838      * @param perms the {@code Permission} arguments which limit the
     839      *              scope of the caller's privileges. The number of arguments
     840      *              is variable.
     841      *
     842      * @return the value returned by the action's {@code run} method.
     843      *
     844      * @throws PrivilegedActionException if the specified action's
     845      *         {@code run} method threw a <i>checked</i> exception
     846      * @throws NullPointerException if action or perms or any element of
     847      *         perms is {@code null}
     848      *
     849      * @see #doPrivileged(PrivilegedAction)
     850      * @see #doPrivileged(PrivilegedAction,AccessControlContext)
     851      *
     852      * @since 1.8
     853      */
     854     @CallerSensitive
     855     public static <T> T doPrivileged(PrivilegedExceptionAction<T> action,
     856                                      AccessControlContext context, Permission... perms)
     857         throws PrivilegedActionException
     858     {
     859         AccessControlContext parent = getContext();
     860         if (perms == null) {
     861             throw new NullPointerException("null permissions parameter");
     862         }
     863         Class<?> caller = Reflection.getCallerClass();
     864         DomainCombiner dc = (context == null) ? null : context.getCombiner();
     865         return AccessController.doPrivileged(action, createWrapper(dc, caller, parent, context, perms));
     866     }
     867
     868
     869     /**
     870      * Performs the specified {@code PrivilegedExceptionAction} with
     871      * privileges enabled and restricted by the specified
     872      * {@code AccessControlContext} and with a privilege scope limited by
     873      * specified {@code Permission} arguments.
     874      *
     875      * The action is performed with the intersection of the permissions
     876      * possessed by the caller's protection domain, and those possessed
     877      * by the domains represented by the specified
     878      * {@code AccessControlContext}.
     879      * <p>
     880      * If the action's {@code run} method throws an (unchecked) exception,
     881      * it will propagate through this method.
     882      *
     883      * <p> This method preserves the current AccessControlContext's
     884      * DomainCombiner (which may be null) while the action is performed.
     885      * <p>
     886      * If a security manager is installed and the specified
     887      * {@code AccessControlContext} was not created by system code and the
     888      * caller's {@code ProtectionDomain} has not been granted the
     889      * {@literal "createAccessControlContext"}
     890      * {@link java.security.SecurityPermission}, then the action is performed
     891      * with no permissions.
     892      *
     893      * @param <T> the type of the value returned by the
     894      *                  PrivilegedExceptionAction's {@code run} method.
     895      * @param action the action to be performed.
     896      * @param context an <i>access control context</i>
     897      *                representing the restriction to be applied to the
     898      *                caller's domain's privileges before performing
     899      *                the specified action.  If the context is
     900      *                {@code null},
     901      *                then no additional restriction is applied.
     902      * @param perms the {@code Permission} arguments which limit the
     903      *              scope of the caller's privileges. The number of arguments
     904      *              is variable.
     905      *
     906      * @return the value returned by the action's {@code run} method.
     907      *
     908      * @throws PrivilegedActionException if the specified action's
     909      *         {@code run} method threw a <i>checked</i> exception
     910      * @throws NullPointerException if action or perms or any element of
     911      *         perms is {@code null}
     912      *
     913      * @see #doPrivileged(PrivilegedAction)
     914      * @see #doPrivileged(PrivilegedAction,AccessControlContext)
     915      * @see java.security.DomainCombiner
     916      *
     917      * @since 1.8
     918      */
     919     @CallerSensitive
     920     public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action,
     921                                                  AccessControlContext context,
     922                                                  Permission... perms)
     923         throws PrivilegedActionException
     924     {
     925         AccessControlContext parent = getContext();
     926         DomainCombiner dc = parent.getCombiner();
     927         if (dc == null && context != null) {
     928             dc = context.getCombiner();
     929         }
     930         if (perms == null) {
     931             throw new NullPointerException("null permissions parameter");
     932         }
     933         Class<?> caller = Reflection.getCallerClass();
     934         return AccessController.doPrivileged(action, createWrapper(dc, caller,
     935             parent, context, perms));
     936     }
     937
     938     /**
     939      * Returns the AccessControl context. i.e., it gets
     940      * the protection domains of all the callers on the stack,
     941      * starting at the first class with a non-null
     942      * ProtectionDomain.
     943      *
     944      * @return the access control context based on the current stack or
     945      *         null if there was only privileged system code.
     946      */
     947
     948     private static native AccessControlContext getStackAccessControlContext();
     949
     950
     951     /**
     952      * Returns the "inherited" AccessControl context. This is the context
     953      * that existed when the thread was created. Package private so
     954      * AccessControlContext can use it.
     955      */
     956
     957     static native AccessControlContext getInheritedAccessControlContext();
     958
     959     /**
     960      * This method takes a "snapshot" of the current calling context, which
     961      * includes the current Thread's inherited AccessControlContext and any
     962      * limited privilege scope, and places it in an AccessControlContext object.
     963      * This context may then be checked at a later point, possibly in another thread.
     964      *
     965      * @see AccessControlContext
     966      *
     967      * @return the AccessControlContext based on the current context.
     968      */
     969
     970     public static AccessControlContext getContext()
     971     {
     972         AccessControlContext acc = getStackAccessControlContext();
     973         if (acc == null) {
     974             // all we had was privileged system code. We don't want
     975             // to return null though, so we construct a real ACC.
     976             return new AccessControlContext(null, true);
     977         } else {
     978             return acc.optimize();
     979         }
     980     }
     981
     982     /**
     983      * Determines whether the access request indicated by the
     984      * specified permission should be allowed or denied, based on
     985      * the current AccessControlContext and security policy.
     986      * This method quietly returns if the access request
     987      * is permitted, or throws an AccessControlException otherwise. The
     988      * getPermission method of the AccessControlException returns the
     989      * {@code perm} Permission object instance.
     990      *
     991      * @param perm the requested permission.
     992      *
     993      * @throws    AccessControlException if the specified permission
     994      *            is not permitted, based on the current security policy.
     995      * @throws    NullPointerException if the specified permission
     996      *            is {@code null} and is checked based on the
     997      *            security policy currently in effect.
     998      */
     999
    1000     public static void checkPermission(Permission perm)
    1001         throws AccessControlException
    1002     {
    1003         //System.err.println("checkPermission "+perm);
    1004         //Thread.currentThread().dumpStack();
    1005
    1006         if (perm == null) {
    1007             throw new NullPointerException("permission can't be null");
    1008         }
    1009
    1010         AccessControlContext stack = getStackAccessControlContext();
    1011         // if context is null, we had privileged system code on the stack.
    1012         if (stack == null) {
    1013             Debug debug = AccessControlContext.getDebug();
    1014             boolean dumpDebug = false;
    1015             if (debug != null) {
    1016                 dumpDebug = !Debug.isOn("codebase=");
    1017                 dumpDebug &= !Debug.isOn("permission=") ||
    1018                     Debug.isOn("permission=" + perm.getClass().getCanonicalName());
    1019             }
    1020
    1021             if (dumpDebug && Debug.isOn("stack")) {
    1022                 Thread.dumpStack();
    1023             }
    1024
    1025             if (dumpDebug && Debug.isOn("domain")) {
    1026                 debug.println("domain (context is null)");
    1027             }
    1028
    1029             if (dumpDebug) {
    1030                 debug.println("access allowed "+perm);
    1031             }
    1032             return;
    1033         }
    1034
    1035         AccessControlContext acc = stack.optimize();
    1036         acc.checkPermission(perm);
    1037     }
    1038 }