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