8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import jdk.internal.reflect.CallerSensitive;
29 import jdk.internal.reflect.Reflection;
30 import jdk.internal.vm.annotation.ForceInline;
31 import sun.invoke.util.ValueConversions;
32 import sun.invoke.util.VerifyAccess;
33 import sun.invoke.util.Wrapper;
34 import sun.reflect.misc.ReflectUtil;
35 import sun.security.util.SecurityConstants;
36
37 import java.lang.invoke.LambdaForm.BasicType;
38 import java.lang.reflect.Constructor;
39 import java.lang.reflect.Field;
40 import java.lang.reflect.Member;
41 import java.lang.reflect.Method;
42 import java.lang.reflect.Modifier;
43 import java.lang.reflect.Module;
44 import java.lang.reflect.ReflectPermission;
45 import java.nio.ByteOrder;
46 import java.util.ArrayList;
47 import java.util.Arrays;
48 import java.util.BitSet;
49 import java.util.Iterator;
50 import java.util.List;
51 import java.util.Objects;
52 import java.util.concurrent.ConcurrentHashMap;
53 import java.util.stream.Collectors;
54 import java.util.stream.Stream;
55
56 import static java.lang.invoke.MethodHandleImpl.Intrinsic;
57 import static java.lang.invoke.MethodHandleNatives.Constants.*;
58 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
59 import static java.lang.invoke.MethodType.methodType;
60
61 /**
62 * This class consists exclusively of static methods that operate on or return
63 * method handles. They fall into several categories:
64 * <ul>
65 * <li>Lookup methods which help create method handles for methods and fields.
174 */
175 public static Lookup privateLookupIn(Class<?> targetClass, Lookup lookup) throws IllegalAccessException {
176 SecurityManager sm = System.getSecurityManager();
177 if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
178 if (targetClass.isPrimitive())
179 throw new IllegalArgumentException(targetClass + " is a primitive class");
180 if (targetClass.isArray())
181 throw new IllegalArgumentException(targetClass + " is an array class");
182 Module targetModule = targetClass.getModule();
183 Module callerModule = lookup.lookupClass().getModule();
184 if (!callerModule.canRead(targetModule))
185 throw new IllegalAccessException(callerModule + " does not read " + targetModule);
186 if (targetModule.isNamed()) {
187 String pn = targetClass.getPackageName();
188 assert pn.length() > 0 : "unnamed package cannot be in named module";
189 if (!targetModule.isOpen(pn, callerModule))
190 throw new IllegalAccessException(targetModule + " does not open " + pn + " to " + callerModule);
191 }
192 if ((lookup.lookupModes() & Lookup.MODULE) == 0)
193 throw new IllegalAccessException("lookup does not have MODULE lookup mode");
194 return new Lookup(targetClass);
195 }
196
197 /**
198 * Performs an unchecked "crack" of a
199 * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
200 * The result is as if the user had obtained a lookup object capable enough
201 * to crack the target method handle, called
202 * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
203 * on the target to obtain its symbolic reference, and then called
204 * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
205 * to resolve the symbolic reference to a member.
206 * <p>
207 * If there is a security manager, its {@code checkPermission} method
208 * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
209 * @param <T> the desired type of the result, either {@link Member} or a subtype
210 * @param target a direct method handle to crack into symbolic reference components
211 * @param expected a class object representing the desired result type {@code T}
212 * @return a reference to the method, constructor, or field object
213 * @exception SecurityException if the caller is not privileged to call {@code setAccessible}
838 * {@code MODULE}, {@code PACKAGE}, {@code PROTECTED}, {@code PRIVATE} or {@code UNCONDITIONAL}
839 * @see MethodHandles#privateLookupIn
840 * @since 9
841 */
842 public Lookup dropLookupMode(int modeToDrop) {
843 int oldModes = lookupModes();
844 int newModes = oldModes & ~(modeToDrop | PROTECTED | UNCONDITIONAL);
845 switch (modeToDrop) {
846 case PUBLIC: newModes &= ~(ALL_MODES); break;
847 case MODULE: newModes &= ~(PACKAGE | PRIVATE); break;
848 case PACKAGE: newModes &= ~(PRIVATE); break;
849 case PROTECTED:
850 case PRIVATE:
851 case UNCONDITIONAL: break;
852 default: throw new IllegalArgumentException(modeToDrop + " is not a valid mode to drop");
853 }
854 if (newModes == oldModes) return this; // return self if no change
855 return new Lookup(lookupClass(), newModes);
856 }
857
858 // Make sure outer class is initialized first.
859 static { IMPL_NAMES.getClass(); }
860
861 /** Package-private version of lookup which is trusted. */
862 static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
863
864 /** Version of lookup which is trusted minimally.
865 * It can only be used to create method handles to publicly accessible
866 * members in packages that are exported unconditionally.
867 */
868 static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, (PUBLIC|UNCONDITIONAL));
869
870 private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
871 String name = lookupClass.getName();
872 if (name.startsWith("java.lang.invoke."))
873 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
874
875 // For caller-sensitive MethodHandles.lookup() disallow lookup from
876 // restricted packages. This a fragile and blunt approach.
877 // TODO replace with a more formal and less fragile mechanism
1931 /**
1932 * Find my trustable caller class if m is a caller sensitive method.
1933 * If this lookup object has private access, then the caller class is the lookupClass.
1934 * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
1935 */
1936 Class<?> findBoundCallerClass(MemberName m) throws IllegalAccessException {
1937 Class<?> callerClass = null;
1938 if (MethodHandleNatives.isCallerSensitive(m)) {
1939 // Only lookups with private access are allowed to resolve caller-sensitive methods
1940 if (hasPrivateAccess()) {
1941 callerClass = lookupClass;
1942 } else {
1943 throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
1944 }
1945 }
1946 return callerClass;
1947 }
1948
1949 /**
1950 * Returns {@code true} if this lookup has {@code PRIVATE} access.
1951 * @return {@code true} if this lookup has {@code PRIVATE} acesss.
1952 * @since 9
1953 */
1954 public boolean hasPrivateAccess() {
1955 return (allowedModes & PRIVATE) != 0;
1956 }
1957
1958 /**
1959 * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
1960 * Determines a trustable caller class to compare with refc, the symbolic reference class.
1961 * If this lookup object has private access, then the caller class is the lookupClass.
1962 */
1963 void checkSecurityManager(Class<?> refc, MemberName m) {
1964 SecurityManager smgr = System.getSecurityManager();
1965 if (smgr == null) return;
1966 if (allowedModes == TRUSTED) return;
1967
1968 // Step 1:
1969 boolean fullPowerLookup = hasPrivateAccess();
1970 if (!fullPowerLookup ||
1971 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
|
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import jdk.internal.misc.SharedSecrets;
29 import jdk.internal.module.IllegalAccessLogger;
30 import jdk.internal.org.objectweb.asm.ClassReader;
31 import jdk.internal.reflect.CallerSensitive;
32 import jdk.internal.reflect.Reflection;
33 import jdk.internal.vm.annotation.ForceInline;
34 import sun.invoke.util.ValueConversions;
35 import sun.invoke.util.VerifyAccess;
36 import sun.invoke.util.Wrapper;
37 import sun.reflect.misc.ReflectUtil;
38 import sun.security.util.SecurityConstants;
39
40 import java.lang.invoke.LambdaForm.BasicType;
41 import java.lang.reflect.Constructor;
42 import java.lang.reflect.Field;
43 import java.lang.reflect.Member;
44 import java.lang.reflect.Method;
45 import java.lang.reflect.Modifier;
46 import java.lang.reflect.Module;
47 import java.lang.reflect.ReflectPermission;
48 import java.nio.ByteOrder;
49 import java.security.AccessController;
50 import java.security.PrivilegedAction;
51 import java.security.ProtectionDomain;
52 import java.util.ArrayList;
53 import java.util.Arrays;
54 import java.util.BitSet;
55 import java.util.Iterator;
56 import java.util.List;
57 import java.util.Objects;
58 import java.util.concurrent.ConcurrentHashMap;
59 import java.util.stream.Collectors;
60 import java.util.stream.Stream;
61
62 import static java.lang.invoke.MethodHandleImpl.Intrinsic;
63 import static java.lang.invoke.MethodHandleNatives.Constants.*;
64 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
65 import static java.lang.invoke.MethodType.methodType;
66
67 /**
68 * This class consists exclusively of static methods that operate on or return
69 * method handles. They fall into several categories:
70 * <ul>
71 * <li>Lookup methods which help create method handles for methods and fields.
180 */
181 public static Lookup privateLookupIn(Class<?> targetClass, Lookup lookup) throws IllegalAccessException {
182 SecurityManager sm = System.getSecurityManager();
183 if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
184 if (targetClass.isPrimitive())
185 throw new IllegalArgumentException(targetClass + " is a primitive class");
186 if (targetClass.isArray())
187 throw new IllegalArgumentException(targetClass + " is an array class");
188 Module targetModule = targetClass.getModule();
189 Module callerModule = lookup.lookupClass().getModule();
190 if (!callerModule.canRead(targetModule))
191 throw new IllegalAccessException(callerModule + " does not read " + targetModule);
192 if (targetModule.isNamed()) {
193 String pn = targetClass.getPackageName();
194 assert pn.length() > 0 : "unnamed package cannot be in named module";
195 if (!targetModule.isOpen(pn, callerModule))
196 throw new IllegalAccessException(targetModule + " does not open " + pn + " to " + callerModule);
197 }
198 if ((lookup.lookupModes() & Lookup.MODULE) == 0)
199 throw new IllegalAccessException("lookup does not have MODULE lookup mode");
200 if (!callerModule.isNamed() && targetModule.isNamed()) {
201 IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
202 if (logger != null) {
203 logger.logIfOpenedByBackdoor(lookup, targetClass);
204 }
205 }
206 return new Lookup(targetClass);
207 }
208
209 /**
210 * Performs an unchecked "crack" of a
211 * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
212 * The result is as if the user had obtained a lookup object capable enough
213 * to crack the target method handle, called
214 * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
215 * on the target to obtain its symbolic reference, and then called
216 * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
217 * to resolve the symbolic reference to a member.
218 * <p>
219 * If there is a security manager, its {@code checkPermission} method
220 * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
221 * @param <T> the desired type of the result, either {@link Member} or a subtype
222 * @param target a direct method handle to crack into symbolic reference components
223 * @param expected a class object representing the desired result type {@code T}
224 * @return a reference to the method, constructor, or field object
225 * @exception SecurityException if the caller is not privileged to call {@code setAccessible}
850 * {@code MODULE}, {@code PACKAGE}, {@code PROTECTED}, {@code PRIVATE} or {@code UNCONDITIONAL}
851 * @see MethodHandles#privateLookupIn
852 * @since 9
853 */
854 public Lookup dropLookupMode(int modeToDrop) {
855 int oldModes = lookupModes();
856 int newModes = oldModes & ~(modeToDrop | PROTECTED | UNCONDITIONAL);
857 switch (modeToDrop) {
858 case PUBLIC: newModes &= ~(ALL_MODES); break;
859 case MODULE: newModes &= ~(PACKAGE | PRIVATE); break;
860 case PACKAGE: newModes &= ~(PRIVATE); break;
861 case PROTECTED:
862 case PRIVATE:
863 case UNCONDITIONAL: break;
864 default: throw new IllegalArgumentException(modeToDrop + " is not a valid mode to drop");
865 }
866 if (newModes == oldModes) return this; // return self if no change
867 return new Lookup(lookupClass(), newModes);
868 }
869
870 /**
871 * Defines a class to the same class loader and in the same runtime package and
872 * {@linkplain java.security.ProtectionDomain protection domain} as this lookup's
873 * {@linkplain #lookupClass() lookup class}.
874 *
875 * <p> The {@linkplain #lookupModes() lookup modes} for this lookup must include
876 * {@link #PACKAGE PACKAGE} access as default (package) members will be
877 * accessible to the class. The {@code PACKAGE} lookup mode serves to authenticate
878 * that the lookup object was created by a caller in the runtime package (or derived
879 * from a lookup originally created by suitably privileged code to a target class in
880 * the runtime package). The lookup modes cannot include {@link #PRIVATE PRIVATE}
881 * access. A lookup with {@code PRIVATE} access can be downgraded to drop this lookup
882 * mode with the {@linkplain #dropLookupMode(int) dropLookupMode} method. </p>
883 *
884 * <p> The {@code bytes} parameter is the class bytes of a valid class file (as defined
885 * by the <em>The Java Virtual Machine Specification</em>) with a class name in the
886 * same package as the lookup class. </p>
887 *
888 * <p> This method does not run the class initializer. The class initializer may
889 * run at a later time, as detailed in section 12.4 of the <em>The Java Language
890 * Specification</em>. </p>
891 *
892 * <p> If there is a security manager, its {@code checkPermission} method is first called
893 * to check {@code RuntimePermission("defineClass")}. </p>
894 *
895 * @param bytes the class bytes
896 * @return the {@code Class} object for the class
897 * @throws IllegalArgumentException the bytes are for a class in a different package
898 * to the lookup class
899 * @throws IllegalAccessException if this lookup does not have {@code PACKAGE} access
900 * @throws UnsupportedOperationException if the lookup class has {@code PRIVATE} access
901 * @throws LinkageError if the class is malformed ({@code ClassFormatError}), cannot be
902 * verified ({@code VerifyError}), is already defined, or another linkage error occurs
903 * @throws SecurityException if denied by the security manager
904 * @throws NullPointerException if {@code bytes} is {@code null}
905 * @since 9
906 * @spec JPMS
907 * @see Lookup#privateLookupIn
908 * @see Lookup#dropLookupMode
909 * @see ClassLoader#defineClass(String,byte[],int,int,ProtectionDomain)
910 */
911 public Class<?> defineClass(byte[] bytes) throws IllegalAccessException {
912 SecurityManager sm = System.getSecurityManager();
913 if (sm != null)
914 sm.checkPermission(new RuntimePermission("defineClass"));
915 if (hasPrivateAccess())
916 throw new UnsupportedOperationException("PRIVATE access not supported");
917 if ((lookupModes() & PACKAGE) == 0)
918 throw new IllegalAccessException("Lookup does not have PACKAGE access");
919 assert (lookupModes() & (MODULE|PUBLIC)) != 0;
920
921 // parse class bytes to get class name (in internal form)
922 bytes = bytes.clone();
923 String name;
924 try {
925 ClassReader reader = new ClassReader(bytes);
926 name = reader.getClassName();
927 } catch (RuntimeException e) {
928 // ASM exceptions are poorly specified
929 ClassFormatError cfe = new ClassFormatError();
930 cfe.initCause(e);
931 throw cfe;
932 }
933
934 // get package and class name in binary form
935 String cn, pn;
936 int index = name.lastIndexOf('/');
937 if (index == -1) {
938 cn = name;
939 pn = "";
940 } else {
941 cn = name.replace('/', '.');
942 pn = cn.substring(0, index);
943 }
944 if (!pn.equals(lookupClass.getPackageName())) {
945 throw new IllegalArgumentException("Class not in same package as lookup class");
946 }
947
948 // invoke the class loader's defineClass method
949 ClassLoader loader = lookupClass.getClassLoader();
950 ProtectionDomain pd = (loader != null) ? lookupClassProtectionDomain() : null;
951 String source = "__Lookup_defineClass__";
952 Class<?> clazz = SharedSecrets.getJavaLangAccess().defineClass(loader, cn, bytes, pd, source);
953 assert clazz.getClassLoader() == lookupClass.getClassLoader()
954 && clazz.getPackageName().equals(lookupClass.getPackageName())
955 && protectionDomain(clazz) == lookupClassProtectionDomain();
956 return clazz;
957 }
958
959 private ProtectionDomain lookupClassProtectionDomain() {
960 ProtectionDomain pd = cachedProtectionDomain;
961 if (pd == null) {
962 cachedProtectionDomain = pd = protectionDomain(lookupClass);
963 }
964 return pd;
965 }
966
967 private ProtectionDomain protectionDomain(Class<?> clazz) {
968 PrivilegedAction<ProtectionDomain> pa = clazz::getProtectionDomain;
969 return AccessController.doPrivileged(pa);
970 }
971
972 // cached protection domain
973 private volatile ProtectionDomain cachedProtectionDomain;
974
975
976 // Make sure outer class is initialized first.
977 static { IMPL_NAMES.getClass(); }
978
979 /** Package-private version of lookup which is trusted. */
980 static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
981
982 /** Version of lookup which is trusted minimally.
983 * It can only be used to create method handles to publicly accessible
984 * members in packages that are exported unconditionally.
985 */
986 static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, (PUBLIC|UNCONDITIONAL));
987
988 private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
989 String name = lookupClass.getName();
990 if (name.startsWith("java.lang.invoke."))
991 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
992
993 // For caller-sensitive MethodHandles.lookup() disallow lookup from
994 // restricted packages. This a fragile and blunt approach.
995 // TODO replace with a more formal and less fragile mechanism
2049 /**
2050 * Find my trustable caller class if m is a caller sensitive method.
2051 * If this lookup object has private access, then the caller class is the lookupClass.
2052 * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
2053 */
2054 Class<?> findBoundCallerClass(MemberName m) throws IllegalAccessException {
2055 Class<?> callerClass = null;
2056 if (MethodHandleNatives.isCallerSensitive(m)) {
2057 // Only lookups with private access are allowed to resolve caller-sensitive methods
2058 if (hasPrivateAccess()) {
2059 callerClass = lookupClass;
2060 } else {
2061 throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
2062 }
2063 }
2064 return callerClass;
2065 }
2066
2067 /**
2068 * Returns {@code true} if this lookup has {@code PRIVATE} access.
2069 * @return {@code true} if this lookup has {@code PRIVATE} access.
2070 * @since 9
2071 */
2072 public boolean hasPrivateAccess() {
2073 return (allowedModes & PRIVATE) != 0;
2074 }
2075
2076 /**
2077 * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
2078 * Determines a trustable caller class to compare with refc, the symbolic reference class.
2079 * If this lookup object has private access, then the caller class is the lookupClass.
2080 */
2081 void checkSecurityManager(Class<?> refc, MemberName m) {
2082 SecurityManager smgr = System.getSecurityManager();
2083 if (smgr == null) return;
2084 if (allowedModes == TRUSTED) return;
2085
2086 // Step 1:
2087 boolean fullPowerLookup = hasPrivateAccess();
2088 if (!fullPowerLookup ||
2089 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
|