Line data Source code
1 : /* src/vm/access.c - checking access rights
2 :
3 : Copyright (C) 1996-2013
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
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.
12 :
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.
17 :
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
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 :
26 : #include "config.h"
27 :
28 : #include <assert.h>
29 : #include <string.h>
30 :
31 : #include "vm/types.hpp"
32 :
33 : #include "native/llni.hpp"
34 :
35 : #include "vm/access.hpp"
36 : #include "vm/jit/builtin.hpp"
37 : #include "vm/class.hpp"
38 : #include "vm/exceptions.hpp"
39 : #include "vm/field.hpp"
40 : #include "vm/globals.hpp"
41 : #include "vm/method.hpp"
42 :
43 : #include "vm/jit/stacktrace.hpp"
44 :
45 : #include "toolbox/buffer.hpp"
46 :
47 : /* access_is_accessible_class **************************************************
48 :
49 : Check if a class is accessible from another class
50 :
51 : IN:
52 : referer..........the class containing the reference
53 : cls..............the result of resolving the reference
54 :
55 : RETURN VALUE:
56 : true.............access permitted
57 : false............access denied
58 :
59 : NOTE:
60 : This function performs the checks listed in section 5.4.4.
61 : "Access Control" of "The Java(TM) Virtual Machine Specification,
62 : Second Edition".
63 :
64 : *******************************************************************************/
65 :
66 277005 : bool access_is_accessible_class(classinfo *referer, classinfo *cls)
67 : {
68 277005 : assert(referer);
69 277005 : assert(cls);
70 :
71 : /* Public classes are always accessible. */
72 :
73 277005 : if (cls->flags & ACC_PUBLIC)
74 232523 : return true;
75 :
76 : /* A class in the same package is always accessible. */
77 :
78 44482 : if (SAME_PACKAGE(referer, cls))
79 44482 : return true;
80 :
81 : #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
82 : /* Code for Sun's OpenJDK (see
83 : hotspot/src/share/vm/runtime/reflection.cpp
84 : (Reflection::verify_class_access)): Allow all accesses from
85 : sun/reflect/MagicAccessorImpl subclasses to succeed
86 : trivially. */
87 :
88 : /* NOTE: This check must be before checks that could return
89 : false. */
90 :
91 : if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
92 : return true;
93 : #endif
94 :
95 : /* A non-public class in another package is not accessible. */
96 :
97 0 : return false;
98 : }
99 :
100 :
101 : /* access_is_accessible_member *************************************************
102 :
103 : Check if a field or method is accessible from a given class
104 :
105 : IN:
106 : referer..........the class containing the reference
107 : declarer.........the class declaring the member
108 : memberflags......the access flags of the member
109 :
110 : RETURN VALUE:
111 : true.............access permitted
112 : false............access denied
113 :
114 : NOTE:
115 : This function only performs the checks listed in section 5.4.4.
116 : "Access Control" of "The Java(TM) Virtual Machine Specification,
117 : Second Edition".
118 :
119 : In particular a special condition for protected access with is
120 : part of the verification process according to the spec is not
121 : checked in this function.
122 :
123 : *******************************************************************************/
124 :
125 490419 : bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
126 : s4 memberflags)
127 : {
128 490419 : assert(referer);
129 490419 : assert(declarer);
130 :
131 : /* Public members are accessible. */
132 :
133 490419 : if (memberflags & ACC_PUBLIC)
134 222199 : return true;
135 :
136 : #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
137 : /* Code for Sun's OpenJDK (see
138 : hotspot/src/share/vm/runtime/reflection.cpp
139 : (Reflection::verify_class_access)): Allow all accesses from
140 : sun/reflect/MagicAccessorImpl subclasses to succeed
141 : trivially. */
142 :
143 : /* NOTE: This check must be before checks that could return
144 : false. */
145 :
146 : if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
147 : return true;
148 : #endif
149 :
150 : /* {declarer is not an interface} */
151 :
152 : /* private members are only accessible by the class itself */
153 :
154 268220 : if (memberflags & ACC_PRIVATE)
155 125848 : return (referer == declarer);
156 :
157 : /* {the member is protected or package private} */
158 :
159 : /* protected and package private members are accessible in the
160 : same package */
161 :
162 142372 : if (SAME_PACKAGE(referer, declarer))
163 138361 : return true;
164 :
165 : /* package private members are not accessible outside the package */
166 :
167 4011 : if (!(memberflags & ACC_PROTECTED))
168 0 : return false;
169 :
170 : /* {the member is protected and declarer is in another package} */
171 :
172 : /* a necessary condition for access is that referer is a subclass
173 : of declarer */
174 :
175 4011 : assert((referer->state & CLASS_LINKED) && (declarer->state & CLASS_LINKED));
176 :
177 4011 : if (class_isanysubclass(referer, declarer))
178 4011 : return true;
179 :
180 0 : return false;
181 : }
182 :
183 :
184 : /* access_check_field **********************************************************
185 :
186 : Check if the (indirect) caller has access rights to the specified
187 : field.
188 :
189 : IN:
190 : f................the field to check
191 : callerdepth......number of callers to ignore
192 : For example if the stacktrace looks like this:
193 :
194 : [0] java.lang.reflect.Method.invokeNative (Native Method)
195 : [1] java.lang.reflect.Method.invoke
196 : [2] <caller>
197 :
198 : you must specify 2 so the access rights of <caller>
199 : are checked.
200 :
201 : RETURN VALUE:
202 : true.............access permitted
203 : false............access denied, an exception has been thrown
204 :
205 : *******************************************************************************/
206 :
207 : #if defined(ENABLE_JAVASE)
208 1 : bool access_check_field(fieldinfo *f, int callerdepth)
209 : {
210 : classinfo *callerclass;
211 :
212 : /* If everything is public, there is nothing to check. */
213 :
214 1 : if ((f->clazz->flags & ACC_PUBLIC) && (f->flags & ACC_PUBLIC))
215 1 : return true;
216 :
217 : /* Get the caller's class. */
218 :
219 0 : callerclass = stacktrace_get_caller_class(callerdepth);
220 :
221 0 : if (callerclass == NULL)
222 0 : return false;
223 :
224 : /* Check access rights. */
225 :
226 0 : if (!access_is_accessible_member(callerclass, f->clazz, f->flags)) {
227 0 : Buffer<> buf;
228 :
229 : Utf8String u = buf.write_slash_to_dot(f->clazz->name)
230 : .write('.')
231 : .write_slash_to_dot(f->name)
232 : .write(" not accessible from ", 21)
233 : .write_slash_to_dot(callerclass->name)
234 0 : .utf8_str();
235 :
236 0 : exceptions_throw_illegalaccessexception(u);
237 0 : return false;
238 : }
239 :
240 : /* access granted */
241 :
242 0 : return true;
243 : }
244 : #endif
245 :
246 :
247 : /* access_check_method *********************************************************
248 :
249 : Check if the (indirect) caller has access rights to the specified
250 : method.
251 :
252 : IN:
253 : m................the method to check
254 : callerdepth......number of callers to ignore
255 : For example if the stacktrace looks like this:
256 :
257 : [1] java.lang.reflect.Method.invokeNative (Native Method)
258 : [1] java.lang.reflect.Method.invoke
259 : [2] <caller>
260 :
261 : you must specify 2 so the access rights of <caller>
262 : are checked.
263 :
264 : RETURN VALUE:
265 : true.............access permitted
266 : false............access denied, an exception has been thrown
267 :
268 : *******************************************************************************/
269 :
270 : #if defined(ENABLE_JAVASE)
271 831 : bool access_check_method(methodinfo *m, int callerdepth)
272 : {
273 : classinfo *callerclass;
274 :
275 : /* If everything is public, there is nothing to check. */
276 :
277 831 : if ((m->clazz->flags & ACC_PUBLIC) && (m->flags & ACC_PUBLIC))
278 829 : return true;
279 :
280 : /* Get the caller's class. */
281 :
282 2 : callerclass = stacktrace_get_caller_class(callerdepth);
283 :
284 2 : if (callerclass == NULL)
285 0 : return false;
286 :
287 : /* Check access rights. */
288 :
289 2 : if (!access_is_accessible_member(callerclass, m->clazz, m->flags)) {
290 0 : Buffer<> buf(64);
291 :
292 : buf.write_slash_to_dot(m->clazz->name)
293 : .write('.')
294 : .write_slash_to_dot(m->name)
295 : .write_slash_to_dot(m->descriptor)
296 : .write(" not accessible from ", 21)
297 0 : .write_slash_to_dot(callerclass->name);
298 :
299 0 : exceptions_throw_illegalaccessexception(buf.utf8_str());
300 0 : return false;
301 : }
302 :
303 : /* access granted */
304 :
305 2 : return true;
306 : }
307 :
308 : #endif
309 :
310 : /*
311 : * These are local overrides for various environment variables in Emacs.
312 : * Please do not remove this and leave it at the end of the file, where
313 : * Emacs will automagically detect them.
314 : * ---------------------------------------------------------------------
315 : * Local variables:
316 : * mode: c++
317 : * indent-tabs-mode: t
318 : * c-basic-offset: 4
319 : * tab-width: 4
320 : * End:
321 : * vim:noexpandtab:sw=4:ts=4:
322 : */
323 :
|