1

I want to sandbox an application where end users can submit Java code to a server where it is compiled and executed (kind of a web-based IDE as part of an educational game). Most aspects can easily be handled by using either the standard security manager or verification of used APIs against a whitelist using ASM or similar.

An open problem is how to deal with infinite loops. As threads have their own stack, StackOverFlowErrors seem to be thread-local. I have done a little spike and came up with this:

public class TryToSurviveAStackOverflow {

public static void main(String[] args) throws Exception {

    final Runnable infiniteLoop = new Runnable() {
        @Override public void run() {
            run();
        }
    };

    Runnable sandboxed = new Runnable() {
            @Override public void run() {
                try {
                    Thread.sleep(10000); // some time to connect VisualVM to monitor this
                    infiniteLoop.run();
                }
                catch (StackOverflowError x) {
                    System.err.println("Thread crashed with stack overflow");
                } catch (InterruptedException e) {
                    System.err.println("Thread interruped");
                }
            }
        };

        Thread thread = new Thread(sandboxed,"infinite loop");
        thread.start();
        thread.join();
        System.out.println(thread.getState());

        System.out.println("I am still alive");

}

}

This seems to work, but how safe is this? In particular, what happens to the stack space used by the unsafe thread? I can see that the state of the thread is set to TERMINATED.

Any help / pointers are highly appreciated !

Cheers, Jens

jens
  • 239
  • 2
  • 11
  • 1
    I think you should use run sand boxed user processes on host OS, instead of managing it all in Java. Then you can limit the RAM, CPU and number of threads per user id. Just route std-out and std-err of the process to the user. – S.D. Aug 21 '13 at 03:54
  • I might have found an answer [here](http://www.coderanch.com/t/518939/java/java/StackOverflowError-handled): _"When any exception happens, the virtual machine searches the stack for active exception handlers (compatible catch blocks), unwinding the stack in the process. When your exception handler in the main() method is found, the stack is already nearly empty (only the main method is on the stack, apart perhaps from some of the VM bootstrap methods); all the go() calls were already removed. "_ - so this seems to work ok – jens Aug 21 '13 at 08:39

0 Answers0