-
JEP
-
Resolution: Delivered
-
P4
-
None
-
None
-
John Rose, Christian Thalinger, Mandy Chung
-
Feature
-
Open
-
JDK
-
-
S
-
176
Summary
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.
Non-Goals
The proposed @CallerSensitive
annotation may be useful for other types
of analyses or audits, but such activities are beyond the scope of this
JEP.
It is also not a goal to provide a public API for non-system code.
Description
A caller-sensitive method varies its behavior according to the class of
its immediate caller. It discovers its caller's class by invoking the
sun.reflect.Reflection.getCallerClass
method.
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
the 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.
The @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
sun.reflect.misc.MethodUtil.invoke
method.
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:
Deprecate the
SecurityManager.checkMemberAccess
method, with a view to changing it to throw an exception unconditionally in a future release. ThecheckMemberAccess
method requires the caller's frame to be at a stack depth of four, which is fragile and difficult to enforce.Revise
java.util.logging.Logger
not 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.
Alternatives
Add the @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
reliable.
Testing
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.
Impact
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
Logger
class will no longer work.