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 8386 2007-08-21 15:21:36Z twisti $
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 /* access_is_accessible_class **************************************************
54 Check if a class is accessible from another class
57 referer..........the class containing the reference
58 cls..............the result of resolving the reference
61 true.............access permitted
62 false............access denied
65 This function performs the checks listed in section 5.4.4.
66 "Access Control" of "The Java(TM) Virtual Machine Specification,
69 *******************************************************************************/
71 bool access_is_accessible_class(classinfo *referer, classinfo *cls)
76 /* Public classes are always accessible. */
78 if (cls->flags & ACC_PUBLIC)
81 /* A class in the same package is always accessible. */
83 if (SAME_PACKAGE(referer, cls))
86 #if defined(WITH_CLASSPATH_SUN)
87 /* Code for Sun's OpenJDK (see
88 hotspot/src/share/vm/runtime/reflection.cpp
89 (Reflection::verify_class_access)): Allow all accesses from
90 sun/reflect/MagicAccessorImpl subclasses to succeed
93 /* NOTE: This check must be before checks that could return
96 if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
100 /* A non-public class in another package is not accessible. */
106 /* access_is_accessible_member *************************************************
108 Check if a field or method is accessible from a given class
111 referer..........the class containing the reference
112 declarer.........the class declaring the member
113 memberflags......the access flags of the member
116 true.............access permitted
117 false............access denied
120 This function only performs the checks listed in section 5.4.4.
121 "Access Control" of "The Java(TM) Virtual Machine Specification,
124 In particular a special condition for protected access with is
125 part of the verification process according to the spec is not
126 checked in this function.
128 *******************************************************************************/
130 bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
136 /* Public members are accessible. */
138 if (memberflags & ACC_PUBLIC)
141 #if defined(WITH_CLASSPATH_SUN)
142 /* Code for Sun's OpenJDK (see
143 hotspot/src/share/vm/runtime/reflection.cpp
144 (Reflection::verify_class_access)): Allow all accesses from
145 sun/reflect/MagicAccessorImpl subclasses to succeed
148 /* NOTE: This check must be before checks that could return
151 if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
155 /* {declarer is not an interface} */
157 /* private members are only accessible by the class itself */
159 if (memberflags & ACC_PRIVATE)
160 return (referer == declarer);
162 /* {the member is protected or package private} */
164 /* protected and package private members are accessible in the
167 if (SAME_PACKAGE(referer, declarer))
170 /* package private members are not accessible outside the package */
172 if (!(memberflags & ACC_PROTECTED))
175 /* {the member is protected and declarer is in another package} */
177 /* a necessary condition for access is that referer is a subclass
180 assert((referer->state & CLASS_LINKED) && (declarer->state & CLASS_LINKED));
182 if (class_isanysubclass(referer, declarer))
189 /* access_check_field **********************************************************
191 Check if the (indirect) caller has access rights to the specified
195 f................the field to check
196 calldepth........number of callers to ignore
197 For example if the stacktrace looks like this:
199 java.lang.reflect.Method.invokeNative (Native Method)
200 [0] java.lang.reflect.Method.invoke (Method.java:329)
203 you must specify 1 so the access rights of <caller>
207 true.............access permitted
208 false............access denied, an exception has been thrown
210 *******************************************************************************/
212 bool access_check_field(fieldinfo *f, s4 calldepth)
214 java_handle_objectarray_t *oa;
215 classinfo *callerclass;
220 /* if everything is public, there is nothing to check */
222 if ((f->class->flags & ACC_PUBLIC) && (f->flags & ACC_PUBLIC))
225 /* get the caller's class */
227 oa = stacktrace_getClassContext();
232 assert(calldepth >= 0 && calldepth < LLNI_array_size(oa));
234 callerclass = (classinfo *) oa->data[calldepth];
236 /* check access rights */
238 if (!access_is_accessible_member(callerclass, f->class, f->flags)) {
240 utf_bytes(f->class->name) +
243 strlen(" not accessible from ") +
244 utf_bytes(callerclass->name) +
247 msg = MNEW(char, msglen);
249 utf_copy_classname(msg, f->class->name);
251 utf_cat_classname(msg, f->name);
252 strcat(msg, " not accessible from ");
253 utf_cat_classname(msg, callerclass->name);
255 u = utf_new_char(msg);
257 MFREE(msg, char, msglen);
259 exceptions_throw_illegalaccessexception(u);
270 /* access_check_method *********************************************************
272 Check if the (indirect) caller has access rights to the specified
276 m................the method to check
277 calldepth........number of callers to ignore
278 For example if the stacktrace looks like this:
280 java.lang.reflect.Method.invokeNative (Native Method)
281 [0] java.lang.reflect.Method.invoke (Method.java:329)
284 you must specify 1 so the access rights of <caller>
288 true.............access permitted
289 false............access denied, an exception has been thrown
291 *******************************************************************************/
293 bool access_check_method(methodinfo *m, s4 calldepth)
295 java_handle_objectarray_t *oa;
296 classinfo *callerclass;
301 /* if everything is public, there is nothing to check */
303 if ((m->class->flags & ACC_PUBLIC) && (m->flags & ACC_PUBLIC))
306 /* get the caller's class */
308 oa = stacktrace_getClassContext();
313 assert(calldepth >= 0 && calldepth < LLNI_array_size(oa));
315 callerclass = (classinfo *) oa->data[calldepth];
317 /* check access rights */
319 if (!access_is_accessible_member(callerclass, m->class, m->flags)) {
321 utf_bytes(m->class->name) +
324 utf_bytes(m->descriptor) +
325 strlen(" not accessible from ") +
326 utf_bytes(callerclass->name) +
329 msg = MNEW(char, msglen);
331 utf_copy_classname(msg, m->class->name);
333 utf_cat_classname(msg, m->name);
334 utf_cat_classname(msg, m->descriptor);
335 strcat(msg, " not accessible from ");
336 utf_cat_classname(msg, callerclass->name);
338 u = utf_new_char(msg);
340 MFREE(msg, char, msglen);
342 exceptions_throw_illegalaccessexception(u);
354 * These are local overrides for various environment variables in Emacs.
355 * Please do not remove this and leave it at the end of the file, where
356 * Emacs will automagically detect them.
357 * ---------------------------------------------------------------------
360 * indent-tabs-mode: t
364 * vim:noexpandtab:sw=4:ts=4: