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.lang.reflect;
27
28 import java.lang.annotation.Annotation;
29 import java.security.AccessController;
30
31 import jdk.internal.reflect.CallerSensitive;
32 import jdk.internal.reflect.Reflection;
33 import jdk.internal.reflect.ReflectionFactory;
34
35 /**
36 * The {@code AccessibleObject} class is the base class for {@code Field},
37 * {@code Method}, and {@code Constructor} objects (known as <em>reflected
38 * objects</em>). It provides the ability to flag a reflected object as
39 * suppressing checks for Java language access control when it is used. This
40 * permits sophisticated applications with sufficient privilege, such as Java
41 * Object Serialization or other persistence mechanisms, to manipulate objects
42 * in a manner that would normally be prohibited.
43 *
44 * <p> Java language access control prevents use of private members outside
45 * their class; package access members outside their package; protected members
46 * outside their package or subclasses; and public members outside their
47 * module unless they are declared in an {@link Module#isExported(String,Module)
48 * exported} package and the user {@link Module#canRead reads} their module. By
49 * default, Java language access control is enforced (with one variation) when
50 * {@code Field}s, {@code Method}s, or {@code Constructor}s are used to get or
51 * set fields, to invoke methods, or to create and initialize new instances of
52 * classes, respectively. Every reflected object checks that the code using it
53 * is in an appropriate class, package, or module. </p>
271 */
272 void checkCanSetAccessible(Class<?> caller) {
273 // do nothing, needs to be overridden by Constructor, Method, Field
274 }
275
276
277 void checkCanSetAccessible(Class<?> caller, Class<?> declaringClass) {
278 checkCanSetAccessible(caller, declaringClass, true);
279 }
280
281 private boolean checkCanSetAccessible(Class<?> caller,
282 Class<?> declaringClass,
283 boolean throwExceptionIfDenied) {
284 Module callerModule = caller.getModule();
285 Module declaringModule = declaringClass.getModule();
286
287 if (callerModule == declaringModule) return true;
288 if (callerModule == Object.class.getModule()) return true;
289 if (!declaringModule.isNamed()) return true;
290
291 // package is open to caller
292 String pn = packageName(declaringClass);
293 if (declaringModule.isOpen(pn, callerModule)) {
294 dumpStackIfOpenedReflectively(declaringModule, pn, callerModule);
295 return true;
296 }
297
298 // package is exported to caller
299 boolean isExported = declaringModule.isExported(pn, callerModule);
300 boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers());
301 int modifiers;
302 if (this instanceof Executable) {
303 modifiers = ((Executable) this).getModifiers();
304 } else {
305 modifiers = ((Field) this).getModifiers();
306 }
307 if (isExported && isClassPublic) {
308
309 // member is public
310 if (Modifier.isPublic(modifiers)) {
311 dumpStackIfExportedReflectively(declaringModule, pn, callerModule);
312 return true;
313 }
314
315 // member is protected-static
316 if (Modifier.isProtected(modifiers)
317 && Modifier.isStatic(modifiers)
318 && isSubclassOf(caller, declaringClass)) {
319 dumpStackIfExportedReflectively(declaringModule, pn, callerModule);
320 return true;
321 }
322 }
323
324 if (throwExceptionIfDenied) {
325 // not accessible
326 String msg = "Unable to make ";
327 if (this instanceof Field)
328 msg += "field ";
329 msg += this + " accessible: " + declaringModule + " does not \"";
330 if (isClassPublic && Modifier.isPublic(modifiers))
331 msg += "exports";
332 else
333 msg += "opens";
334 msg += " " + pn + "\" to " + callerModule;
335 InaccessibleObjectException e = new InaccessibleObjectException(msg);
336 if (Reflection.printStackTraceWhenAccessFails()) {
337 e.printStackTrace(System.err);
338 }
339 throw e;
340 }
341 return false;
342 }
343
344 private boolean isSubclassOf(Class<?> queryClass, Class<?> ofClass) {
345 while (queryClass != null) {
346 if (queryClass == ofClass) {
347 return true;
348 }
349 queryClass = queryClass.getSuperclass();
350 }
351 return false;
352 }
353
354 private void dumpStackIfOpenedReflectively(Module module,
355 String pn,
356 Module other) {
357 dumpStackIfExposedReflectively(module, pn, other, true);
358 }
359
360 private void dumpStackIfExportedReflectively(Module module,
361 String pn,
362 Module other) {
363 dumpStackIfExposedReflectively(module, pn, other, false);
364 }
365
366 private void dumpStackIfExposedReflectively(Module module,
367 String pn,
368 Module other,
369 boolean open)
370 {
371 if (Reflection.printStackTraceWhenAccessSucceeds()
372 && !module.isStaticallyExportedOrOpen(pn, other, open))
373 {
374 String msg = other + " allowed to invoke setAccessible on ";
375 if (this instanceof Field)
376 msg += "field ";
377 msg += this;
378 new Exception(msg) {
379 private static final long serialVersionUID = 42L;
380 public String toString() {
381 return "WARNING: " + getMessage();
382 }
383 }.printStackTrace(System.err);
384 }
385 }
386
387 /**
388 * Returns the package name of the given class.
389 */
390 private static String packageName(Class<?> c) {
391 while (c.isArray()) {
392 c = c.getComponentType();
393 }
394 String pn = c.getPackageName();
395 return (pn != null) ? pn : "";
396 }
397
398 /**
399 * Get the value of the {@code accessible} flag for this reflected object.
400 *
401 * @return the value of the object's {@code accessible} flag
402 *
403 * @deprecated
404 * This method is deprecated because its name hints that it checks
405 * if the reflected object is accessible when it actually indicates
406 * if the checks for Java language access control are suppressed.
407 * This method may return {@code false} on a reflected object that is
408 * accessible to the caller. To test if this reflected object is accessible,
409 * it should use {@link #canAccess(Object)}.
410 *
411 * @revised 9
412 */
413 @Deprecated(since="9")
414 public boolean isAccessible() {
415 return override;
416 }
417
418 /**
419 * Test if the caller can access this reflected object. If this reflected
420 * object corresponds to an instance method or field then this method tests
421 * if the caller can access the given {@code obj} with the reflected object.
422 * For instance methods or fields then the {@code obj} argument must be an
423 * instance of the {@link Member#getDeclaringClass() declaring class}. For
424 * static members and constructors then {@code obj} must be {@code null}.
425 *
426 * <p> This method returns {@code true} if the {@code accessible} flag
427 * is set to {@code true}, i.e. the checks for Java language access control
428 * are suppressed, or if the caller can access the member as
429 * specified in <cite>The Java™ Language Specification</cite>,
430 * with the variation noted in the class description. </p>
431 *
466 // if this object is an instance member, the given object
467 // must be a subclass of the declaring class of this reflected object
468 if (!declaringClass.isAssignableFrom(obj.getClass())) {
469 throw new IllegalArgumentException("object is not an instance of "
470 + declaringClass.getName());
471 }
472 } else if (obj != null) {
473 throw new IllegalArgumentException("non-null object for " + this);
474 }
475
476 // access check is suppressed
477 if (override) return true;
478
479 Class<?> caller = Reflection.getCallerClass();
480 Class<?> targetClass;
481 if (this instanceof Constructor) {
482 targetClass = declaringClass;
483 } else {
484 targetClass = Modifier.isStatic(modifiers) ? null : obj.getClass();
485 }
486 return Reflection.verifyMemberAccess(caller,
487 declaringClass,
488 targetClass,
489 modifiers);
490 }
491
492 /**
493 * Constructor: only used by the Java Virtual Machine.
494 */
495 protected AccessibleObject() {}
496
497 // Indicates whether language-level access checks are overridden
498 // by this object. Initializes to "false". This field is used by
499 // Field, Method, and Constructor.
500 //
501 // NOTE: for security purposes, this field must not be visible
502 // outside this package.
503 boolean override;
504
505 // Reflection factory used by subclasses for creating field,
506 // method, and constructor accessors. Note that this is called
507 // very early in the bootstrapping process.
508 static final ReflectionFactory reflectionFactory =
509 AccessController.doPrivileged(
581 // it is necessary to perform somewhat expensive security checks.
582 // If the security check succeeds for a given class, it will
583 // always succeed (it is not affected by the granting or revoking
584 // of permissions); we speed up the check in the common case by
585 // remembering the last Class for which the check succeeded.
586 //
587 // The simple security check for Constructor is to see if
588 // the caller has already been seen, verified, and cached.
589 // (See also Class.newInstance(), which uses a similar method.)
590 //
591 // A more complicated security check cache is needed for Method and Field
592 // The cache can be either null (empty cache), a 2-array of {caller,targetClass},
593 // or a caller (with targetClass implicitly equal to memberClass).
594 // In the 2-array case, the targetClass is always different from the memberClass.
595 volatile Object securityCheckCache;
596
597 final void checkAccess(Class<?> caller, Class<?> memberClass,
598 Class<?> targetClass, int modifiers)
599 throws IllegalAccessException
600 {
601 if (caller == memberClass) { // quick check
602 return; // ACCESS IS OK
603 }
604 Object cache = securityCheckCache; // read volatile
605 if (targetClass != null // instance member or constructor
606 && Modifier.isProtected(modifiers)
607 && targetClass != memberClass) {
608 // Must match a 2-list of { caller, targetClass }.
609 if (cache instanceof Class[]) {
610 Class<?>[] cache2 = (Class<?>[]) cache;
611 if (cache2[1] == targetClass &&
612 cache2[0] == caller) {
613 return; // ACCESS IS OK
614 }
615 // (Test cache[1] first since range check for [1]
616 // subsumes range check for [0].)
617 }
618 } else if (cache == caller) {
619 // Non-protected case (or targetClass == memberClass or static member).
620 return; // ACCESS IS OK
621 }
622
623 // If no return, fall through to the slow path.
624 slowCheckMemberAccess(caller, memberClass, targetClass, modifiers);
625 }
626
627 // Keep all this slow stuff out of line:
628 void slowCheckMemberAccess(Class<?> caller, Class<?> memberClass,
629 Class<?> targetClass, int modifiers)
630 throws IllegalAccessException
631 {
632 Reflection.ensureMemberAccess(caller, memberClass, targetClass, modifiers);
633
634 // Success: Update the cache.
635 Object cache = (targetClass != null
636 && Modifier.isProtected(modifiers)
637 && targetClass != memberClass)
638 ? new Class<?>[] { caller, targetClass }
639 : caller;
640
641 // Note: The two cache elements are not volatile,
642 // but they are effectively final. The Java memory model
643 // guarantees that the initializing stores for the cache
644 // elements will occur before the volatile write.
645 securityCheckCache = cache; // write volatile
646 }
647 }
|
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.lang.reflect;
27
28 import java.lang.annotation.Annotation;
29 import java.security.AccessController;
30
31 import jdk.internal.misc.VM;
32 import jdk.internal.module.IllegalAccessLogger;
33 import jdk.internal.reflect.CallerSensitive;
34 import jdk.internal.reflect.Reflection;
35 import jdk.internal.reflect.ReflectionFactory;
36 import sun.security.action.GetPropertyAction;
37
38 /**
39 * The {@code AccessibleObject} class is the base class for {@code Field},
40 * {@code Method}, and {@code Constructor} objects (known as <em>reflected
41 * objects</em>). It provides the ability to flag a reflected object as
42 * suppressing checks for Java language access control when it is used. This
43 * permits sophisticated applications with sufficient privilege, such as Java
44 * Object Serialization or other persistence mechanisms, to manipulate objects
45 * in a manner that would normally be prohibited.
46 *
47 * <p> Java language access control prevents use of private members outside
48 * their class; package access members outside their package; protected members
49 * outside their package or subclasses; and public members outside their
50 * module unless they are declared in an {@link Module#isExported(String,Module)
51 * exported} package and the user {@link Module#canRead reads} their module. By
52 * default, Java language access control is enforced (with one variation) when
53 * {@code Field}s, {@code Method}s, or {@code Constructor}s are used to get or
54 * set fields, to invoke methods, or to create and initialize new instances of
55 * classes, respectively. Every reflected object checks that the code using it
56 * is in an appropriate class, package, or module. </p>
274 */
275 void checkCanSetAccessible(Class<?> caller) {
276 // do nothing, needs to be overridden by Constructor, Method, Field
277 }
278
279
280 void checkCanSetAccessible(Class<?> caller, Class<?> declaringClass) {
281 checkCanSetAccessible(caller, declaringClass, true);
282 }
283
284 private boolean checkCanSetAccessible(Class<?> caller,
285 Class<?> declaringClass,
286 boolean throwExceptionIfDenied) {
287 Module callerModule = caller.getModule();
288 Module declaringModule = declaringClass.getModule();
289
290 if (callerModule == declaringModule) return true;
291 if (callerModule == Object.class.getModule()) return true;
292 if (!declaringModule.isNamed()) return true;
293
294 String pn = declaringClass.getPackageName();
295 int modifiers;
296 if (this instanceof Executable) {
297 modifiers = ((Executable) this).getModifiers();
298 } else {
299 modifiers = ((Field) this).getModifiers();
300 }
301
302 // class is public and package is exported to caller
303 boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers());
304 if (isClassPublic && declaringModule.isExported(pn, callerModule)) {
305 // member is public
306 if (Modifier.isPublic(modifiers)) {
307 logIfExportedByBackdoor(caller, declaringClass);
308 return true;
309 }
310
311 // member is protected-static
312 if (Modifier.isProtected(modifiers)
313 && Modifier.isStatic(modifiers)
314 && isSubclassOf(caller, declaringClass)) {
315 logIfExportedByBackdoor(caller, declaringClass);
316 return true;
317 }
318 }
319
320 // package is open to caller
321 if (declaringModule.isOpen(pn, callerModule)) {
322 logIfOpenedByBackdoor(caller, declaringClass);
323 return true;
324 }
325
326 if (throwExceptionIfDenied) {
327 // not accessible
328 String msg = "Unable to make ";
329 if (this instanceof Field)
330 msg += "field ";
331 msg += this + " accessible: " + declaringModule + " does not \"";
332 if (isClassPublic && Modifier.isPublic(modifiers))
333 msg += "exports";
334 else
335 msg += "opens";
336 msg += " " + pn + "\" to " + callerModule;
337 InaccessibleObjectException e = new InaccessibleObjectException(msg);
338 if (printStackTraceWhenAccessFails()) {
339 e.printStackTrace(System.err);
340 }
341 throw e;
342 }
343 return false;
344 }
345
346 private boolean isSubclassOf(Class<?> queryClass, Class<?> ofClass) {
347 while (queryClass != null) {
348 if (queryClass == ofClass) {
349 return true;
350 }
351 queryClass = queryClass.getSuperclass();
352 }
353 return false;
354 }
355
356 private void logIfOpenedByBackdoor(Class<?> caller, Class<?> declaringClass) {
357 Module callerModule = caller.getModule();
358 Module targetModule = declaringClass.getModule();
359 // callerModule is null during early startup
360 if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
361 IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
362 if (logger != null) {
363 logger.logIfOpenedByBackdoor(caller, declaringClass, this::toShortString);
364 }
365 }
366 }
367
368 private void logIfExportedByBackdoor(Class<?> caller, Class<?> declaringClass) {
369 Module callerModule = caller.getModule();
370 Module targetModule = declaringClass.getModule();
371 // callerModule is null during early startup
372 if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
373 IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
374 if (logger != null) {
375 logger.logIfExportedByBackdoor(caller, declaringClass, this::toShortString);
376 }
377 }
378 }
379
380 /**
381 * Returns a short descriptive string to describe this object in log messages.
382 */
383 String toShortString() {
384 return toString();
385 }
386
387 /**
388 * Get the value of the {@code accessible} flag for this reflected object.
389 *
390 * @return the value of the object's {@code accessible} flag
391 *
392 * @deprecated
393 * This method is deprecated because its name hints that it checks
394 * if the reflected object is accessible when it actually indicates
395 * if the checks for Java language access control are suppressed.
396 * This method may return {@code false} on a reflected object that is
397 * accessible to the caller. To test if this reflected object is accessible,
398 * it should use {@link #canAccess(Object)}.
399 *
400 * @revised 9
401 * @spec JPMS
402 */
403 @Deprecated(since="9")
404 public boolean isAccessible() {
405 return override;
406 }
407
408 /**
409 * Test if the caller can access this reflected object. If this reflected
410 * object corresponds to an instance method or field then this method tests
411 * if the caller can access the given {@code obj} with the reflected object.
412 * For instance methods or fields then the {@code obj} argument must be an
413 * instance of the {@link Member#getDeclaringClass() declaring class}. For
414 * static members and constructors then {@code obj} must be {@code null}.
415 *
416 * <p> This method returns {@code true} if the {@code accessible} flag
417 * is set to {@code true}, i.e. the checks for Java language access control
418 * are suppressed, or if the caller can access the member as
419 * specified in <cite>The Java™ Language Specification</cite>,
420 * with the variation noted in the class description. </p>
421 *
456 // if this object is an instance member, the given object
457 // must be a subclass of the declaring class of this reflected object
458 if (!declaringClass.isAssignableFrom(obj.getClass())) {
459 throw new IllegalArgumentException("object is not an instance of "
460 + declaringClass.getName());
461 }
462 } else if (obj != null) {
463 throw new IllegalArgumentException("non-null object for " + this);
464 }
465
466 // access check is suppressed
467 if (override) return true;
468
469 Class<?> caller = Reflection.getCallerClass();
470 Class<?> targetClass;
471 if (this instanceof Constructor) {
472 targetClass = declaringClass;
473 } else {
474 targetClass = Modifier.isStatic(modifiers) ? null : obj.getClass();
475 }
476 return verifyAccess(caller, declaringClass, targetClass, modifiers);
477 }
478
479 /**
480 * Constructor: only used by the Java Virtual Machine.
481 */
482 protected AccessibleObject() {}
483
484 // Indicates whether language-level access checks are overridden
485 // by this object. Initializes to "false". This field is used by
486 // Field, Method, and Constructor.
487 //
488 // NOTE: for security purposes, this field must not be visible
489 // outside this package.
490 boolean override;
491
492 // Reflection factory used by subclasses for creating field,
493 // method, and constructor accessors. Note that this is called
494 // very early in the bootstrapping process.
495 static final ReflectionFactory reflectionFactory =
496 AccessController.doPrivileged(
568 // it is necessary to perform somewhat expensive security checks.
569 // If the security check succeeds for a given class, it will
570 // always succeed (it is not affected by the granting or revoking
571 // of permissions); we speed up the check in the common case by
572 // remembering the last Class for which the check succeeded.
573 //
574 // The simple security check for Constructor is to see if
575 // the caller has already been seen, verified, and cached.
576 // (See also Class.newInstance(), which uses a similar method.)
577 //
578 // A more complicated security check cache is needed for Method and Field
579 // The cache can be either null (empty cache), a 2-array of {caller,targetClass},
580 // or a caller (with targetClass implicitly equal to memberClass).
581 // In the 2-array case, the targetClass is always different from the memberClass.
582 volatile Object securityCheckCache;
583
584 final void checkAccess(Class<?> caller, Class<?> memberClass,
585 Class<?> targetClass, int modifiers)
586 throws IllegalAccessException
587 {
588 if (!verifyAccess(caller, memberClass, targetClass, modifiers)) {
589 IllegalAccessException e = Reflection.newIllegalAccessException(
590 caller, memberClass, targetClass, modifiers);
591 if (printStackTraceWhenAccessFails()) {
592 e.printStackTrace(System.err);
593 }
594 throw e;
595 }
596 }
597
598 final boolean verifyAccess(Class<?> caller, Class<?> memberClass,
599 Class<?> targetClass, int modifiers)
600 {
601 if (caller == memberClass) { // quick check
602 return true; // ACCESS IS OK
603 }
604 Object cache = securityCheckCache; // read volatile
605 if (targetClass != null // instance member or constructor
606 && Modifier.isProtected(modifiers)
607 && targetClass != memberClass) {
608 // Must match a 2-list of { caller, targetClass }.
609 if (cache instanceof Class[]) {
610 Class<?>[] cache2 = (Class<?>[]) cache;
611 if (cache2[1] == targetClass &&
612 cache2[0] == caller) {
613 return true; // ACCESS IS OK
614 }
615 // (Test cache[1] first since range check for [1]
616 // subsumes range check for [0].)
617 }
618 } else if (cache == caller) {
619 // Non-protected case (or targetClass == memberClass or static member).
620 return true; // ACCESS IS OK
621 }
622
623 // If no return, fall through to the slow path.
624 return slowVerifyAccess(caller, memberClass, targetClass, modifiers);
625 }
626
627 // Keep all this slow stuff out of line:
628 private boolean slowVerifyAccess(Class<?> caller, Class<?> memberClass,
629 Class<?> targetClass, int modifiers)
630 {
631 if (!Reflection.verifyMemberAccess(caller, memberClass, targetClass, modifiers)) {
632 // access denied
633 return false;
634 }
635
636 // access okay
637 logIfExportedByBackdoor(caller, memberClass);
638
639 // Success: Update the cache.
640 Object cache = (targetClass != null
641 && Modifier.isProtected(modifiers)
642 && targetClass != memberClass)
643 ? new Class<?>[] { caller, targetClass }
644 : caller;
645
646 // Note: The two cache elements are not volatile,
647 // but they are effectively final. The Java memory model
648 // guarantees that the initializing stores for the cache
649 // elements will occur before the volatile write.
650 securityCheckCache = cache; // write volatile
651 return true;
652 }
653
654 // true to print a stack trace when access fails
655 private static volatile boolean printStackWhenAccessFails;
656
657 // true if printStack* values are initialized
658 private static volatile boolean printStackPropertiesSet;
659
660 /**
661 * Returns true if a stack trace should be printed when access fails.
662 */
663 private static boolean printStackTraceWhenAccessFails() {
664 if (!printStackPropertiesSet && VM.initLevel() >= 1) {
665 String s = GetPropertyAction.privilegedGetProperty(
666 "sun.reflect.debugModuleAccessChecks");
667 if (s != null) {
668 printStackWhenAccessFails = !s.equalsIgnoreCase("false");
669 }
670 printStackPropertiesSet = true;
671 }
672 return printStackWhenAccessFails;
673 }
674 }
|