Wow. Having thought about this daunting undertaking for all of about 7 minutes I apologize in advance for anything stupid I am about to say.
Is this going to be something like UVA Judge?
If the goal is to allow relatively simple programs to run without allowing malicious users destroying your system then it seems you need to be more proactive than this or you will be patching holes until the end of time.
At a minimum I think you would need to strip out user header files and substitute one of your own that contains the minimum functionality. Disallow assembler. Use a modified stdlib and/or kernel that no-ops or kills the process on any attempted syscall(), etc.
There is an awful lot to consider here.