< prev index next >

src/java.base/share/classes/sun/invoke/util/VerifyAccess.java

Print this page




 219                 if (!jdk.internal.misc.VM.isModuleSystemInited())
 220                     return true;
 221             }
 222 
 223             // public class not accessible to lookupClass
 224             return false;
 225         }
 226         if ((allowedModes & PACKAGE_ALLOWED) != 0 &&
 227             isSamePackage(lookupClass, refc))
 228             return true;
 229         return false;
 230     }
 231 
 232     /**
 233      * Decide if the given method type, attributed to a member or symbolic
 234      * reference of a given reference class, is really visible to that class.
 235      * @param type the supposed type of a member or symbolic reference of refc
 236      * @param refc the class attempting to make the reference
 237      */
 238     public static boolean isTypeVisible(Class<?> type, Class<?> refc) {
 239         if (type == refc) {
 240             return true;  // easy check
 241         }
 242         while (type.isArray())  type = type.getComponentType();
 243         if (type.isPrimitive() || type == Object.class) {
 244             return true;
 245         }
 246         ClassLoader typeLoader = type.getClassLoader();
 247         ClassLoader refcLoader = refc.getClassLoader();
 248         if (typeLoader == refcLoader) {
 249             return true;
 250         }
 251         if (refcLoader == null && typeLoader != null) {
 252             return false;
 253         }
 254         if (typeLoader == null && type.getName().startsWith("java.")) {
 255             // Note:  The API for actually loading classes, ClassLoader.defineClass,
 256             // guarantees that classes with names beginning "java." cannot be aliased,
 257             // because class loaders cannot load them directly.
 258             return true;
 259         }


 267         // This would be wasted effort, but it is expected to be very rare, occurring
 268         // only when an attacker is attempting to create a type alias.
 269         // In the normal case, one class loader will simply delegate to the other,
 270         // and the same type will be visible through both, with no extra loading.
 271         //
 272         // It is important to go through Class.forName instead of ClassLoader.loadClass
 273         // because Class.forName goes through the JVM system dictionary, which records
 274         // the class lookup once for all. This means that even if a not-well-behaved class loader
 275         // would "change its mind" about the meaning of the name, the Class.forName request
 276         // will use the result cached in the JVM system dictionary. Note that the JVM system dictionary
 277         // will record the first successful result. Unsuccessful results are not stored.
 278         //
 279         // We use doPrivileged in order to allow an unprivileged caller to ask an arbitrary
 280         // class loader about the binding of the proposed name (type.getName()).
 281         // The looked up type ("res") is compared for equality against the proposed
 282         // type ("type") and then is discarded.  Thus, the worst that can happen to
 283         // the "child" class loader is that it is bothered to load and report a class
 284         // that differs from "type"; this happens once due to JVM system dictionary
 285         // memoization.  And the caller never gets to look at the alternate type binding
 286         // ("res"), whether it exists or not.

 287         final String name = type.getName();
 288         Class<?> res = java.security.AccessController.doPrivileged(
 289                 new java.security.PrivilegedAction<>() {
 290                     public Class<?> run() {
 291                         try {
 292                             return Class.forName(name, false, refcLoader);
 293                         } catch (ClassNotFoundException | LinkageError e) {
 294                             return null; // Assume the class is not found
 295                         }
 296                     }
 297             });
 298         return (type == res);
 299     }
 300 
 301     /**
 302      * Decide if the given method type, attributed to a member or symbolic
 303      * reference of a given reference class, is really visible to that class.
 304      * @param type the supposed type of a member or symbolic reference of refc
 305      * @param refc the class attempting to make the reference
 306      */
 307     public static boolean isTypeVisible(java.lang.invoke.MethodType type, Class<?> refc) {
 308         if (!isTypeVisible(type.returnType(), refc)) {
 309             return false;
 310         }
 311         for (int n = 0, max = type.parameterCount(); n < max; n++) {
 312             if (!isTypeVisible(type.parameterType(n), refc)) {
 313                 return false;
 314             }
 315         }
 316         return true;
 317     }
 318 




 219                 if (!jdk.internal.misc.VM.isModuleSystemInited())
 220                     return true;
 221             }
 222 
 223             // public class not accessible to lookupClass
 224             return false;
 225         }
 226         if ((allowedModes & PACKAGE_ALLOWED) != 0 &&
 227             isSamePackage(lookupClass, refc))
 228             return true;
 229         return false;
 230     }
 231 
 232     /**
 233      * Decide if the given method type, attributed to a member or symbolic
 234      * reference of a given reference class, is really visible to that class.
 235      * @param type the supposed type of a member or symbolic reference of refc
 236      * @param refc the class attempting to make the reference
 237      */
 238     public static boolean isTypeVisible(Class<?> type, Class<?> refc) {
 239         if (type.asPrimaryType() == refc.asPrimaryType()) {
 240             return true;  // easy check
 241         }
 242         while (type.isArray())  type = type.getComponentType();
 243         if (type.isPrimitive() || type == Object.class) {
 244             return true;
 245         }
 246         ClassLoader typeLoader = type.getClassLoader();
 247         ClassLoader refcLoader = refc.getClassLoader();
 248         if (typeLoader == refcLoader) {
 249             return true;
 250         }
 251         if (refcLoader == null && typeLoader != null) {
 252             return false;
 253         }
 254         if (typeLoader == null && type.getName().startsWith("java.")) {
 255             // Note:  The API for actually loading classes, ClassLoader.defineClass,
 256             // guarantees that classes with names beginning "java." cannot be aliased,
 257             // because class loaders cannot load them directly.
 258             return true;
 259         }


 267         // This would be wasted effort, but it is expected to be very rare, occurring
 268         // only when an attacker is attempting to create a type alias.
 269         // In the normal case, one class loader will simply delegate to the other,
 270         // and the same type will be visible through both, with no extra loading.
 271         //
 272         // It is important to go through Class.forName instead of ClassLoader.loadClass
 273         // because Class.forName goes through the JVM system dictionary, which records
 274         // the class lookup once for all. This means that even if a not-well-behaved class loader
 275         // would "change its mind" about the meaning of the name, the Class.forName request
 276         // will use the result cached in the JVM system dictionary. Note that the JVM system dictionary
 277         // will record the first successful result. Unsuccessful results are not stored.
 278         //
 279         // We use doPrivileged in order to allow an unprivileged caller to ask an arbitrary
 280         // class loader about the binding of the proposed name (type.getName()).
 281         // The looked up type ("res") is compared for equality against the proposed
 282         // type ("type") and then is discarded.  Thus, the worst that can happen to
 283         // the "child" class loader is that it is bothered to load and report a class
 284         // that differs from "type"; this happens once due to JVM system dictionary
 285         // memoization.  And the caller never gets to look at the alternate type binding
 286         // ("res"), whether it exists or not.
 287 
 288         final String name = type.getName();
 289         Class<?> res = java.security.AccessController.doPrivileged(
 290                 new java.security.PrivilegedAction<>() {
 291                     public Class<?> run() {
 292                         try {
 293                             return Class.forName(name, false, refcLoader);
 294                         } catch (ClassNotFoundException | LinkageError e) {
 295                             return null; // Assume the class is not found
 296                         }
 297                     }
 298             });
 299         return (type.asPrimaryType() == res);
 300     }
 301 
 302     /**
 303      * Decide if the given method type, attributed to a member or symbolic
 304      * reference of a given reference class, is really visible to that class.
 305      * @param type the supposed type of a member or symbolic reference of refc
 306      * @param refc the class attempting to make the reference
 307      */
 308     public static boolean isTypeVisible(java.lang.invoke.MethodType type, Class<?> refc) {
 309         if (!isTypeVisible(type.returnType(), refc)) {
 310             return false;
 311         }
 312         for (int n = 0, max = type.parameterCount(); n < max; n++) {
 313             if (!isTypeVisible(type.parameterType(n), refc)) {
 314                 return false;
 315             }
 316         }
 317         return true;
 318     }
 319 


< prev index next >