1 /*
  2  * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  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 jdk.internal.reflect;
 27 
 28 import java.io.Externalizable;
 29 import java.io.ObjectInputStream;
 30 import java.io.ObjectOutputStream;
 31 import java.io.ObjectStreamClass;
 32 import java.io.OptionalDataException;
 33 import java.io.Serializable;
 34 import java.lang.invoke.MethodHandle;
 35 import java.lang.invoke.MethodHandles;
 36 import java.lang.reflect.Constructor;
 37 import java.lang.reflect.Executable;
 38 import java.lang.reflect.Field;
 39 import java.lang.reflect.InvocationTargetException;
 40 import java.lang.reflect.Method;
 41 import java.lang.reflect.Modifier;
 42 import java.security.PrivilegedAction;
 43 import java.util.Properties;
 44 import jdk.internal.access.JavaLangReflectAccess;
 45 import jdk.internal.access.SharedSecrets;
 46 import jdk.internal.misc.VM;
 47 import jdk.internal.vm.annotation.Stable;
 48 import sun.security.action.GetPropertyAction;
 49 import sun.security.util.SecurityConstants;
 50 
 51 /** <P> The master factory for all reflective objects, both those in
 52     java.lang.reflect (Fields, Methods, Constructors) as well as their
 53     delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
 54     </P>
 55 
 56     <P> The methods in this class are extremely unsafe and can cause
 57     subversion of both the language and the verifier. For this reason,
 58     they are all instance methods, and access to the constructor of
 59     this factory is guarded by a security check, in similar style to
 60     {@link jdk.internal.misc.Unsafe}. </P>
 61 */
 62 
 63 public class ReflectionFactory {
 64 
 65     private static final ReflectionFactory soleInstance = new ReflectionFactory();
 66 
 67 
 68     /* Method for static class initializer <clinit>, or null */
 69     private static volatile Method hasStaticInitializerMethod;
 70 
 71     private final JavaLangReflectAccess langReflectAccess;
 72     private ReflectionFactory() {
 73         this.langReflectAccess = SharedSecrets.getJavaLangReflectAccess();
 74     }
 75 
 76     /**
 77      * A convenience class for acquiring the capability to instantiate
 78      * reflective objects.  Use this instead of a raw call to {@link
 79      * #getReflectionFactory} in order to avoid being limited by the
 80      * permissions of your callers.
 81      *
 82      * <p>An instance of this class can be used as the argument of
 83      * <code>AccessController.doPrivileged</code>.
 84      */
 85     public static final class GetReflectionFactoryAction
 86         implements PrivilegedAction<ReflectionFactory> {
 87         public ReflectionFactory run() {
 88             return getReflectionFactory();
 89         }
 90     }
 91 
 92     /**
 93      * Provides the caller with the capability to instantiate reflective
 94      * objects.
 95      *
 96      * <p> First, if there is a security manager, its
 97      * <code>checkPermission</code> method is called with a {@link
 98      * java.lang.RuntimePermission} with target
 99      * <code>"reflectionFactoryAccess"</code>.  This may result in a
100      * security exception.
101      *
102      * <p> The returned <code>ReflectionFactory</code> object should be
103      * carefully guarded by the caller, since it can be used to read and
104      * write private data and invoke private methods, as well as to load
105      * unverified bytecodes.  It must never be passed to untrusted code.
106      *
107      * @exception SecurityException if a security manager exists and its
108      *             <code>checkPermission</code> method doesn't allow
109      *             access to the RuntimePermission "reflectionFactoryAccess".  */
110     public static ReflectionFactory getReflectionFactory() {
111         @SuppressWarnings("removal")
112         SecurityManager security = System.getSecurityManager();
113         if (security != null) {
114             security.checkPermission(
115                 SecurityConstants.REFLECTION_FACTORY_ACCESS_PERMISSION);
116         }
117         return soleInstance;
118     }
119 
120     //--------------------------------------------------------------------------
121     //
122     // Routines used by java.lang.reflect
123     //
124     //
125 
126     /*
127      * Note: this routine can cause the declaring class for the field
128      * be initialized and therefore must not be called until the
129      * first get/set of this field.
130      * @param field the field
131      * @param override true if caller has overridden accessibility
132      */
133     public FieldAccessor newFieldAccessor(Field field, boolean override) {
134         Field root = langReflectAccess.getRoot(field);
135         if (root != null) {
136             // FieldAccessor will use the root unless the modifiers have
137             // been overridden
138             if (root.getModifiers() == field.getModifiers() || !override) {
139                 field = root;
140             }
141         }
142         boolean isFinal = Modifier.isFinal(field.getModifiers());
143         boolean isReadOnly = isFinal && (!override || langReflectAccess.isTrustedFinalField(field));
144         return MethodHandleAccessorFactory.newFieldAccessor(field, isReadOnly);
145     }
146 
147     public MethodAccessor newMethodAccessor(Method method, boolean callerSensitive) {
148         // use the root Method that will not cache caller class
149         Method root = langReflectAccess.getRoot(method);
150         if (root != null) {
151             method = root;
152         }
153 
154         return MethodHandleAccessorFactory.newMethodAccessor(method, callerSensitive);
155     }
156 
157     public ConstructorAccessor newConstructorAccessor(Constructor<?> c) {
158         Class<?> declaringClass = c.getDeclaringClass();
159         if (Modifier.isAbstract(declaringClass.getModifiers())) {
160             return new InstantiationExceptionConstructorAccessorImpl(null);
161         }
162         if (declaringClass == Class.class) {
163             return new InstantiationExceptionConstructorAccessorImpl
164                 ("Can not instantiate java.lang.Class");
165         }
166 
167         // use the root Constructor that will not cache caller class
168         Constructor<?> root = langReflectAccess.getRoot(c);
169         if (root != null) {
170             c = root;
171         }
172 
173         return MethodHandleAccessorFactory.newConstructorAccessor(c);
174     }
175 
176     //--------------------------------------------------------------------------
177     //
178     // Routines used by java.lang
179     //
180     //
181 
182     /** Creates a new java.lang.reflect.Constructor. Access checks as
183         per java.lang.reflect.AccessibleObject are not overridden. */
184     public Constructor<?> newConstructor(Class<?> declaringClass,
185                                          Class<?>[] parameterTypes,
186                                          Class<?>[] checkedExceptions,
187                                          int modifiers,
188                                          int slot,
189                                          String signature,
190                                          byte[] annotations,
191                                          byte[] parameterAnnotations)
192     {
193         return langReflectAccess.newConstructor(declaringClass,
194                                                 parameterTypes,
195                                                 checkedExceptions,
196                                                 modifiers,
197                                                 slot,
198                                                 signature,
199                                                 annotations,
200                                                 parameterAnnotations);
201     }
202 
203     /** Gets the ConstructorAccessor object for a
204         java.lang.reflect.Constructor */
205     public ConstructorAccessor getConstructorAccessor(Constructor<?> c) {
206         return langReflectAccess.getConstructorAccessor(c);
207     }
208 
209     /** Sets the ConstructorAccessor object for a
210         java.lang.reflect.Constructor */
211     public void setConstructorAccessor(Constructor<?> c,
212                                        ConstructorAccessor accessor)
213     {
214         langReflectAccess.setConstructorAccessor(c, accessor);
215     }
216 
217     /** Makes a copy of the passed method. The returned method is a
218         "child" of the passed one; see the comments in Method.java for
219         details. */
220     public Method copyMethod(Method arg) {
221         return langReflectAccess.copyMethod(arg);
222     }
223 
224     /** Makes a copy of the passed method. The returned method is NOT
225      * a "child" but a "sibling" of the Method in arg. Should only be
226      * used on non-root methods. */
227     public Method leafCopyMethod(Method arg) {
228         return langReflectAccess.leafCopyMethod(arg);
229     }
230 
231 
232     /** Makes a copy of the passed field. The returned field is a
233         "child" of the passed one; see the comments in Field.java for
234         details. */
235     public Field copyField(Field arg) {
236         return langReflectAccess.copyField(arg);
237     }
238 
239     /** Makes a copy of the passed constructor. The returned
240         constructor is a "child" of the passed one; see the comments
241         in Constructor.java for details. */
242     public <T> Constructor<T> copyConstructor(Constructor<T> arg) {
243         return langReflectAccess.copyConstructor(arg);
244     }
245 
246     /** Gets the byte[] that encodes TypeAnnotations on an executable.
247      */
248     public byte[] getExecutableTypeAnnotationBytes(Executable ex) {
249         return langReflectAccess.getExecutableTypeAnnotationBytes(ex);
250     }
251 
252     public Class<?>[] getExecutableSharedParameterTypes(Executable ex) {
253         return langReflectAccess.getExecutableSharedParameterTypes(ex);
254     }
255 
256     public <T> T newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)
257         throws IllegalAccessException, InstantiationException, InvocationTargetException
258     {
259         return langReflectAccess.newInstance(ctor, args, caller);
260     }
261 
262     //--------------------------------------------------------------------------
263     //
264     // Routines used by serialization
265     //
266     //
267 
268     public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
269         if (!Externalizable.class.isAssignableFrom(cl)) {
270             return null;
271         }
272         if (cl.isValue()) {
273             throw new UnsupportedOperationException("newConstructorForExternalization does not support value classes");
274         }
275         try {
276             Constructor<?> cons = cl.getConstructor();
277             cons.setAccessible(true);
278             return cons;
279         } catch (NoSuchMethodException ex) {
280             return null;
281         }
282     }
283 
284     public final Constructor<?> newConstructorForSerialization(Class<?> cl,
285                                                                Constructor<?> constructorToCall)
286     {
287         if (constructorToCall.getDeclaringClass() == cl) {
288             constructorToCall.setAccessible(true);
289             return constructorToCall;
290         }
291         if (cl.isValue()) {
292             throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes");
293         }
294         return generateConstructor(cl, constructorToCall);
295     }
296 
297     /**
298      * Given a class, determines whether its superclass has
299      * any constructors that are accessible from the class.
300      * This is a special purpose method intended to do access
301      * checking for a serializable class and its superclasses
302      * up to, but not including, the first non-serializable
303      * superclass. This also implies that the superclass is
304      * always non-null, because a serializable class must be a
305      * class (not an interface) and Object is not serializable.
306      *
307      * @param cl the class from which access is checked
308      * @return whether the superclass has a constructor accessible from cl
309      */
310     private boolean superHasAccessibleConstructor(Class<?> cl) {
311         Class<?> superCl = cl.getSuperclass();
312         assert Serializable.class.isAssignableFrom(cl);
313         assert superCl != null;
314         if (packageEquals(cl, superCl)) {
315             // accessible if any non-private constructor is found
316             for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
317                 if ((ctor.getModifiers() & Modifier.PRIVATE) == 0) {
318                     return true;
319                 }
320             }
321             if (Reflection.areNestMates(cl, superCl)) {
322                 return true;
323             }
324             return false;
325         } else {
326             // sanity check to ensure the parent is protected or public
327             if ((superCl.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) {
328                 return false;
329             }
330             // accessible if any constructor is protected or public
331             for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
332                 if ((ctor.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) != 0) {
333                     return true;
334                 }
335             }
336             return false;
337         }
338     }
339 
340     /**
341      * Returns a constructor that allocates an instance of cl and that then initializes
342      * the instance by calling the no-arg constructor of its first non-serializable
343      * superclass. This is specified in the Serialization Specification, section 3.1,
344      * in step 11 of the deserialization process. If cl is not serializable, returns
345      * cl's no-arg constructor. If no accessible constructor is found, or if the
346      * class hierarchy is somehow malformed (e.g., a serializable class has no
347      * superclass), null is returned.
348      *
349      * @param cl the class for which a constructor is to be found
350      * @return the generated constructor, or null if none is available
351      */
352     public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
353         if (cl.isValue()) {
354             throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes");
355         }
356 
357         Class<?> initCl = cl;
358         while (Serializable.class.isAssignableFrom(initCl)) {
359             Class<?> prev = initCl;
360             if ((initCl = initCl.getSuperclass()) == null ||
361                 (!disableSerialConstructorChecks() && !superHasAccessibleConstructor(prev))) {
362                 return null;
363             }
364         }
365         Constructor<?> constructorToCall;
366         try {
367             constructorToCall = initCl.getDeclaredConstructor();
368             int mods = constructorToCall.getModifiers();
369             if ((mods & Modifier.PRIVATE) != 0 ||
370                     ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
371                             !packageEquals(cl, initCl))) {
372                 return null;
373             }
374         } catch (NoSuchMethodException ex) {
375             return null;
376         }
377         return generateConstructor(cl, constructorToCall);
378     }
379 
380     private final Constructor<?> generateConstructor(Class<?> cl,
381                                                      Constructor<?> constructorToCall) {
382 
383         Constructor<?> ctor = newConstructor(constructorToCall.getDeclaringClass(),
384                                              constructorToCall.getParameterTypes(),
385                                              constructorToCall.getExceptionTypes(),
386                                              constructorToCall.getModifiers(),
387                                              langReflectAccess.getConstructorSlot(constructorToCall),
388                                              langReflectAccess.getConstructorSignature(constructorToCall),
389                                              langReflectAccess.getConstructorAnnotations(constructorToCall),
390                                              langReflectAccess.getConstructorParameterAnnotations(constructorToCall));
391         ConstructorAccessor acc;
392         if (useOldSerializableConstructor()) {
393             acc = new SerializationConstructorAccessorGenerator().
394                                 generateSerializationConstructor(cl,
395                                                                  constructorToCall.getParameterTypes(),
396                                                                  constructorToCall.getModifiers(),
397                                                                  constructorToCall.getDeclaringClass());
398         } else {
399             acc = MethodHandleAccessorFactory.newSerializableConstructorAccessor(cl, ctor);
400         }
401         setConstructorAccessor(ctor, acc);
402         ctor.setAccessible(true);
403         return ctor;
404     }
405 
406     public final MethodHandle readObjectForSerialization(Class<?> cl) {
407         return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class);
408     }
409 
410     public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
411         return findReadWriteObjectForSerialization(cl, "readObjectNoData", null);
412     }
413 
414     public final MethodHandle writeObjectForSerialization(Class<?> cl) {
415         return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class);
416     }
417 
418     private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl,
419                                                                    String methodName,
420                                                                    Class<?> streamClass) {
421         if (!Serializable.class.isAssignableFrom(cl)) {
422             return null;
423         }
424 
425         try {
426             Method meth = streamClass == null ? cl.getDeclaredMethod(methodName)
427                     : cl.getDeclaredMethod(methodName, streamClass);
428             int mods = meth.getModifiers();
429             if (meth.getReturnType() != Void.TYPE ||
430                     Modifier.isStatic(mods) ||
431                     !Modifier.isPrivate(mods)) {
432                 return null;
433             }
434             meth.setAccessible(true);
435             return MethodHandles.lookup().unreflect(meth);
436         } catch (NoSuchMethodException ex) {
437             return null;
438         } catch (IllegalAccessException ex1) {
439             throw new InternalError("Error", ex1);
440         }
441     }
442 
443     /**
444      * Returns a MethodHandle for {@code writeReplace} on the serializable class
445      * or null if no match found.
446      * @param cl a serializable class
447      * @return the {@code writeReplace} MethodHandle or {@code null} if not found
448      */
449     public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
450         return getReplaceResolveForSerialization(cl, "writeReplace");
451     }
452 
453     /**
454      * Returns a MethodHandle for {@code readResolve} on the serializable class
455      * or null if no match found.
456      * @param cl a serializable class
457      * @return the {@code writeReplace} MethodHandle or {@code null} if not found
458      */
459     public final MethodHandle readResolveForSerialization(Class<?> cl) {
460         return getReplaceResolveForSerialization(cl, "readResolve");
461     }
462 
463     /**
464      * Lookup readResolve or writeReplace on a class with specified
465      * signature constraints.
466      * @param cl a serializable class
467      * @param methodName the method name to find
468      * @return a MethodHandle for the method or {@code null} if not found or
469      *       has the wrong signature.
470      */
471     private MethodHandle getReplaceResolveForSerialization(Class<?> cl,
472                                                            String methodName) {
473         if (!Serializable.class.isAssignableFrom(cl)) {
474             return null;
475         }
476 
477         Class<?> defCl = cl;
478         while (defCl != null) {
479             try {
480                 Method m = defCl.getDeclaredMethod(methodName);
481                 if (m.getReturnType() != Object.class) {
482                     return null;
483                 }
484                 int mods = m.getModifiers();
485                 if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) {
486                     return null;
487                 } else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) {
488                     // fall through
489                 } else if (Modifier.isPrivate(mods) && (cl != defCl)) {
490                     return null;
491                 } else if (!packageEquals(cl, defCl)) {
492                     return null;
493                 }
494                 try {
495                     // Normal return
496                     m.setAccessible(true);
497                     return MethodHandles.lookup().unreflect(m);
498                 } catch (IllegalAccessException ex0) {
499                     // setAccessible should prevent IAE
500                     throw new InternalError("Error", ex0);
501                 }
502             } catch (NoSuchMethodException ex) {
503                 defCl = defCl.getSuperclass();
504             }
505         }
506         return null;
507     }
508 
509     /**
510      * Returns true if the given class defines a static initializer method,
511      * false otherwise.
512      */
513     public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
514         Method m = hasStaticInitializerMethod;
515         if (m == null) {
516             try {
517                 m = ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer",
518                         new Class<?>[]{Class.class});
519                 m.setAccessible(true);
520                 hasStaticInitializerMethod = m;
521             } catch (NoSuchMethodException ex) {
522                 throw new InternalError("No such method hasStaticInitializer on "
523                         + ObjectStreamClass.class, ex);
524             }
525         }
526         try {
527             return (Boolean) m.invoke(null, cl);
528         } catch (InvocationTargetException | IllegalAccessException ex) {
529             throw new InternalError("Exception invoking hasStaticInitializer", ex);
530         }
531     }
532 
533     /**
534      * Return the accessible constructor for OptionalDataException signaling eof.
535      * @return the eof constructor for OptionalDataException
536      */
537     public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() {
538         try {
539             Constructor<OptionalDataException> boolCtor =
540                     OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE);
541             boolCtor.setAccessible(true);
542             return boolCtor;
543         } catch (NoSuchMethodException ex) {
544             throw new InternalError("Constructor not found", ex);
545         }
546     }
547 
548     //--------------------------------------------------------------------------
549     //
550     // Internals only below this point
551     //
552 
553     /*
554      * If -Djdk.reflect.useNativeAccessorOnly is set, use the native accessor only.
555      * For testing purpose only.
556      */
557     static boolean useNativeAccessorOnly() {
558         return config().useNativeAccessorOnly;
559     }
560 
561     static boolean useOldSerializableConstructor() {
562         return config().useOldSerializableConstructor;
563     }
564 
565     private static boolean disableSerialConstructorChecks() {
566         return config().disableSerialConstructorChecks;
567     }
568 
569     /**
570      * The configuration is lazily initialized after the module system is initialized. The
571      * default config would be used before the proper config is loaded.
572      *
573      * The static initializer of ReflectionFactory is run before the system properties are set up.
574      * The class initialization is caused by the class initialization of java.lang.reflect.Method
575      * (more properly, caused by the class initialization for java.lang.reflect.AccessibleObject)
576      * that happens very early VM startup, initPhase1.
577      */
578     private static @Stable Config config;
579 
580     private static final Config DEFAULT_CONFIG = new Config(false, // useNativeAccessorOnly
581                                                             false,  // useOldSerializeableConstructor
582                                                             false); // disableSerialConstructorChecks
583 
584     /**
585      * The configurations for the reflection factory. Configurable via
586      * system properties but only available after ReflectionFactory is
587      * loaded during early VM startup.
588      *
589      * Note that the default implementations of the object methods of
590      * this Config record (toString, equals, hashCode) use indy,
591      * which is available to use only after initPhase1. These methods
592      * are currently not called, but should they be needed, a workaround
593      * is to override them.
594      */
595     private record Config(boolean useNativeAccessorOnly,
596                           boolean useOldSerializableConstructor,
597                           boolean disableSerialConstructorChecks) {
598     }
599 
600     private static Config config() {
601         Config c = config;
602         if (c != null) {
603             return c;
604         }
605 
606         // Always use the default configuration until the module system is initialized.
607         if (!VM.isModuleSystemInited()) {
608             return DEFAULT_CONFIG;
609         }
610 
611         return config = loadConfig();
612     }
613 
614     private static Config loadConfig() {
615         assert VM.isModuleSystemInited();
616 
617         Properties props = GetPropertyAction.privilegedGetProperties();
618         boolean useNativeAccessorOnly =
619             "true".equals(props.getProperty("jdk.reflect.useNativeAccessorOnly"));
620         boolean useOldSerializableConstructor =
621             "true".equals(props.getProperty("jdk.reflect.useOldSerializableConstructor"));
622         boolean disableSerialConstructorChecks =
623             "true".equals(props.getProperty("jdk.disableSerialConstructorChecks"));
624 
625         return new Config(useNativeAccessorOnly, useOldSerializableConstructor, disableSerialConstructorChecks);
626     }
627 
628     /**
629      * Returns true if classes are defined in the classloader and same package, false
630      * otherwise.
631      * @param cl1 a class
632      * @param cl2 another class
633      * @return true if the two classes are in the same classloader and package
634      */
635     private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
636         assert !cl1.isArray() && !cl2.isArray();
637 
638         if (cl1 == cl2) {
639             return true;
640         }
641 
642         return cl1.getClassLoader() == cl2.getClassLoader() &&
643                 cl1.getPackageName() == cl2.getPackageName();
644     }
645 
646 }