RFR: 8217920: Lookup.defineClass injects a class that can access private members of any class in its own module

Paul Sandoz psandoz at openjdk.org
Thu Jan 26 21:57:18 UTC 2023


On Thu, 26 Jan 2023 21:03:59 GMT, Mandy Chung <mchung at openjdk.org> wrote:

> Currently, a `Lookup` object with `PACKAGE` access can be used to inject a class in the runtime package of the Lookup's lookup class via `Lookup::defineClass`.   The classes that are injected have the same access as other members in the module and can access private members of all types in the module via reflection.
> 
> However, changing `Lookup.defineClass` to require full privilege access (`PRIVATE` + `MODULE`) is an incompatible change that would break existing frameworks which use `privateLookupIn` and `Lookup::defineClass` to inject auxiliary classes in a module.   A module authorizes the framework by opening a package for it to access and `Lookup::defineClass` was the supported replacement for `setAccessible` on `ClassLoader::defineClass` hack in JDK 9.    
> 
> This PR proposes to keep existing behavior and provide better documentation to help developers to beware of the permissions given out when opening a package to another module. A class injected in a module has the same privilege as other module members.

src/java.base/share/classes/java/lang/Module.java line 607:

> 605:      * {@link java.lang.invoke.MethodHandles.Lookup Lookup} object that can be used to
> 606:      * {@link java.lang.invoke.MethodHandles.Lookup#defineClass(byte[]) inject classes}
> 607:      * in package {@code p}. </p>

Suggestion:

     * <p> A package {@code p} opened to module {@code M} means that code in
     * {@code M} is allowed to do deep reflection on all types in the package.
     * Further, if {@code M} reads this module it can obtain a
     * {@link java.lang.invoke.MethodHandles.Lookup Lookup} object that is allowed to
     * {@link java.lang.invoke.MethodHandles.Lookup#defineClass(byte[]) define classes}
     * in package {@code p}. </p>

Trying to reuse existing terms. I am presuming deep reflection implies on all members and setAccessible so there is no need to mention it?

Also i don't see "inject" used in existing text, so just reuse "define"?

src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 240:

> 238:      * of {@code targetClass}. Extreme caution should be taken when opening a package
> 239:      * to another module.  The injected classes have the same full privilege
> 240:      * access as other members in the target module.

Suggestion:

     * The {@code Lookup} object returned by this method is allowed to
     * {@linkplain Lookup#defineClass(byte[]) define classes} in the runtime package
     * of {@code targetClass}. Extreme caution should be taken when opening a package
     * to another module as such defined classes have the same full privilege
     * access as other members in the target module.

src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 883:

> 881:      * of {@code T}. Extreme caution should be taken when opening a package
> 882:      * to another module.  The injected classes have the same full privilege
> 883:      * access as other members in the target module.

Suggestion:

     * <p>
     * The {@code Lookup} object returned by {@code privateLookupIn} is allowed to
     * {@linkplain Lookup#defineClass(byte[]) define classes} in the runtime package
     * of {@code T}. Extreme caution should be taken when opening a package
     * to another module as such defined classes have the same full privilege
     * access as other members in the target module.


You mention "target module" but i don't think i it is defined for the Lookup class JavaDoc. In this case are we referring to module M2?

-------------

PR: https://git.openjdk.org/jdk/pull/12236


More information about the core-libs-dev mailing list