Esempio n. 1
0
int get_page_fault_mem(struct rusage & ruse, pid_t & pidApp) {
	//java use pagefault
	int m_vmpeak, m_vmdata, m_minflt;
	m_minflt = ruse.ru_minflt * getpagesize();
	if (0 && DEBUG) {
		m_vmpeak = get_proc_status(pidApp, "VmPeak:");
		m_vmdata = get_proc_status(pidApp, "VmData:");
		printf("VmPeak:%d KB VmData:%d KB minflt:%d KB\n", m_vmpeak, m_vmdata,
				m_minflt >> 10);
	}
Esempio n. 2
0
int watch_solution(pid_t pid, int *flag) {
	struct rusage	usage;
	struct user_regs_struct regs;
	long orig_eax, eax;
	int status, vm, signo, insyscall;

	insyscall = 1;
	while (1) {
		wait4(-1, &status, 0, &usage);

		vm = get_proc_status(pid, "VmPeak");
		if (vm > AS_LMT) {
			*flag = ML;
			ptrace(PTRACE_KILL, pid, NULL, NULL);
			break;
		}
		if (WIFEXITED(status)) {
			break;
		}
		if (get_file_size("error.out")) {
			*flag = RE;
			ptrace(PTRACE_KILL, pid, NULL, NULL);
		}
		if (WIFSIGNALED(status)) {
			signo = WTERMSIG(status);
			switch (signo) {
				case SIGCHLD:
				case SIGALRM:
				case SIGKILL:
				case SIGXCPU:
					*flag = TL;
					break;
				case SIGXFSZ:
					*flag = OL;
					break;
				default:
					*flag = RE;
					break;
			}
			ptrace(PTRACE_KILL, pid, NULL, NULL);
			break;
		}
		
		orig_eax = ptrace(PTRACE_PEEKUSER, pid, 4*ORIG_EAX, NULL);
		if (insyscall && orig_eax>0) {
			if (call_counter[orig_eax] > syscall_limit[orig_eax]) {
				*flag = RE;
				fprintf(stderr, "process %d is calling %s which is not allowed\n", pid,\
					syscall_list[orig_eax]);
				ptrace(PTRACE_KILL, pid, NULL, NULL);
				break;
			} else {
				printf("process %d is calling %s\n", pid, syscall_list[orig_eax]);
			}
		}
		insyscall = 1-insyscall;
		ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
	}//while
	return 0;
}
Esempio n. 3
0
int watch_solution(pid_t pid, int *flag) {
	struct rusage	usage;
	struct user_regs_struct regs;
	long orig_eax, eax;
	int status, vm, signo, insyscall, ptraceflag;

	insyscall = 1;
	while (1) {
		pid_t pid = wait4(-1, &status, 0, &usage);
		ptraceflag = 0;

		vm = get_proc_status(pid, "VmPeak");
		if (vm > AS_LMT) {
			*flag = CODE_ML;
			ptrace(PTRACE_KILL, pid, NULL, NULL);
			break;
		}
		if (WIFEXITED(status)) {
			break;
		}
		if (get_file_size(RE_OUT)) {
			*flag = CODE_RE;
			ptrace(PTRACE_KILL, pid, NULL, NULL);
		}
		if (WIFSTOPPED(status)) {
			signo = WSTOPSIG(status);
			//psignal(signo, "in stopped");
			switch (signo) {
				case SIGCHLD:
				case SIGALRM:
				case SIGKILL:
				case SIGXCPU:
					*flag = CODE_TL;
					break;
				case SIGXFSZ:
					*flag = CODE_OL;
					break;
				case SIGTRAP:
					ptraceflag = 1;
					break;
				default:
					*flag = CODE_RE;
					break;
			}
			if (ptraceflag == 0) {
				ptrace(PTRACE_KILL, pid, NULL, NULL);
				break;
			}
		}
		if (ptraceflag == 0 && WIFSIGNALED(status)) {
			signo = WTERMSIG(status);
			//psignal(signo, "in signaled");
			switch (signo) {
				case SIGCHLD:
				case SIGALRM:
				case SIGKILL:
				case SIGXCPU:
					*flag = CODE_TL;
					break;
				case SIGXFSZ:
					*flag = CODE_OL;
					break;
				default:
					*flag = CODE_RE;
					break;
			}
			ptrace(PTRACE_KILL, pid, NULL, NULL);
			break;
		}
		
		orig_eax = ptrace(PTRACE_PEEKUSER, pid, 4*ORIG_EAX, NULL);
		if (insyscall && orig_eax>0) {
			if (call_counter[orig_eax] > syscall_limit[orig_eax]) {
				*flag = CODE_RE;
				write_log(LOG, 0, "process %d is calling %s which is not allowed", pid, syscall_list[orig_eax]);
				write_log(LOG, 0, "process %d is calling %s", pid, syscall_list[orig_eax]);
				ptrace(PTRACE_KILL, pid, NULL, NULL);
				break;
			} else {
				//write_log(LOG, 0, "process %d is calling %s\n", pid, syscall_list[orig_eax]);
			}
		}
		insyscall = 1-insyscall;
		ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
	}//while
	return 0;
}
Esempio n. 4
0
void OS_get_table()
{
    /* dir walker storage */
    DIR             *dir;
    struct dirent   *dir_ent, *dir_result;
    
    /* all our storage is going to be here */
    struct obstack  mem_pool;
    
    /* container for scaped process values */
    struct procstat *prs;

    /* string containing our local copy of format_str, elements will be
     * lower cased if we are able to figure them out */
    char            *format_str;

    /* initlize a small memory pool for this function */
    obstack_init(&mem_pool);

    /* put the dirent on the obstack, since it's rather large */
    dir_ent = obstack_alloc(&mem_pool, sizeof(struct dirent));

    if ((dir = opendir("/proc")) == NULL)
        return;

    /* Iterate through all the process entries (numeric) under /proc */
    while(readdir_r(dir, dir_ent, &dir_result) == 0 && dir_result) {

        /* Only look at this file if it's a proc id; that is, all numbers */
        if(!is_pid(dir_result->d_name))
            continue;

        /* allocate container for storing process values */
        prs = obstack_alloc(&mem_pool, sizeof(struct procstat));
        bzero(prs, sizeof(struct procstat));

        /* intilize the format string */
        obstack_printf(&mem_pool, get_string(STR_DEFAULT_FORMAT));
        obstack_1grow(&mem_pool, '\0');
        format_str = (char *) obstack_finish(&mem_pool);

        /* get process' uid/guid */
        get_user_info(dir_result->d_name, format_str, prs, &mem_pool);

        /* scrape /proc/${pid}/stat */
        if (get_proc_stat(dir_result->d_name, format_str, prs, &mem_pool) == false) {
            /* did the pid directory go away mid flight? */
            if (pid_exists(dir_result->d_name, &mem_pool) == false)
                continue;
        }

        /* correct values (times) found in /proc/${pid}/stat */
        fixup_stat_values(format_str, prs);

		/* get process' cmndline */
		get_proc_cmndline(dir_result->d_name, format_str, prs, &mem_pool);

        /* get process' cwd & exec values from the symblink */
        eval_link(dir_result->d_name, "cwd", F_CWD, &prs->cwd, format_str,
            &mem_pool);
        eval_link(dir_result->d_name, "exe", F_EXEC, &prs->exec, format_str,
            &mem_pool);

        /* scapre from /proc/{$pid}/status */
        get_proc_status(dir_result->d_name, format_str, prs, &mem_pool);

		/* calculate precent cpu & mem values */
		calc_prec(format_str, prs, &mem_pool);

        /* Go ahead and bless into a perl object */
        bless_into_proc(format_str, field_names,
            prs->uid,			
            prs->gid,			
            prs->pid,			
            prs->comm,			
            prs->ppid,			
            prs->pgrp,			
            prs->sid,			
            prs->tty,			
            prs->flags,			
            prs->minflt,		
            prs->cminflt,		
            prs->majflt,		
            prs->cmajflt,		
            prs->utime,			
            prs->stime,			
            prs->cutime,		
            prs->cstime,		
            prs->priority,		
            prs->start_time,	
            prs->vsize,			
            prs->rss,			
            prs->wchan,			
	    prs->time,			
	    prs->ctime,			
            prs->state,			
            prs->euid,
            prs->suid,
            prs->fuid,
            prs->egid,
            prs->sgid,
            prs->fgid,
            prs->pctcpu,
            prs->pctmem,
            prs->cmndline,
            prs->exec,
            prs->cwd
        );

        /* we want a new prs, for the next itteration */
        obstack_free(&mem_pool, prs);
    }
    
    closedir(dir);

    /* free all our tempoary memory */
    obstack_free(&mem_pool, NULL);
}
Esempio n. 5
0
void trace_submit(int pid, int *status, int *usedtime, int *usedmem, int timelimit, int casetimelimit, int memlimit, int language, int spj)
{
    int pstat, sig, ecode;
    struct user_regs_struct regs;
    struct rusage usage;
    int tmpmem, tmptime, sub=0;
    while(1)
    {
        wait4(pid, &pstat, 0, &usage);
        if(language==LANG_JAVA)tmpmem=(usage.ru_minflt*getpagesize())>>10;
        else tmpmem=get_proc_status(pid, "VmPeak:");
        if(tmpmem>*usedmem)*usedmem=tmpmem;
        if(get_file_size("error.out"))
        {
            *status=JG_RE;
            ptrace(PTRACE_KILL, pid, NULL, NULL);
            break;
        }
        if(!spj&&get_file_size("user.out")>get_file_size("data.out")*2+1024)
        {
            *status=JG_OL;
            ptrace(PTRACE_KILL, pid, NULL, NULL);
            break;
        }
        if(WIFEXITED(pstat))break;
        ecode=WEXITSTATUS(pstat);
        if(ecode==0x05||ecode==0);
        else
        {
            if(*status==JG_AC)
            {
                switch(ecode)
                {
                    case SIGCHLD:
                    case SIGALRM:
                        alarm(0);
                    case SIGKILL:
                    case SIGXCPU:
                        *status=JG_TL;
                        break;
                    case SIGXFSZ:
                        *status=JG_OL;
                        break;
                    default:
                        *status=JG_RE;
                }
                print_runtime_error(strsignal(ecode));
            }
            ptrace(PTRACE_KILL, pid, NULL, NULL);
            break;
        }
        if(WIFSIGNALED(pstat))
        {
            sig=WTERMSIG(pstat);
            if(*status==JG_AC)
            {
                switch(sig)
                {
                    case SIGCHLD:
                    case SIGALRM:
                        alarm(0);
                    case SIGKILL:
                    case SIGXCPU:
                        *status=JG_TL;
                        break;
                    case SIGXFSZ:
                        *status=JG_OL;
                        break;
                    default:
                        *status=JG_RE;
                }
                print_runtime_error(strsignal(sig));
            }
            break;
        }
        ptrace(PTRACE_GETREGS, pid, NULL, &regs);
        if(oksyscall[regs.REG_SYSCALL]==0)
        {
            *status=JG_RE;
            char msg[MAXLINE+1];
            sprintf(msg, "does not allow syscall id:%d name:%s", (int)regs.REG_SYSCALL, syscallname[regs.REG_SYSCALL]);
            print_runtime_error(msg);
            ptrace(PTRACE_KILL, pid, NULL, NULL);
            break;
        }
        else if(sub==1&&oksyscall[regs.REG_SYSCALL]>0)
            --oksyscall[regs.REG_SYSCALL];
        sub=1-sub;
        ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
    }
Esempio n. 6
0
OJ_Reinfo Sandbox::watch_cpp(pid_t pid)
{
	OJ_Reinfo res;

	try{
		string outfile  = m_info.pro_id + "-" + m_info.title_in + ".out";
		string ansfile = "../../" + PH_IO + m_info.pro_id + "/" + m_info.title_in + ".out";

		int topmemory = 0;
		int tempmemory = 0;
		int status = 0 ;
		int sig = 0;
		int  exitcode = 0;
		struct user_regs_struct reg;
		struct rusage ruse;

		if(topmemory==0) {
			topmemory= get_proc_status(pid, "VmRSS:") << 10;
		}
		while (1){
			wait4(pid, &status, WUNTRACED, &ruse);

			tempmemory = get_proc_status(pid, "VmPeak:") << 10;

			if (tempmemory > topmemory){
				topmemory = tempmemory;
			}

			if (topmemory > m_info.mem_lim * STD_KB){
					throw (OJ_ERROR) OJ_MLE;
				ptrace(PTRACE_KILL, pid, NULL, NULL);
			}
			
			if (0 != WIFEXITED(status)){	//子进程正常退出
				break;
			}

			if (get_file_size(outfile.c_str()) > get_file_size(ansfile.c_str()) * 2){
				throw (OJ_ERROR) OJ_OLE;
				ptrace(PTRACE_KILL, pid, NULL, NULL);
				break;
			}			

			exitcode = WEXITSTATUS(status);

			if (exitcode != 0x05 && exitcode != 0){/*exitcode == 5 waiting for next CPU allocation  */
				switch (exitcode)
				{
					case SIGCHLD:
						alarm(0);
					case SIGALRM:
					case SIGKILL:
					case SIGXCPU:
						throw (OJ_ERROR) OJ_TLE;
						break;
					case SIGXFSZ:
						throw (OJ_ERROR) OJ_OLE;
						break;
					default:
						throw (OJ_ERROR) OJ_RE;
						break;
				}
			}

			if (WIFSIGNALED(status))
			{
				sig = WTERMSIG(status);

				switch (sig)
				{
					case SIGCHLD:
						alarm(0);
					case SIGALRM:
					case SIGKILL:
					case SIGXCPU:
						throw (OJ_ERROR) OJ_TLE;
						break;
					case SIGXFSZ:
						throw (OJ_ERROR) OJ_OLE;
						break;
					default:
						throw (OJ_ERROR) OJ_RE;
						break;
				}
			}

			/*检查系统调用*/
			ptrace(PTRACE_GETREGS, pid, NULL, &reg);
			
			// if (call_counter[reg.REG_SYSCALL] ){
			// 	//call_counter[reg.REG_SYSCALL]--;
			// }else if (0) {
			// 	call_counter[reg.REG_SYSCALL] = 1;
			// }else { //do not limit JVM syscall for using different JVM
			// 	throw (OJ_ERROR) OJ_PF;
			// 	ptrace(PTRACE_KILL, pidApp, NULL, NULL);
			// }
			// int usedtime = 0;
			// printf("%lld\n%lld\n%lld\n%lld\n",ruse.ru_utime.tv_sec,ruse.ru_utime.tv_usec,ruse.ru_stime.tv_sec,ruse.ru_stime.tv_usec);
			// usedtime += (ruse.ru_stime.tv_sec * 1000 + ruse.ru_stime??
			ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
		}
			
		ptrace(PTRACE_KILL, pid, NULL, NULL);

		res.time = 0;
		res.memory = topmemory/1024;
		// cout<<res.memory<<endl;
	}catch(OJ_ERROR msg){
		ptrace(PTRACE_KILL, pid, NULL, NULL);
		cerr<<"运行程序时出错"<<endl;
		throw ;
	}

	return res;
}
Esempio n. 7
0
void watch(pid_t pid,enum judge_status &judge_status,long &max_used_memory,long &used_time,long error_size)
{
    long init_used_time = used_time;
    long used_memory;

    init_syscall_limit();

    int status;
    struct rusage ru;

    while(1)
    {
        pid_t pid_ret = wait4(pid,&status,0,&ru);
        if(pid_ret != pid)
            error_report("wait4");

        //TLE
        used_time = init_used_time + ru.ru_utime.tv_sec * 100 + ru.ru_utime.tv_usec / 1000;
        if(used_time >= time_limit * 1000)
        {
            judge_status = JUDGE_TLE;
            goto send_kill;
        }

        //MLE
        if (language == LANG_JAVA)
        {
            // JVM GC ask VM before need, so used kernel page fault times and page size.
            used_memory = get_page_fault_memory(ru, pid);
        } else
        {
            // other use VmPeak
            used_memory = get_proc_status(pid, "VmPeak:") << 10;
        }

        if(used_memory > max_used_memory)
            max_used_memory = used_memory;
        if(max_used_memory > memory_limit)
        {
            judge_status = JUDGE_MLE;
            goto send_kill;
        }


        //RE 判断stderr
        if(get_file_size(code_error_path) > error_size)
        {
            judge_status = JUDGE_RE;
            goto send_kill;
        }

        //进程退出
        if(WIFEXITED(status))
        {
            int exitcode = WEXITSTATUS(status);
            if(exitcode != 0)
            {
                judge_status = JUDGE_RE;
            }
            break;
        }

        //未捕捉到信号而中止
        if(WIFSIGNALED(status))
        {
            int sigcode = WTERMSIG(status);
            break;
        }

        // 未捕捉信号而暂停
        // 子进程被追踪(ptrace)或调用WUN-TRACED时才可能发生
        if (WIFSTOPPED(status))
        {

            int sigcode = WSTOPSIG(status);

            switch (sigcode) {
                case SIGSTOP:
                    // JAVA 使用 SIGSTOP 等待下次 CPU 运行
                    if (language != LANG_JAVA) {
                        judge_status = JUDGE_RE;
                        goto send_kill;
                    }
                case SIGTRAP:
                    // c++ case 语句中不能出现带初始化的变量声明
                    unsigned long syscall;
                    syscall = get_syscall(pid);
                    //printf("System call: %lu\n", syscall);
                    switch (check_syscall(syscall)) {
                        case 0:

                            judge_status = JUDGE_RE;
                            goto send_kill;
                        case 1:
                            ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
                            break;
                        case 2:
                            //ptrace(PTRACE_SETREGS, pid, NULL, NULL);
                            break;
                    }

                    break;
                case SIGSEGV:
                    judge_status = JUDGE_MLE;
                    goto send_kill;
                case SIGCHLD:
                case SIGALRM:
                    alarm(0);
                case SIGXCPU:
                case SIGKILL:
                    judge_status = JUDGE_TLE;
                    goto send_kill;
                case SIGXFSZ:
                    judge_status = JUDGE_OLE;
                    goto send_kill;
                default:
                    judge_status = JUDGE_SE;
                    goto send_kill;
            }

        }
    }

    return;
    send_kill:
        ptrace(PTRACE_KILL,pid,NULL,NULL);
}