From 359a2fe2c301275cf0c1e7b88fe3d910de92324e Mon Sep 17 00:00:00 2001 From: MeiK Date: Thu, 3 Sep 2020 18:39:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A2=99=E4=B8=8A=E6=97=B6?= =?UTF-8?q?=E9=92=9F=E9=99=90=E5=88=B6=EF=BC=8C=E9=98=B2=E6=AD=A2=E5=8D=A1?= =?UTF-8?q?=E8=AF=84=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/judger.rs | 8 ++++--- src/process.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/judger.rs b/src/judger.rs index cf1b2c9..51fb7bc 100644 --- a/src/judger.rs +++ b/src/judger.rs @@ -55,10 +55,11 @@ pub async fn judger(request: &JudgeRequest, path: &Path) -> Result Result libc::c_int; +} + fn run(process: Process) { // 子进程里崩溃也无法返回,崩溃就直接崩溃了 let exec_args = ExecArgs::build(&process.cmd).unwrap(); // 修改工作目录 env::set_current_dir(process.workdir).unwrap(); + let mut rl = libc::rlimit { + rlim_cur: 0, + rlim_max: 0, + }; + // 实际运行时间限制设置为 CPU 时间 + 2 * 2,尽量在防止恶意代码占用评测资源的情况下给正常用户的代码最宽松的环境 + let rt = libc::itimerval { + it_interval: libc::timeval { + tv_sec: 0, + tv_usec: 0, + }, + it_value: libc::timeval { + tv_sec: i64::from(process.time_limit / 1000 + 2) * 2, + tv_usec: 0, + }, + }; unsafe { - // TODO: 资源限制等 // 重定向文件描述符 if let Some(file) = process.stdin_file { let filename = file.to_str().unwrap(); @@ -196,6 +224,33 @@ fn run(process: Process) { libc::O_CREAT | libc::O_RDWR, 0o644, ); + // 墙上时钟限制 + if setitimer(ITIMER_REAL, &rt, ptr::null_mut()) == -1 { + eprintln!("setitimer failure!"); + eprintln!("{:?}", io::Error::last_os_error().raw_os_error()); + panic!("How dare you!"); + } + // CPU 时间限制,粒度为 S + rl.rlim_cur = (process.time_limit / 1000 + 1) as u64; + rl.rlim_max = rl.rlim_cur + 1; + if libc::setrlimit(libc::RLIMIT_CPU, &rl) != 0 { + eprintln!("setrlimit failure!"); + eprintln!("{:?}", io::Error::last_os_error().raw_os_error()); + panic!("How dare you!"); + } + // 设置内存限制 + rl.rlim_cur = (process.memory_limit * 1024) as u64; + rl.rlim_max = rl.rlim_cur + 1024; + if libc::setrlimit(libc::RLIMIT_DATA, &rl) != 0 { + eprintln!("setrlimit failure!"); + eprintln!("{:?}", io::Error::last_os_error().raw_os_error()); + panic!("How dare you!"); + } + if libc::setrlimit(libc::RLIMIT_AS, &rl) != 0 { + eprintln!("setrlimit failure!"); + eprintln!("{:?}", io::Error::last_os_error().raw_os_error()); + panic!("How dare you!"); + } libc::execve(exec_args.pathname, exec_args.argv, exec_args.envp); } panic!("How dare you!"); @@ -208,11 +263,13 @@ unsafe fn dup(filename: &str, to: libc::c_int, flag: libc::c_int, mode: libc::c_ if fd < 0 { let err = io::Error::last_os_error().raw_os_error(); eprintln!("open failure!"); + eprintln!("{:?}", io::Error::last_os_error().raw_os_error()); panic!(errno_str(err)); } if libc::dup2(fd, to) < 0 { let err = io::Error::last_os_error().raw_os_error(); eprintln!("dup2 failure!"); + eprintln!("{:?}", io::Error::last_os_error().raw_os_error()); panic!(errno_str(err)); } }