RFR 8014678: Spurious AccessControlException thrown in java.lang.Class.getEnclosingMethod()
Peter Levart
peter.levart at gmail.com
Wed Feb 25 14:22:46 UTC 2015
Hi Joel,
On 02/24/2015 12:26 PM, Joel Borggrén-Franck wrote:
> Hi,
>
> Here is a fix for an old issue with Class.getEnclosingMethod() and Class.getEnclosingConstructor(). The problem is that we throw a spurious AccessControlException in some cases when looking up enclosingMethod/Ctor in the presence of a SecurityManager.
>
> Consider the following classes:
>
> class C {}
>
> class A {
> public void someMetod() {
> class B {}
> }
> }
>
> If client C has a Class<?> token for B it can call classForB.getEnclosingMethod(). While the client C must have permissions to look at declared members of A, in the nested call java.lang.Class will be looking at declared members of A while constructing the answer, and java.lang.Class might not have permissions to do this, even though the “real” caller C has the correct permissions. So we and up with a call stack that looks like
>
> Caller: Call:
>
> j.l.Class(for A.class) A.class::checkMemberAccess(classloader for j.l.Class); // this can throw ACE if A is loaded in a separate loader from java.lang.Class
> j.l.Class(for B.class) A.class::getDeclaredMethods(); // j.l.Class is the caller here
> C B.class::getEnclosingMethod();
> .... application code ….
>
> The solution here is to insert a doPrivileged block around the call where j.l.Class gets the members to construct the answer.
>
> Webrev: http://cr.openjdk.java.net/~jfranck/8014678/
>
> Bug is not open but the tests show how this is reproduced.
>
> cheers
> /Joel
Is the AccessControlException result of the fact that client code C is
loaded by same class loader as A and therefore can access declared
memebers of A without special permissions, but if the caller of
getDeclaredMethods() is j.l.Class (system code), then it is not loaded
by same class loader as A and the permission *is* checked, but C does
not have it?
You are elevating the permission of the call to getDeclaredMethods() and
therefore give client C access memeber of A even in situations where
classloaders of C and A differ and C does not have special permission.
I think the right solution should be to pass the caller of
getEnclosingMethod() to the logic of getDecalredMethods() without
elevating the privilege. You'd have to create a private
getDeclaredMethods() method taking additional 'caller' parameter to
which both public methods getEnclosingMethod() and getDecalredMethods()
would delegate.
Regards, Peter
More information about the core-libs-dev
mailing list