Re: problem with class accessiblity check in invoke (natMethod.cc)

Erik Groeneveld <[email protected]>
Newsgroups gmane.comp.gcc.java.devel
Message-ID <[email protected]>
Hello Andrew,

Thanks for your quick reply. We include code below.

On Wed, Dec 23, 2009 at 11:46, Andrew Haley <[email protected]> wrote:
> On 12/23/2009 10:38 AM, Erik Groeneveld wrote:
>
[...]
>>       else
>>       // Method is public, check to see if class is accessible.
>>       {
>>         jint flags = (declaringClass->accflags
>>                       & (Modifier::PUBLIC
>>                          | Modifier::PROTECTED
>>                          | Modifier::PRIVATE));
>>         if (flags == 0) // i.e. class is package private
>>           {
>>             Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
>>             if (! _Jv_ClassNameSamePackage (caller->name,
>>                                             declaringClass->name))
>>               throw new IllegalAccessException;
>>           }
>>       }
>>     }
>>
[...]

>> 1. The systems segfaults on the caller->name because there is no calling class.
>
> How can there be no calling class?

Because we call it from C++ not from Java.  We forgot to mention that.

>> 2. We believe class accessibility is not relevant here: there is no
>> reason why a Method object with public access should not be invokable,
>> or is there?
[...]
>
> Yes, but can you send a test case before we go any further?  Then at least
> we'll all know what you're talking about.

The following code demonstrates the problem.

#include <gcj/cni.h>
#include <java/util/ArrayList.h>
#include <java/util/Iterator.h>
#include <java/lang/reflect/Method.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
    JvCreateJavaVM(NULL);
    JvAttachCurrentThread(NULL, NULL);
    java::util::ArrayList* l = new java::util::ArrayList();
    java::util::Iterator* i = l->iterator();
    java::lang::reflect::Method* m = i->getClass()->getDeclaredMethod(
            JvNewStringUTF("hasNext"), NULL);
    printf("calling invoke, it'll dump core in natMethod.cc line 194\n");
    m->invoke(i, NULL);
    return 0;
}

$gcc problem.cpp -lgcj
$./a.out
calling invoke
Aborted (core dumped)

$gdb -core core a.out
(gdb) where
#0  0x00002adf9252bed5 in raise () from /lib/libc.so.6
#1  0x00002adf9252d3f3 in abort () from /lib/libc.so.6
#2  0x00002adf90bdeed8 in _Jv_Throw (value=0x2adf932cd370) at
../../../src/libjava/exception.cc:128
#3  0x00002adf90bd2a2a in _Jv_catch_segv (_p=<value optimized out>) at
../../../src/libjava/prims.cc:184
#4  <signal handler called>
#5  0x00002adf90c217d3 in java::lang::reflect::Method::invoke
(this=0x2adf932d1c80, obj=0x2adf93ba6e40,
    args=0x0) at ../../../src/libjava/java/lang/reflect/natMethod.cc:194
#6  0x0000000000400a5c in main ()

The top of the stack is from the NULL-pointer catching signal handler
we believe, so #5 and #6 are the relevant ones.

The point is that we believe that the scenario in the C++ code is
valid, both from Java and from C++, and we do not see the reasons for
the additional check that has been added to the invoke() method.

Erik
Jurjan-Paul
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.