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)
|