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 sun.security.util.SecurityConstants; 35 import jdk.internal.reflect.CallerSensitive; 36 import jdk.internal.reflect.Reflection; 37 import jdk.internal.vm.annotation.DontInline; 38 import jdk.internal.vm.annotation.ForceInline; 39 import jdk.internal.vm.annotation.ReservedStackAccess; 40 41 /** 42 * <p> The AccessController class is used for access control operations 43 * and decisions. 44 * 45 * <p> More specifically, the AccessController class is used for 46 * three purposes: 47 * 48 * <ul> 49 * <li> to decide whether an access to a critical system 50 * resource is to be allowed or denied, based on the security policy 51 * currently in effect, 52 * <li>to mark code as being "privileged", thus affecting subsequent 53 * access determinations, and 54 * <li>to obtain a "snapshot" of the current calling context so 55 * access-control decisions from a different context can be made with 56 * respect to the saved context. </ul> 57 * 58 * <p> The {@link #checkPermission(Permission) checkPermission} method 59 * determines whether the access request indicated by a specified 60 * permission should be granted or denied. A sample call appears 61 * below. In this example, {@code checkPermission} will determine 62 * whether or not to grant "read" access to the file named "testFile" in 63 * the "/temp" directory. 64 * 65 * <pre> 66 * 67 * FilePermission perm = new FilePermission("/temp/testFile", "read"); 68 * AccessController.checkPermission(perm); 69 * 70 * </pre> 71 * 72 * <p> If a requested access is allowed, 73 * {@code checkPermission} returns quietly. If denied, an 74 * AccessControlException is 75 * thrown. AccessControlException can also be thrown if the requested 76 * permission is of an incorrect type or contains an invalid value. 77 * Such information is given whenever possible. 78 * 79 * Suppose the current thread traversed m callers, in the order of caller 1 80 * to caller 2 to caller m. Then caller m invoked the 81 * {@code checkPermission} method. 82 * The {@code checkPermission} method determines whether access 83 * is granted or denied based on the following algorithm: 84 * 85 * <pre> {@code 86 * for (int i = m; i > 0; i--) { 87 * 88 * if (caller i's domain does not have the permission) 89 * throw AccessControlException 90 * 91 * else if (caller i is marked as privileged) { 92 * if (a context was specified in the call to doPrivileged) 93 * context.checkPermission(permission) 94 * if (limited permissions were specified in the call to doPrivileged) { 95 * for (each limited permission) { 96 * if (the limited permission implies the requested permission) 97 * return; 98 * } 99 * } else 100 * return; 101 * } 102 * } 103 * 104 * // Next, check the context inherited when the thread was created. 105 * // Whenever a new thread is created, the AccessControlContext at 106 * // that time is stored and associated with the new thread, as the 107 * // "inherited" context. 108 * 109 * inheritedContext.checkPermission(permission); 110 * }</pre> 111 * 112 * <p> A caller can be marked as being "privileged" 113 * (see {@link #doPrivileged(PrivilegedAction) doPrivileged} and below). 114 * When making access control decisions, the {@code checkPermission} 115 * method stops checking if it reaches a caller that 116 * was marked as "privileged" via a {@code doPrivileged} 117 * call without a context argument (see below for information about a 118 * context argument). If that caller's domain has the 119 * specified permission and at least one limiting permission argument (if any) 120 * implies the requested permission, no further checking is done and 121 * {@code checkPermission} 122 * returns quietly, indicating that the requested access is allowed. 123 * If that domain does not have the specified permission, an exception 124 * is thrown, as usual. If the caller's domain had the specified permission 125 * but it was not implied by any limiting permission arguments given in the call 126 * to {@code doPrivileged} then the permission checking continues 127 * until there are no more callers or another {@code doPrivileged} 128 * call matches the requested permission and returns normally. 129 * 130 * <p> The normal use of the "privileged" feature is as follows. If you 131 * don't need to return a value from within the "privileged" block, do 132 * the following: 133 * 134 * <pre> {@code 135 * somemethod() { 136 * ...normal code here... 137 * AccessController.doPrivileged(new PrivilegedAction<Void>() { 138 * public Void run() { 139 * // privileged code goes here, for example: 140 * System.loadLibrary("awt"); 141 * return null; // nothing to return 142 * } 143 * }); 144 * ...normal code here... 145 * }}</pre> 146 * 147 * <p> 148 * PrivilegedAction is an interface with a single method, named 149 * {@code run}. 150 * The above example shows creation of an implementation 151 * of that interface; a concrete implementation of the 152 * {@code run} method is supplied. 153 * When the call to {@code doPrivileged} is made, an 154 * instance of the PrivilegedAction implementation is passed 155 * to it. The {@code doPrivileged} method calls the 156 * {@code run} method from the PrivilegedAction 157 * implementation after enabling privileges, and returns the 158 * {@code run} method's return value as the 159 * {@code doPrivileged} return value (which is 160 * ignored in this example). 161 * 162 * <p> If you need to return a value, you can do something like the following: 163 * 164 * <pre> {@code 165 * somemethod() { 166 * ...normal code here... 167 * String user = AccessController.doPrivileged( 168 * new PrivilegedAction<String>() { 169 * public String run() { 170 * return System.getProperty("user.name"); 171 * } 172 * }); 173 * ...normal code here... 174 * }}</pre> 175 * 176 * <p>If the action performed in your {@code run} method could 177 * throw a "checked" exception (those listed in the {@code throws} clause 178 * of a method), then you need to use the 179 * {@code PrivilegedExceptionAction} interface instead of the 180 * {@code PrivilegedAction} interface: 181 * 182 * <pre> {@code 183 * somemethod() throws FileNotFoundException { 184 * ...normal code here... 185 * try { 186 * FileInputStream fis = AccessController.doPrivileged( 187 * new PrivilegedExceptionAction<FileInputStream>() { 188 * public FileInputStream run() throws FileNotFoundException { 189 * return new FileInputStream("someFile"); 190 * } 191 * }); 192 * } catch (PrivilegedActionException e) { 193 * // e.getException() should be an instance of FileNotFoundException, 194 * // as only "checked" exceptions will be "wrapped" in a 195 * // PrivilegedActionException. 196 * throw (FileNotFoundException) e.getException(); 197 * } 198 * ...normal code here... 199 * }}</pre> 200 * 201 * <p> Be *very* careful in your use of the "privileged" construct, and 202 * always remember to make the privileged code section as small as possible. 203 * You can pass {@code Permission} arguments to further limit the 204 * scope of the "privilege" (see below). 205 * 206 * 207 * <p> Note that {@code checkPermission} always performs security checks 208 * within the context of the currently executing thread. 209 * Sometimes a security check that should be made within a given context 210 * will actually need to be done from within a 211 * <i>different</i> context (for example, from within a worker thread). 212 * The {@link #getContext() getContext} method and 213 * AccessControlContext class are provided 214 * for this situation. The {@code getContext} method takes a "snapshot" 215 * of the current calling context, and places 216 * it in an AccessControlContext object, which it returns. A sample call is 217 * the following: 218 * 219 * <pre> 220 * 221 * AccessControlContext acc = AccessController.getContext() 222 * 223 * </pre> 224 * 225 * <p> 226 * AccessControlContext itself has a {@code checkPermission} method 227 * that makes access decisions based on the context <i>it</i> encapsulates, 228 * rather than that of the current execution thread. 229 * Code within a different context can thus call that method on the 230 * previously-saved AccessControlContext object. A sample call is the 231 * following: 232 * 233 * <pre> 234 * 235 * acc.checkPermission(permission) 236 * 237 * </pre> 238 * 239 * <p> There are also times where you don't know a priori which permissions 240 * to check the context against. In these cases you can use the 241 * doPrivileged method that takes a context. You can also limit the scope 242 * of the privileged code by passing additional {@code Permission} 243 * parameters. 244 * 245 * <pre> {@code 246 * somemethod() { 247 * AccessController.doPrivileged(new PrivilegedAction<Object>() { 248 * public Object run() { 249 * // Code goes here. Any permission checks within this 250 * // run method will require that the intersection of the 251 * // caller's protection domain and the snapshot's 252 * // context have the desired permission. If a requested 253 * // permission is not implied by the limiting FilePermission 254 * // argument then checking of the thread continues beyond the 255 * // caller of doPrivileged. 256 * } 257 * }, acc, new FilePermission("/temp/*", read)); 258 * ...normal code here... 259 * }}</pre> 260 * <p> Passing a limiting {@code Permission} argument of an instance of 261 * {@code AllPermission} is equivalent to calling the equivalent 262 * {@code doPrivileged} method without limiting {@code Permission} 263 * arguments. Passing a zero length array of {@code Permission} disables 264 * the code privileges so that checking always continues beyond the caller of 265 * that {@code doPrivileged} method. 266 * 267 * @see AccessControlContext 268 * 269 * @author Li Gong 270 * @author Roland Schemers 271 * @since 1.2 272 */ 273 274 public final class AccessController { 275 276 /** 277 * Don't allow anyone to instantiate an AccessController 278 */ 279 private AccessController() { } 280 281 /** 282 * Performs the specified {@code PrivilegedAction} with privileges 283 * enabled. The action is performed with <i>all</i> of the permissions 284 * possessed by the caller's protection domain. 285 * 286 * <p> If the action's {@code run} method throws an (unchecked) 287 * exception, it will propagate through this method. 288 * 289 * <p> Note that any DomainCombiner associated with the current 290 * AccessControlContext will be ignored while the action is performed. 291 * 292 * @param <T> the type of the value returned by the PrivilegedAction's 293 * {@code run} method. 294 * 295 * @param action the action to be performed. 296 * 297 * @return the value returned by the action's {@code run} method. 298 * 299 * @exception NullPointerException if the action is {@code null} 300 * 301 * @see #doPrivileged(PrivilegedAction,AccessControlContext) 302 * @see #doPrivileged(PrivilegedExceptionAction) 303 * @see #doPrivilegedWithCombiner(PrivilegedAction) 304 * @see java.security.DomainCombiner 305 */ 306 307 @CallerSensitive 308 public static <T> T doPrivileged(PrivilegedAction<T> action) 309 { 310 return executePrivileged(action, null, Reflection.getCallerClass()); 311 } 312 313 /** 314 * Performs the specified {@code PrivilegedAction} with privileges 315 * enabled. The action is performed with <i>all</i> of the permissions 316 * possessed by the caller's protection domain. 317 * 318 * <p> If the action's {@code run} method throws an (unchecked) 319 * exception, it will propagate through this method. 320 * 321 * <p> This method preserves the current AccessControlContext's 322 * DomainCombiner (which may be null) while the action is performed. 323 * 324 * @param <T> the type of the value returned by the PrivilegedAction's 325 * {@code run} method. 326 * 327 * @param action the action to be performed. 328 * 329 * @return the value returned by the action's {@code run} method. 330 * 331 * @exception NullPointerException if the action is {@code null} 332 * 333 * @see #doPrivileged(PrivilegedAction) 334 * @see java.security.DomainCombiner 335 * 336 * @since 1.6 337 */ 338 @CallerSensitive 339 public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) { 340 AccessControlContext acc = getStackAccessControlContext(); 341 if (acc == null) { 342 return AccessController.doPrivileged(action); 343 } 344 DomainCombiner dc = acc.getAssignedCombiner(); 345 return AccessController.doPrivileged(action, 346 preserveCombiner(dc, Reflection.getCallerClass())); 347 } 348 349 350 /** 351 * Performs the specified {@code PrivilegedAction} with privileges 352 * enabled and restricted by the specified {@code AccessControlContext}. 353 * The action is performed with the intersection of the permissions 354 * possessed by the caller's protection domain, and those possessed 355 * by the domains represented by the specified {@code AccessControlContext}. 356 * <p> 357 * If the action's {@code run} method throws an (unchecked) exception, 358 * it will propagate through this method. 359 * <p> 360 * If a security manager is installed and the specified 361 * {@code AccessControlContext} was not created by system code and the 362 * caller's {@code ProtectionDomain} has not been granted the 363 * {@literal "createAccessControlContext"} 364 * {@link java.security.SecurityPermission}, then the action is performed 365 * with no permissions. 366 * 367 * @param <T> the type of the value returned by the PrivilegedAction's 368 * {@code run} method. 369 * @param action the action to be performed. 370 * @param context an <i>access control context</i> 371 * representing the restriction to be applied to the 372 * caller's domain's privileges before performing 373 * the specified action. If the context is 374 * {@code null}, then no additional restriction is applied. 375 * 376 * @return the value returned by the action's {@code run} method. 377 * 378 * @exception NullPointerException if the action is {@code null} 379 * 380 * @see #doPrivileged(PrivilegedAction) 381 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 382 */ 383 @CallerSensitive 384 public static <T> T doPrivileged(PrivilegedAction<T> action, 385 AccessControlContext context) 386 { 387 Class<?> caller = Reflection.getCallerClass(); 388 context = checkContext(context, caller); 389 return executePrivileged(action, context, caller); 390 } 391 392 393 /** 394 * Performs the specified {@code PrivilegedAction} with privileges 395 * enabled and restricted by the specified 396 * {@code AccessControlContext} and with a privilege scope limited 397 * by specified {@code Permission} arguments. 398 * 399 * The action is performed with the intersection of the permissions 400 * possessed by the caller's protection domain, and those possessed 401 * by the domains represented by the specified 402 * {@code AccessControlContext}. 403 * <p> 404 * If the action's {@code run} method throws an (unchecked) exception, 405 * it will propagate through this method. 406 * <p> 407 * If a security manager is installed and the specified 408 * {@code AccessControlContext} was not created by system code and the 409 * caller's {@code ProtectionDomain} has not been granted the 410 * {@literal "createAccessControlContext"} 411 * {@link java.security.SecurityPermission}, then the action is performed 412 * with no permissions. 413 * 414 * @param <T> the type of the value returned by the PrivilegedAction's 415 * {@code run} method. 416 * @param action the action to be performed. 417 * @param context an <i>access control context</i> 418 * representing the restriction to be applied to the 419 * caller's domain's privileges before performing 420 * the specified action. If the context is 421 * {@code null}, 422 * then no additional restriction is applied. 423 * @param perms the {@code Permission} arguments which limit the 424 * scope of the caller's privileges. The number of arguments 425 * is variable. 426 * 427 * @return the value returned by the action's {@code run} method. 428 * 429 * @throws NullPointerException if action or perms or any element of 430 * perms is {@code null} 431 * 432 * @see #doPrivileged(PrivilegedAction) 433 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 434 * 435 * @since 1.8 436 */ 437 @CallerSensitive 438 public static <T> T doPrivileged(PrivilegedAction<T> action, 439 AccessControlContext context, Permission... perms) { 440 441 AccessControlContext parent = getContext(); 442 if (perms == null) { 443 throw new NullPointerException("null permissions parameter"); 444 } 445 Class<?> caller = Reflection.getCallerClass(); 446 return AccessController.doPrivileged(action, createWrapper(null, 447 caller, parent, context, perms)); 448 } 449 450 451 /** 452 * Performs the specified {@code PrivilegedAction} with privileges 453 * enabled and restricted by the specified 454 * {@code AccessControlContext} and with a privilege scope limited 455 * by specified {@code Permission} arguments. 456 * 457 * The action is performed with the intersection of the permissions 458 * possessed by the caller's protection domain, and those possessed 459 * by the domains represented by the specified 460 * {@code AccessControlContext}. 461 * <p> 462 * If the action's {@code run} method throws an (unchecked) exception, 463 * it will propagate through this method. 464 * 465 * <p> This method preserves the current AccessControlContext's 466 * DomainCombiner (which may be null) while the action is performed. 467 * <p> 468 * If a security manager is installed and the specified 469 * {@code AccessControlContext} was not created by system code and the 470 * caller's {@code ProtectionDomain} has not been granted the 471 * {@literal "createAccessControlContext"} 472 * {@link java.security.SecurityPermission}, then the action is performed 473 * with no permissions. 474 * 475 * @param <T> the type of the value returned by the PrivilegedAction's 476 * {@code run} method. 477 * @param action the action to be performed. 478 * @param context an <i>access control context</i> 479 * representing the restriction to be applied to the 480 * caller's domain's privileges before performing 481 * the specified action. If the context is 482 * {@code null}, 483 * then no additional restriction is applied. 484 * @param perms the {@code Permission} arguments which limit the 485 * scope of the caller's privileges. The number of arguments 486 * is variable. 487 * 488 * @return the value returned by the action's {@code run} method. 489 * 490 * @throws NullPointerException if action or perms or any element of 491 * perms is {@code null} 492 * 493 * @see #doPrivileged(PrivilegedAction) 494 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 495 * @see java.security.DomainCombiner 496 * 497 * @since 1.8 498 */ 499 @CallerSensitive 500 public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action, 501 AccessControlContext context, Permission... perms) { 502 503 AccessControlContext parent = getContext(); 504 DomainCombiner dc = parent.getCombiner(); 505 if (dc == null && context != null) { 506 dc = context.getCombiner(); 507 } 508 if (perms == null) { 509 throw new NullPointerException("null permissions parameter"); 510 } 511 Class<?> caller = Reflection.getCallerClass(); 512 return AccessController.doPrivileged(action, createWrapper(dc, caller, 513 parent, context, perms)); 514 } 515 516 /** 517 * Performs the specified {@code PrivilegedExceptionAction} with 518 * privileges enabled. The action is performed with <i>all</i> of the 519 * permissions possessed by the caller's protection domain. 520 * 521 * <p> If the action's {@code run} method throws an <i>unchecked</i> 522 * exception, it will propagate through this method. 523 * 524 * <p> Note that any DomainCombiner associated with the current 525 * AccessControlContext will be ignored while the action is performed. 526 * 527 * @param <T> the type of the value returned by the 528 * PrivilegedExceptionAction's {@code run} method. 529 * 530 * @param action the action to be performed 531 * 532 * @return the value returned by the action's {@code run} method 533 * 534 * @exception PrivilegedActionException if the specified action's 535 * {@code run} method threw a <i>checked</i> exception 536 * @exception NullPointerException if the action is {@code null} 537 * 538 * @see #doPrivileged(PrivilegedAction) 539 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 540 * @see #doPrivilegedWithCombiner(PrivilegedExceptionAction) 541 * @see java.security.DomainCombiner 542 */ 543 @CallerSensitive 544 public static <T> T 545 doPrivileged(PrivilegedExceptionAction<T> action) 546 throws PrivilegedActionException 547 { 548 AccessControlContext context = null; 549 Class<?> caller = Reflection.getCallerClass(); 550 try { 551 return executePrivileged(action, context, caller); 552 } catch (RuntimeException e) { 553 throw e; 554 } catch (Exception e) { 555 throw wrapException(e); 556 } 557 } 558 559 /** 560 * Performs the specified {@code PrivilegedExceptionAction} with 561 * privileges enabled. The action is performed with <i>all</i> of the 562 * permissions possessed by the caller's protection domain. 563 * 564 * <p> If the action's {@code run} method throws an <i>unchecked</i> 565 * exception, it will propagate through this method. 566 * 567 * <p> This method preserves the current AccessControlContext's 568 * DomainCombiner (which may be null) while the action is performed. 569 * 570 * @param <T> the type of the value returned by the 571 * PrivilegedExceptionAction's {@code run} method. 572 * 573 * @param action the action to be performed. 574 * 575 * @return the value returned by the action's {@code run} method 576 * 577 * @exception PrivilegedActionException if the specified action's 578 * {@code run} method threw a <i>checked</i> exception 579 * @exception NullPointerException if the action is {@code null} 580 * 581 * @see #doPrivileged(PrivilegedAction) 582 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 583 * @see java.security.DomainCombiner 584 * 585 * @since 1.6 586 */ 587 @CallerSensitive 588 public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action) 589 throws PrivilegedActionException 590 { 591 AccessControlContext acc = getStackAccessControlContext(); 592 if (acc == null) { 593 return AccessController.doPrivileged(action); 594 } 595 DomainCombiner dc = acc.getAssignedCombiner(); 596 return AccessController.doPrivileged(action, 597 preserveCombiner(dc, Reflection.getCallerClass())); 598 } 599 600 /** 601 * preserve the combiner across the doPrivileged call 602 */ 603 private static AccessControlContext preserveCombiner(DomainCombiner combiner, 604 Class<?> caller) 605 { 606 return createWrapper(combiner, caller, null, null, null); 607 } 608 609 /** 610 * Create a wrapper to contain the limited privilege scope data. 611 */ 612 private static AccessControlContext 613 createWrapper(DomainCombiner combiner, Class<?> caller, 614 AccessControlContext parent, AccessControlContext context, 615 Permission[] perms) 616 { 617 ProtectionDomain callerPD = getProtectionDomain(caller); 618 // check if caller is authorized to create context 619 if (System.getSecurityManager() != null && 620 context != null && !context.isAuthorized() && 621 !callerPD.implies(SecurityConstants.CREATE_ACC_PERMISSION)) 622 { 623 return getInnocuousAcc(); 624 } else { 625 return new AccessControlContext(callerPD, combiner, parent, 626 context, perms); 627 } 628 } 629 630 private static class AccHolder { 631 // An AccessControlContext with no granted permissions. 632 // Only initialized on demand when getInnocuousAcc() is called. 633 static final AccessControlContext innocuousAcc = 634 new AccessControlContext(new ProtectionDomain[] { 635 new ProtectionDomain(null, null) }); 636 } 637 private static AccessControlContext getInnocuousAcc() { 638 return AccHolder.innocuousAcc; 639 } 640 641 private static native ProtectionDomain getProtectionDomain(final Class<?> caller); 642 643 /** 644 * Performs the specified {@code PrivilegedExceptionAction} with 645 * privileges enabled and restricted by the specified 646 * {@code AccessControlContext}. The action is performed with the 647 * intersection of the permissions possessed by the caller's 648 * protection domain, and those possessed by the domains represented by the 649 * specified {@code AccessControlContext}. 650 * <p> 651 * If the action's {@code run} method throws an <i>unchecked</i> 652 * exception, it will propagate through this method. 653 * <p> 654 * If a security manager is installed and the specified 655 * {@code AccessControlContext} was not created by system code and the 656 * caller's {@code ProtectionDomain} has not been granted the 657 * {@literal "createAccessControlContext"} 658 * {@link java.security.SecurityPermission}, then the action is performed 659 * with no permissions. 660 * 661 * @param <T> the type of the value returned by the 662 * PrivilegedExceptionAction's {@code run} method. 663 * @param action the action to be performed 664 * @param context an <i>access control context</i> 665 * representing the restriction to be applied to the 666 * caller's domain's privileges before performing 667 * the specified action. If the context is 668 * {@code null}, then no additional restriction is applied. 669 * 670 * @return the value returned by the action's {@code run} method 671 * 672 * @exception PrivilegedActionException if the specified action's 673 * {@code run} method threw a <i>checked</i> exception 674 * @exception NullPointerException if the action is {@code null} 675 * 676 * @see #doPrivileged(PrivilegedAction) 677 * @see #doPrivileged(PrivilegedAction,AccessControlContext) 678 */ 679 @CallerSensitive 680 public static <T> T 681 doPrivileged(PrivilegedExceptionAction<T> action, 682 AccessControlContext context) 683 throws PrivilegedActionException 684 { 685 Class<?> caller = Reflection.getCallerClass(); 686 context = checkContext(context, caller); 687 try { 688 return executePrivileged(action, context, caller); 689 } catch (RuntimeException e) { 690 throw e; 691 } catch (Exception e) { 692 throw wrapException(e); 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 */ 793 @Hidden 794 @ForceInline 795 @ReservedStackAccess 796 private static PrivilegedActionException wrapException(Exception e) { 797 return new PrivilegedActionException(e); 798 } 799 800 /** 801 * Performs the specified {@code PrivilegedExceptionAction} with 802 * privileges enabled and restricted by the specified 803 * {@code AccessControlContext} and with a privilege scope limited by 804 * specified {@code Permission} arguments. 805 * 806 * The action is performed with the intersection of the permissions 807 * possessed by the caller's protection domain, and those possessed 808 * by the domains represented by the specified 809 * {@code AccessControlContext}. 810 * <p> 811 * If the action's {@code run} method throws an (unchecked) exception, 812 * it will propagate through this method. 813 * <p> 814 * If a security manager is installed and the specified 815 * {@code AccessControlContext} was not created by system code and the 816 * caller's {@code ProtectionDomain} has not been granted the 817 * {@literal "createAccessControlContext"} 818 * {@link java.security.SecurityPermission}, then the action is performed 819 * with no permissions. 820 * 821 * @param <T> the type of the value returned by the 822 * PrivilegedExceptionAction's {@code run} method. 823 * @param action the action to be performed. 824 * @param context an <i>access control context</i> 825 * representing the restriction to be applied to the 826 * caller's domain's privileges before performing 827 * the specified action. If the context is 828 * {@code null}, 829 * then no additional restriction is applied. 830 * @param perms the {@code Permission} arguments which limit the 831 * scope of the caller's privileges. The number of arguments 832 * is variable. 833 * 834 * @return the value returned by the action's {@code run} method. 835 * 836 * @throws PrivilegedActionException if the specified action's 837 * {@code run} method threw a <i>checked</i> exception 838 * @throws NullPointerException if action or perms or any element of 839 * perms is {@code null} 840 * 841 * @see #doPrivileged(PrivilegedAction) 842 * @see #doPrivileged(PrivilegedAction,AccessControlContext) 843 * 844 * @since 1.8 845 */ 846 @CallerSensitive 847 public static <T> T doPrivileged(PrivilegedExceptionAction<T> action, 848 AccessControlContext context, Permission... perms) 849 throws PrivilegedActionException 850 { 851 AccessControlContext parent = getContext(); 852 if (perms == null) { 853 throw new NullPointerException("null permissions parameter"); 854 } 855 Class<?> caller = Reflection.getCallerClass(); 856 return AccessController.doPrivileged(action, createWrapper(null, caller, parent, context, perms)); 857 } 858 859 860 /** 861 * Performs the specified {@code PrivilegedExceptionAction} with 862 * privileges enabled and restricted by the specified 863 * {@code AccessControlContext} and with a privilege scope limited by 864 * specified {@code Permission} arguments. 865 * 866 * The action is performed with the intersection of the permissions 867 * possessed by the caller's protection domain, and those possessed 868 * by the domains represented by the specified 869 * {@code AccessControlContext}. 870 * <p> 871 * If the action's {@code run} method throws an (unchecked) exception, 872 * it will propagate through this method. 873 * 874 * <p> This method preserves the current AccessControlContext's 875 * DomainCombiner (which may be null) while the action is performed. 876 * <p> 877 * If a security manager is installed and the specified 878 * {@code AccessControlContext} was not created by system code and the 879 * caller's {@code ProtectionDomain} has not been granted the 880 * {@literal "createAccessControlContext"} 881 * {@link java.security.SecurityPermission}, then the action is performed 882 * with no permissions. 883 * 884 * @param <T> the type of the value returned by the 885 * PrivilegedExceptionAction's {@code run} method. 886 * @param action the action to be performed. 887 * @param context an <i>access control context</i> 888 * representing the restriction to be applied to the 889 * caller's domain's privileges before performing 890 * the specified action. If the context is 891 * {@code null}, 892 * then no additional restriction is applied. 893 * @param perms the {@code Permission} arguments which limit the 894 * scope of the caller's privileges. The number of arguments 895 * is variable. 896 * 897 * @return the value returned by the action's {@code run} method. 898 * 899 * @throws PrivilegedActionException if the specified action's 900 * {@code run} method threw a <i>checked</i> exception 901 * @throws NullPointerException if action or perms or any element of 902 * perms is {@code null} 903 * 904 * @see #doPrivileged(PrivilegedAction) 905 * @see #doPrivileged(PrivilegedAction,AccessControlContext) 906 * @see java.security.DomainCombiner 907 * 908 * @since 1.8 909 */ 910 @CallerSensitive 911 public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action, 912 AccessControlContext context, 913 Permission... perms) 914 throws PrivilegedActionException 915 { 916 AccessControlContext parent = getContext(); 917 DomainCombiner dc = parent.getCombiner(); 918 if (dc == null && context != null) { 919 dc = context.getCombiner(); 920 } 921 if (perms == null) { 922 throw new NullPointerException("null permissions parameter"); 923 } 924 Class<?> caller = Reflection.getCallerClass(); 925 return AccessController.doPrivileged(action, createWrapper(dc, caller, 926 parent, context, perms)); 927 } 928 929 /** 930 * Returns the AccessControl context. i.e., it gets 931 * the protection domains of all the callers on the stack, 932 * starting at the first class with a non-null 933 * ProtectionDomain. 934 * 935 * @return the access control context based on the current stack or 936 * null if there was only privileged system code. 937 */ 938 939 private static native AccessControlContext getStackAccessControlContext(); 940 941 942 /** 943 * Returns the "inherited" AccessControl context. This is the context 944 * that existed when the thread was created. Package private so 945 * AccessControlContext can use it. 946 */ 947 948 static native AccessControlContext getInheritedAccessControlContext(); 949 950 /** 951 * This method takes a "snapshot" of the current calling context, which 952 * includes the current Thread's inherited AccessControlContext and any 953 * limited privilege scope, and places it in an AccessControlContext object. 954 * This context may then be checked at a later point, possibly in another thread. 955 * 956 * @see AccessControlContext 957 * 958 * @return the AccessControlContext based on the current context. 959 */ 960 961 public static AccessControlContext getContext() 962 { 963 AccessControlContext acc = getStackAccessControlContext(); 964 if (acc == null) { 965 // all we had was privileged system code. We don't want 966 // to return null though, so we construct a real ACC. 967 return new AccessControlContext(null, true); 968 } else { 969 return acc.optimize(); 970 } 971 } 972 973 /** 974 * Determines whether the access request indicated by the 975 * specified permission should be allowed or denied, based on 976 * the current AccessControlContext and security policy. 977 * This method quietly returns if the access request 978 * is permitted, or throws an AccessControlException otherwise. The 979 * getPermission method of the AccessControlException returns the 980 * {@code perm} Permission object instance. 981 * 982 * @param perm the requested permission. 983 * 984 * @exception AccessControlException if the specified permission 985 * is not permitted, based on the current security policy. 986 * @exception NullPointerException if the specified permission 987 * is {@code null} and is checked based on the 988 * security policy currently in effect. 989 */ 990 991 public static void checkPermission(Permission perm) 992 throws AccessControlException 993 { 994 //System.err.println("checkPermission "+perm); 995 //Thread.currentThread().dumpStack(); 996 997 if (perm == null) { 998 throw new NullPointerException("permission can't be null"); 999 } 1000 1001 AccessControlContext stack = getStackAccessControlContext(); 1002 // if context is null, we had privileged system code on the stack. 1003 if (stack == null) { 1004 Debug debug = AccessControlContext.getDebug(); 1005 boolean dumpDebug = false; 1006 if (debug != null) { 1007 dumpDebug = !Debug.isOn("codebase="); 1008 dumpDebug &= !Debug.isOn("permission=") || 1009 Debug.isOn("permission=" + perm.getClass().getCanonicalName()); 1010 } 1011 1012 if (dumpDebug && Debug.isOn("stack")) { 1013 Thread.dumpStack(); 1014 } 1015 1016 if (dumpDebug && Debug.isOn("domain")) { 1017 debug.println("domain (context is null)"); 1018 } 1019 1020 if (dumpDebug) { 1021 debug.println("access allowed "+perm); 1022 } 1023 return; 1024 } 1025 1026 AccessControlContext acc = stack.optimize(); 1027 acc.checkPermission(perm); 1028 } 1029 }