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         try {
273             Constructor<?> cons = cl.getConstructor();
274             cons.setAccessible(true);
275             return cons;
276         } catch (NoSuchMethodException ex) {
277             return null;
278         }
279     }
280 
281     public final Constructor<?> newConstructorForSerialization(Class<?> cl,
282                                                                Constructor<?> constructorToCall)
283     {
284         if (constructorToCall.getDeclaringClass() == cl) {
285             constructorToCall.setAccessible(true);
286             return constructorToCall;
287         }
288         return generateConstructor(cl, constructorToCall);
289     }
290 
291     /**
292      * Given a class, determines whether its superclass has
293      * any constructors that are accessible from the class.
294      * This is a special purpose method intended to do access
295      * checking for a serializable class and its superclasses
296      * up to, but not including, the first non-serializable
297      * superclass. This also implies that the superclass is
298      * always non-null, because a serializable class must be a
299      * class (not an interface) and Object is not serializable.
300      *
301      * @param cl the class from which access is checked
302      * @return whether the superclass has a constructor accessible from cl
303      */
304     private boolean superHasAccessibleConstructor(Class<?> cl) {
305         Class<?> superCl = cl.getSuperclass();
306         assert Serializable.class.isAssignableFrom(cl);
307         assert superCl != null;
308         if (packageEquals(cl, superCl)) {
309             // accessible if any non-private constructor is found
310             for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
311                 if ((ctor.getModifiers() & Modifier.PRIVATE) == 0) {
312                     return true;
313                 }
314             }
315             if (Reflection.areNestMates(cl, superCl)) {
316                 return true;
317             }
318             return false;
319         } else {
320             // sanity check to ensure the parent is protected or public
321             if ((superCl.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) {
322                 return false;
323             }
324             // accessible if any constructor is protected or public
325             for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
326                 if ((ctor.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) != 0) {
327                     return true;
328                 }
329             }
330             return false;
331         }
332     }
333 
334     /**
335      * Returns a constructor that allocates an instance of cl and that then initializes
336      * the instance by calling the no-arg constructor of its first non-serializable
337      * superclass. This is specified in the Serialization Specification, section 3.1,
338      * in step 11 of the deserialization process. If cl is not serializable, returns
339      * cl's no-arg constructor. If no accessible constructor is found, or if the
340      * class hierarchy is somehow malformed (e.g., a serializable class has no
341      * superclass), null is returned.
342      *
343      * @param cl the class for which a constructor is to be found
344      * @return the generated constructor, or null if none is available
345      */
346     public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
347         Class<?> initCl = cl;
348         while (Serializable.class.isAssignableFrom(initCl)) {
349             Class<?> prev = initCl;
350             if ((initCl = initCl.getSuperclass()) == null ||
351                 (!disableSerialConstructorChecks() && !superHasAccessibleConstructor(prev))) {
352                 return null;
353             }
354         }
355         Constructor<?> constructorToCall;
356         try {
357             constructorToCall = initCl.getDeclaredConstructor();
358             int mods = constructorToCall.getModifiers();
359             if ((mods & Modifier.PRIVATE) != 0 ||
360                     ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
361                             !packageEquals(cl, initCl))) {
362                 return null;
363             }
364         } catch (NoSuchMethodException ex) {
365             return null;
366         }
367         return generateConstructor(cl, constructorToCall);
368     }
369 
370     private final Constructor<?> generateConstructor(Class<?> cl,
371                                                      Constructor<?> constructorToCall) {
372 
373         Constructor<?> ctor = newConstructor(constructorToCall.getDeclaringClass(),
374                                              constructorToCall.getParameterTypes(),
375                                              constructorToCall.getExceptionTypes(),
376                                              constructorToCall.getModifiers(),
377                                              langReflectAccess.getConstructorSlot(constructorToCall),
378                                              langReflectAccess.getConstructorSignature(constructorToCall),
379                                              langReflectAccess.getConstructorAnnotations(constructorToCall),
380                                              langReflectAccess.getConstructorParameterAnnotations(constructorToCall));
381         ConstructorAccessor acc;
382         if (useOldSerializableConstructor()) {
383             acc = new SerializationConstructorAccessorGenerator().
384                                 generateSerializationConstructor(cl,
385                                                                  constructorToCall.getParameterTypes(),
386                                                                  constructorToCall.getModifiers(),
387                                                                  constructorToCall.getDeclaringClass());
388         } else {
389             acc = MethodHandleAccessorFactory.newSerializableConstructorAccessor(cl, ctor);
390         }
391         setConstructorAccessor(ctor, acc);
392         ctor.setAccessible(true);
393         return ctor;
394     }
395 
396     public final MethodHandle readObjectForSerialization(Class<?> cl) {
397         return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class);
398     }
399 
400     public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
401         return findReadWriteObjectForSerialization(cl, "readObjectNoData", null);
402     }
403 
404     public final MethodHandle writeObjectForSerialization(Class<?> cl) {
405         return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class);
406     }
407 
408     private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl,
409                                                                    String methodName,
410                                                                    Class<?> streamClass) {
411         if (!Serializable.class.isAssignableFrom(cl)) {
412             return null;
413         }
414 
415         try {
416             Method meth = streamClass == null ? cl.getDeclaredMethod(methodName)
417                     : cl.getDeclaredMethod(methodName, streamClass);
418             int mods = meth.getModifiers();
419             if (meth.getReturnType() != Void.TYPE ||
420                     Modifier.isStatic(mods) ||
421                     !Modifier.isPrivate(mods)) {
422                 return null;
423             }
424             meth.setAccessible(true);
425             return MethodHandles.lookup().unreflect(meth);
426         } catch (NoSuchMethodException ex) {
427             return null;
428         } catch (IllegalAccessException ex1) {
429             throw new InternalError("Error", ex1);
430         }
431     }
432 
433     /**
434      * Returns a MethodHandle for {@code writeReplace} on the serializable class
435      * or null if no match found.
436      * @param cl a serializable class
437      * @return the {@code writeReplace} MethodHandle or {@code null} if not found
438      */
439     public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
440         return getReplaceResolveForSerialization(cl, "writeReplace");
441     }
442 
443     /**
444      * Returns a MethodHandle for {@code readResolve} 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 readResolveForSerialization(Class<?> cl) {
450         return getReplaceResolveForSerialization(cl, "readResolve");
451     }
452 
453     /**
454      * Lookup readResolve or writeReplace on a class with specified
455      * signature constraints.
456      * @param cl a serializable class
457      * @param methodName the method name to find
458      * @return a MethodHandle for the method or {@code null} if not found or
459      *       has the wrong signature.
460      */
461     private MethodHandle getReplaceResolveForSerialization(Class<?> cl,
462                                                            String methodName) {
463         if (!Serializable.class.isAssignableFrom(cl)) {
464             return null;
465         }
466 
467         Class<?> defCl = cl;
468         while (defCl != null) {
469             try {
470                 Method m = defCl.getDeclaredMethod(methodName);
471                 if (m.getReturnType() != Object.class) {
472                     return null;
473                 }
474                 int mods = m.getModifiers();
475                 if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) {
476                     return null;
477                 } else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) {
478                     // fall through
479                 } else if (Modifier.isPrivate(mods) && (cl != defCl)) {
480                     return null;
481                 } else if (!packageEquals(cl, defCl)) {
482                     return null;
483                 }
484                 try {
485                     // Normal return
486                     m.setAccessible(true);
487                     return MethodHandles.lookup().unreflect(m);
488                 } catch (IllegalAccessException ex0) {
489                     // setAccessible should prevent IAE
490                     throw new InternalError("Error", ex0);
491                 }
492             } catch (NoSuchMethodException ex) {
493                 defCl = defCl.getSuperclass();
494             }
495         }
496         return null;
497     }
498 
499     /**
500      * Returns true if the given class defines a static initializer method,
501      * false otherwise.
502      */
503     public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
504         Method m = hasStaticInitializerMethod;
505         if (m == null) {
506             try {
507                 m = ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer",
508                         new Class<?>[]{Class.class});
509                 m.setAccessible(true);
510                 hasStaticInitializerMethod = m;
511             } catch (NoSuchMethodException ex) {
512                 throw new InternalError("No such method hasStaticInitializer on "
513                         + ObjectStreamClass.class, ex);
514             }
515         }
516         try {
517             return (Boolean) m.invoke(null, cl);
518         } catch (InvocationTargetException | IllegalAccessException ex) {
519             throw new InternalError("Exception invoking hasStaticInitializer", ex);
520         }
521     }
522 
523     /**
524      * Return the accessible constructor for OptionalDataException signaling eof.
525      * @return the eof constructor for OptionalDataException
526      */
527     public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() {
528         try {
529             Constructor<OptionalDataException> boolCtor =
530                     OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE);
531             boolCtor.setAccessible(true);
532             return boolCtor;
533         } catch (NoSuchMethodException ex) {
534             throw new InternalError("Constructor not found", ex);
535         }
536     }
537 
538     //--------------------------------------------------------------------------
539     //
540     // Internals only below this point
541     //
542 
543     /*
544      * If -Djdk.reflect.useNativeAccessorOnly is set, use the native accessor only.
545      * For testing purpose only.
546      */
547     static boolean useNativeAccessorOnly() {
548         return config().useNativeAccessorOnly;
549     }
550 
551     static boolean useOldSerializableConstructor() {
552         return config().useOldSerializableConstructor;
553     }
554 
555     private static boolean disableSerialConstructorChecks() {
556         return config().disableSerialConstructorChecks;
557     }
558 
559     /**
560      * The configuration is lazily initialized after the module system is initialized. The
561      * default config would be used before the proper config is loaded.
562      *
563      * The static initializer of ReflectionFactory is run before the system properties are set up.
564      * The class initialization is caused by the class initialization of java.lang.reflect.Method
565      * (more properly, caused by the class initialization for java.lang.reflect.AccessibleObject)
566      * that happens very early VM startup, initPhase1.
567      */
568     private static @Stable Config config;
569 
570     private static final Config DEFAULT_CONFIG = new Config(false, // useNativeAccessorOnly
571                                                             false,  // useOldSerializeableConstructor
572                                                             false); // disableSerialConstructorChecks
573 
574     /**
575      * The configurations for the reflection factory. Configurable via
576      * system properties but only available after ReflectionFactory is
577      * loaded during early VM startup.
578      *
579      * Note that the default implementations of the object methods of
580      * this Config record (toString, equals, hashCode) use indy,
581      * which is available to use only after initPhase1. These methods
582      * are currently not called, but should they be needed, a workaround
583      * is to override them.
584      */
585     private record Config(boolean useNativeAccessorOnly,
586                           boolean useOldSerializableConstructor,
587                           boolean disableSerialConstructorChecks) {
588     }
589 
590     private static Config config() {
591         Config c = config;
592         if (c != null) {
593             return c;
594         }
595 
596         // Always use the default configuration until the module system is initialized.
597         if (!VM.isModuleSystemInited()) {
598             return DEFAULT_CONFIG;
599         }
600 
601         return config = loadConfig();
602     }
603 
604     private static Config loadConfig() {
605         assert VM.isModuleSystemInited();
606 
607         Properties props = GetPropertyAction.privilegedGetProperties();
608         boolean useNativeAccessorOnly =
609             "true".equals(props.getProperty("jdk.reflect.useNativeAccessorOnly"));
610         boolean useOldSerializableConstructor =
611             "true".equals(props.getProperty("jdk.reflect.useOldSerializableConstructor"));
612         boolean disableSerialConstructorChecks =
613             "true".equals(props.getProperty("jdk.disableSerialConstructorChecks"));
614 
615         return new Config(useNativeAccessorOnly, useOldSerializableConstructor, disableSerialConstructorChecks);
616     }
617 
618     /**
619      * Returns true if classes are defined in the classloader and same package, false
620      * otherwise.
621      * @param cl1 a class
622      * @param cl2 another class
623      * @return true if the two classes are in the same classloader and package
624      */
625     private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
626         assert !cl1.isArray() && !cl2.isArray();
627 
628         if (cl1 == cl2) {
629             return true;
630         }
631 
632         return cl1.getClassLoader() == cl2.getClassLoader() &&
633                 cl1.getPackageName() == cl2.getPackageName();
634     }
635 
636 }