A DESCRIPTION OF THE PROBLEM : The problem is that a public @CallerSensitive methods can be tricked to see MethodHandle as caller. This can be done by getting the Method, call setAccessible(true) on it. Since it is public this call will succeed. Using this Method now in Lookup.unreflect will use the IMPL_LOOKUP, since the Method is accessible and does therefore not bind the caller. Calling the resulting MethodHandle via invokeWithArguments, the Method will see MethodHandle as caller. This can be used to open java.base. STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : Run: Method m = Module.class.getMethod("addOpens", String.class, Module.class); m.setAccessible(true); MethodHandle mh = MethodHandles.lookup().unreflect(m); mh.invokeWithArguments(Object.class.getModule(), "java.lang", Test.class.getModule()); EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - Exception in thread "main" java.lang.IllegalCallerException: java.lang is not open to module test. ACTUAL - Module java.lang is opened to module test. ---------- BEGIN SOURCE ---------- package test; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; public class Test { public static void main(String[] args) throws Throwable { Method m = Module.class.getMethod("addOpens", String.class, Module.class); m.setAccessible(true); MethodHandle mh = MethodHandles.lookup().unreflect(m); mh.invokeWithArguments(Object.class.getModule(), "java.lang", Test.class.getModule()); } } ---------- END SOURCE ---------- FREQUENCY : always
|