8

I developed a Linux application that runs untrusted code received from users (contestants). More specifically, the application is an online judge, which is something like UVa OJ, SPOJ and Codeforces, but mainly like BOCA Online Contest Administrator. My OJ supports C, C++, Java and Python.

Currently, my OJ is very unsafe, because there is no sandboxing when running untrusted code. So I'm searching for the best way to do that. The main requirement for the solution is: the user (who is setting up the contest, not a contestant) must spend as little effort as possible to setup my application. I think that git clone repo, make, sudo make install,
pjudge install <contest_dir>, cd <contest_dir>, change some .txt files, put secret test cases inside problems/ and pjudge start <port> is already too much.

First of all, I'd rather let my software be unsafe than force the user to setup a root directory, considering a solution with chroot(2)/chroot(8). This solution is more painful for me, as developer and user, than I am willing to suffer with this personal project.

I have also considered a solution with ptrace(2), to kill the process if it makes forbidden syscalls. I tried some simple code to see if it works, but it didn't seem to work correctly for some syscalls. Also, I think I'd have to filter a lot of syscalls... And I don't know what syscalls a JVM/the Python runtime needs... I'm not sure if this solution could work. If somebody knows how to use this solution properly, please, help me!

And I also found seccomp(2). This makes the process able to call only read(2), write(2), _exit(2) and sigreturn(2). This solution seems great. It would be easy to implement it in my application and it should work exactly as I need... But only for C and C++. Java and Python are a problem again. I don't know how this solution could work for the two latter languages, considering I use fork(2)+exec(2)/system(3) in my source code (which is in C++, by the way).

Any help would be really appreciated. Maybe some correct/effective way to use ptrace(2)/seccomp(2), or some other solution that I'm missing. But, please, something that meets my only requirement! It should be very easy, simple, and fast for the user to setup my application.

Thanks in advance!

matheuscscp
  • 827
  • 7
  • 23
  • Would docker solve your problem? Your contestants could submit the code in a docker image which you can run in a controlled way for judging. – lamirap Mar 24 '16 at 05:32
  • Docker seems like killing a fly with a sledgehammer. Contestants have, on average, 30 minutes per problem to do everything: read the problem statement, think of an algorithm, code it, debug it and then submit the code. Would Docker be feasible for this situation? Only the OJ should deal with it... Contestants should only send C/C++/Java/Python code, nothing else. – matheuscscp Mar 24 '16 at 06:05
  • And the user of my OJ setting a contest would have to install Docker... This is too much trouble =( – matheuscscp Mar 24 '16 at 06:09
  • 2
    With seccomp-bpf, you can decide precisely which syscalls are enabled (and use ptrace for syscalls for which you need a more fine-grained decision) – ysdx Mar 30 '16 at 13:37

1 Answers1

3

Developing own sandboxing mechanism is hard and will lead to unobvious security flaws. And your definitely should not use chroot and ptrace as security tools.

Use a matured tools instead. I recommend to start with bubblewrap - because it very easy to use, lightweight and doesn't require root privileges. It will engage Linux namespaces(7) to securely isolate submissions from root filesystem, network and process listing.

Next thing you should care about is resource limits. This could be done by Linux cgroups(7) feature. Try systemd-nspawn tool with systemd.resource-control(5) attributes set. It requires a root privileges to run so be careful.

Finally harden syscall invocations using platform-dependent (native, python, java) seccomp-bpf filter.

snizovtsev
  • 79
  • 6