< prev index next >

src/java.base/share/classes/java/security/AccessController.java

Print this page
rev 52360 : 8212605: Pure-Java implementation of AccessController.doPrivileged
* * *
8212605: Pure-Java implementation of AccessController.doPrivileged
Reviewed-by: dholmes
rev 52361 : [mq]: webrev.3


 596                                              preserveCombiner(dc, Reflection.getCallerClass()));
 597     }
 598 
 599     /**
 600      * preserve the combiner across the doPrivileged call
 601      */
 602     private static AccessControlContext preserveCombiner(DomainCombiner combiner,
 603                                                          Class<?> caller)
 604     {
 605         return createWrapper(combiner, caller, null, null, null);
 606     }
 607 
 608     /**
 609      * Create a wrapper to contain the limited privilege scope data.
 610      */
 611     private static AccessControlContext
 612         createWrapper(DomainCombiner combiner, Class<?> caller,
 613                       AccessControlContext parent, AccessControlContext context,
 614                       Permission[] perms)
 615     {
 616         ProtectionDomain callerPD = getCallerPD(caller);
 617         // check if caller is authorized to create context
 618         if (context != null && !context.isAuthorized() &&
 619             System.getSecurityManager() != null &&
 620             !callerPD.impliesCreateAccessControlContext())
 621         {
 622             return getInnocuousAcc();
 623         } else {
 624             return new AccessControlContext(callerPD, combiner, parent,
 625                                             context, perms);
 626         }
 627     }
 628 
 629     private static class AccHolder {
 630         // An AccessControlContext with no granted permissions.
 631         // Only initialized on demand when getInnocuousAcc() is called.
 632         static final AccessControlContext innocuousAcc =
 633             new AccessControlContext(new ProtectionDomain[] {
 634                                      new ProtectionDomain(null, null) });
 635     }
 636     private static AccessControlContext getInnocuousAcc() {
 637         return AccHolder.innocuousAcc;
 638     }
 639 
 640     private static native ProtectionDomain getProtectionDomain(final Class <?> caller);
 641 
 642     private static ProtectionDomain getCallerPD(final Class <?> caller) {
 643         ProtectionDomain callerPd = doPrivileged
 644             (new PrivilegedAction<>() {
 645             public ProtectionDomain run() {
 646                 return caller.getProtectionDomain();
 647             }
 648         });
 649 
 650         return callerPd;
 651     }
 652 
 653     /**
 654      * Performs the specified {@code PrivilegedExceptionAction} with
 655      * privileges enabled and restricted by the specified
 656      * {@code AccessControlContext}.  The action is performed with the
 657      * intersection of the permissions possessed by the caller's
 658      * protection domain, and those possessed by the domains represented by the
 659      * specified {@code AccessControlContext}.
 660      * <p>
 661      * If the action's {@code run} method throws an <i>unchecked</i>
 662      * exception, it will propagate through this method.
 663      * <p>
 664      * If a security manager is installed and the specified
 665      * {@code AccessControlContext} was not created by system code and the
 666      * caller's {@code ProtectionDomain} has not been granted the
 667      * {@literal "createAccessControlContext"}
 668      * {@link java.security.SecurityPermission}, then the action is performed
 669      * with no permissions.
 670      *
 671      * @param <T> the type of the value returned by the
 672      *                  PrivilegedExceptionAction's {@code run} method.


 690     public static <T> T
 691         doPrivileged(PrivilegedExceptionAction<T> action,
 692                      AccessControlContext context)
 693         throws PrivilegedActionException
 694     {
 695         Class <?> caller = Reflection.getCallerClass();
 696         context = checkContext(context, caller);
 697         try {
 698             return executePrivileged(action, context, caller);
 699         } catch (RuntimeException e) {
 700             throw e;
 701         } catch (Exception e) {
 702             throw wrapException(e);
 703         }
 704     }
 705 
 706     private static AccessControlContext checkContext(AccessControlContext context,
 707         Class <?> caller)
 708     {
 709         // check if caller is authorized to create context
 710         if (context != null && !context.isAuthorized() &&
 711             context != getInnocuousAcc() &&
 712             System.getSecurityManager() != null)
 713         {
 714             ProtectionDomain callerPD = getProtectionDomain(caller);
 715             if (callerPD != null && !callerPD.impliesCreateAccessControlContext()) {
 716                 return getInnocuousAcc();
 717             }
 718         }
 719         return context;
 720     }
 721 
 722     private static boolean isPrivileged() {
 723         AccessControlContext ctx = getStackAccessControlContext();
 724         return ctx == null || ctx.isPrivileged();
 725     }
 726 
 727     @Hidden
 728     @ForceInline
 729     private static <T> T
 730         executePrivileged(PrivilegedAction<T> action,
 731                           AccessControlContext context,
 732                           Class <?> caller)




 596                                              preserveCombiner(dc, Reflection.getCallerClass()));
 597     }
 598 
 599     /**
 600      * preserve the combiner across the doPrivileged call
 601      */
 602     private static AccessControlContext preserveCombiner(DomainCombiner combiner,
 603                                                          Class<?> caller)
 604     {
 605         return createWrapper(combiner, caller, null, null, null);
 606     }
 607 
 608     /**
 609      * Create a wrapper to contain the limited privilege scope data.
 610      */
 611     private static AccessControlContext
 612         createWrapper(DomainCombiner combiner, Class<?> caller,
 613                       AccessControlContext parent, AccessControlContext context,
 614                       Permission[] perms)
 615     {
 616         ProtectionDomain callerPD = getProtectionDomain(caller);
 617         // check if caller is authorized to create context
 618         if (System.getSecurityManager() != null &&
 619             context != null && !context.isAuthorized() &&
 620             !callerPD.impliesCreateAccessControlContext())
 621         {
 622             return getInnocuousAcc();
 623         } else {
 624             return new AccessControlContext(callerPD, combiner, parent,
 625                                             context, perms);
 626         }
 627     }
 628 
 629     private static class AccHolder {
 630         // An AccessControlContext with no granted permissions.
 631         // Only initialized on demand when getInnocuousAcc() is called.
 632         static final AccessControlContext innocuousAcc =
 633             new AccessControlContext(new ProtectionDomain[] {
 634                                      new ProtectionDomain(null, null) });
 635     }
 636     private static AccessControlContext getInnocuousAcc() {
 637         return AccHolder.innocuousAcc;
 638     }
 639 
 640     private static native ProtectionDomain getProtectionDomain(final Class <?> caller);
 641 











 642     /**
 643      * Performs the specified {@code PrivilegedExceptionAction} with
 644      * privileges enabled and restricted by the specified
 645      * {@code AccessControlContext}.  The action is performed with the
 646      * intersection of the permissions possessed by the caller's
 647      * protection domain, and those possessed by the domains represented by the
 648      * specified {@code AccessControlContext}.
 649      * <p>
 650      * If the action's {@code run} method throws an <i>unchecked</i>
 651      * exception, it will propagate through this method.
 652      * <p>
 653      * If a security manager is installed and the specified
 654      * {@code AccessControlContext} was not created by system code and the
 655      * caller's {@code ProtectionDomain} has not been granted the
 656      * {@literal "createAccessControlContext"}
 657      * {@link java.security.SecurityPermission}, then the action is performed
 658      * with no permissions.
 659      *
 660      * @param <T> the type of the value returned by the
 661      *                  PrivilegedExceptionAction's {@code run} method.


 679     public static <T> T
 680         doPrivileged(PrivilegedExceptionAction<T> action,
 681                      AccessControlContext context)
 682         throws PrivilegedActionException
 683     {
 684         Class <?> caller = Reflection.getCallerClass();
 685         context = checkContext(context, caller);
 686         try {
 687             return executePrivileged(action, context, caller);
 688         } catch (RuntimeException e) {
 689             throw e;
 690         } catch (Exception e) {
 691             throw wrapException(e);
 692         }
 693     }
 694 
 695     private static AccessControlContext checkContext(AccessControlContext context,
 696         Class <?> caller)
 697     {
 698         // check if caller is authorized to create context
 699         if (System.getSecurityManager() != null &&
 700             context != null && !context.isAuthorized() &&
 701             context != getInnocuousAcc())
 702         {
 703             ProtectionDomain callerPD = getProtectionDomain(caller);
 704             if (callerPD != null && !callerPD.impliesCreateAccessControlContext()) {
 705                 return getInnocuousAcc();
 706             }
 707         }
 708         return context;
 709     }
 710 
 711     private static boolean isPrivileged() {
 712         AccessControlContext ctx = getStackAccessControlContext();
 713         return ctx == null || ctx.isPrivileged();
 714     }
 715 
 716     @Hidden
 717     @ForceInline
 718     private static <T> T
 719         executePrivileged(PrivilegedAction<T> action,
 720                           AccessControlContext context,
 721                           Class <?> caller)


< prev index next >