Re: RFR: 6378384 (reflect) subclass can’t access superclass’s protected fields and methods by reflection
Peter Levart
peter.levart at gmail.com
Sun Oct 2 21:51:39 UTC 2016
Hi,
I added an exhaustive jtreg test that covers all possible situations.
From the set of the following classes:
package a;
public class PublicSuper {...}
package a;
class Package {...}
package b;
public class PublicSub extends a.PublicSuper {...}
package b;
class Package {...}
it creates a set of all possible triplets:
(currentClass, memberClass, targetClass)
where:
currentClass - the class making the reflective access
memberClass - the member's declaring class
targetClass - the target object's class (for accessing instance fields
and methods - must be equal to or subclass of memberClass)
For each such triplet it checks the reflective access to each of the
following members:
{private, package, protected, public} x {instance, static} x {field, method}
and:
{private, package, protected, public} x {constructor}
When running on unpatched build 9-ea+137, the result is:
http://cr.openjdk.java.net/~plevart/jdk9-dev/6378384_Reflection.ensureAccess/AccessControlTest_unpatched.jtr
When running on patched build of 9, the result is:
http://cr.openjdk.java.net/~plevart/jdk9-dev/6378384_Reflection.ensureAccess/AccessControlTest_patched.jtr
The difference is exactly in the following two cases which fail for
unpatched and are fixed by the patch:
b.PublicSub accessing a.PublicSuper's PROTECTED_STATIC_FIELD - expected
allowed, actual denied : FAILURE
b.PublicSub accessing a.PublicSuper's PROTECTED_STATIC_METHOD - expected
allowed, actual denied : FAILURE
QED.
This is new webrev:
http://cr.openjdk.java.net/~plevart/jdk9-dev/6378384_Reflection.ensureAccess/webrev.02/
I think the test proves the effect of the patch is as intended,
therefore it should not be a problem to review it.
Regards, Peter
On 10/01/2016 12:20 AM, Peter Levart wrote:
> Hi,
>
> I have a fix for a 10 year old bug (JDK-6378384
> <https://bugs.openjdk.java.net/browse/JDK-6378384>). It was marked as
> a duplicate of a 19 year old bug (JDK-4032740
> <https://bugs.openjdk.java.net/browse/JDK-4032740>) which is marked as
> a duplicate of a 17 year old bug (JDK-4283544
> <https://bugs.openjdk.java.net/browse/JDK-4283544>) which is still
> open. But this bug is not a strict duplicate. This bug only concerns
> reflective access to protected members.
>
> Here's a proposed fix:
>
> http://cr.openjdk.java.net/~plevart/jdk9-dev/6378384_Reflection.ensureAccess/webrev.01/
>
>
> The bug manifests itself as not being able to access protected static
> methods or fields from a subclass located in a different package.
> Instance protected methods and fields can be accessed, and using an
> undocumented trick, also static methods and fields, but the trick is
> very subtle. The specification for Field.get/set and Method.invoke
> says, respectively:
>
> * <p>If the underlying field is a static field, the {@code obj}
> argument
> * is ignored; it may be null.
>
> and:
>
> * <p>If the underlying method is static, then the specified
> {@code obj}
> * argument is ignored. It may be null.
>
> Well, it is not exactly so! The obj argument is used as a 'target'
> even for protected static members and it is ensured that its class is
> equal or a subclass of the class that accesses the member. So if you
> pass an instance of a subclass of the protected method's declaring
> class into the get/set/invoke, you can access the static protected
> member. If you pass 'null', you get IllegalAccessException.
>
> The problem is in the design of
> jdk.internal.reflect.Reflection#ensureMemberAccess method which is
> used to check reflective access. It takes an Object 'target' argument,
> which is supposed to be null when accessing static methods/fields and
> it is null also when accessing constructors. Because of constructors
> and the method's API, it has to be overly restrictive as it must only
> allow calling protected constructors from within the constructor's
> declaring class itself or same package, while protected static methods
> could be called from any subclass.
>
> By redesigning the API of this method, replacing Object 'target'
> parameter with Class<?> 'targetClass' parameter and by passing the
> constructor's declaring class into this method instead of null,
> reflective checks suddenly start to look more like JLS dictates (but
> still a long way from it, unfortunately).
>
> As a bonus, sun.reflect.misc.ReflectUtil#ensureMemberAccess method
> (used from AtomicXXXFieldUpdater classes) does not need the following
> comment any more:
>
> * Reflection.ensureMemberAccess is overly-restrictive
> * due to a bug. We awkwardly work around it for now.
>
> ...as it can now delegate straight to Reflection.ensureMemberAccess
> without invoking it twice with different modified member access
> modifiers and performing part of the check itself.
>
> java.lang.reflect.AccessibleObject#checkAccess delegates to
> Reflection.ensureMemberAccess and caches the result, so it had to be
> modified too.
>
> Constructor now passes it's declaring class to the 'targetClass'
> parameter and Filed/Method obey the spec and REALLY IGNORE 'obj'
> parameter in get/set/invoke on a static member.
>
> All java/lang/reflect and java/util/concurrent/atomic tests pass with
> this patch applied except the following:
>
> java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java: Test
> java.lang.reflect.AccessibleObject with modules
> java/lang/reflect/Generics/TestBadSignatures.java: Test bad signatures
> get a GenericSignatureFormatError thrown.
> java/lang/reflect/Method/invoke/TestPrivateInterfaceMethodReflect.java:
> Reflection support for private methods in interfaces
> java/lang/reflect/Module/AddExportsTest.java: Test Module isExported
> methods with exports changed by -AddExportsTest
> java/lang/reflect/Proxy/ProxyModuleMapping.java: Basic test of proxy
> module mapping and the access to Proxy class
> java/lang/reflect/WeakPairMap/Driver.java: Functional test for
> WeakPairMap
>
> ...which all fail because of:
>
> javac: invalid flag: -XaddExports:java.base/jdk.internal....
>
>
>
> Regards, Peter
>
>
More information about the core-libs-dev
mailing list