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

Reply via email to