1 /*
2 * Copyright (c) 2008, 2012, 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.invoke.util;
27
28 import java.lang.reflect.Modifier;
29 import static java.lang.reflect.Modifier.*;
30
31 /**
32 * This class centralizes information about the JVM's linkage access control.
33 * @author jrose
34 */
35 public class VerifyAccess {
36
37 private VerifyAccess() { } // cannot instantiate
38
39 private static final int PACKAGE_ONLY = 0;
40 private static final int PACKAGE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.PACKAGE;
41 private static final int PROTECTED_OR_PACKAGE_ALLOWED = (PACKAGE_ALLOWED|PROTECTED);
42 private static final int ALL_ACCESS_MODES = (PUBLIC|PRIVATE|PROTECTED|PACKAGE_ONLY);
43 private static final boolean ALLOW_NESTMATE_ACCESS = false;
44
45 /**
46 * Evaluate the JVM linkage rules for access to the given method
47 * on behalf of a caller class which proposes to perform the access.
48 * Return true if the caller class has privileges to invoke a method
49 * or access a field with the given properties.
123 case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access.
124 return ((allowedModes & PACKAGE_ALLOWED) != 0 &&
125 isSamePackage(defc, lookupClass));
126 case PRIVATE:
127 // Loosened rules for privates follows access rules for inner classes.
128 return (ALLOW_NESTMATE_ACCESS &&
129 (allowedModes & PRIVATE) != 0 &&
130 isSamePackageMember(defc, lookupClass));
131 default:
132 throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods));
133 }
134 }
135
136 static boolean isRelatedClass(Class<?> refc, Class<?> lookupClass) {
137 return (refc == lookupClass ||
138 refc.isAssignableFrom(lookupClass) ||
139 lookupClass.isAssignableFrom(refc));
140 }
141
142 static boolean isPublicSuperClass(Class<?> defc, Class<?> lookupClass) {
143 return isPublic(defc.getModifiers()) && defc.isAssignableFrom(lookupClass);
144 }
145
146 /**
147 * Evaluate the JVM linkage rules for access to the given class on behalf of caller.
148 * <h3>JVM Specification, 5.4.4 "Access Control"</h3>
149 * A class or interface C is accessible to a class or interface D
150 * if and only if either of the following conditions are true:<ul>
151 * <li>C is public.
152 * <li>C and D are members of the same runtime package.
153 * </ul>
154 * @param refc the symbolic reference class to which access is being checked (C)
155 * @param lookupClass the class performing the lookup (D)
156 */
157 public static boolean isClassAccessible(Class<?> refc, Class<?> lookupClass,
158 int allowedModes) {
159 if (allowedModes == 0) return false;
160 assert((allowedModes & PUBLIC) != 0 &&
161 (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED)) == 0);
162 int mods = refc.getModifiers();
163 if (isPublic(mods))
164 return true;
165 if ((allowedModes & PACKAGE_ALLOWED) != 0 &&
166 isSamePackage(lookupClass, refc))
167 return true;
168 return false;
169 }
170
171 /**
172 * Decide if the given method type, attributed to a member or symbolic
173 * reference of a given reference class, is really visible to that class.
174 * @param type the supposed type of a member or symbolic reference of refc
175 * @param refc the class attempting to make the reference
176 */
177 public static boolean isTypeVisible(Class<?> type, Class<?> refc) {
178 if (type == refc) return true; // easy check
179 while (type.isArray()) type = type.getComponentType();
180 if (type.isPrimitive() || type == Object.class) return true;
181 ClassLoader parent = type.getClassLoader();
182 if (parent == null) return true;
| 1 /*
2 * Copyright (c) 2008, 2013, 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.invoke.util;
27
28 import java.lang.reflect.Modifier;
29 import static java.lang.reflect.Modifier.*;
30 import sun.reflect.Reflection;
31
32 /**
33 * This class centralizes information about the JVM's linkage access control.
34 * @author jrose
35 */
36 public class VerifyAccess {
37
38 private VerifyAccess() { } // cannot instantiate
39
40 private static final int PACKAGE_ONLY = 0;
41 private static final int PACKAGE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.PACKAGE;
42 private static final int PROTECTED_OR_PACKAGE_ALLOWED = (PACKAGE_ALLOWED|PROTECTED);
43 private static final int ALL_ACCESS_MODES = (PUBLIC|PRIVATE|PROTECTED|PACKAGE_ONLY);
44 private static final boolean ALLOW_NESTMATE_ACCESS = false;
45
46 /**
47 * Evaluate the JVM linkage rules for access to the given method
48 * on behalf of a caller class which proposes to perform the access.
49 * Return true if the caller class has privileges to invoke a method
50 * or access a field with the given properties.
124 case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access.
125 return ((allowedModes & PACKAGE_ALLOWED) != 0 &&
126 isSamePackage(defc, lookupClass));
127 case PRIVATE:
128 // Loosened rules for privates follows access rules for inner classes.
129 return (ALLOW_NESTMATE_ACCESS &&
130 (allowedModes & PRIVATE) != 0 &&
131 isSamePackageMember(defc, lookupClass));
132 default:
133 throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods));
134 }
135 }
136
137 static boolean isRelatedClass(Class<?> refc, Class<?> lookupClass) {
138 return (refc == lookupClass ||
139 refc.isAssignableFrom(lookupClass) ||
140 lookupClass.isAssignableFrom(refc));
141 }
142
143 static boolean isPublicSuperClass(Class<?> defc, Class<?> lookupClass) {
144 return isPublic(getClassModifiers(defc)) && defc.isAssignableFrom(lookupClass);
145 }
146
147 static int getClassModifiers(Class<?> c) {
148 // This would return the mask stored by javac for the source-level modifiers.
149 // return c.getModifiers();
150 // But what we need for JVM access checks are the actual bits from the class header.
151 // ...But arrays and primitives are synthesized with their own odd flags:
152 if (c.isArray() || c.isPrimitive())
153 return c.getModifiers();
154 return Reflection.getClassAccessFlags(c);
155 }
156
157 /**
158 * Evaluate the JVM linkage rules for access to the given class on behalf of caller.
159 * <h3>JVM Specification, 5.4.4 "Access Control"</h3>
160 * A class or interface C is accessible to a class or interface D
161 * if and only if either of the following conditions are true:<ul>
162 * <li>C is public.
163 * <li>C and D are members of the same runtime package.
164 * </ul>
165 * @param refc the symbolic reference class to which access is being checked (C)
166 * @param lookupClass the class performing the lookup (D)
167 */
168 public static boolean isClassAccessible(Class<?> refc, Class<?> lookupClass,
169 int allowedModes) {
170 if (allowedModes == 0) return false;
171 assert((allowedModes & PUBLIC) != 0 &&
172 (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED)) == 0);
173 int mods = getClassModifiers(refc);
174 if (isPublic(mods))
175 return true;
176 if ((allowedModes & PACKAGE_ALLOWED) != 0 &&
177 isSamePackage(lookupClass, refc))
178 return true;
179 return false;
180 }
181
182 /**
183 * Decide if the given method type, attributed to a member or symbolic
184 * reference of a given reference class, is really visible to that class.
185 * @param type the supposed type of a member or symbolic reference of refc
186 * @param refc the class attempting to make the reference
187 */
188 public static boolean isTypeVisible(Class<?> type, Class<?> refc) {
189 if (type == refc) return true; // easy check
190 while (type.isArray()) type = type.getComponentType();
191 if (type.isPrimitive() || type == Object.class) return true;
192 ClassLoader parent = type.getClassLoader();
193 if (parent == null) return true;
|