JEP 176: Mechanical Checking of Caller-Sensitive Methods
|Authors||John Rose, Christian Thalinger, Mandy Chung|
|Discussion||core dash libs dash dev at openjdk dot java dot net|
|Reviewed by||Alan Bateman, Sean Mullan|
|Endorsed by||Brian Goetz|
Improve the security of the JDK's method-handle implementation by replacing the existing hand-maintained list of caller-sensitive methods with a mechanism that accurately identifies such methods and allows their callers to be discovered reliably.
@CallerSensitive annotation may be useful for other types
of analyses or audits, but such activities are beyond the scope of this
It is also not a goal to provide a public API for non-system code.
A caller-sensitive method varies its behavior according to the class of
its immediate caller. It discovers its caller's class by invoking the
Most caller-sensitive methods act in some way as an agent for the caller.
When invoked via reflection, these methods must be handled specially in
order to ensure that the class of the actual caller, rather than some
class of the reflection mechanism itself, is returned by the
getCallerClass method. The logic for doing this involves pattern
matching against a hand-maintained list of caller-sensitive methods,
which is brittle and difficult to maintain.
To improve on this we will mark all caller-sensitive methods in the JDK
with the internal annotation
@sun.reflect.CallerSensitive. The JVM
will track this annotation and, optionally, enforce the invariant that
sun.reflect.Reflection.getCallerClass method can only report the
caller of a method when that method is marked with this annotation. The
JVM will set a new caller-sensitive bit when resolving a MemberName, and
the package-private method
java.lang.invoke.MethodHandleNatives.isCallerSensitive will be upgraded
to query it directly rather than consult a list of method names.
@CallerSensitive annotation might be useful for other purposes,
such as tracking the introduction of new caller-sensitive methods or
providing similar special handling in the
There are two places in the JDK where methods examine stack frames beyond their immediate callers. We propose the following changes in order to enforce the caller-sensitivity check reliably:
SecurityManager.checkMemberAccessmethod, with a view to changing it to throw an exception unconditionally in a future release. The
checkMemberAccessmethod requires the caller's frame to be at a stack depth of four, which is fragile and difficult to enforce.
java.util.logging.Loggernot to walk the stack in search of a resource bundle. This stack walk was intended as a temporary measure to allow containers to transition to using the context class loader. It is already specified to be removed in a future release.
@CallerSensitive annotation, as described above, but use it
only to validate the hand-maintained method list. This alternative would
be an improvement, but checking the annotation at runtime is more
Existing test suites will serve well as positive test cases for this feature. New negative test cases are required to identify caller-sensitive methods that are not properly marked.
Risks and Assumptions
There is a small risk that this change will cause side effects. We assume that the already-planned extensive testing of JDK 8 will uncover any such issues.
Performance: We expect negligible performance impact. The JVM is already parsing runtime method annotations for JSR 292 and the check will be relatively cheap compared to the expensive stack-walk operation.
Compatibility: Applications that depend upon the stack-walking behavior of the
Loggerclass will no longer work.