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 */
|
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 * The value needs to be physically located in the frame, so that it
714 * can be found by a stack walk.
715 */
716 @Hidden
717 private static native void ensureMaterializedForStackWalk(Object o);
718
719 /**
720 * Sanity check that the caller context is indeed privileged.
721 *
722 * Used by executePrivileged to make sure the frame is properly
723 * recognized by the VM.
724 */
725 private static boolean isPrivileged() {
726 AccessControlContext ctx = getStackAccessControlContext();
727 return ctx == null || ctx.isPrivileged();
728 }
729
730 /**
731 * Execute the action as privileged.
732 *
733 * The VM recognizes this method as special, so any changes to the
734 * name or signature require corresponding changes in
735 * getStackAccessControlContext().
736 */
737 @Hidden
738 @ForceInline
739 private static <T> T
740 executePrivileged(PrivilegedAction<T> action,
741 AccessControlContext context,
742 Class<?> caller)
743 {
744 // Ensure context has a physical value in the frame
745 if (context != null) {
746 ensureMaterializedForStackWalk(context);
747 }
748
749 assert isPrivileged(); // sanity check invariant
750 T result = action.run();
751 assert isPrivileged(); // sanity check invariant
752
753 // Keep these alive across the run() call so they can be
754 // retrieved by getStackAccessControlContext().
755 Reference.reachabilityFence(context);
756 Reference.reachabilityFence(caller);
757 return result;
758 }
759
760 /**
761 * Execute the action as privileged.
762 *
763 * The VM recognizes this method as special, so any changes to the
764 * name or signature require corresponding changes in
765 * getStackAccessControlContext().
766 */
767 @Hidden
768 @ForceInline
769 private static <T> T
770 executePrivileged(PrivilegedExceptionAction<T> action,
771 AccessControlContext context,
772 Class<?> caller)
773 throws Exception
774 {
775 // Ensure context has a physical value in the frame
776 if (context != null) {
777 ensureMaterializedForStackWalk(context);
778 }
779
780 assert isPrivileged(); // sanity check invariant
781 T result = action.run();
782 assert isPrivileged(); // sanity check invariant
783
784 // Keep these alive across the run() call so they can be
785 // retrieved by getStackAccessControlContext().
786 Reference.reachabilityFence(context);
787 Reference.reachabilityFence(caller);
788 return result;
789 }
790
791
792 /**
793 * Internal marker for hidden implementation frames.
794 */
795 /*non-public*/
796 @Target(ElementType.METHOD)
797 @Retention(RetentionPolicy.RUNTIME)
798 @interface Hidden {
799 }
800
801
802 /**
803 * Wrap an exception. The annotations are used in a best effort to
804 * avoid StackOverflowError in the caller. Inlining the callees as
805 * well and tail-call elimination could also help here, but are not
806 * needed for correctness, only quality of implementation.
807 */
|