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 59 * permission should be granted or denied. A sample call appears 60 * below. In this example, {@code checkPermission} will determine 61 * whether or not to grant "read" access to the file named "testFile" in 62 * the "/temp" directory. 63 * 64 * <pre> 65 * 66 * FilePermission perm = new FilePermission("/temp/testFile", "read"); 67 * AccessController.checkPermission(perm); 68 * 69 * </pre> 70 * 71 * <p> If a requested access is allowed, 72 * {@code checkPermission} returns quietly. If denied, an 73 * AccessControlException is 74 * thrown. AccessControlException can also be thrown if the requested 75 * permission is of an incorrect type or contains an invalid value. 76 * Such information is given whenever possible. 77 * 78 * Suppose the current thread traversed m callers, in the order of caller 1 79 * to caller 2 to caller m. Then caller m invoked the 80 * {@code checkPermission} method. 81 * The {@code checkPermission} method determines whether access 82 * is granted or denied based on the following algorithm: 83 * 84 * <pre> {@code 85 * for (int i = m; i > 0; i--) { 86 * 87 * if (caller i's domain does not have the permission) 88 * throw AccessControlException 89 * 90 * else if (caller i is marked as privileged) { 91 * if (a context was specified in the call to doPrivileged) 92 * context.checkPermission(permission) 93 * if (limited permissions were specified in the call to doPrivileged) { 94 * for (each limited permission) { 95 * if (the limited permission implies the requested permission) 96 * return; 97 * } 98 * } else 99 * return; 100 * } 101 * } 102 * 103 * // Next, check the context inherited when the thread was created. 104 * // Whenever a new thread is created, the AccessControlContext at 105 * // that time is stored and associated with the new thread, as the 106 * // "inherited" context. 107 * 108 * inheritedContext.checkPermission(permission); 109 * }</pre> 110 * 111 * <p> A caller can be marked as being "privileged" 112 * (see {@link #doPrivileged(PrivilegedAction) doPrivileged} and below). 113 * When making access control decisions, the {@code checkPermission} 114 * method stops checking if it reaches a caller that 115 * was marked as "privileged" via a {@code doPrivileged} 116 * call without a context argument (see below for information about a 117 * context argument). If that caller's domain has the 118 * specified permission and at least one limiting permission argument (if any) 119 * implies the requested permission, no further checking is done and 120 * {@code checkPermission} 121 * returns quietly, indicating that the requested access is allowed. 122 * If that domain does not have the specified permission, an exception 123 * is thrown, as usual. If the caller's domain had the specified permission 124 * but it was not implied by any limiting permission arguments given in the call 125 * to {@code doPrivileged} then the permission checking continues 126 * until there are no more callers or another {@code doPrivileged} 127 * call matches the requested permission and returns normally. 128 * 129 * <p> The normal use of the "privileged" feature is as follows. If you 130 * don't need to return a value from within the "privileged" block, do 131 * the following: 132 * 133 * <pre> {@code 134 * somemethod() { 135 * ...normal code here... 136 * AccessController.doPrivileged(new PrivilegedAction<Void>() { 137 * public Void run() { 138 * // privileged code goes here, for example: 139 * System.loadLibrary("awt"); 140 * return null; // nothing to return 141 * } 142 * }); 143 * ...normal code here... 144 * }}</pre> 145 * 146 * <p> 147 * PrivilegedAction is an interface with a single method, named 148 * {@code run}. 149 * The above example shows creation of an implementation 150 * of that interface; a concrete implementation of the 151 * {@code run} method is supplied. 152 * When the call to {@code doPrivileged} is made, an 153 * instance of the PrivilegedAction implementation is passed 154 * to it. The {@code doPrivileged} method calls the 155 * {@code run} method from the PrivilegedAction 156 * implementation after enabling privileges, and returns the 157 * {@code run} method's return value as the 158 * {@code doPrivileged} return value (which is 159 * ignored in this example). 160 * 161 * <p> If you need to return a value, you can do something like the following: 162 * 163 * <pre> {@code 164 * somemethod() { 165 * ...normal code here... 166 * String user = AccessController.doPrivileged( 167 * new PrivilegedAction<String>() { 168 * public String run() { 169 * return System.getProperty("user.name"); 170 * } 171 * }); 172 * ...normal code here... 173 * }}</pre> 174 * 175 * <p>If the action performed in your {@code run} method could 176 * throw a "checked" exception (those listed in the {@code throws} clause 177 * of a method), then you need to use the 178 * {@code PrivilegedExceptionAction} interface instead of the 179 * {@code PrivilegedAction} interface: 180 * 181 * <pre> {@code 182 * somemethod() throws FileNotFoundException { 183 * ...normal code here... 184 * try { 185 * FileInputStream fis = AccessController.doPrivileged( 186 * new PrivilegedExceptionAction<FileInputStream>() { 187 * public FileInputStream run() throws FileNotFoundException { 188 * return new FileInputStream("someFile"); 189 * } 190 * }); 191 * } catch (PrivilegedActionException e) { 192 * // e.getException() should be an instance of FileNotFoundException, 193 * // as only "checked" exceptions will be "wrapped" in a 194 * // PrivilegedActionException. 195 * throw (FileNotFoundException) e.getException(); 196 * } 197 * ...normal code here... 198 * }}</pre> 199 * 200 * <p> Be *very* careful in your use of the "privileged" construct, and 201 * always remember to make the privileged code section as small as possible. 202 * You can pass {@code Permission} arguments to further limit the 203 * scope of the "privilege" (see below). 204 * 205 * 206 * <p> Note that {@code checkPermission} always performs security checks 207 * within the context of the currently executing thread. 208 * Sometimes a security check that should be made within a given context 209 * will actually need to be done from within a 210 * <i>different</i> context (for example, from within a worker thread). 211 * The {@link #getContext() getContext} method and 212 * AccessControlContext class are provided 213 * for this situation. The {@code getContext} method takes a "snapshot" 214 * of the current calling context, and places 215 * it in an AccessControlContext object, which it returns. A sample call is 216 * the following: 217 * 218 * <pre> 219 * 220 * AccessControlContext acc = AccessController.getContext() 221 * 222 * </pre> 223 * 224 * <p> 225 * AccessControlContext itself has a {@code checkPermission} method 226 * that makes access decisions based on the context <i>it</i> encapsulates, 227 * rather than that of the current execution thread. 228 * Code within a different context can thus call that method on the 229 * previously-saved AccessControlContext object. A sample call is the 230 * following: 231 * 232 * <pre> 233 * 234 * acc.checkPermission(permission) 235 * 236 * </pre> 237 * 238 * <p> There are also times where you don't know a priori which permissions 239 * to check the context against. In these cases you can use the 240 * doPrivileged method that takes a context. You can also limit the scope 241 * of the privileged code by passing additional {@code Permission} 242 * parameters. 243 * 244 * <pre> {@code 245 * somemethod() { 246 * AccessController.doPrivileged(new PrivilegedAction<Object>() { 247 * public Object run() { 248 * // Code goes here. Any permission checks within this 249 * // run method will require that the intersection of the 250 * // caller's protection domain and the snapshot's 251 * // context have the desired permission. If a requested 252 * // permission is not implied by the limiting FilePermission 253 * // argument then checking of the thread continues beyond the 254 * // caller of doPrivileged. 255 * } 256 * }, acc, new FilePermission("/temp/*", read)); 257 * ...normal code here... 258 * }}</pre> 259 * <p> Passing a limiting {@code Permission} argument of an instance of 260 * {@code AllPermission} is equivalent to calling the equivalent 261 * {@code doPrivileged} method without limiting {@code Permission} 262 * arguments. Passing a zero length array of {@code Permission} disables 263 * the code privileges so that checking always continues beyond the caller of 264 * that {@code doPrivileged} method. 265 * 266 * @see AccessControlContext 267 * 268 * @author Li Gong 269 * @author Roland Schemers 270 * @since 1.2 271 */ 272 273 public final class AccessController { 274 275 /** 276 * Don't allow anyone to instantiate an AccessController 277 */ 278 private AccessController() { } 279 280 /** 281 * Performs the specified {@code PrivilegedAction} with privileges 282 * enabled. The action is performed with <i>all</i> of the permissions 283 * possessed by the caller's protection domain. 284 * 285 * <p> If the action's {@code run} method throws an (unchecked) 286 * exception, it will propagate through this method. 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} 331 * 332 * @see #doPrivileged(PrivilegedAction) 333 * @see java.security.DomainCombiner 334 * 335 * @since 1.6 336 */ 337 @CallerSensitive 338 public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) { 339 AccessControlContext acc = getStackAccessControlContext(); 340 if (acc == null) { 341 return AccessController.doPrivileged(action); 342 } 343 DomainCombiner dc = acc.getAssignedCombiner(); 344 return AccessController.doPrivileged(action, 345 preserveCombiner(dc, Reflection.getCallerClass())); 346 } 347 348 349 /** 350 * Performs the specified {@code PrivilegedAction} with privileges 351 * enabled and restricted by the specified {@code AccessControlContext}. 352 * The action is performed with the intersection of the permissions 353 * possessed by the caller's protection domain, and those possessed 354 * by the domains represented by the specified {@code AccessControlContext}. 355 * <p> 356 * If the action's {@code run} method throws an (unchecked) exception, 357 * it will propagate through this method. 358 * <p> 359 * If a security manager is installed and the specified 360 * {@code AccessControlContext} was not created by system code and the 361 * caller's {@code ProtectionDomain} has not been granted the 362 * {@literal "createAccessControlContext"} 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"} 410 * {@link java.security.SecurityPermission}, then the action is performed 411 * with no permissions. 412 * 413 * @param <T> the type of the value returned by the PrivilegedAction's 414 * {@code run} method. 415 * @param action the action to be performed. 416 * @param context an <i>access control context</i> 417 * representing the restriction to be applied to the 418 * caller's domain's privileges before performing 419 * the specified action. If the context is 420 * {@code null}, 421 * then no additional restriction is applied. 422 * @param perms the {@code Permission} arguments which limit the 423 * scope of the caller's privileges. The number of arguments 424 * is variable. 425 * 426 * @return the value returned by the action's {@code run} method. 427 * 428 * @throws NullPointerException if action or perms or any element of 429 * perms is {@code null} 430 * 431 * @see #doPrivileged(PrivilegedAction) 432 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 433 * 434 * @since 1.8 435 */ 436 @CallerSensitive 437 public static <T> T doPrivileged(PrivilegedAction<T> action, 438 AccessControlContext context, Permission... perms) { 439 440 AccessControlContext parent = getContext(); 441 if (perms == null) { 442 throw new NullPointerException("null permissions parameter"); 443 } 444 Class <?> caller = Reflection.getCallerClass(); 445 return AccessController.doPrivileged(action, createWrapper(null, 446 caller, parent, context, perms)); 447 } 448 449 450 /** 451 * Performs the specified {@code PrivilegedAction} with privileges 452 * enabled and restricted by the specified 453 * {@code AccessControlContext} and with a privilege scope limited 454 * by specified {@code Permission} arguments. 455 * 456 * The action is performed with the intersection of the permissions 457 * possessed by the caller's protection domain, and those possessed 458 * by the domains represented by the specified 459 * {@code AccessControlContext}. 460 * <p> 461 * If the action's {@code run} method throws an (unchecked) exception, 462 * it will propagate through this method. 463 * 464 * <p> This method preserves the current AccessControlContext's 465 * DomainCombiner (which may be null) while the action is performed. 466 * <p> 467 * If a security manager is installed and the specified 468 * {@code AccessControlContext} was not created by system code and the 469 * caller's {@code ProtectionDomain} has not been granted the 470 * {@literal "createAccessControlContext"} 471 * {@link java.security.SecurityPermission}, then the action is performed 472 * with no permissions. 473 * 474 * @param <T> the type of the value returned by the PrivilegedAction's 475 * {@code run} method. 476 * @param action the action to be performed. 477 * @param context an <i>access control context</i> 478 * representing the restriction to be applied to the 479 * caller's domain's privileges before performing 480 * the specified action. If the context is 481 * {@code null}, 482 * then no additional restriction is applied. 483 * @param perms the {@code Permission} arguments which limit the 484 * scope of the caller's privileges. The number of arguments 485 * is variable. 486 * 487 * @return the value returned by the action's {@code run} method. 488 * 489 * @throws NullPointerException if action or perms or any element of 490 * perms is {@code null} 491 * 492 * @see #doPrivileged(PrivilegedAction) 493 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 494 * @see java.security.DomainCombiner 495 * 496 * @since 1.8 497 */ 498 @CallerSensitive 499 public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action, 500 AccessControlContext context, Permission... perms) { 501 502 AccessControlContext parent = getContext(); 503 DomainCombiner dc = parent.getCombiner(); 504 if (dc == null && context != null) { 505 dc = context.getCombiner(); 506 } 507 if (perms == null) { 508 throw new NullPointerException("null permissions parameter"); 509 } 510 Class <?> caller = Reflection.getCallerClass(); 511 return AccessController.doPrivileged(action, createWrapper(dc, caller, 512 parent, context, perms)); 513 } 514 515 /** 516 * Performs the specified {@code PrivilegedExceptionAction} with 517 * privileges enabled. The action is performed with <i>all</i> of the 518 * permissions possessed by the caller's protection domain. 519 * 520 * <p> If the action's {@code run} method throws an <i>unchecked</i> 521 * exception, it will propagate through this method. 522 * 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 577 * {@code run} method threw a <i>checked</i> exception 578 * @exception NullPointerException if the action is {@code null} 579 * 580 * @see #doPrivileged(PrivilegedAction) 581 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 582 * @see java.security.DomainCombiner 583 * 584 * @since 1.6 585 */ 586 @CallerSensitive 587 public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action) 588 throws PrivilegedActionException 589 { 590 AccessControlContext acc = getStackAccessControlContext(); 591 if (acc == null) { 592 return AccessController.doPrivileged(action); 593 } 594 DomainCombiner dc = acc.getAssignedCombiner(); 595 return AccessController.doPrivileged(action, 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. 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 805 * with no permissions. 806 * 807 * @param <T> the type of the value returned by the 808 * PrivilegedExceptionAction's {@code run} method. 809 * @param action the action to be performed. 810 * @param context an <i>access control context</i> 811 * representing the restriction to be applied to the 812 * caller's domain's privileges before performing 813 * the specified action. If the context is 814 * {@code null}, 815 * then no additional restriction is applied. 816 * @param perms the {@code Permission} arguments which limit the 817 * scope of the caller's privileges. The number of arguments 818 * is variable. 819 * 820 * @return the value returned by the action's {@code run} method. 821 * 822 * @throws PrivilegedActionException if the specified action's 823 * {@code run} method threw a <i>checked</i> exception 824 * @throws NullPointerException if action or perms or any element of 825 * perms is {@code null} 826 * 827 * @see #doPrivileged(PrivilegedAction) 828 * @see #doPrivileged(PrivilegedAction,AccessControlContext) 829 * 830 * @since 1.8 831 */ 832 @CallerSensitive 833 public static <T> T doPrivileged(PrivilegedExceptionAction<T> action, 834 AccessControlContext context, Permission... perms) 835 throws PrivilegedActionException 836 { 837 AccessControlContext parent = getContext(); 838 if (perms == null) { 839 throw new NullPointerException("null permissions parameter"); 840 } 841 Class <?> caller = Reflection.getCallerClass(); 842 return AccessController.doPrivileged(action, createWrapper(null, caller, parent, context, perms)); 843 } 844 845 846 /** 847 * Performs the specified {@code PrivilegedExceptionAction} with 848 * privileges enabled and restricted by the specified 849 * {@code AccessControlContext} and with a privilege scope limited by 850 * specified {@code Permission} arguments. 851 * 852 * The action is performed with the intersection of the permissions 853 * possessed by the caller's protection domain, and those possessed 854 * by the domains represented by the specified 855 * {@code AccessControlContext}. 856 * <p> 857 * If the action's {@code run} method throws an (unchecked) exception, 858 * it will propagate through this method. 859 * 860 * <p> This method preserves the current AccessControlContext's 861 * DomainCombiner (which may be null) while the action is performed. 862 * <p> 863 * If a security manager is installed and the specified 864 * {@code AccessControlContext} was not created by system code and the 865 * caller's {@code ProtectionDomain} has not been granted the 866 * {@literal "createAccessControlContext"} 867 * {@link java.security.SecurityPermission}, then the action is performed 868 * with no permissions. 869 * 870 * @param <T> the type of the value returned by the 871 * PrivilegedExceptionAction's {@code run} method. 872 * @param action the action to be performed. 873 * @param context an <i>access control context</i> 874 * representing the restriction to be applied to the 875 * caller's domain's privileges before performing 876 * the specified action. If the context is 877 * {@code null}, 878 * then no additional restriction is applied. 879 * @param perms the {@code Permission} arguments which limit the 880 * scope of the caller's privileges. The number of arguments 881 * is variable. 882 * 883 * @return the value returned by the action's {@code run} method. 884 * 885 * @throws PrivilegedActionException if the specified action's 886 * {@code run} method threw a <i>checked</i> exception 887 * @throws NullPointerException if action or perms or any element of 888 * perms is {@code null} 889 * 890 * @see #doPrivileged(PrivilegedAction) 891 * @see #doPrivileged(PrivilegedAction,AccessControlContext) 892 * @see java.security.DomainCombiner 893 * 894 * @since 1.8 895 */ 896 @CallerSensitive 897 public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action, 898 AccessControlContext context, 899 Permission... perms) 900 throws PrivilegedActionException 901 { 902 AccessControlContext parent = getContext(); 903 DomainCombiner dc = parent.getCombiner(); 904 if (dc == null && context != null) { 905 dc = context.getCombiner(); 906 } 907 if (perms == null) { 908 throw new NullPointerException("null permissions parameter"); 909 } 910 Class <?> caller = Reflection.getCallerClass(); 911 return AccessController.doPrivileged(action, createWrapper(dc, caller, 912 parent, context, perms)); 913 } 914 915 /** 916 * Returns the AccessControl context. i.e., it gets 917 * the protection domains of all the callers on the stack, 918 * starting at the first class with a non-null 919 * ProtectionDomain. 920 * 921 * @return the access control context based on the current stack or 922 * null if there was only privileged system code. 923 */ 924 925 private static native AccessControlContext getStackAccessControlContext(); 926 927 928 /** 929 * Returns the "inherited" AccessControl context. This is the context 930 * that existed when the thread was created. Package private so 931 * AccessControlContext can use it. 932 */ 933 934 static native AccessControlContext getInheritedAccessControlContext(); 935 936 /** 937 * This method takes a "snapshot" of the current calling context, which 938 * includes the current Thread's inherited AccessControlContext and any 939 * limited privilege scope, and places it in an AccessControlContext object. 940 * This context may then be checked at a later point, possibly in another thread. 941 * 942 * @see AccessControlContext 943 * 944 * @return the AccessControlContext based on the current context. 945 */ 946 947 public static AccessControlContext getContext() 948 { 949 AccessControlContext acc = getStackAccessControlContext(); 950 if (acc == null) { 951 // all we had was privileged system code. We don't want 952 // to return null though, so we construct a real ACC. 953 return new AccessControlContext(null, true); 954 } else { 955 return acc.optimize(); 956 } 957 } 958 959 /** 960 * Determines whether the access request indicated by the 961 * specified permission should be allowed or denied, based on 962 * the current AccessControlContext and security policy. 963 * This method quietly returns if the access request 964 * is permitted, or throws an AccessControlException otherwise. The 965 * getPermission method of the AccessControlException returns the 966 * {@code perm} Permission object instance. 967 * 968 * @param perm the requested permission. 969 * 970 * @exception AccessControlException if the specified permission 971 * is not permitted, based on the current security policy. 972 * @exception NullPointerException if the specified permission 973 * is {@code null} and is checked based on the 974 * security policy currently in effect. 975 */ 976 977 public static void checkPermission(Permission perm) 978 throws AccessControlException 979 { 980 //System.err.println("checkPermission "+perm); 981 //Thread.currentThread().dumpStack(); 982 983 if (perm == null) { 984 throw new NullPointerException("permission can't be null"); 985 } 986 987 AccessControlContext stack = getStackAccessControlContext(); 988 // if context is null, we had privileged system code on the stack. 989 if (stack == null) { 990 Debug debug = AccessControlContext.getDebug(); 991 boolean dumpDebug = false; 992 if (debug != null) { 993 dumpDebug = !Debug.isOn("codebase="); 994 dumpDebug &= !Debug.isOn("permission=") || 995 Debug.isOn("permission=" + perm.getClass().getCanonicalName()); 996 } 997 998 if (dumpDebug && Debug.isOn("stack")) { 999 Thread.dumpStack(); 1000 } 1001 1002 if (dumpDebug && Debug.isOn("domain")) { 1003 debug.println("domain (context is null)"); 1004 } 1005 1006 if (dumpDebug) { 1007 debug.println("access allowed "+perm); 1008 } 1009 return; 1010 } 1011 1012 AccessControlContext acc = stack.optimize(); 1013 acc.checkPermission(perm); 1014 } 1015 }