Skip to content

Instantly share code, notes, and snippets.

@Yangff
Created March 23, 2014 13:41
Show Gist options
  • Save Yangff/9723224 to your computer and use it in GitHub Desktop.
Save Yangff/9723224 to your computer and use it in GitHub Desktop.
static int sandbox_main(Sandbox::SandboxSettings *args){
// Set Limit
#define ERROR {}
#define SetRLimit(name, lmt) {rlimit limit; limit.rlim_cur = limit.rlim_max = (lmt); setrlimit(name, &limit);}
if (args->doTimeLimit){
SetRLimit(RLIMIT_CPU, (args->TimeLimit/1000) + 1); // some function will not take cpu time!
} else
SetRLimit(RLIMIT_CPU, (Sandbox::MaxRuningTime/1000) + 1);
if (args->doStackLimit)
SetRLimit(RLIMIT_STACK, args->StackLimit);
if (args->doOutputLimit)
SetRLimit(RLIMIT_FSIZE, args->OutputLimit);
if (args->StandardInput.length() && !freopen(args->StandardInput.c_str(), "r", stdin))
return 0;
if (args->StandardOutput.length() && !freopen(args->StandardOutput.c_str(), "w", stdout))
return 0;
if (args->StandardErrput.length() && !freopen(args->StandardErrput.c_str(), "w", stderr))
return 0;
// Set seccomp
scmp_filter_ctx ctx;
if ((ctx = seccomp_init(SCMP_ACT_KILL)) == 0)
return 0;
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1,
SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO)) < 0)
return 0;
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1,
SCMP_A0(SCMP_CMP_EQ, args->sockets[0])) < 0)
return 0;
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
SCMP_A0(SCMP_CMP_EQ, args->sockets[0])) < 0)
return 0;
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)) < 0)
return 0;
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO)) < 0)
return 0;
#define makeAllow(x) {if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(x), 0) < 0) return 0; }
makeAllow(read);
makeAllow(write);
makeAllow(close);
makeAllow(exit);
makeAllow(fstat64);
makeAllow(stat64);
makeAllow(getdents);
makeAllow(getdents64);
makeAllow(mmap2);
makeAllow(mremap);
makeAllow(gettimeofday);
makeAllow(time);
makeAllow(exit_group);
makeAllow(creat);
makeAllow(stat);
makeAllow(lseek);
makeAllow(fstat);
makeAllow(access);
makeAllow(sync);
makeAllow(brk);
makeAllow(ioctl);
makeAllow(fcntl);
makeAllow(olduname);
makeAllow(getrlimit);
makeAllow(select);
makeAllow(lstat);
makeAllow(readlink);
makeAllow(readdir);
makeAllow(mmap);
makeAllow(munmap);
makeAllow(uname);
makeAllow(idle);
makeAllow(mprotect);
makeAllow(rt_sigaction);
makeAllow(uselib);
makeAllow(execve);
makeAllow(ptrace);
if (seccomp_load(ctx) != 0)
return 0;
seccomp_release(ctx);
char opt[2] = {'O','\0'};
// send prepared sign
write(args->sockets[0], opt, sizeof(opt)); // 1
// waiting timer
read(args->sockets[0], opt, sizeof(opt)); // 2
if (opt[0] == 'S'){
char ** pass_args = new char*[args->Args.size() + 1];
int cnt = 0;
BOOST_FOREACH(std:: string arg, args->Args){
pass_args[cnt] = new char[arg.length() + 1];
strcpy(pass_args[cnt], arg.c_str()); cnt++;
}
pass_args[cnt] = 0;
fprintf(stderr, "e");
execvp(args->cmd.c_str(), NULL); // 3
}
return -1;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment