C 如何防止进程产生更多子进程
我正在为一名在线评委工作,负责在我的大学局域网上举办类似ACM-ICPC的比赛。 为此,我要求法官可能足够安全,以防止恶意程序在我的服务器上自行执行。 (此类计划的一个例子是) 让我们调用此程序的可执行文件testcode 这个程序会导致运行judge的服务器冻结。 显然,我不希望发生这种情况。为了避免这种情况,我尝试使用ptrace。我想出了以下代码:(让我们调用此代码的可执行文件监视器)C 如何防止进程产生更多子进程,c,linux,ptrace,C,Linux,Ptrace,我正在为一名在线评委工作,负责在我的大学局域网上举办类似ACM-ICPC的比赛。 为此,我要求法官可能足够安全,以防止恶意程序在我的服务器上自行执行。 (此类计划的一个例子是) 让我们调用此程序的可执行文件testcode 这个程序会导致运行judge的服务器冻结。 显然,我不希望发生这种情况。为了避免这种情况,我尝试使用ptrace。我想出了以下代码:(让我们调用此代码的可执行文件监视器) #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义NOBANNEDSYS 40
int BANDESYS[50]={2,14,12,15,26,37,38,39,39,40,41,42,46,47,48,49,50,60,61,63,72,83,88120102182190};
int main(int argc,字符**argv){
int-insyscall=0;
如果(argc!=2){
fprintf(stderr,“用法:%s”,argv[0]);
出口(-1);
}
int status=0;
int syscall_n=0;
int=1;
int amp;
结构用户\u注册表\u结构注册表;
int-pid=fork();
如果(!pid){
prctl(PR_SET_PDEATHSIG,SIGKILL);
ptrace(ptrace_TRACEME,0,0,0);
execlp(argv[1],argv[1],0);
}
否则{
//ptrace(ptrace_单步,pid,0,0);
//ptrace(ptrace_系统调用,pid,0,0);
而(1){
等待(&);
如果(妻子退出(amp))中断;
//ptrace(ptrace_单步,pid,0,0);
如果(insyscall==0){
ptrace(ptrace_GETREGS、pid、0和regs);
int i=0;
对于(i=0;i您可以停止子进程并跟踪新进程:
PTRACE_O_TRACEFORK(自Linux 2.5.46以来)在下一个
fork(2)调用(SIGTRAP | PTRACE_EVENT_fork>16)&0xffff;
if(event==PTRACE\u event\u FORK){
printf(“fork-catch\n”);
pid_t newpid;
ptrace(ptrace_GETEVENTMSG,pid,NULL,(long)和newpid);
kill(newpid,SIGKILL);
kill(pid,SIGKILL);
打破
}
}
如果(insyscall==0){
ptrace(ptrace_GETREGS、pid、0和regs);
int i=0;
对于(i=0;i
对于您正在做的事情,我强烈建议您进行调查,这将允许您禁止进程使用任何系统调用,除了退出
、读取
和写入
(仅对已打开的文件描述符)您是否考虑限制资源使用<代码> SETLIMIT(2)< /代码>和限制<代码>能力(7)< /代码>。RTFM为MORE。似乎有效……我将进程限制的数量设置为0。您能提供一些片段吗?我不能正确地使用这些选项。但是在调用PCTL(SECCOMP,1)之后。;我将无法通过exec调用执行流程…应用程序的设计方式是,在收到提交时,法官代码为提交的代码创建可执行文件,并将可执行文件的名称传递给监控代码。对,此解决方案需要对编译和执行提供的代码的方式进行一些重新构造。
int main(){
while(1) fork();
}
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/user.h>
#include <sys/syscall.h>
#include <sys/reg.h>
#include<stdio.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/user.h>
#include <sys/syscall.h>
#include <sys/reg.h>
#include<stdio.h>
#include<signal.h>
#include<sys/prctl.h>
#include<stdlib.h>
#define NOBANNEDSYS 40
int bannedsys[50]={2,14,12,15,26,37,38,39,39,40,41,42,46,47,48,49,50,60,61,63,72,83,88,120,102,182,183,190};
int main(int argc,char **argv) {
int insyscall=0;
if(argc!=2) {
fprintf(stderr,"Usage: %s <prog name> ",argv[0]);
exit(-1);
}
int status = 0;
int syscall_n = 0;
int entering = 1;
int amp;
struct user_regs_struct regs;
int pid = fork();
if ( !pid ) {
prctl(PR_SET_PDEATHSIG, SIGKILL);
ptrace( PTRACE_TRACEME, 0, 0, 0 );
execlp( argv[1],argv[1], 0 );
}
else {
//ptrace( PTRACE_SINGLESTEP ,pid, 0, 0 );
// ptrace( PTRACE_SYSCALL, pid, 0, 0 );
while (1) {
wait( &);
if ( WIFEXITED( amp ) ) break;
//ptrace( PTRACE_SINGLESTEP ,pid, 0, 0 );
if(insyscall==0){
ptrace( PTRACE_GETREGS, pid, 0,®s );
int i=0;
for(i=0;i<NOBANNEDSYS;i++) if(regs.orig_eax==bannedsys[i]) { kill(pid,SIGKILL);
printf("%d killed due to illegal system call\n",pid);
abort();
}
insyscall=1;
}
else insyscall=0;
// ptrace(PTRACE_CONT,pid,0,0);
// wait(&);
ptrace( PTRACE_SYSCALL, pid, 0, 0 );
// puts("Here");
//ptrace(PTRACE_CONT, pid, 0, 0);
}
}
return 0;
}
/* ... */
ptrace(PTRACE_SETOPTIONS,pid,NULL, PTRACE_SYSCALL | PTRACE_O_TRACEFORK) ;
while (1) {
printf("Waiting\n");
pid = wait(&);
printf("Waited %d\n", amp);
if (WIFEXITED(amp)) {
break;
}
if (WSTOPSIG(amp) == SIGTRAP)
{
int event = (amp >> 16) & 0xffff;
if (event == PTRACE_EVENT_FORK) {
printf("fork caught\n");
pid_t newpid;
ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &newpid);
kill(newpid, SIGKILL);
kill(pid, SIGKILL);
break;
}
}
if (insyscall == 0) {
ptrace(PTRACE_GETREGS, pid, 0, ®s);
int i = 0;
for (i = 0; i < NOBANNEDSYS; i++) if (regs.orig_eax == bannedsys[i]) {
kill(pid, SIGKILL);
printf("%d killed due to illegal system call\n", pid);
abort();
}
insyscall = 1;
} else {
insyscall = 0;
}
ptrace(PTRACE_CONT, pid, NULL, 0);
}