Hotspot loves PHP.reboot / stack capturing exception
John Rose
john.r.rose at oracle.com
Mon Sep 12 15:59:52 PDT 2011
On Sep 12, 2011, at 10:23 AM, Thomas Wuerthinger wrote:
> If this special exception class is declared as a checked exception, a method would itself chose if its stack is exposed or not based on its "throws" clause. I think in that case the possible exploitations are less than reflection (because it would not be possible to access data declared "private", but only the stacks of methods that are explicitly declared accessible). That this is a first step towards continuation support would be a nice side effect of this solution.
We have explored reified JVM states already; it's interesting but hard to tame:
http://hg.openjdk.java.net/mlvm/mlvm/hotspot/file/tip/callcc_old.txt
Let's assume (for the moment) that each participating frame will have a handler which can contain special code (or metadata) to collect the required locals of the participating frame.
There's a more direct way to solve the current problem, which doesn't require a complex security model, and decouples the local-grabbing hack from exceptions.
The idea is to introduce something like the x86 "pusha" instruction to the JVM. Introduce a native-coded intrinsic which returns a Object[] array (or tuple) of all the locals in the *immediate* caller of the intrinsic. (Should be an instruction, maybe, but can be an intrinsic.)
static int unity() {
int x = 1; String y = "tu";
System.out.println(Arrays.asList(System.getLocalArray()));
// might print [1, tu] or [1, null]
return x;
}
This exposes the question of liveness: JVMs routinely nullify non-live variables, but what if the only remaining use is the getLocalArray intrinsic? Shouldn't it count as a weak reference? Or will we allow it to "reanimate" all local values? That would impose a systemic cost on the register allocator, for the whole method.
Perhaps an argument to getLocalArray (64-bit bitmask) could be used to select locals explicitly. It's still gross, since you have to teach the register allocator to look at calls to getLocalArray; and what if the argument is non-constant?
(This feels like the JVM version of JavaScript eval. BTW, I don't think the exception-based formulation helps clean this up.)
The getLocalArray intrinsic could be defined in a way that is self-evidently secure. Just like pusha is a shorthand for a lot of individual pushes, the getLocalArray intrinsic could be defined as a shorthand for a lot of individual data motion instructions. Besides compactness, the advantage of the shorthand would be that it would hint to the system that the variable definitions could be put on the slow path.
But all this could be accomplished more simply by just putting the data motion instructions (apush #N etc.) in the slow path, just before a well-crafted invokedynamic instruction. Let the normal profiling supply the required hint about slow paths, and sink the data movement instructions into the deopt. metadata.
Now I want to back up to Thomas' specific suggestion. Instead of putting in a catch, suppose we use the "throws" clause of the method to control local capture. This is a clever way to have existing metadata encode an intention to collect locals "automagically", without explicit bytecodes or handlers. It requires an overloading of the idea of "throws", so it might be better to use a new attribute or annotation.
In any case, it seems to me that magic frame metadata which causes fillInStackTrace (of selected Throwable types) to collect local values is almost completely equivalent (modulo some simulation overhead) to collecting the locals in each affected frame's handler.
I say "almost" because the magic metadata can provide the local information in unpopped frames, while the less magic method (which can be done today) requires each dying frame to be popped, except perhaps for the oldest, in order for the local values (and other state) to be collected into the flying exception.
-- John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20110912/bd595bff/attachment.html
More information about the mlvm-dev
mailing list