Question: I have to mark C code and part of that involves running and timing their submissions. The problem is that their code then runs as me and they can in principle do whatever they like using my permission settings. For example, they could copy my ssh private key.

I could set up a virtual machine and run their code within it (although I am not entirely sure of the best way to lock this down either). A problem with this is that the speed performance will now not be realistic. I could provide the same virtual machine to all the users to test their code on beforehand so at least they have the same set up to test with. 

Is there a good way to set up an environment where you can run code written by others but limit the damage it can do?

Answer: 
1. Run the code as `nobody`, which should give you minimal privileges. Depending on how hair-raising the configuration is, this may not be safe
2. Run in a `chroot` jail. Depending on the code this may change the behaviour, and jails can often be broken out of. [They are *not* a security feature.](http://securityblog.redhat.com/2013/03/27/is-chroot-a-security-feature/)
3. Run in a virtual machine. I *think* there are only very few known instances of being able to break out of those, but I'm not sure. You can use for example Vagrant to set up very simple virtualisation. [Example configuration](https://github.com/l0b0/tilde/blob/7c4c15598cad1a0e533a37ff8605a83b3a59cafc/Vagrantfile) and [commands](https://github.com/l0b0/tilde/blob/2dfffe0f95a93de2d66912ea43f2884f416a3f2b/.bash_history#L1689-L1696).
I have worked on a similar system a few years ago. What I did was to use ptrace to limit the system calls (see code [here](https://code.google.com/p/orzoj/source/browse?repo=server-judge#git/orzoj/judge/lib/orzoj-limiter/linux)), and optionally change user id or chroot. If the programs are simple, involving only pure algorithms and basic I/O tasks, this should be a practical solution that you could consider.

BTW, it is worth mentioning that you should also limit compiler time/memory usage. Some malicious programs may include directives like `#include </dev/random>` which could cause the compiler to hang for a long time, or some recursive macros causing the compiler to eat up lots of memory.