Maybe I found the answer on my own. Comments highly desired!
I'm trying to use the seccomp library to disallow all, but certain syscalls.
It seems to work, i.e. in my naïve tests I can read from stdin, write to stdout, but cannot open files via Python.
#include <stdio.h>
#include <seccomp.h>
#include <python2.7/Python.h>
#define ERR_EXIT(err) do { \
fprintf(stderr, "%s near line %d\n", strerror(-err), __LINE__); \
exit(-1); } while (0);
int main(int argc, char** argv)
{
int i;
scmp_filter_ctx ctx;
int err;
Py_Initialize();
/* return illegal calls with error */
if (!(ctx = seccomp_init(SCMP_ACT_ERRNO(1)))) {
ERR_EXIT(1);
}
/* allow write, but only to stdout */
if ((err = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write),
1, SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)))) {
ERR_EXIT(err);
}
/* allow read, but only from stdin */
if ((err = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read),
1, SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO)))) {
ERR_EXIT(err);
}
/* brk, exit, exit_group, and rt_sigaction are needed by Python */
if ((err = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0))) {
ERR_EXIT(err);
}
if ((err = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0))) {
ERR_EXIT(err);
}
if ((err = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0))) {
ERR_EXIT(err);
}
if ((err = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigaction), 0))) {
ERR_EXIT(err);
}
if ((err = seccomp_load(ctx))) {
ERR_EXIT(err);
}
for (i = 1; i < argc; i++) {
PyRun_SimpleString(argv[i]);
}
Py_Finalize();
return 0;
}
I very much appreciate any critique on this approach, thanks!