1 /* src/vm/access.c - checking access rights
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33 #include "mm/memory.h"
35 #include "native/llni.h"
37 #include "vm/access.h"
38 #include "vm/jit/builtin.hpp"
39 #include "vm/class.hpp"
40 #include "vm/exceptions.hpp"
41 #include "vm/field.hpp"
42 #include "vm/globals.hpp"
43 #include "vm/method.hpp"
45 #include "vm/jit/stacktrace.hpp"
48 /* access_is_accessible_class **************************************************
50 Check if a class is accessible from another class
53 referer..........the class containing the reference
54 cls..............the result of resolving the reference
57 true.............access permitted
58 false............access denied
61 This function performs the checks listed in section 5.4.4.
62 "Access Control" of "The Java(TM) Virtual Machine Specification,
65 *******************************************************************************/
67 bool access_is_accessible_class(classinfo *referer, classinfo *cls)
72 /* Public classes are always accessible. */
74 if (cls->flags & ACC_PUBLIC)
77 /* A class in the same package is always accessible. */
79 if (SAME_PACKAGE(referer, cls))
82 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
83 /* Code for Sun's OpenJDK (see
84 hotspot/src/share/vm/runtime/reflection.cpp
85 (Reflection::verify_class_access)): Allow all accesses from
86 sun/reflect/MagicAccessorImpl subclasses to succeed
89 /* NOTE: This check must be before checks that could return
92 if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
96 /* A non-public class in another package is not accessible. */
102 /* access_is_accessible_member *************************************************
104 Check if a field or method is accessible from a given class
107 referer..........the class containing the reference
108 declarer.........the class declaring the member
109 memberflags......the access flags of the member
112 true.............access permitted
113 false............access denied
116 This function only performs the checks listed in section 5.4.4.
117 "Access Control" of "The Java(TM) Virtual Machine Specification,
120 In particular a special condition for protected access with is
121 part of the verification process according to the spec is not
122 checked in this function.
124 *******************************************************************************/
126 bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
132 /* Public members are accessible. */
134 if (memberflags & ACC_PUBLIC)
137 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
138 /* Code for Sun's OpenJDK (see
139 hotspot/src/share/vm/runtime/reflection.cpp
140 (Reflection::verify_class_access)): Allow all accesses from
141 sun/reflect/MagicAccessorImpl subclasses to succeed
144 /* NOTE: This check must be before checks that could return
147 if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
151 /* {declarer is not an interface} */
153 /* private members are only accessible by the class itself */
155 if (memberflags & ACC_PRIVATE)
156 return (referer == declarer);
158 /* {the member is protected or package private} */
160 /* protected and package private members are accessible in the
163 if (SAME_PACKAGE(referer, declarer))
166 /* package private members are not accessible outside the package */
168 if (!(memberflags & ACC_PROTECTED))
171 /* {the member is protected and declarer is in another package} */
173 /* a necessary condition for access is that referer is a subclass
176 assert((referer->state & CLASS_LINKED) && (declarer->state & CLASS_LINKED));
178 if (class_isanysubclass(referer, declarer))
185 /* access_check_field **********************************************************
187 Check if the (indirect) caller has access rights to the specified
191 f................the field to check
192 callerdepth......number of callers to ignore
193 For example if the stacktrace looks like this:
195 [0] java.lang.reflect.Method.invokeNative (Native Method)
196 [1] java.lang.reflect.Method.invoke
199 you must specify 2 so the access rights of <caller>
203 true.............access permitted
204 false............access denied, an exception has been thrown
206 *******************************************************************************/
208 #if defined(ENABLE_JAVASE)
209 bool access_check_field(fieldinfo *f, int callerdepth)
211 classinfo *callerclass;
216 /* If everything is public, there is nothing to check. */
218 if ((f->clazz->flags & ACC_PUBLIC) && (f->flags & ACC_PUBLIC))
221 /* Get the caller's class. */
223 callerclass = stacktrace_get_caller_class(callerdepth);
225 if (callerclass == NULL)
228 /* Check access rights. */
230 if (!access_is_accessible_member(callerclass, f->clazz, f->flags)) {
232 utf_bytes(f->clazz->name) +
235 strlen(" not accessible from ") +
236 utf_bytes(callerclass->name) +
239 msg = MNEW(char, msglen);
241 utf_copy_classname(msg, f->clazz->name);
243 utf_cat_classname(msg, f->name);
244 strcat(msg, " not accessible from ");
245 utf_cat_classname(msg, callerclass->name);
247 u = utf_new_char(msg);
249 MFREE(msg, char, msglen);
251 exceptions_throw_illegalaccessexception(u);
263 /* access_check_method *********************************************************
265 Check if the (indirect) caller has access rights to the specified
269 m................the method to check
270 callerdepth......number of callers to ignore
271 For example if the stacktrace looks like this:
273 [1] java.lang.reflect.Method.invokeNative (Native Method)
274 [1] java.lang.reflect.Method.invoke
277 you must specify 2 so the access rights of <caller>
281 true.............access permitted
282 false............access denied, an exception has been thrown
284 *******************************************************************************/
286 #if defined(ENABLE_JAVASE)
287 bool access_check_method(methodinfo *m, int callerdepth)
289 classinfo *callerclass;
294 /* If everything is public, there is nothing to check. */
296 if ((m->clazz->flags & ACC_PUBLIC) && (m->flags & ACC_PUBLIC))
299 /* Get the caller's class. */
301 callerclass = stacktrace_get_caller_class(callerdepth);
303 if (callerclass == NULL)
306 /* Check access rights. */
308 if (!access_is_accessible_member(callerclass, m->clazz, m->flags)) {
310 utf_bytes(m->clazz->name) +
313 utf_bytes(m->descriptor) +
314 strlen(" not accessible from ") +
315 utf_bytes(callerclass->name) +
318 msg = MNEW(char, msglen);
320 utf_copy_classname(msg, m->clazz->name);
322 utf_cat_classname(msg, m->name);
323 utf_cat_classname(msg, m->descriptor);
324 strcat(msg, " not accessible from ");
325 utf_cat_classname(msg, callerclass->name);
327 u = utf_new_char(msg);
329 MFREE(msg, char, msglen);
331 exceptions_throw_illegalaccessexception(u);
344 * These are local overrides for various environment variables in Emacs.
345 * Please do not remove this and leave it at the end of the file, where
346 * Emacs will automagically detect them.
347 * ---------------------------------------------------------------------
350 * indent-tabs-mode: t
354 * vim:noexpandtab:sw=4:ts=4: