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 8237 2007-07-27 16:15:29Z twisti $
37 #include "mm/memory.h"
39 #include "vm/access.h"
40 #include "vm/builtin.h"
41 #include "vm/exceptions.h"
43 #include "vm/jit/stacktrace.h"
45 #include "vmcore/class.h"
46 #include "vmcore/field.h"
47 #include "vmcore/method.h"
50 /****************************************************************************/
52 /****************************************************************************/
54 /* access_is_accessible_class **************************************************
56 Check if a class is accessible from another class
59 referer..........the class containing the reference
60 cls..............the result of resolving the reference
63 true.............access permitted
64 false............access denied
67 This function performs the checks listed in section 5.4.4.
68 "Access Control" of "The Java(TM) Virtual Machine Specification,
71 *******************************************************************************/
73 bool access_is_accessible_class(classinfo *referer, classinfo *cls)
78 /* Public classes are always accessible. */
80 if (cls->flags & ACC_PUBLIC)
83 /* A class in the same package is always accessible. */
85 if (SAME_PACKAGE(referer, cls))
88 #if defined(WITH_CLASSPATH_SUN)
89 /* Code for Sun's OpenJDK (see
90 hotspot/src/share/vm/runtime/reflection.cpp
91 (Reflection::verify_class_access)): Allow all accesses from
92 sun/reflect/MagicAccessorImpl subclasses to succeed
95 /* NOTE: This check must be before checks that could return
98 if (class_issubclass(cls, class_sun_reflect_MagicAccessorImpl))
102 /* A non-public class in another package is not accessible. */
108 /* access_is_accessible_member *************************************************
110 Check if a field or method is accessible from a given class
113 referer..........the class containing the reference
114 declarer.........the class declaring the member
115 memberflags......the access flags of the member
118 true.............access permitted
119 false............access denied
122 This function only performs the checks listed in section 5.4.4.
123 "Access Control" of "The Java(TM) Virtual Machine Specification,
126 In particular a special condition for protected access with is
127 part of the verification process according to the spec is not
128 checked in this function.
130 *******************************************************************************/
132 bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
138 /* Public members are accessible. */
140 if (memberflags & ACC_PUBLIC)
143 #if defined(WITH_CLASSPATH_SUN)
144 /* Code for Sun's OpenJDK (see
145 hotspot/src/share/vm/runtime/reflection.cpp
146 (Reflection::verify_class_access)): Allow all accesses from
147 sun/reflect/MagicAccessorImpl subclasses to succeed
150 /* NOTE: This check must be before checks that could return
153 if (class_issubclass(declarer, class_sun_reflect_MagicAccessorImpl))
157 /* {declarer is not an interface} */
159 /* private members are only accessible by the class itself */
161 if (memberflags & ACC_PRIVATE)
162 return (referer == declarer);
164 /* {the member is protected or package private} */
166 /* protected and package private members are accessible in the
169 if (SAME_PACKAGE(referer, declarer))
172 /* package private members are not accessible outside the package */
174 if (!(memberflags & ACC_PROTECTED))
177 /* {the member is protected and declarer is in another package} */
179 /* a necessary condition for access is that referer is a subclass
182 assert((referer->state & CLASS_LINKED) && (declarer->state & CLASS_LINKED));
184 if (class_isanysubclass(referer, declarer))
191 /* access_check_field **********************************************************
193 Check if the (indirect) caller has access rights to the specified
197 f................the field to check
198 calldepth........number of callers to ignore
199 For example if the stacktrace looks like this:
201 java.lang.reflect.Method.invokeNative (Native Method)
202 [0] java.lang.reflect.Method.invoke (Method.java:329)
205 you must specify 1 so the access rights of <caller>
209 true.............access permitted
210 false............access denied, an exception has been thrown
212 *******************************************************************************/
214 bool access_check_field(fieldinfo *f, s4 calldepth)
216 java_objectarray *oa;
217 classinfo *callerclass;
222 /* if everything is public, there is nothing to check */
224 if ((f->class->flags & ACC_PUBLIC) && (f->flags & ACC_PUBLIC))
227 /* get the caller's class */
229 oa = stacktrace_getClassContext();
234 assert(calldepth >= 0 && calldepth < oa->header.size);
236 callerclass = (classinfo *) oa->data[calldepth];
238 /* check access rights */
240 if (!access_is_accessible_member(callerclass, f->class, f->flags)) {
242 utf_bytes(f->class->name) +
245 strlen(" not accessible from ") +
246 utf_bytes(callerclass->name) +
249 msg = MNEW(char, msglen);
251 utf_copy_classname(msg, f->class->name);
253 utf_cat_classname(msg, f->name);
254 strcat(msg, " not accessible from ");
255 utf_cat_classname(msg, callerclass->name);
257 u = utf_new_char(msg);
259 MFREE(msg, char, msglen);
261 exceptions_throw_illegalaccessexception(u);
272 /* access_check_method *********************************************************
274 Check if the (indirect) caller has access rights to the specified
278 m................the method to check
279 calldepth........number of callers to ignore
280 For example if the stacktrace looks like this:
282 java.lang.reflect.Method.invokeNative (Native Method)
283 [0] java.lang.reflect.Method.invoke (Method.java:329)
286 you must specify 1 so the access rights of <caller>
290 true.............access permitted
291 false............access denied, an exception has been thrown
293 *******************************************************************************/
295 bool access_check_method(methodinfo *m, s4 calldepth)
297 java_objectarray *oa;
298 classinfo *callerclass;
303 /* if everything is public, there is nothing to check */
305 if ((m->class->flags & ACC_PUBLIC) && (m->flags & ACC_PUBLIC))
308 /* get the caller's class */
310 oa = stacktrace_getClassContext();
315 assert(calldepth >= 0 && calldepth < oa->header.size);
317 callerclass = (classinfo *) oa->data[calldepth];
319 /* check access rights */
321 if (!access_is_accessible_member(callerclass, m->class, m->flags)) {
323 utf_bytes(m->class->name) +
326 utf_bytes(m->descriptor) +
327 strlen(" not accessible from ") +
328 utf_bytes(callerclass->name) +
331 msg = MNEW(char, msglen);
333 utf_copy_classname(msg, m->class->name);
335 utf_cat_classname(msg, m->name);
336 utf_cat_classname(msg, m->descriptor);
337 strcat(msg, " not accessible from ");
338 utf_cat_classname(msg, callerclass->name);
340 u = utf_new_char(msg);
342 MFREE(msg, char, msglen);
344 exceptions_throw_illegalaccessexception(u);
356 * These are local overrides for various environment variables in Emacs.
357 * Please do not remove this and leave it at the end of the file, where
358 * Emacs will automagically detect them.
359 * ---------------------------------------------------------------------
362 * indent-tabs-mode: t
366 * vim:noexpandtab:sw=4:ts=4: