LCOV - code coverage report
Current view: top level - vm - access.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 30 47 63.8 %
Date: 2017-07-14 10:03:36 Functions: 4 4 100.0 %

          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      277004 : bool access_is_accessible_class(classinfo *referer, classinfo *cls)
      67             : {
      68      277004 :         assert(referer);
      69      277004 :         assert(cls);
      70             : 
      71             :         /* Public classes are always accessible. */
      72             : 
      73      277004 :         if (cls->flags & ACC_PUBLIC)
      74      232522 :                 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             : 

Generated by: LCOV version 1.11