The dispatcher, as the name implies, fetches judge tasks from RabbitMQ, dispatches them to the sandbox workers and gets the results back synchronously. In
Justice, the sandboxes are language-specific:
- If the submission is written in Java, we can sandbox it with Java Security Manager.
- If the submission is written in C/CPP, we need another sandbox to jail the compiling and running process on Linux.
Since dispatcher is also written in Java, it could also play the role of Java sandbox. The implement of sandbox for C/CPP binaries will be discussed in the next article.
Our sandboxes are going to meet the following requirements due to security reasons:
- Run sandbox with resource usage limit including CPU, memory, IO, network, etc.
- In case the program in the sandbox is running like forever, we need to set a proper timeout on the child process, kill if necessary.
- Be careful about the information leaking whenever the sandbox compiles the source code or runs the binary.
We run the compiled Java class with
-Xmx (AKA the maximum memory allocation pool for a JVM), so when memory usage exceeds beyond
-Xmx we will get a
Get out of the endless looping
Apache commons exec can execute an external processes with a watchdog, here is an example of executing compilation of java code:
If the submission contains a compiler bomb, runs an endless looping or takes a 1-minute nap(looks like forever to the sandbox), our sandbox will kill it after waiting for
Prevent information leaking
System-related information may get exposed in various ways:
- Network connections based on TCP or UDP, both inbound and outbound direction.
- Output containing security-related items, like kernel version.
- Compiling errors, like
For (1) and (2), running a Java class with an empty policy file could eliminate all of the risks.
For (3), we should give a clear and concise tip like “Compile Error” instead of the whole compiling error message.