< prev index next >

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

Print this page




  71      *     a superclass of D, or D itself.
  72      *     <p>During verification, it was also required that, even if T is
  73      *     a superclass of D, the target reference of a protected instance
  74      *     field access or method invocation must be an instance of D or a
  75      *     subclass of D (4.10.1.8).</p></li>
  76      * <li>R is either protected or has default access (that is, neither
  77      *     public nor protected nor private), and is declared by a class
  78      *     in the same run-time package as D.</li>
  79      * <li>R is private and is declared in D by a class or interface
  80      *     belonging to the same nest as D.</li>
  81      * </ul>
  82      * If a referenced field or method is not accessible, access checking
  83      * throws an IllegalAccessError. If an exception is thrown while
  84      * attempting to determine the nest host of a class or interface,
  85      * access checking fails for the same reason.
  86      *
  87      * @param refc the class used in the symbolic reference to the proposed member
  88      * @param defc the class in which the proposed member is actually defined
  89      * @param mods modifier flags for the proposed member
  90      * @param lookupClass the class for which the access check is being made


  91      * @return true iff the accessing class can access such a member
  92      */
  93     public static boolean isMemberAccessible(Class<?> refc,  // symbolic ref class
  94                                              Class<?> defc,  // actual def class
  95                                              int      mods,  // actual member mods
  96                                              Class<?> lookupClass,

  97                                              int      allowedModes) {
  98         if (allowedModes == 0)  return false;
  99         assert((allowedModes & PUBLIC) != 0 &&
 100                (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0);
 101         // The symbolic reference class (refc) must always be fully verified.
 102         if (!isClassAccessible(refc, lookupClass, allowedModes)) {
 103             return false;
 104         }
 105         // Usually refc and defc are the same, but verify defc also in case they differ.
 106         if (defc == lookupClass  &&
 107             (allowedModes & PRIVATE) != 0)
 108             return true;        // easy check; all self-access is OK with a private lookup
 109 
 110         switch (mods & ALL_ACCESS_MODES) {
 111         case PUBLIC:

 112             return true;  // already checked above
 113         case PROTECTED:
 114             assert !defc.isInterface(); // protected members aren't allowed in interfaces
 115             if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 &&
 116                 isSamePackage(defc, lookupClass))
 117                 return true;
 118             if ((allowedModes & PROTECTED) == 0)
 119                 return false;
 120             // Protected members are accessible by subclasses, which does not include interfaces.
 121             // Interfaces are types, not classes. They should not have access to
 122             // protected members in j.l.Object, even though it is their superclass.
 123             if ((mods & STATIC) != 0 &&
 124                 !isRelatedClass(refc, lookupClass))
 125                 return false;
 126             if ((allowedModes & PROTECTED) != 0 &&
 127                 isSubClass(lookupClass, defc))
 128                 return true;
 129             return false;
 130         case PACKAGE_ONLY:  // That is, zero.  Unmarked member is package-only access.
 131             assert !defc.isInterface(); // package-private members aren't allowed in interfaces


 158     static int getClassModifiers(Class<?> c) {
 159         // This would return the mask stored by javac for the source-level modifiers.
 160         //   return c.getModifiers();
 161         // But what we need for JVM access checks are the actual bits from the class header.
 162         // ...But arrays and primitives are synthesized with their own odd flags:
 163         if (c.isArray() || c.isPrimitive())
 164             return c.getModifiers();
 165         return Reflection.getClassAccessFlags(c);
 166     }
 167 
 168     /**
 169      * Evaluate the JVM linkage rules for access to the given class on behalf of caller.
 170      * <h3>JVM Specification, 5.4.4 "Access Control"</h3>
 171      * A class or interface C is accessible to a class or interface D
 172      * if and only if any of the following conditions are true:<ul>
 173      * <li>C is public and in the same module as D.
 174      * <li>D is in a module that reads the module containing C, C is public and in a
 175      * package that is exported to the module that contains D.
 176      * <li>C and D are members of the same runtime package.
 177      * </ul>

 178      * @param refc the symbolic reference class to which access is being checked (C)
 179      * @param lookupClass the class performing the lookup (D)


 180      */
 181     public static boolean isClassAccessible(Class<?> refc, Class<?> lookupClass,


 182                                             int allowedModes) {
 183         if (allowedModes == 0)  return false;
 184         assert((allowedModes & PUBLIC) != 0 &&
 185                (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0);




 186         int mods = getClassModifiers(refc);
 187         if (isPublic(mods)) {
 188 
 189             Module lookupModule = lookupClass.getModule();
 190             Module refModule = refc.getModule();
 191 
 192             // early VM startup case, java.base not defined
 193             if (lookupModule == null) {
 194                 assert refModule == null;
 195                 return true;
 196             }
 197 
 198             // trivially allow
 199             if ((allowedModes & MODULE_ALLOWED) != 0 &&
 200                 (lookupModule == refModule))
 201                 return true;
 202 
 203             // check readability when UNCONDITIONAL not allowed
 204             if (((allowedModes & UNCONDITIONAL_ALLOWED) != 0)
 205                 || lookupModule.canRead(refModule)) {
 206 
 207                 // check that refc is in an exported package
 208                 if ((allowedModes & MODULE_ALLOWED) != 0) {
 209                     if (refModule.isExported(refc.getPackageName(), lookupModule))
 210                         return true;
 211                 } else {
 212                     // exported unconditionally
 213                     if (refModule.isExported(refc.getPackageName()))
 214                         return true;



 215                 }
 216 









 217                 // not exported but allow access during VM initialization
 218                 // because java.base does not have its exports setup
 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) {




  71      *     a superclass of D, or D itself.
  72      *     <p>During verification, it was also required that, even if T is
  73      *     a superclass of D, the target reference of a protected instance
  74      *     field access or method invocation must be an instance of D or a
  75      *     subclass of D (4.10.1.8).</p></li>
  76      * <li>R is either protected or has default access (that is, neither
  77      *     public nor protected nor private), and is declared by a class
  78      *     in the same run-time package as D.</li>
  79      * <li>R is private and is declared in D by a class or interface
  80      *     belonging to the same nest as D.</li>
  81      * </ul>
  82      * If a referenced field or method is not accessible, access checking
  83      * throws an IllegalAccessError. If an exception is thrown while
  84      * attempting to determine the nest host of a class or interface,
  85      * access checking fails for the same reason.
  86      *
  87      * @param refc the class used in the symbolic reference to the proposed member
  88      * @param defc the class in which the proposed member is actually defined
  89      * @param mods modifier flags for the proposed member
  90      * @param lookupClass the class for which the access check is being made
  91      * @param prevLookupClass the class for which the access check is being made
  92      * @param allowedModes allowed modes
  93      * @return true iff the accessing class can access such a member
  94      */
  95     public static boolean isMemberAccessible(Class<?> refc,  // symbolic ref class
  96                                              Class<?> defc,  // actual def class
  97                                              int      mods,  // actual member mods
  98                                              Class<?> lookupClass,
  99                                              Class<?> prevLookupClass,
 100                                              int      allowedModes) {
 101         if (allowedModes == 0)  return false;
 102         assert((allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0);

 103         // The symbolic reference class (refc) must always be fully verified.
 104         if (!isClassAccessible(refc, lookupClass, prevLookupClass, allowedModes)) {
 105             return false;
 106         }
 107         // Usually refc and defc are the same, but verify defc also in case they differ.
 108         if (defc == lookupClass  &&
 109             (allowedModes & PRIVATE) != 0)
 110             return true;        // easy check; all self-access is OK with a private lookup
 111 
 112         switch (mods & ALL_ACCESS_MODES) {
 113         case PUBLIC:
 114             assert (allowedModes & PUBLIC) != 0 || (allowedModes & UNCONDITIONAL_ALLOWED) != 0;
 115             return true;  // already checked above
 116         case PROTECTED:
 117             assert !defc.isInterface(); // protected members aren't allowed in interfaces
 118             if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 &&
 119                 isSamePackage(defc, lookupClass))
 120                 return true;
 121             if ((allowedModes & PROTECTED) == 0)
 122                 return false;
 123             // Protected members are accessible by subclasses, which does not include interfaces.
 124             // Interfaces are types, not classes. They should not have access to
 125             // protected members in j.l.Object, even though it is their superclass.
 126             if ((mods & STATIC) != 0 &&
 127                 !isRelatedClass(refc, lookupClass))
 128                 return false;
 129             if ((allowedModes & PROTECTED) != 0 &&
 130                 isSubClass(lookupClass, defc))
 131                 return true;
 132             return false;
 133         case PACKAGE_ONLY:  // That is, zero.  Unmarked member is package-only access.
 134             assert !defc.isInterface(); // package-private members aren't allowed in interfaces


 161     static int getClassModifiers(Class<?> c) {
 162         // This would return the mask stored by javac for the source-level modifiers.
 163         //   return c.getModifiers();
 164         // But what we need for JVM access checks are the actual bits from the class header.
 165         // ...But arrays and primitives are synthesized with their own odd flags:
 166         if (c.isArray() || c.isPrimitive())
 167             return c.getModifiers();
 168         return Reflection.getClassAccessFlags(c);
 169     }
 170 
 171     /**
 172      * Evaluate the JVM linkage rules for access to the given class on behalf of caller.
 173      * <h3>JVM Specification, 5.4.4 "Access Control"</h3>
 174      * A class or interface C is accessible to a class or interface D
 175      * if and only if any of the following conditions are true:<ul>
 176      * <li>C is public and in the same module as D.
 177      * <li>D is in a module that reads the module containing C, C is public and in a
 178      * package that is exported to the module that contains D.
 179      * <li>C and D are members of the same runtime package.
 180      * </ul>
 181      *
 182      * @param refc the symbolic reference class to which access is being checked (C)
 183      * @param lookupClass the class performing the lookup (D)
 184      * @param prevLookupClass the class from which the lookup was teleported or null
 185      * @param allowedModes allowed modes
 186      */
 187     public static boolean isClassAccessible(Class<?> refc,
 188                                             Class<?> lookupClass,
 189                                             Class<?> prevLookupClass,
 190                                             int allowedModes) {
 191         if (allowedModes == 0)  return false;
 192         assert((allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0);
 193 
 194         if ((allowedModes & PACKAGE_ALLOWED) != 0 &&
 195             isSamePackage(lookupClass, refc))
 196             return true;
 197 
 198         int mods = getClassModifiers(refc);
 199         if (isPublic(mods)) {
 200 
 201             Module lookupModule = lookupClass.getModule();
 202             Module refModule = refc.getModule();
 203 
 204             // early VM startup case, java.base not defined
 205             if (lookupModule == null) {
 206                 assert refModule == null;
 207                 return true;
 208             }
 209 
 210             // allow access to public types in all unconditionally exported packages
 211             if ((allowedModes & UNCONDITIONAL_ALLOWED) != 0) {
 212                 return refModule.isExported(refc.getPackageName());
 213             }
 214 
 215             if (lookupModule == refModule && prevLookupClass == null) {
 216                 // allow access to all public types in lookupModule
 217                 if ((allowedModes & MODULE_ALLOWED) != 0)








 218                     return true;
 219 
 220                 assert (allowedModes & PUBLIC) != 0;
 221                 return refModule.isExported(refc.getPackageName());
 222             }
 223 
 224             // cross-module access
 225             // 1. refc is in different module from lookupModule, or
 226             // 2. refc is in lookupModule and a different module from prevLookupModule
 227             Module prevLookupModule = prevLookupClass != null ? prevLookupClass.getModule()
 228                                                               : lookupModule;
 229             assert refModule != lookupModule || refModule != prevLookupModule;
 230             if (isModuleAccessible(refc, lookupModule, prevLookupModule))
 231                 return true;
 232 
 233             // not exported but allow access during VM initialization
 234             // because java.base does not have its exports setup
 235             if (!jdk.internal.misc.VM.isModuleSystemInited())
 236                 return true;

 237 
 238             // public class not accessible to lookupClass
 239             return false;
 240         }
 241 
 242         return false;
 243     }
 244 
 245     /*
 246      * A class or interface C in m is accessible to m1 and m2 if and only if
 247      * both m1 and m2 read m and m exports the package of C at least to
 248      * both m1 and m2.
 249      */
 250     public static boolean isModuleAccessible(Class<?> refc,  Module m1, Module m2) {
 251         Module refModule = refc.getModule();
 252         assert refModule != m1 || refModule != m2;
 253         int mods = getClassModifiers(refc);
 254         if (isPublic(mods)) {
 255             if (m1.canRead(refModule) && m2.canRead(refModule)) {
 256                 String pn = refc.getPackageName();
 257 
 258                 // refc is exported package to at least both m1 and m2
 259                 if (refModule.isExported(pn, m1) && refModule.isExported(pn, m2))
 260                     return true;
 261             }
 262         }
 263         return false;
 264     }
 265 
 266     /**
 267      * Decide if the given method type, attributed to a member or symbolic
 268      * reference of a given reference class, is really visible to that class.
 269      * @param type the supposed type of a member or symbolic reference of refc
 270      * @param refc the class attempting to make the reference
 271      */
 272     public static boolean isTypeVisible(Class<?> type, Class<?> refc) {
 273         if (type == refc) {
 274             return true;  // easy check
 275         }
 276         while (type.isArray())  type = type.getComponentType();
 277         if (type.isPrimitive() || type == Object.class) {
 278             return true;
 279         }
 280         ClassLoader typeLoader = type.getClassLoader();
 281         ClassLoader refcLoader = refc.getClassLoader();
 282         if (typeLoader == refcLoader) {


< prev index next >