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/builtin.h"
39 #include "vm/exceptions.h"
41 #include "vm/jit/stacktrace.hpp"
43 #include "vmcore/class.h"
44 #include "vmcore/field.h"
45 #include "vmcore/globals.hpp"
46 #include "vmcore/method.h"
49 /* access_is_accessible_class **************************************************
51 Check if a class is accessible from another class
54 referer..........the class containing the reference
55 cls..............the result of resolving the reference
58 true.............access permitted
59 false............access denied
62 This function performs the checks listed in section 5.4.4.
63 "Access Control" of "The Java(TM) Virtual Machine Specification,
66 *******************************************************************************/
68 bool access_is_accessible_class(classinfo *referer, classinfo *cls)
73 /* Public classes are always accessible. */
75 if (cls->flags & ACC_PUBLIC)
78 /* A class in the same package is always accessible. */
80 if (SAME_PACKAGE(referer, cls))
83 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
84 /* Code for Sun's OpenJDK (see
85 hotspot/src/share/vm/runtime/reflection.cpp
86 (Reflection::verify_class_access)): Allow all accesses from
87 sun/reflect/MagicAccessorImpl subclasses to succeed
90 /* NOTE: This check must be before checks that could return
93 if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
97 /* A non-public class in another package is not accessible. */
103 /* access_is_accessible_member *************************************************
105 Check if a field or method is accessible from a given class
108 referer..........the class containing the reference
109 declarer.........the class declaring the member
110 memberflags......the access flags of the member
113 true.............access permitted
114 false............access denied
117 This function only performs the checks listed in section 5.4.4.
118 "Access Control" of "The Java(TM) Virtual Machine Specification,
121 In particular a special condition for protected access with is
122 part of the verification process according to the spec is not
123 checked in this function.
125 *******************************************************************************/
127 bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
133 /* Public members are accessible. */
135 if (memberflags & ACC_PUBLIC)
138 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
139 /* Code for Sun's OpenJDK (see
140 hotspot/src/share/vm/runtime/reflection.cpp
141 (Reflection::verify_class_access)): Allow all accesses from
142 sun/reflect/MagicAccessorImpl subclasses to succeed
145 /* NOTE: This check must be before checks that could return
148 if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
152 /* {declarer is not an interface} */
154 /* private members are only accessible by the class itself */
156 if (memberflags & ACC_PRIVATE)
157 return (referer == declarer);
159 /* {the member is protected or package private} */
161 /* protected and package private members are accessible in the
164 if (SAME_PACKAGE(referer, declarer))
167 /* package private members are not accessible outside the package */
169 if (!(memberflags & ACC_PROTECTED))
172 /* {the member is protected and declarer is in another package} */
174 /* a necessary condition for access is that referer is a subclass
177 assert((referer->state & CLASS_LINKED) && (declarer->state & CLASS_LINKED));
179 if (class_isanysubclass(referer, declarer))
186 /* access_check_field **********************************************************
188 Check if the (indirect) caller has access rights to the specified
192 f................the field to check
193 callerdepth......number of callers to ignore
194 For example if the stacktrace looks like this:
196 [0] java.lang.reflect.Method.invokeNative (Native Method)
197 [1] java.lang.reflect.Method.invoke
200 you must specify 2 so the access rights of <caller>
204 true.............access permitted
205 false............access denied, an exception has been thrown
207 *******************************************************************************/
209 #if defined(ENABLE_JAVASE)
210 bool access_check_field(fieldinfo *f, int callerdepth)
212 classinfo *callerclass;
217 /* If everything is public, there is nothing to check. */
219 if ((f->clazz->flags & ACC_PUBLIC) && (f->flags & ACC_PUBLIC))
222 /* Get the caller's class. */
224 callerclass = stacktrace_get_caller_class(callerdepth);
226 if (callerclass == NULL)
229 /* Check access rights. */
231 if (!access_is_accessible_member(callerclass, f->clazz, f->flags)) {
233 utf_bytes(f->clazz->name) +
236 strlen(" not accessible from ") +
237 utf_bytes(callerclass->name) +
240 msg = MNEW(char, msglen);
242 utf_copy_classname(msg, f->clazz->name);
244 utf_cat_classname(msg, f->name);
245 strcat(msg, " not accessible from ");
246 utf_cat_classname(msg, callerclass->name);
248 u = utf_new_char(msg);
250 MFREE(msg, char, msglen);
252 exceptions_throw_illegalaccessexception(u);
264 /* access_check_method *********************************************************
266 Check if the (indirect) caller has access rights to the specified
270 m................the method to check
271 callerdepth......number of callers to ignore
272 For example if the stacktrace looks like this:
274 [1] java.lang.reflect.Method.invokeNative (Native Method)
275 [1] java.lang.reflect.Method.invoke
278 you must specify 2 so the access rights of <caller>
282 true.............access permitted
283 false............access denied, an exception has been thrown
285 *******************************************************************************/
287 #if defined(ENABLE_JAVASE)
288 bool access_check_method(methodinfo *m, int callerdepth)
290 classinfo *callerclass;
295 /* If everything is public, there is nothing to check. */
297 if ((m->clazz->flags & ACC_PUBLIC) && (m->flags & ACC_PUBLIC))
300 /* Get the caller's class. */
302 callerclass = stacktrace_get_caller_class(callerdepth);
304 if (callerclass == NULL)
307 /* Check access rights. */
309 if (!access_is_accessible_member(callerclass, m->clazz, m->flags)) {
311 utf_bytes(m->clazz->name) +
314 utf_bytes(m->descriptor) +
315 strlen(" not accessible from ") +
316 utf_bytes(callerclass->name) +
319 msg = MNEW(char, msglen);
321 utf_copy_classname(msg, m->clazz->name);
323 utf_cat_classname(msg, m->name);
324 utf_cat_classname(msg, m->descriptor);
325 strcat(msg, " not accessible from ");
326 utf_cat_classname(msg, callerclass->name);
328 u = utf_new_char(msg);
330 MFREE(msg, char, msglen);
332 exceptions_throw_illegalaccessexception(u);
345 * These are local overrides for various environment variables in Emacs.
346 * Please do not remove this and leave it at the end of the file, where
347 * Emacs will automagically detect them.
348 * ---------------------------------------------------------------------
351 * indent-tabs-mode: t
355 * vim:noexpandtab:sw=4:ts=4: