diff options
author | Timotej Lazar <timotej.lazar@araneo.org> | 2015-10-07 17:25:35 +0200 |
---|---|---|
committer | Timotej Lazar <timotej.lazar@araneo.org> | 2015-10-07 17:25:35 +0200 |
commit | 76cbfe9d620ca66a374b828c011c937918f80c2c (patch) | |
tree | 8ee165821df9ab46fda38869d1ae856be4efd2c7 /python | |
parent | b7b4979f03f4d06919e251cfcc24642ccf9407ad (diff) |
Add a sandbox for Python interpreter
Switch to user "nobody" and set additional limits.
Diffstat (limited to 'python')
-rwxr-xr-x | python/runner/interpreter.py (renamed from python/interpreter.py) | 0 | ||||
-rw-r--r-- | python/runner/sandbox.c | 47 | ||||
-rw-r--r-- | python/runner/terminator.c | 32 |
3 files changed, 79 insertions, 0 deletions
diff --git a/python/interpreter.py b/python/runner/interpreter.py index dae4d59..dae4d59 100755 --- a/python/interpreter.py +++ b/python/runner/interpreter.py diff --git a/python/runner/sandbox.c b/python/runner/sandbox.c new file mode 100644 index 0000000..12e2720 --- /dev/null +++ b/python/runner/sandbox.c @@ -0,0 +1,47 @@ +#include <fcntl.h> +#include <pwd.h> +#include <stdio.h> +#include <sys/prctl.h> +#include <sys/resource.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +int main(int argc, char* argv[]) +{ + if (argc < 3) { + fprintf(stderr, "usage: %s USERNAME FILE\n", argv[0]); + return 1; + } + + // switch user (requires root or "setcap cap_setuid,cap_setgid+ep") + char const* username = argv[1]; + struct passwd const* pw = getpwnam(username); + if (!pw) { + fprintf(stderr, "no such user: %s\n", username); + return 1; + } + int ret = 0; + if ((ret = setuid(pw->pw_uid)) != 0) + fprintf(stderr, "setuid returned %d\n", ret); + if ((ret = setgid(pw->pw_gid)) != 0) + fprintf(stderr, "setgid returned %d\n", ret); + + // limit CPU time to 1 second + struct rlimit const cpu_limit = { .rlim_cur = 1, .rlim_max = 1 }; + if ((ret = setrlimit(RLIMIT_CPU, &cpu_limit)) != 0) + fprintf(stderr, "setrlimit(CPU) returned %d\n", ret); + + // don't allow writing files of any size + struct rlimit const fsize_limit = { .rlim_cur = 0, .rlim_max = 0 }; + if ((ret = setrlimit(RLIMIT_FSIZE, &fsize_limit)) != 0) + fprintf(stderr, "setrlimit(FSIZE) returned %d\n", ret); + + // there will be no fork + struct rlimit const nproc_limit = { .rlim_cur = 0, .rlim_max = 0 }; + if ((ret = setrlimit(RLIMIT_NPROC, &nproc_limit)) != 0) + fprintf(stderr, "setrlimit(NPROC) returned %d\n", ret); + + char* const args[] = { argv[2], (char*)0 }; + return execvp(argv[2], args); +} diff --git a/python/runner/terminator.c b/python/runner/terminator.c new file mode 100644 index 0000000..a994bde --- /dev/null +++ b/python/runner/terminator.c @@ -0,0 +1,32 @@ +#include <pwd.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> + +int main(int argc, char* argv[]) +{ + if (argc < 4) { + fprintf(stderr, "usage: %s USERNAME PID SIGNAL\n", argv[0]); + return 1; + } + + // switch user (requires root or "setcap cap_setuid,cap_setgid+ep") + char const* username = argv[1]; + struct passwd const* pw = getpwnam(username); + if (!pw) { + fprintf(stderr, "no such user: %s\n", username); + return 1; + } + int ret = 0; + if ((ret = setuid(pw->pw_uid)) != 0) + fprintf(stderr, "setuid returned %d\n", ret); + if ((ret = setgid(pw->pw_gid)) != 0) + fprintf(stderr, "setgid returned %d\n", ret); + + pid_t pid = atol(argv[2]); + int signum = atoi(argv[3]); + kill(pid, signum); + return 0; +} |