1 /*
   2  * Copyright (c) 2004, 2016, 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 sun.corba ;
  27 
  28 import java.io.OptionalDataException;
  29 import java.lang.invoke.MethodHandle;
  30 import java.lang.reflect.Field;
  31 import java.lang.reflect.Constructor;
  32 import java.lang.reflect.InvocationTargetException;
  33 import java.lang.StackWalker;
  34 import java.lang.StackWalker.StackFrame;
  35 import java.util.Optional;
  36 import java.util.stream.Stream;
  37 
  38 import java.security.AccessController;
  39 import java.security.Permission;
  40 import java.security.PrivilegedAction;
  41 import java.security.ProtectionDomain;
  42 
  43 import sun.misc.Unsafe;
  44 import sun.reflect.ReflectionFactory;
  45 
  46 /** This class provides the methods for fundamental JVM operations
  47  * needed in the ORB that are not part of the public Java API.  This includes:
  48  * <ul>
  49  * <li>throwException, which can throw undeclared checked exceptions.
  50  * This is needed to handle throwing arbitrary exceptions across a standardized
  51  * OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
  52  * <li>putXXX/getXXX methods that allow unchecked access to fields of objects.
  53  * This is used for setting uninitialzed non-static final fields (which is
  54  * impossible with reflection) and for speed.</li>
  55  * <li>objectFieldOffset to obtain the field offsets for use in the putXXX/getXXX methods</li>
  56  * <li>newConstructorForSerialization to get the special constructor required for a
  57  * Serializable class</li>
  58  * <li>latestUserDefinedLoader to get the latest user defined class loader from
  59  * the call stack as required by the RMI-IIOP specification (really from the
  60  * JDK 1.1 days)</li>
  61  * </ul>
  62  * The code that calls Bridge.get() must have the following Permissions:
  63  * <ul>
  64  * <li>BridgePermission "getBridge"</li>
  65  * <li>ReflectPermission "suppressAccessChecks"</li>
  66  * <li>RuntimePermission "getStackWalkerWithClassReference"</li>
  67  * <li>RuntimePermission "reflectionFactoryAccess"</li>
  68  * </ul>
  69  * <p>
  70  * All of these permissions are required to obtain and correctly initialize
  71  * the instance of Bridge.  No security checks are performed on calls
  72  * made to Bridge instance methods, so access to the Bridge instance
  73  * must be protected.
  74  * <p>
  75  * This class is a singleton (per ClassLoader of course).  Access to the
  76  * instance is obtained through the Bridge.get() method.
  77  */
  78 public final class Bridge
  79 {
  80     private static final Permission getBridgePermission =
  81             new BridgePermission("getBridge");
  82     private static Bridge bridge = null ;
  83 
  84     /** Access to Unsafe to read/write fields. */
  85     private static final Unsafe unsafe = AccessController.doPrivileged(
  86             (PrivilegedAction<Unsafe>)() -> {
  87                 try {
  88                     Field field = Unsafe.class.getDeclaredField("theUnsafe");
  89                     field.setAccessible(true);
  90                     return (Unsafe)field.get(null);
  91 
  92                 } catch (NoSuchFieldException |IllegalAccessException ex) {
  93                     throw new InternalError("Unsafe.theUnsafe field not available", ex);
  94                 }
  95             }
  96     ) ;
  97 
  98     private final ReflectionFactory reflectionFactory ;
  99     private final StackWalker stackWalker;
 100 
 101     private Bridge() {
 102         reflectionFactory = ReflectionFactory.getReflectionFactory();
 103         stackWalker  = StackWalker.getInstance(
 104                             StackWalker.Option.RETAIN_CLASS_REFERENCE);
 105     }
 106 
 107     /** Fetch the Bridge singleton.  This requires the following
 108      * permissions:
 109      * <ul>
 110      * <li>BridgePermission "getBridge"</li>
 111      * <li>ReflectPermission "suppressAccessChecks"</li>
 112      * <li>RuntimePermission "getStackWalkerWithClassReference"</li>
 113      * <li>RuntimePermission "reflectionFactoryAccess"</li>
 114      * </ul>
 115      * @return The singleton instance of the Bridge class
 116      * @throws SecurityException if the caller does not have the
 117      * required permissions and the caller has a non-null security manager.
 118      */
 119     public static final synchronized Bridge get()
 120     {
 121         SecurityManager sman = System.getSecurityManager() ;
 122         if (sman != null)
 123             sman.checkPermission( getBridgePermission ) ;
 124 
 125         if (bridge == null) {
 126             bridge = new Bridge() ;
 127         }
 128 
 129         return bridge ;
 130     }
 131 
 132     /** Returns true if the loader that loaded the frame's declaring class
 133      * is a user loader (if it is not the platform class loader or one of
 134      * its ancestor).
 135      */
 136     private boolean isUserLoader(StackFrame sf) {
 137         ClassLoader cl = sf.getDeclaringClass().getClassLoader();
 138         if (cl == null) return false;
 139         ClassLoader p = ClassLoader.getPlatformClassLoader();
 140         while (cl != p && p != null) p = p.getParent();
 141         return cl != p;
 142     }
 143 
 144     private Optional<StackFrame> getLatestUserDefinedLoaderFrame(Stream<StackFrame> stream) {
 145         return stream.filter(this::isUserLoader).findFirst();
 146     }
 147 
 148 
 149     /** Obtain the latest user defined ClassLoader from the call stack.
 150      * This is required by the RMI-IIOP specification.
 151      */
 152     public final ClassLoader getLatestUserDefinedLoader() {
 153         // requires getClassLoader permission => needs doPrivileged.
 154         PrivilegedAction<ClassLoader> pa = () ->
 155             stackWalker.walk(this::getLatestUserDefinedLoaderFrame)
 156                 .map(sf -> sf.getDeclaringClass().getClassLoader())
 157                 .orElseGet(() -> ClassLoader.getPlatformClassLoader());
 158         return AccessController.doPrivileged(pa);
 159     }
 160 
 161     /**
 162      * Fetches a field element within the given
 163      * object <code>o</code> at the given offset.
 164      * The result is undefined unless the offset was obtained from
 165      * {@link #objectFieldOffset} on the {@link java.lang.reflect.Field}
 166      * of some Java field and the object referred to by <code>o</code>
 167      * is of a class compatible with that field's class.
 168      * @param o Java heap object in which the field from which the offset
 169      * was obtained resides
 170      * @param offset indication of where the field resides in a Java heap
 171      *        object
 172      * @return the value fetched from the indicated Java field
 173      * @throws RuntimeException No defined exceptions are thrown, not even
 174      *         {@link NullPointerException}
 175      */
 176     public final int getInt(Object o, long offset)
 177     {
 178         return unsafe.getInt( o, offset ) ;
 179     }
 180 
 181     /**
 182      * Stores a value into a given Java field.
 183      * <p>
 184      * The first two parameters are interpreted exactly as with
 185      * {@link #getInt(Object, long)} to refer to a specific
 186      * Java field.  The given value is stored into that field.
 187      * <p>
 188      * The field must be of the same type as the method
 189      * parameter <code>x</code>.
 190      *
 191      * @param o Java heap object in which the field resides, if any, else
 192      *        null
 193      * @param offset indication of where the field resides in a Java heap
 194      *        object.
 195      * @param x the value to store into the indicated Java field
 196      * @throws RuntimeException No defined exceptions are thrown, not even
 197      *         {@link NullPointerException}
 198      */
 199     public final void putInt(Object o, long offset, int x)
 200     {
 201         unsafe.putInt( o, offset, x ) ;
 202     }
 203 
 204     /**
 205      * @see #getInt(Object, long)
 206      */
 207     public final Object getObject(Object o, long offset)
 208     {
 209         return unsafe.getObject( o, offset ) ;
 210     }
 211 
 212     /**
 213      * @see #putInt(Object, long, int)
 214      */
 215     public final void putObject(Object o, long offset, Object x)
 216     {
 217         unsafe.putObject( o, offset, x ) ;
 218     }
 219 
 220     /** @see #getInt(Object, long) */
 221     public final boolean getBoolean(Object o, long offset)
 222     {
 223         return unsafe.getBoolean( o, offset ) ;
 224     }
 225     /** @see #putInt(Object, long, int) */
 226     public final void    putBoolean(Object o, long offset, boolean x)
 227     {
 228         unsafe.putBoolean( o, offset, x ) ;
 229     }
 230     /** @see #getInt(Object, long) */
 231     public final byte    getByte(Object o, long offset)
 232     {
 233         return unsafe.getByte( o, offset ) ;
 234     }
 235     /** @see #putInt(Object, long, int) */
 236     public final void    putByte(Object o, long offset, byte x)
 237     {
 238         unsafe.putByte( o, offset, x ) ;
 239     }
 240     /** @see #getInt(Object, long) */
 241     public final short   getShort(Object o, long offset)
 242     {
 243         return unsafe.getShort( o, offset ) ;
 244     }
 245     /** @see #putInt(Object, long, int) */
 246     public final void    putShort(Object o, long offset, short x)
 247     {
 248         unsafe.putShort( o, offset, x ) ;
 249     }
 250     /** @see #getInt(Object, long) */
 251     public final char    getChar(Object o, long offset)
 252     {
 253         return unsafe.getChar( o, offset ) ;
 254     }
 255     /** @see #putInt(Object, long, int) */
 256     public final void    putChar(Object o, long offset, char x)
 257     {
 258         unsafe.putChar( o, offset, x ) ;
 259     }
 260     /** @see #getInt(Object, long) */
 261     public final long    getLong(Object o, long offset)
 262     {
 263         return unsafe.getLong( o, offset ) ;
 264     }
 265     /** @see #putInt(Object, long, int) */
 266     public final void    putLong(Object o, long offset, long x)
 267     {
 268         unsafe.putLong( o, offset, x ) ;
 269     }
 270     /** @see #getInt(Object, long) */
 271     public final float   getFloat(Object o, long offset)
 272     {
 273         return unsafe.getFloat( o, offset ) ;
 274     }
 275     /** @see #putInt(Object, long, int) */
 276     public final void    putFloat(Object o, long offset, float x)
 277     {
 278         unsafe.putFloat( o, offset, x ) ;
 279     }
 280     /** @see #getInt(Object, long) */
 281     public final double  getDouble(Object o, long offset)
 282     {
 283         return unsafe.getDouble( o, offset ) ;
 284     }
 285     /** @see #putInt(Object, long, int) */
 286     public final void    putDouble(Object o, long offset, double x)
 287     {
 288         unsafe.putDouble( o, offset, x ) ;
 289     }
 290 
 291     /**
 292      * This constant differs from all results that will ever be returned from
 293      * {@link #objectFieldOffset}.
 294      */
 295     public static final long INVALID_FIELD_OFFSET   = -1;
 296 
 297     /**
 298      * Returns the offset of a non-static field.
 299      */
 300     public final long objectFieldOffset(Field f)
 301     {
 302         return unsafe.objectFieldOffset( f ) ;
 303     }
 304 
 305     /**
 306      * Returns the offset of a static field.
 307      */
 308     public final long staticFieldOffset(Field f)
 309     {
 310         return unsafe.staticFieldOffset( f ) ;
 311     }
 312 
 313     /**
 314      * Ensure that the class has been initalized.
 315      * @param cl the class to ensure is initialized
 316      */
 317     public final void ensureClassInitialized(Class<?> cl) {
 318         unsafe.ensureClassInitialized(cl);
 319     }
 320 
 321 
 322     /** Throw the exception.
 323      * The exception may be an undeclared checked exception.
 324      */
 325     public final void throwException(Throwable ee)
 326     {
 327         unsafe.throwException( ee ) ;
 328     }
 329 
 330     /**
 331      * Obtain a constructor for Class cl.
 332      * This is used to create a constructor for Serializable classes that
 333      * construct an instance of the Serializable class using the
 334      * no args constructor of the first non-Serializable superclass
 335      * of the Serializable class.
 336      */
 337     public final Constructor<?> newConstructorForSerialization( Class<?> cl ) {
 338         return reflectionFactory.newConstructorForSerialization( cl ) ;
 339     }
 340 
 341     public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
 342         return reflectionFactory.newConstructorForExternalization( cl ) ;
 343     }
 344 
 345     /**
 346      * Invokes the supplied constructor, adding the provided protection domains
 347      * to the invocation stack before invoking {@code Constructor::newInstance}.
 348      *
 349      * This is equivalent to calling
 350      * {@code ReflectionFactory.newInstanceForSerialization(cons,domains)}.
 351      *
 352      * @param cons A constructor obtained from {@code
 353      *        newConstructorForSerialization} or {@code
 354      *        newConstructorForExternalization}.
 355      *
 356      * @param domains An array of protection domains that limit the privileges
 357      *        with which the constructor is invoked. Can be {@code null}
 358      *        or empty, in which case privileges are only limited by the
 359      *        {@linkplain AccessController#getContext() current context}.
 360      *
 361      * @return A new object built from the provided constructor.
 362      *
 363      * @throws NullPointerException if {@code cons} is {@code null}.
 364      * @throws InstantiationException if thrown by {@code cons.newInstance()}.
 365      * @throws InvocationTargetException if thrown by {@code cons.newInstance()}.
 366      * @throws IllegalAccessException if thrown by {@code cons.newInstance()}.
 367      */
 368     public final Object newInstanceForSerialization(Constructor<?> cons,
 369                                                     ProtectionDomain[] domains)
 370         throws InstantiationException, InvocationTargetException, IllegalAccessException
 371     {
 372         return reflectionFactory.newInstanceForSerialization(cons, domains);
 373     }
 374 
 375     /**
 376      * Returns true if the given class defines a static initializer method,
 377      * false otherwise.
 378      */
 379     public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
 380         return reflectionFactory.hasStaticInitializerForSerialization(cl);
 381     }
 382 
 383     public final MethodHandle writeObjectForSerialization(Class<?> cl) {
 384         return reflectionFactory.writeObjectForSerialization(cl);
 385     }
 386 
 387     public final MethodHandle readObjectForSerialization(Class<?> cl) {
 388         return reflectionFactory.readObjectForSerialization(cl);
 389     }
 390 
 391     public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
 392         return reflectionFactory.readObjectNoDataForSerialization(cl);
 393     }
 394 
 395     public final MethodHandle readResolveForSerialization(Class<?> cl) {
 396         return reflectionFactory.readResolveForSerialization(cl);
 397     }
 398 
 399     public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
 400         return reflectionFactory.writeReplaceForSerialization(cl);
 401     }
 402 
 403     /**
 404      * Return a new OptionalDataException instance.
 405      * @return a new OptionalDataException instance
 406      */
 407     public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
 408         return reflectionFactory.newOptionalDataExceptionForSerialization(bool);
 409     }
 410 
 411 }