1 /* |
1 /* |
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
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. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package java.security; |
26 package java.security; |
27 |
27 |
|
28 import java.lang.ref.Reference; |
28 import sun.security.util.Debug; |
29 import sun.security.util.Debug; |
29 import jdk.internal.reflect.CallerSensitive; |
30 import jdk.internal.reflect.CallerSensitive; |
30 import jdk.internal.reflect.Reflection; |
31 import jdk.internal.reflect.Reflection; |
|
32 import jdk.internal.vm.annotation.DontInline; |
|
33 import jdk.internal.vm.annotation.ForceInline; |
|
34 import jdk.internal.vm.annotation.ReservedStackAccess; |
31 |
35 |
32 /** |
36 /** |
33 * <p> The AccessController class is used for access control operations |
37 * <p> The AccessController class is used for access control operations |
34 * and decisions. |
38 * and decisions. |
35 * |
39 * |
294 * @see #doPrivilegedWithCombiner(PrivilegedAction) |
298 * @see #doPrivilegedWithCombiner(PrivilegedAction) |
295 * @see java.security.DomainCombiner |
299 * @see java.security.DomainCombiner |
296 */ |
300 */ |
297 |
301 |
298 @CallerSensitive |
302 @CallerSensitive |
299 public static native <T> T doPrivileged(PrivilegedAction<T> action); |
303 public static <T> T doPrivileged(PrivilegedAction<T> action) |
|
304 { |
|
305 return executePrivileged(action, null, Reflection.getCallerClass()); |
|
306 } |
300 |
307 |
301 /** |
308 /** |
302 * Performs the specified {@code PrivilegedAction} with privileges |
309 * Performs the specified {@code PrivilegedAction} with privileges |
303 * enabled. The action is performed with <i>all</i> of the permissions |
310 * enabled. The action is performed with <i>all</i> of the permissions |
304 * possessed by the caller's protection domain. |
311 * possessed by the caller's protection domain. |
367 * |
374 * |
368 * @see #doPrivileged(PrivilegedAction) |
375 * @see #doPrivileged(PrivilegedAction) |
369 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) |
376 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) |
370 */ |
377 */ |
371 @CallerSensitive |
378 @CallerSensitive |
372 public static native <T> T doPrivileged(PrivilegedAction<T> action, |
379 public static <T> T doPrivileged(PrivilegedAction<T> action, |
373 AccessControlContext context); |
380 AccessControlContext context) |
|
381 { |
|
382 Class <?> caller = Reflection.getCallerClass(); |
|
383 context = checkContext(context, caller); |
|
384 return executePrivileged(action, context, caller); |
|
385 } |
374 |
386 |
375 |
387 |
376 /** |
388 /** |
377 * Performs the specified {@code PrivilegedAction} with privileges |
389 * Performs the specified {@code PrivilegedAction} with privileges |
378 * enabled and restricted by the specified |
390 * enabled and restricted by the specified |
522 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) |
534 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) |
523 * @see #doPrivilegedWithCombiner(PrivilegedExceptionAction) |
535 * @see #doPrivilegedWithCombiner(PrivilegedExceptionAction) |
524 * @see java.security.DomainCombiner |
536 * @see java.security.DomainCombiner |
525 */ |
537 */ |
526 @CallerSensitive |
538 @CallerSensitive |
527 public static native <T> T |
539 public static <T> T |
528 doPrivileged(PrivilegedExceptionAction<T> action) |
540 doPrivileged(PrivilegedExceptionAction<T> action) |
529 throws PrivilegedActionException; |
541 throws PrivilegedActionException |
530 |
542 { |
|
543 AccessControlContext context = null; |
|
544 Class <?> caller = Reflection.getCallerClass(); |
|
545 try { |
|
546 return executePrivileged(action, context, caller); |
|
547 } catch (RuntimeException e) { |
|
548 throw e; |
|
549 } catch (Exception e) { |
|
550 throw wrapException(e); |
|
551 } |
|
552 } |
531 |
553 |
532 /** |
554 /** |
533 * Performs the specified {@code PrivilegedExceptionAction} with |
555 * Performs the specified {@code PrivilegedExceptionAction} with |
534 * privileges enabled. The action is performed with <i>all</i> of the |
556 * privileges enabled. The action is performed with <i>all</i> of the |
535 * permissions possessed by the caller's protection domain. |
557 * permissions possessed by the caller's protection domain. |
601 } |
623 } |
602 |
624 |
603 private static class AccHolder { |
625 private static class AccHolder { |
604 // An AccessControlContext with no granted permissions. |
626 // An AccessControlContext with no granted permissions. |
605 // Only initialized on demand when getInnocuousAcc() is called. |
627 // Only initialized on demand when getInnocuousAcc() is called. |
|
628 // TODO: set isAuthorized |
606 static final AccessControlContext innocuousAcc = |
629 static final AccessControlContext innocuousAcc = |
607 new AccessControlContext(new ProtectionDomain[] { |
630 new AccessControlContext(new ProtectionDomain[] { |
608 new ProtectionDomain(null, null) }); |
631 new ProtectionDomain(null, null) }); |
609 } |
632 } |
610 private static AccessControlContext getInnocuousAcc() { |
633 private static AccessControlContext getInnocuousAcc() { |
611 return AccHolder.innocuousAcc; |
634 return AccHolder.innocuousAcc; |
612 } |
635 } |
|
636 |
|
637 private static native ProtectionDomain getProtectionDomain(final Class <?> caller); |
613 |
638 |
614 private static ProtectionDomain getCallerPD(final Class <?> caller) { |
639 private static ProtectionDomain getCallerPD(final Class <?> caller) { |
615 ProtectionDomain callerPd = doPrivileged |
640 ProtectionDomain callerPd = doPrivileged |
616 (new PrivilegedAction<>() { |
641 (new PrivilegedAction<>() { |
617 public ProtectionDomain run() { |
642 public ProtectionDomain run() { |
657 * |
682 * |
658 * @see #doPrivileged(PrivilegedAction) |
683 * @see #doPrivileged(PrivilegedAction) |
659 * @see #doPrivileged(PrivilegedAction,AccessControlContext) |
684 * @see #doPrivileged(PrivilegedAction,AccessControlContext) |
660 */ |
685 */ |
661 @CallerSensitive |
686 @CallerSensitive |
662 public static native <T> T |
687 public static <T> T |
663 doPrivileged(PrivilegedExceptionAction<T> action, |
688 doPrivileged(PrivilegedExceptionAction<T> action, |
664 AccessControlContext context) |
689 AccessControlContext context) |
665 throws PrivilegedActionException; |
690 throws PrivilegedActionException |
666 |
691 { |
|
692 Class <?> caller = Reflection.getCallerClass(); |
|
693 context = checkContext(context, caller); |
|
694 try { |
|
695 return executePrivileged(action, context, caller); |
|
696 } catch (RuntimeException e) { |
|
697 throw e; |
|
698 } catch (Exception e) { |
|
699 throw wrapException(e); |
|
700 } |
|
701 } |
|
702 |
|
703 private static AccessControlContext checkContext(AccessControlContext context, |
|
704 Class <?> caller) |
|
705 { |
|
706 // check if caller is authorized to create context |
|
707 if (context != null && !context.isAuthorized() && |
|
708 context != getInnocuousAcc() && |
|
709 System.getSecurityManager() != null) |
|
710 { |
|
711 ProtectionDomain callerPD = getProtectionDomain(caller); |
|
712 if (callerPD != null && !callerPD.impliesCreateAccessControlContext()) { |
|
713 return getInnocuousAcc(); |
|
714 } |
|
715 } |
|
716 return context; |
|
717 } |
|
718 |
|
719 @ForceInline |
|
720 private static <T> T |
|
721 executePrivileged(PrivilegedAction<T> action, |
|
722 AccessControlContext context, |
|
723 Class <?> caller) |
|
724 { |
|
725 { |
|
726 AccessControlContext ctx = getStackAccessControlContext(); |
|
727 assert ctx == null || ctx.isPrivileged(); |
|
728 } |
|
729 T result = action.run(); |
|
730 { |
|
731 AccessControlContext ctx = getStackAccessControlContext(); |
|
732 assert ctx == null || ctx.isPrivileged(); |
|
733 } |
|
734 Reference.reachabilityFence(context); |
|
735 Reference.reachabilityFence(caller); |
|
736 Reference.reachabilityFence(action); // FIXME: for debugging |
|
737 return result; |
|
738 } |
|
739 |
|
740 @ForceInline |
|
741 private static <T> T |
|
742 executePrivileged(PrivilegedExceptionAction<T> action, |
|
743 AccessControlContext context, |
|
744 Class <?> caller) |
|
745 throws Exception |
|
746 { |
|
747 { |
|
748 AccessControlContext ctx = getStackAccessControlContext(); |
|
749 assert ctx == null || ctx.isPrivileged(); |
|
750 } |
|
751 T result = action.run(); |
|
752 { |
|
753 AccessControlContext ctx = getStackAccessControlContext(); |
|
754 assert ctx == null || ctx.isPrivileged(); |
|
755 } |
|
756 Reference.reachabilityFence(context); |
|
757 Reference.reachabilityFence(caller); |
|
758 Reference.reachabilityFence(action); // FIXME: for debugging |
|
759 return result; |
|
760 } |
|
761 |
|
762 @ForceInline |
|
763 @ReservedStackAccess |
|
764 private static PrivilegedActionException wrapException(Exception e) { |
|
765 return new PrivilegedActionException(e); |
|
766 } |
667 |
767 |
668 /** |
768 /** |
669 * Performs the specified {@code PrivilegedExceptionAction} with |
769 * Performs the specified {@code PrivilegedExceptionAction} with |
670 * privileges enabled and restricted by the specified |
770 * privileges enabled and restricted by the specified |
671 * {@code AccessControlContext} and with a privilege scope limited by |
771 * {@code AccessControlContext} and with a privilege scope limited by |