1 /* src/vm/access.c - checking access rights
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: access.c 8318 2007-08-16 10:05:34Z michi $
37 #include "mm/memory.h"
39 #include "native/llni.h"
41 #include "vm/access.h"
42 #include "vm/builtin.h"
43 #include "vm/exceptions.h"
45 #include "vm/jit/stacktrace.h"
47 #include "vmcore/class.h"
48 #include "vmcore/field.h"
49 #include "vmcore/method.h"
52 /****************************************************************************/
54 /****************************************************************************/
56 /* access_is_accessible_class **************************************************
58 Check if a class is accessible from another class
61 referer..........the class containing the reference
62 cls..............the result of resolving the reference
65 true.............access permitted
66 false............access denied
69 This function performs the checks listed in section 5.4.4.
70 "Access Control" of "The Java(TM) Virtual Machine Specification,
73 *******************************************************************************/
75 bool access_is_accessible_class(classinfo *referer, classinfo *cls)
80 /* Public classes are always accessible. */
82 if (cls->flags & ACC_PUBLIC)
85 /* A class in the same package is always accessible. */
87 if (SAME_PACKAGE(referer, cls))
90 #if defined(WITH_CLASSPATH_SUN)
91 /* Code for Sun's OpenJDK (see
92 hotspot/src/share/vm/runtime/reflection.cpp
93 (Reflection::verify_class_access)): Allow all accesses from
94 sun/reflect/MagicAccessorImpl subclasses to succeed
97 /* NOTE: This check must be before checks that could return
100 if (class_issubclass(cls, class_sun_reflect_MagicAccessorImpl))
104 /* A non-public class in another package is not accessible. */
110 /* access_is_accessible_member *************************************************
112 Check if a field or method is accessible from a given class
115 referer..........the class containing the reference
116 declarer.........the class declaring the member
117 memberflags......the access flags of the member
120 true.............access permitted
121 false............access denied
124 This function only performs the checks listed in section 5.4.4.
125 "Access Control" of "The Java(TM) Virtual Machine Specification,
128 In particular a special condition for protected access with is
129 part of the verification process according to the spec is not
130 checked in this function.
132 *******************************************************************************/
134 bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
140 /* Public members are accessible. */
142 if (memberflags & ACC_PUBLIC)
145 #if defined(WITH_CLASSPATH_SUN)
146 /* Code for Sun's OpenJDK (see
147 hotspot/src/share/vm/runtime/reflection.cpp
148 (Reflection::verify_class_access)): Allow all accesses from
149 sun/reflect/MagicAccessorImpl subclasses to succeed
152 /* NOTE: This check must be before checks that could return
155 if (class_issubclass(declarer, class_sun_reflect_MagicAccessorImpl))
159 /* {declarer is not an interface} */
161 /* private members are only accessible by the class itself */
163 if (memberflags & ACC_PRIVATE)
164 return (referer == declarer);
166 /* {the member is protected or package private} */
168 /* protected and package private members are accessible in the
171 if (SAME_PACKAGE(referer, declarer))
174 /* package private members are not accessible outside the package */
176 if (!(memberflags & ACC_PROTECTED))
179 /* {the member is protected and declarer is in another package} */
181 /* a necessary condition for access is that referer is a subclass
184 assert((referer->state & CLASS_LINKED) && (declarer->state & CLASS_LINKED));
186 if (class_isanysubclass(referer, declarer))
193 /* access_check_field **********************************************************
195 Check if the (indirect) caller has access rights to the specified
199 f................the field to check
200 calldepth........number of callers to ignore
201 For example if the stacktrace looks like this:
203 java.lang.reflect.Method.invokeNative (Native Method)
204 [0] java.lang.reflect.Method.invoke (Method.java:329)
207 you must specify 1 so the access rights of <caller>
211 true.............access permitted
212 false............access denied, an exception has been thrown
214 *******************************************************************************/
216 bool access_check_field(fieldinfo *f, s4 calldepth)
218 java_handle_objectarray_t *oa;
219 classinfo *callerclass;
224 /* if everything is public, there is nothing to check */
226 if ((f->class->flags & ACC_PUBLIC) && (f->flags & ACC_PUBLIC))
229 /* get the caller's class */
231 oa = stacktrace_getClassContext();
236 assert(calldepth >= 0 && calldepth < LLNI_array_size(oa));
238 callerclass = (classinfo *) oa->data[calldepth];
240 /* check access rights */
242 if (!access_is_accessible_member(callerclass, f->class, f->flags)) {
244 utf_bytes(f->class->name) +
247 strlen(" not accessible from ") +
248 utf_bytes(callerclass->name) +
251 msg = MNEW(char, msglen);
253 utf_copy_classname(msg, f->class->name);
255 utf_cat_classname(msg, f->name);
256 strcat(msg, " not accessible from ");
257 utf_cat_classname(msg, callerclass->name);
259 u = utf_new_char(msg);
261 MFREE(msg, char, msglen);
263 exceptions_throw_illegalaccessexception(u);
274 /* access_check_method *********************************************************
276 Check if the (indirect) caller has access rights to the specified
280 m................the method to check
281 calldepth........number of callers to ignore
282 For example if the stacktrace looks like this:
284 java.lang.reflect.Method.invokeNative (Native Method)
285 [0] java.lang.reflect.Method.invoke (Method.java:329)
288 you must specify 1 so the access rights of <caller>
292 true.............access permitted
293 false............access denied, an exception has been thrown
295 *******************************************************************************/
297 bool access_check_method(methodinfo *m, s4 calldepth)
299 java_handle_objectarray_t *oa;
300 classinfo *callerclass;
305 /* if everything is public, there is nothing to check */
307 if ((m->class->flags & ACC_PUBLIC) && (m->flags & ACC_PUBLIC))
310 /* get the caller's class */
312 oa = stacktrace_getClassContext();
317 assert(calldepth >= 0 && calldepth < LLNI_array_size(oa));
319 callerclass = (classinfo *) oa->data[calldepth];
321 /* check access rights */
323 if (!access_is_accessible_member(callerclass, m->class, m->flags)) {
325 utf_bytes(m->class->name) +
328 utf_bytes(m->descriptor) +
329 strlen(" not accessible from ") +
330 utf_bytes(callerclass->name) +
333 msg = MNEW(char, msglen);
335 utf_copy_classname(msg, m->class->name);
337 utf_cat_classname(msg, m->name);
338 utf_cat_classname(msg, m->descriptor);
339 strcat(msg, " not accessible from ");
340 utf_cat_classname(msg, callerclass->name);
342 u = utf_new_char(msg);
344 MFREE(msg, char, msglen);
346 exceptions_throw_illegalaccessexception(u);
358 * These are local overrides for various environment variables in Emacs.
359 * Please do not remove this and leave it at the end of the file, where
360 * Emacs will automagically detect them.
361 * ---------------------------------------------------------------------
364 * indent-tabs-mode: t
368 * vim:noexpandtab:sw=4:ts=4: