[security-dev 00021]: Loading an unverified class
Nuno Cruces
ncruces at gmail.com
Fri Oct 5 12:56:46 UTC 2007
Hi,
First off, a little introduction, so I'm hopefully not considered heretic.
I'm the (sole) developer of a project called JauVM
(http://jauvm.sf.net/). This project implements a JVM bytecode
interpreter in Java, which allows interpreted JVM code to use both
tail-calls and continuations. Some examples of this can be found in:
http://jauvm.svn.sf.net/viewvc/jauvm/trunk/jauvm/test/
Interpreted and "native" code can coexist and be freely mixed in one
program. Methods tagged by the @interpretable annotation are
interpreted by the JauVM, and all other methods are delegated to the
underlying JVM (e.g.: Sun's; the JauVM is a Java program, that itself
runs atop a JVM). For an example of this look at:
http://jauvm.svn.sf.net/viewvc/jauvm/trunk/jauvm/test/Pythag.java?view=markup
If you have any questions on the JauVM, feel free to ask, either on or
off band. But now to the problem at hand.
The interpreter calls "native" methods using reflection, which works
in all but one situation: non-virtual calls on the super instance.
Static methods, interface methods, virtual methods all work.
Constructors and private methods, also work (private methods thanks to
setAccessible), and are non-virtual. It doesn't seem possible,
however, to make the non-virtual call to a public/protected method,
required to implement invokespecial on the super instance.
The only way I've been able to do this, is by generating a class at
runtime, which is fine, except the verifier is quite strict, even on
ACC_SUPER-less classes. For instance, the following two classes fail
with "Illegal use of nonvirtual function call" and "Incompatible
object argument for invokespecial", despite working flawlessly with
"-noverify".
class superA {
public static void call(A a);
%load a
invokespecial A.fn()void
return
}
}
class superA extends A {
public static void call(A a);
%load a
invokespecial A.fn()void
return
}
}
So, my question is, is it possible in any way to load specific classes
at runtime bypassing the verifier? I understand this is a security
issue, but so is (e.g.) accessing the Unsafe object, which you can do
easily thanks to reflection and setAccessible (and my code already
requires setAccessible to handle private members, as above). A
non-portable solution (e.g., using Unsafe) would also help. I've tried
Unsafe.defineClass, which seems to bypass some security checks, but
not the verifier. Having the class be loaded by the null classloader
seems to bypass verification, but then references to A above can't be
resolved.
If you have any other ideas on how to implement this, that would be a
great help too, obviously. JNI is always a possibility and I'm
interested in a JNI solution, but even then I would still rather have
a bytecoded option available alongside (even if unportable, unsafe).
Thank you all for your time and patience. If this is the wrong medium
to ask such a question, I'm sorry. I'd still be glad if you could at
least be so kind to point me in the right direction.
Regards,
Nuno Cruces
PS:
As a curiosity, the only other "similar" issue I've had implementing
the JauVM is the need for unbalanced synchronization (which JVMs is
allowed, but not required to accept). There, a combination of three
implementations work to "solve" the problem: a pure Java version for
those VMs that allow unbalanced syncronization; a Unsafe based version
where available; a JNI version where available.
I have a working prototype of this, it still isn't available in the
project page.
Thanks again!
More information about the security-dev
mailing list