Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can the JVM verify there's no potential operand stack overflow when loading a class?

Going over some presentation, I've come across the following claim: When the JVM loads a class, it can analyze its content and make sure there's no overflow or underflow of the operand stack. I've found a lot of sources that make the same claim, but without specifying how it's done.

It is unclear to me how such verification can be made using static analysis. Say I have a (malicious) method that gets some value as an argument, and uses it to perform a series of pops. At load time, the number of iterations is not known, as it depends on the argument given by the method's caller. Therefore, it seems to me that only at runtime should it be possible to determined whether there will be an underflow or not. What am I missing here?

like image 475
eran Avatar asked May 10 '12 20:05

eran


People also ask

Why are Java bytecodes need to be verified at run time stage?

The byte code verification aims to enforce static security constraints on Java-based mobile code: the applet. Such a code can be downloaded and executed on a personal device running a browser. This popular model raises security issues concerning the access to personal information on the client side.

Which checks does the bytecode verifier perform on a Java class?

The bytecode verifier acts as a sort of gatekeeper: it ensures that code passed to the Java interpreter is in a fit state to be executed and can run without fear of breaking the Java interpreter. Imported code is not allowed to execute by any means until after it has passed the verifier's tests.

Is the bytecode verifier part of the JVM?

After the class loader in the JVM loads the byte code of . class file to the machine the Bytecode is first checked for validity by the verifier and this process is called as verification.

Which of the following verifications is are done by bytecode verifier?

The bytecode verifier traverses the bytecodes, constructs the type state information, and verifies the types of the parameters to all the bytecode instructions.


2 Answers

You can find basic description of the Bytecode Verifier in Java Virtual Machine specification.

To put it simple, stack depth is known at every branching point, and two execution paths merging at the same merge point must also have the same stack depth. So, the verifier won't allow you to perform series of pops without corresponding puts.

like image 148
Eugene Kuleshov Avatar answered Oct 15 '22 15:10

Eugene Kuleshov


The code of the method is split into execution blocks. A "block" is a sequence of instructions that can be executed without jumping out or into. The blocks build a directed graph of all possible execution paths.

A block always expects a certain stack size at its beginning and has a fixed stack size at its end (beginning + all the pushes - all the pops). The verifier checks that for all blocks 'a' that can be reached from a given block 'b', the end stack-size of b matches the beginning stack-size of a.

like image 6
Cephalopod Avatar answered Oct 15 '22 16:10

Cephalopod