static result_t set_resource_limits(const resource_limits_t * const rl) { succeed_or_fail( set_resource_limit(RLIMIT_CORE, 0) && // disallow creation of core files set_resource_limit(RLIMIT_CPU, rl->max_cpu_time_in_seconds) && // set maximum number of CPU seconds set_resource_limit(RLIMIT_AS, rl->max_memory_in_bytes) // set maximum memory ); }
static int execute_target_process(char * const argv[]) { /* Create a new process group for pid, and the process tree it may spawn. We * do this, because later on we might want to kill pid _and_ all processes * spawned by it and its descendants. */ setpgid(0, 0); /* Redirect the standard input, if requested. */ if (g_target_redirect_input) { FILE *fp = fopen(g_target_redirect_input, "r"); if (!fp) { perror("fopen"); return EXITCODE_MONITORING_FAILURE; } int fd = fileno(fp); if (dup2(fd, 0) < 0) { perror("dup2"); return EXITCODE_MONITORING_FAILURE; } fclose(fp); } /* Redirect the standard output, if requested. */ if (g_target_redirect_output) { FILE *fp = fopen(g_target_redirect_output, "w"); if (!fp) { perror("fopen"); return EXITCODE_MONITORING_FAILURE; } int fd = fileno(fp); if (dup2(fd, 1) < 0 || dup2(fd, 2) < 0) { perror("dup2"); return EXITCODE_MONITORING_FAILURE; } fclose(fp); } /* Honor any requested resource limits. */ if (g_target_cpu_limit != ~(rlim_t) 0) { set_resource_limit(RLIMIT_CPU, g_target_cpu_limit); } if (g_target_stack_size_limit != ~(rlim_t) 0) { set_resource_limit(RLIMIT_STACK, g_target_stack_size_limit); } if (g_target_data_size_limit != ~(rlim_t) 0) { set_resource_limit(RLIMIT_DATA, g_target_data_size_limit); } if (g_target_rss_size_limit != ~(rlim_t) 0) { set_resource_limit(RLIMIT_RSS, g_target_rss_size_limit); } if (g_target_file_size_limit != ~(rlim_t) 0) { set_resource_limit(RLIMIT_FSIZE, g_target_file_size_limit); } if (g_target_core_limit != ~(rlim_t) 0) { set_resource_limit(RLIMIT_CORE, g_target_core_limit); } if (g_target_file_count_limit != ~(rlim_t) 0) { set_resource_limit(RLIMIT_NOFILE, g_target_file_count_limit); } if (g_target_subprocess_count_limit != ~(rlim_t) 0) { set_resource_limit(RLIMIT_NPROC, g_target_subprocess_count_limit); } /* Honor the desired target execute directory. */ if (g_target_exec_directory) { if (chdir(g_target_exec_directory) < 0) { perror("chdir"); return EXITCODE_MONITORING_FAILURE; } } execvp(argv[0], argv); perror("execv"); if (errno == ENOENT) { return EXITCODE_EXEC_NOENTRY; } else if (errno == EACCES) { return EXITCODE_EXEC_NOPERMISSION; } return EXITCODE_EXEC_FAILURE; }