1 /*
2 * Copyright (c) 1997, 2013, 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 sun.security.util.Debug;
29 import jdk.internal.reflect.CallerSensitive;
30 import jdk.internal.reflect.Reflection;
31
32 /**
33 * <p> The AccessController class is used for access control operations
34 * and decisions.
35 *
36 * <p> More specifically, the AccessController class is used for
37 * three purposes:
38 *
39 * <ul>
40 * <li> to decide whether an access to a critical system
41 * resource is to be allowed or denied, based on the security policy
42 * currently in effect,
43 * <li>to mark code as being "privileged", thus affecting subsequent
44 * access determinations, and
45 * <li>to obtain a "snapshot" of the current calling context so
46 * access-control decisions from a different context can be made with
47 * respect to the saved context. </ul>
48 *
49 * <p> The {@link #checkPermission(Permission) checkPermission} method
50 * determines whether the access request indicated by a specified
279 *
280 * <p> Note that any DomainCombiner associated with the current
281 * AccessControlContext will be ignored while the action is performed.
282 *
283 * @param <T> the type of the value returned by the PrivilegedAction's
284 * {@code run} method.
285 *
286 * @param action the action to be performed.
287 *
288 * @return the value returned by the action's {@code run} method.
289 *
290 * @exception NullPointerException if the action is {@code null}
291 *
292 * @see #doPrivileged(PrivilegedAction,AccessControlContext)
293 * @see #doPrivileged(PrivilegedExceptionAction)
294 * @see #doPrivilegedWithCombiner(PrivilegedAction)
295 * @see java.security.DomainCombiner
296 */
297
298 @CallerSensitive
299 public static native <T> T doPrivileged(PrivilegedAction<T> action);
300
301 /**
302 * Performs the specified {@code PrivilegedAction} with privileges
303 * enabled. The action is performed with <i>all</i> of the permissions
304 * possessed by the caller's protection domain.
305 *
306 * <p> If the action's {@code run} method throws an (unchecked)
307 * exception, it will propagate through this method.
308 *
309 * <p> This method preserves the current AccessControlContext's
310 * DomainCombiner (which may be null) while the action is performed.
311 *
312 * @param <T> the type of the value returned by the PrivilegedAction's
313 * {@code run} method.
314 *
315 * @param action the action to be performed.
316 *
317 * @return the value returned by the action's {@code run} method.
318 *
319 * @exception NullPointerException if the action is {@code null}
352 * {@link java.security.SecurityPermission}, then the action is performed
353 * with no permissions.
354 *
355 * @param <T> the type of the value returned by the PrivilegedAction's
356 * {@code run} method.
357 * @param action the action to be performed.
358 * @param context an <i>access control context</i>
359 * representing the restriction to be applied to the
360 * caller's domain's privileges before performing
361 * the specified action. If the context is
362 * {@code null}, then no additional restriction is applied.
363 *
364 * @return the value returned by the action's {@code run} method.
365 *
366 * @exception NullPointerException if the action is {@code null}
367 *
368 * @see #doPrivileged(PrivilegedAction)
369 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
370 */
371 @CallerSensitive
372 public static native <T> T doPrivileged(PrivilegedAction<T> action,
373 AccessControlContext context);
374
375
376 /**
377 * Performs the specified {@code PrivilegedAction} with privileges
378 * enabled and restricted by the specified
379 * {@code AccessControlContext} and with a privilege scope limited
380 * by specified {@code Permission} arguments.
381 *
382 * The action is performed with the intersection of the permissions
383 * possessed by the caller's protection domain, and those possessed
384 * by the domains represented by the specified
385 * {@code AccessControlContext}.
386 * <p>
387 * If the action's {@code run} method throws an (unchecked) exception,
388 * it will propagate through this method.
389 * <p>
390 * If a security manager is installed and the specified
391 * {@code AccessControlContext} was not created by system code and the
392 * caller's {@code ProtectionDomain} has not been granted the
393 * {@literal "createAccessControlContext"}
507 * <p> Note that any DomainCombiner associated with the current
508 * AccessControlContext will be ignored while the action is performed.
509 *
510 * @param <T> the type of the value returned by the
511 * PrivilegedExceptionAction's {@code run} method.
512 *
513 * @param action the action to be performed
514 *
515 * @return the value returned by the action's {@code run} method
516 *
517 * @exception PrivilegedActionException if the specified action's
518 * {@code run} method threw a <i>checked</i> exception
519 * @exception NullPointerException if the action is {@code null}
520 *
521 * @see #doPrivileged(PrivilegedAction)
522 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
523 * @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)
524 * @see java.security.DomainCombiner
525 */
526 @CallerSensitive
527 public static native <T> T
528 doPrivileged(PrivilegedExceptionAction<T> action)
529 throws PrivilegedActionException;
530
531
532 /**
533 * Performs the specified {@code PrivilegedExceptionAction} with
534 * privileges enabled. The action is performed with <i>all</i> of the
535 * permissions possessed by the caller's protection domain.
536 *
537 * <p> If the action's {@code run} method throws an <i>unchecked</i>
538 * exception, it will propagate through this method.
539 *
540 * <p> This method preserves the current AccessControlContext's
541 * DomainCombiner (which may be null) while the action is performed.
542 *
543 * @param <T> the type of the value returned by the
544 * PrivilegedExceptionAction's {@code run} method.
545 *
546 * @param action the action to be performed.
547 *
548 * @return the value returned by the action's {@code run} method
549 *
550 * @exception PrivilegedActionException if the specified action's
594 !callerPD.impliesCreateAccessControlContext())
595 {
596 return getInnocuousAcc();
597 } else {
598 return new AccessControlContext(callerPD, combiner, parent,
599 context, perms);
600 }
601 }
602
603 private static class AccHolder {
604 // An AccessControlContext with no granted permissions.
605 // Only initialized on demand when getInnocuousAcc() is called.
606 static final AccessControlContext innocuousAcc =
607 new AccessControlContext(new ProtectionDomain[] {
608 new ProtectionDomain(null, null) });
609 }
610 private static AccessControlContext getInnocuousAcc() {
611 return AccHolder.innocuousAcc;
612 }
613
614 private static ProtectionDomain getCallerPD(final Class <?> caller) {
615 ProtectionDomain callerPd = doPrivileged
616 (new PrivilegedAction<>() {
617 public ProtectionDomain run() {
618 return caller.getProtectionDomain();
619 }
620 });
621
622 return callerPd;
623 }
624
625 /**
626 * Performs the specified {@code PrivilegedExceptionAction} with
627 * privileges enabled and restricted by the specified
628 * {@code AccessControlContext}. The action is performed with the
629 * intersection of the permissions possessed by the caller's
630 * protection domain, and those possessed by the domains represented by the
631 * specified {@code AccessControlContext}.
632 * <p>
633 * If the action's {@code run} method throws an <i>unchecked</i>
642 *
643 * @param <T> the type of the value returned by the
644 * PrivilegedExceptionAction's {@code run} method.
645 * @param action the action to be performed
646 * @param context an <i>access control context</i>
647 * representing the restriction to be applied to the
648 * caller's domain's privileges before performing
649 * the specified action. If the context is
650 * {@code null}, then no additional restriction is applied.
651 *
652 * @return the value returned by the action's {@code run} method
653 *
654 * @exception PrivilegedActionException if the specified action's
655 * {@code run} method threw a <i>checked</i> exception
656 * @exception NullPointerException if the action is {@code null}
657 *
658 * @see #doPrivileged(PrivilegedAction)
659 * @see #doPrivileged(PrivilegedAction,AccessControlContext)
660 */
661 @CallerSensitive
662 public static native <T> T
663 doPrivileged(PrivilegedExceptionAction<T> action,
664 AccessControlContext context)
665 throws PrivilegedActionException;
666
667
668 /**
669 * Performs the specified {@code PrivilegedExceptionAction} with
670 * privileges enabled and restricted by the specified
671 * {@code AccessControlContext} and with a privilege scope limited by
672 * specified {@code Permission} arguments.
673 *
674 * The action is performed with the intersection of the permissions
675 * possessed by the caller's protection domain, and those possessed
676 * by the domains represented by the specified
677 * {@code AccessControlContext}.
678 * <p>
679 * If the action's {@code run} method throws an (unchecked) exception,
680 * it will propagate through this method.
681 * <p>
682 * If a security manager is installed and the specified
683 * {@code AccessControlContext} was not created by system code and the
684 * caller's {@code ProtectionDomain} has not been granted the
685 * {@literal "createAccessControlContext"}
686 * {@link java.security.SecurityPermission}, then the action is performed
|
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 jdk.internal.reflect.CallerSensitive;
35 import jdk.internal.reflect.Reflection;
36 import jdk.internal.vm.annotation.DontInline;
37 import jdk.internal.vm.annotation.ForceInline;
38 import jdk.internal.vm.annotation.ReservedStackAccess;
39
40 /**
41 * <p> The AccessController class is used for access control operations
42 * and decisions.
43 *
44 * <p> More specifically, the AccessController class is used for
45 * three purposes:
46 *
47 * <ul>
48 * <li> to decide whether an access to a critical system
49 * resource is to be allowed or denied, based on the security policy
50 * currently in effect,
51 * <li>to mark code as being "privileged", thus affecting subsequent
52 * access determinations, and
53 * <li>to obtain a "snapshot" of the current calling context so
54 * access-control decisions from a different context can be made with
55 * respect to the saved context. </ul>
56 *
57 * <p> The {@link #checkPermission(Permission) checkPermission} method
58 * determines whether the access request indicated by a specified
287 *
288 * <p> Note that any DomainCombiner associated with the current
289 * AccessControlContext will be ignored while the action is performed.
290 *
291 * @param <T> the type of the value returned by the PrivilegedAction's
292 * {@code run} method.
293 *
294 * @param action the action to be performed.
295 *
296 * @return the value returned by the action's {@code run} method.
297 *
298 * @exception NullPointerException if the action is {@code null}
299 *
300 * @see #doPrivileged(PrivilegedAction,AccessControlContext)
301 * @see #doPrivileged(PrivilegedExceptionAction)
302 * @see #doPrivilegedWithCombiner(PrivilegedAction)
303 * @see java.security.DomainCombiner
304 */
305
306 @CallerSensitive
307 public static <T> T doPrivileged(PrivilegedAction<T> action)
308 {
309 return executePrivileged(action, null, Reflection.getCallerClass());
310 }
311
312 /**
313 * Performs the specified {@code PrivilegedAction} with privileges
314 * enabled. The action is performed with <i>all</i> of the permissions
315 * possessed by the caller's protection domain.
316 *
317 * <p> If the action's {@code run} method throws an (unchecked)
318 * exception, it will propagate through this method.
319 *
320 * <p> This method preserves the current AccessControlContext's
321 * DomainCombiner (which may be null) while the action is performed.
322 *
323 * @param <T> the type of the value returned by the PrivilegedAction's
324 * {@code run} method.
325 *
326 * @param action the action to be performed.
327 *
328 * @return the value returned by the action's {@code run} method.
329 *
330 * @exception NullPointerException if the action is {@code null}
363 * {@link java.security.SecurityPermission}, then the action is performed
364 * with no permissions.
365 *
366 * @param <T> the type of the value returned by the PrivilegedAction's
367 * {@code run} method.
368 * @param action the action to be performed.
369 * @param context an <i>access control context</i>
370 * representing the restriction to be applied to the
371 * caller's domain's privileges before performing
372 * the specified action. If the context is
373 * {@code null}, then no additional restriction is applied.
374 *
375 * @return the value returned by the action's {@code run} method.
376 *
377 * @exception NullPointerException if the action is {@code null}
378 *
379 * @see #doPrivileged(PrivilegedAction)
380 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
381 */
382 @CallerSensitive
383 public static <T> T doPrivileged(PrivilegedAction<T> action,
384 AccessControlContext context)
385 {
386 Class <?> caller = Reflection.getCallerClass();
387 context = checkContext(context, caller);
388 return executePrivileged(action, context, caller);
389 }
390
391
392 /**
393 * Performs the specified {@code PrivilegedAction} with privileges
394 * enabled and restricted by the specified
395 * {@code AccessControlContext} and with a privilege scope limited
396 * by specified {@code Permission} arguments.
397 *
398 * The action is performed with the intersection of the permissions
399 * possessed by the caller's protection domain, and those possessed
400 * by the domains represented by the specified
401 * {@code AccessControlContext}.
402 * <p>
403 * If the action's {@code run} method throws an (unchecked) exception,
404 * it will propagate through this method.
405 * <p>
406 * If a security manager is installed and the specified
407 * {@code AccessControlContext} was not created by system code and the
408 * caller's {@code ProtectionDomain} has not been granted the
409 * {@literal "createAccessControlContext"}
523 * <p> Note that any DomainCombiner associated with the current
524 * AccessControlContext will be ignored while the action is performed.
525 *
526 * @param <T> the type of the value returned by the
527 * PrivilegedExceptionAction's {@code run} method.
528 *
529 * @param action the action to be performed
530 *
531 * @return the value returned by the action's {@code run} method
532 *
533 * @exception PrivilegedActionException if the specified action's
534 * {@code run} method threw a <i>checked</i> exception
535 * @exception NullPointerException if the action is {@code null}
536 *
537 * @see #doPrivileged(PrivilegedAction)
538 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
539 * @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)
540 * @see java.security.DomainCombiner
541 */
542 @CallerSensitive
543 public static <T> T
544 doPrivileged(PrivilegedExceptionAction<T> action)
545 throws PrivilegedActionException
546 {
547 AccessControlContext context = null;
548 Class <?> caller = Reflection.getCallerClass();
549 try {
550 return executePrivileged(action, context, caller);
551 } catch (RuntimeException e) {
552 throw e;
553 } catch (Exception e) {
554 throw wrapException(e);
555 }
556 }
557
558 /**
559 * Performs the specified {@code PrivilegedExceptionAction} with
560 * privileges enabled. The action is performed with <i>all</i> of the
561 * permissions possessed by the caller's protection domain.
562 *
563 * <p> If the action's {@code run} method throws an <i>unchecked</i>
564 * exception, it will propagate through this method.
565 *
566 * <p> This method preserves the current AccessControlContext's
567 * DomainCombiner (which may be null) while the action is performed.
568 *
569 * @param <T> the type of the value returned by the
570 * PrivilegedExceptionAction's {@code run} method.
571 *
572 * @param action the action to be performed.
573 *
574 * @return the value returned by the action's {@code run} method
575 *
576 * @exception PrivilegedActionException if the specified action's
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>
670 *
671 * @param <T> the type of the value returned by the
672 * PrivilegedExceptionAction's {@code run} method.
673 * @param action the action to be performed
674 * @param context an <i>access control context</i>
675 * representing the restriction to be applied to the
676 * caller's domain's privileges before performing
677 * the specified action. If the context is
678 * {@code null}, then no additional restriction is applied.
679 *
680 * @return the value returned by the action's {@code run} method
681 *
682 * @exception PrivilegedActionException if the specified action's
683 * {@code run} method threw a <i>checked</i> exception
684 * @exception NullPointerException if the action is {@code null}
685 *
686 * @see #doPrivileged(PrivilegedAction)
687 * @see #doPrivileged(PrivilegedAction,AccessControlContext)
688 */
689 @CallerSensitive
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)
733 {
734 assert isPrivileged();
735 T result = action.run();
736 assert isPrivileged();
737
738 // Keep these alive across the run() call so they can be
739 // retrieved by getStackAccessControlContext().
740 Reference.reachabilityFence(context);
741 Reference.reachabilityFence(caller);
742 Reference.reachabilityFence(action);
743 return result;
744 }
745
746 @Hidden
747 @ForceInline
748 private static <T> T
749 executePrivileged(PrivilegedExceptionAction<T> action,
750 AccessControlContext context,
751 Class <?> caller)
752 throws Exception
753 {
754 assert isPrivileged();
755 T result = action.run();
756 assert isPrivileged();
757
758 // Keep these alive across the run() call so they can be
759 // retrieved by getStackAccessControlContext().
760 Reference.reachabilityFence(context);
761 Reference.reachabilityFence(caller);
762 Reference.reachabilityFence(action);
763 return result;
764 }
765
766
767 /**
768 * Internal marker for hidden implementation frames.
769 */
770 /*non-public*/
771 @Target(ElementType.METHOD)
772 @Retention(RetentionPolicy.RUNTIME)
773 @interface Hidden {
774 }
775
776
777 @Hidden
778 @ForceInline
779 @ReservedStackAccess
780 private static PrivilegedActionException wrapException(Exception e) {
781 // Nice place for tail-call elimination, if only there was a
782 // version of <init> that returned "this" instead of "void".
783 return new PrivilegedActionException(e);
784 }
785
786 /**
787 * Performs the specified {@code PrivilegedExceptionAction} with
788 * privileges enabled and restricted by the specified
789 * {@code AccessControlContext} and with a privilege scope limited by
790 * specified {@code Permission} arguments.
791 *
792 * The action is performed with the intersection of the permissions
793 * possessed by the caller's protection domain, and those possessed
794 * by the domains represented by the specified
795 * {@code AccessControlContext}.
796 * <p>
797 * If the action's {@code run} method throws an (unchecked) exception,
798 * it will propagate through this method.
799 * <p>
800 * If a security manager is installed and the specified
801 * {@code AccessControlContext} was not created by system code and the
802 * caller's {@code ProtectionDomain} has not been granted the
803 * {@literal "createAccessControlContext"}
804 * {@link java.security.SecurityPermission}, then the action is performed
|