If
1. the program can be modified to make a system call of your choice before any of the untrusted code (this might be done via LD_PRELOAD), and
2. the program doesn't need to do any system calls beyond `exit()`, `sigreturn()`, `read()` and `write()`
then you can use seccomp (Wikipedia article). To allow for more that just those system calls there's seccomp-bpf, which uses Berkeley Packet Filter to determine which system calls to allow. The libseccomp library simplifies seccomp-bpf so (for example) if you wanted to allow the `close()` system call:
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
Or for something similar to `chroot`, but which can't be broken out of, you could try Linux containers, OpenVZ or Linux VServer.