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.hpp"
35 #include "native/llni.h"
37 #include "vm/access.hpp"
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"
47 #if defined(__cplusplus)
51 /* access_is_accessible_class **************************************************
53 Check if a class is accessible from another class
56 referer..........the class containing the reference
57 cls..............the result of resolving the reference
60 true.............access permitted
61 false............access denied
64 This function performs the checks listed in section 5.4.4.
65 "Access Control" of "The Java(TM) Virtual Machine Specification,
68 *******************************************************************************/
70 bool access_is_accessible_class(classinfo *referer, classinfo *cls)
75 /* Public classes are always accessible. */
77 if (cls->flags & ACC_PUBLIC)
80 /* A class in the same package is always accessible. */
82 if (SAME_PACKAGE(referer, cls))
85 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
86 /* Code for Sun's OpenJDK (see
87 hotspot/src/share/vm/runtime/reflection.cpp
88 (Reflection::verify_class_access)): Allow all accesses from
89 sun/reflect/MagicAccessorImpl subclasses to succeed
92 /* NOTE: This check must be before checks that could return
95 if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
99 /* A non-public class in another package is not accessible. */
105 /* access_is_accessible_member *************************************************
107 Check if a field or method is accessible from a given class
110 referer..........the class containing the reference
111 declarer.........the class declaring the member
112 memberflags......the access flags of the member
115 true.............access permitted
116 false............access denied
119 This function only performs the checks listed in section 5.4.4.
120 "Access Control" of "The Java(TM) Virtual Machine Specification,
123 In particular a special condition for protected access with is
124 part of the verification process according to the spec is not
125 checked in this function.
127 *******************************************************************************/
129 bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
135 /* Public members are accessible. */
137 if (memberflags & ACC_PUBLIC)
140 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
141 /* Code for Sun's OpenJDK (see
142 hotspot/src/share/vm/runtime/reflection.cpp
143 (Reflection::verify_class_access)): Allow all accesses from
144 sun/reflect/MagicAccessorImpl subclasses to succeed
147 /* NOTE: This check must be before checks that could return
150 if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
154 /* {declarer is not an interface} */
156 /* private members are only accessible by the class itself */
158 if (memberflags & ACC_PRIVATE)
159 return (referer == declarer);
161 /* {the member is protected or package private} */
163 /* protected and package private members are accessible in the
166 if (SAME_PACKAGE(referer, declarer))
169 /* package private members are not accessible outside the package */
171 if (!(memberflags & ACC_PROTECTED))
174 /* {the member is protected and declarer is in another package} */
176 /* a necessary condition for access is that referer is a subclass
179 assert((referer->state & CLASS_LINKED) && (declarer->state & CLASS_LINKED));
181 if (class_isanysubclass(referer, declarer))
188 /* access_check_field **********************************************************
190 Check if the (indirect) caller has access rights to the specified
194 f................the field to check
195 callerdepth......number of callers to ignore
196 For example if the stacktrace looks like this:
198 [0] java.lang.reflect.Method.invokeNative (Native Method)
199 [1] java.lang.reflect.Method.invoke
202 you must specify 2 so the access rights of <caller>
206 true.............access permitted
207 false............access denied, an exception has been thrown
209 *******************************************************************************/
211 #if defined(ENABLE_JAVASE)
212 bool access_check_field(fieldinfo *f, int callerdepth)
214 classinfo *callerclass;
219 /* If everything is public, there is nothing to check. */
221 if ((f->clazz->flags & ACC_PUBLIC) && (f->flags & ACC_PUBLIC))
224 /* Get the caller's class. */
226 callerclass = stacktrace_get_caller_class(callerdepth);
228 if (callerclass == NULL)
231 /* Check access rights. */
233 if (!access_is_accessible_member(callerclass, f->clazz, f->flags)) {
235 utf_bytes(f->clazz->name) +
238 strlen(" not accessible from ") +
239 utf_bytes(callerclass->name) +
242 msg = MNEW(char, msglen);
244 utf_copy_classname(msg, f->clazz->name);
246 utf_cat_classname(msg, f->name);
247 strcat(msg, " not accessible from ");
248 utf_cat_classname(msg, callerclass->name);
250 u = utf_new_char(msg);
252 MFREE(msg, char, msglen);
254 exceptions_throw_illegalaccessexception(u);
266 /* access_check_method *********************************************************
268 Check if the (indirect) caller has access rights to the specified
272 m................the method to check
273 callerdepth......number of callers to ignore
274 For example if the stacktrace looks like this:
276 [1] java.lang.reflect.Method.invokeNative (Native Method)
277 [1] java.lang.reflect.Method.invoke
280 you must specify 2 so the access rights of <caller>
284 true.............access permitted
285 false............access denied, an exception has been thrown
287 *******************************************************************************/
289 #if defined(ENABLE_JAVASE)
290 bool access_check_method(methodinfo *m, int callerdepth)
292 classinfo *callerclass;
297 /* If everything is public, there is nothing to check. */
299 if ((m->clazz->flags & ACC_PUBLIC) && (m->flags & ACC_PUBLIC))
302 /* Get the caller's class. */
304 callerclass = stacktrace_get_caller_class(callerdepth);
306 if (callerclass == NULL)
309 /* Check access rights. */
311 if (!access_is_accessible_member(callerclass, m->clazz, m->flags)) {
313 utf_bytes(m->clazz->name) +
316 utf_bytes(m->descriptor) +
317 strlen(" not accessible from ") +
318 utf_bytes(callerclass->name) +
321 msg = MNEW(char, msglen);
323 utf_copy_classname(msg, m->clazz->name);
325 utf_cat_classname(msg, m->name);
326 utf_cat_classname(msg, m->descriptor);
327 strcat(msg, " not accessible from ");
328 utf_cat_classname(msg, callerclass->name);
330 u = utf_new_char(msg);
332 MFREE(msg, char, msglen);
334 exceptions_throw_illegalaccessexception(u);
346 #if defined(__cplusplus)
352 * These are local overrides for various environment variables in Emacs.
353 * Please do not remove this and leave it at the end of the file, where
354 * Emacs will automagically detect them.
355 * ---------------------------------------------------------------------
358 * indent-tabs-mode: t
362 * vim:noexpandtab:sw=4:ts=4: