mirror of
https://github.com/QingdaoU/Judger.git
synced 2024-12-29 16:31:42 +00:00
修复了不能同时写入多个log文件的问题
- 全局变量只会被初始化一次,所以下次使用的时候log文件处于打开状态 - 去掉全部的全局变量,使用传入文件指针的方式打开文件 - flock函数可以防止多线程和多进程对文件的并发修改
This commit is contained in:
parent
f2e1b01392
commit
7fa58f5d72
@ -13,8 +13,8 @@ def _compile():
|
|||||||
max_memory=judger.MEMORY_UNLIMITED,
|
max_memory=judger.MEMORY_UNLIMITED,
|
||||||
args=[os.path.join(base_path, "demo.c"), "-o", os.path.join(base_path, "demo")],
|
args=[os.path.join(base_path, "demo.c"), "-o", os.path.join(base_path, "demo")],
|
||||||
env=["PATH=" + os.environ["PATH"]],
|
env=["PATH=" + os.environ["PATH"]],
|
||||||
|
log_path="compile.log",
|
||||||
use_sandbox=False,
|
use_sandbox=False,
|
||||||
log_path="test.log",
|
|
||||||
use_nobody=False)
|
use_nobody=False)
|
||||||
|
|
||||||
|
|
||||||
@ -28,9 +28,10 @@ def run(use_sandbox, use_nobody):
|
|||||||
max_cpu_time=2000,
|
max_cpu_time=2000,
|
||||||
# Byte
|
# Byte
|
||||||
max_memory=200000000,
|
max_memory=200000000,
|
||||||
# args and env are optional
|
# args env and log_path are optional
|
||||||
args=["1", "2", "####"],
|
args=["1", "2", "####"],
|
||||||
env=["aaa=123"],
|
env=["aaa=123"],
|
||||||
|
log_path="run.log",
|
||||||
# default is True
|
# default is True
|
||||||
use_sandbox=use_sandbox,
|
use_sandbox=use_sandbox,
|
||||||
use_nobody=use_nobody)
|
use_nobody=use_nobody)
|
||||||
|
110
logger.h
110
logger.h
@ -1,33 +1,3 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* LOGGER v0.0.3
|
|
||||||
* A simple logger for c/c++ under linux, multiprocess-safe
|
|
||||||
*
|
|
||||||
* ---- CopyLeft by Felix021 @ http://www.felix021.com ----
|
|
||||||
*
|
|
||||||
* LOG Format:
|
|
||||||
* --LEVEL_NOTE--\x7 [Y-m-d H:m:s]\x7 [FILE:LINE]\x7 [EXTRA_INFO]\x7 log_info
|
|
||||||
* // LEVEL_NOTE stands for one of DEBUG/TRACE/NOTICE...
|
|
||||||
* // \x7 is a special character to separate logged fields.
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* //Open log file first. Supply a log file name.
|
|
||||||
* log_open("log.txt");
|
|
||||||
*
|
|
||||||
* //use it just as printf
|
|
||||||
* LOG_INFO("some info %d", 123);
|
|
||||||
*
|
|
||||||
* //6 level: DEBUG, TRACE, NOTICE, MONITOR, WARNING, FATAL
|
|
||||||
* LOG_DEBUG("hi there");
|
|
||||||
*
|
|
||||||
* //Need EXTRA_INFO to be logged automatically?
|
|
||||||
* log_add_info("pid:123");
|
|
||||||
*
|
|
||||||
* //You don't need to call log_close manually, it'll be called at exit
|
|
||||||
* log_close();
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LOGGER__
|
#ifndef __LOGGER__
|
||||||
#define __LOGGER__
|
#define __LOGGER__
|
||||||
|
|
||||||
@ -40,10 +10,9 @@
|
|||||||
#include <error.h>
|
#include <error.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
|
|
||||||
int log_open(const char *filename);
|
FILE* log_open(const char *);
|
||||||
void log_close(void);
|
void log_close(FILE*);
|
||||||
static void log_write(int, const char *, const int, const char *, ...);
|
static void log_write(int level, const char* source_filename, const int line_number, const FILE* log_fp, const char*, ...);
|
||||||
void log_add_info(const char *info);
|
|
||||||
|
|
||||||
const int LOG_FATAL = 0;
|
const int LOG_FATAL = 0;
|
||||||
const int LOG_WARNING = 1;
|
const int LOG_WARNING = 1;
|
||||||
@ -51,65 +20,40 @@ const int LOG_INFO = 2;
|
|||||||
const int LOG_DEBUG = 3;
|
const int LOG_DEBUG = 3;
|
||||||
static char LOG_LEVEL_NOTE[][10] =
|
static char LOG_LEVEL_NOTE[][10] =
|
||||||
{ "FATAL", "WARNING", "INFO", "DEBUG" };
|
{ "FATAL", "WARNING", "INFO", "DEBUG" };
|
||||||
#define LOG_DEBUG(x...) log_write(LOG_DEBUG, __FILE__, __LINE__, ##x)
|
#define LOG_DEBUG(log_fp, x...) log_write(LOG_DEBUG, __FILE__, __LINE__, log_fp, ##x)
|
||||||
#define LOG_INFO(x...) log_write(LOG_INFO, __FILE__ __LINE__, ##x)
|
#define LOG_INFO(log_fp, x...) log_write(LOG_INFO, __FILE__ __LINE__, log_fp, ##x)
|
||||||
#define LOG_WARNING(x...) log_write(LOG_WARNING, __FILE__, __LINE__, ##x)
|
#define LOG_WARNING(log_fp, x...) log_write(LOG_WARNING, __FILE__, __LINE__, log_fp, ##x)
|
||||||
#define LOG_FATAL(x...) log_write(LOG_FATAL, __FILE__, __LINE__, ##x)
|
#define LOG_FATAL(log_fp, x...) log_write(LOG_FATAL, __FILE__, __LINE__, log_fp, ##x)
|
||||||
|
|
||||||
|
|
||||||
static FILE *log_fp = NULL;
|
|
||||||
static char *log_filename = NULL;
|
|
||||||
static int log_opened = 0;
|
|
||||||
|
|
||||||
#define log_buffer_size 8192
|
#define log_buffer_size 8192
|
||||||
static char log_buffer[log_buffer_size];
|
|
||||||
static char log_extra_info[log_buffer_size];
|
|
||||||
|
|
||||||
int log_open(const char* filename)
|
FILE* log_open(const char* filename)
|
||||||
{
|
{
|
||||||
if (log_opened == 1)
|
FILE* log_fp = fopen(filename, "a");
|
||||||
{
|
|
||||||
fprintf(stderr, "logger: log already opened\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int len = strlen(filename);
|
|
||||||
log_filename = (char *)malloc(sizeof(char) * len + 1);
|
|
||||||
strcpy(log_filename, filename);
|
|
||||||
log_fp = fopen(log_filename, "a");
|
|
||||||
if (log_fp == NULL)
|
if (log_fp == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "log_file: %s", log_filename);
|
fprintf(stderr, "can not open log file %s", filename);
|
||||||
perror("can't not open log file");
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
return log_fp;
|
||||||
atexit(log_close);
|
|
||||||
log_opened = 1;
|
|
||||||
log_extra_info[0] = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_close(void)
|
void log_close(FILE* log_fp)
|
||||||
{
|
{
|
||||||
if (log_opened)
|
if (log_fp != NULL)
|
||||||
{
|
{
|
||||||
fclose(log_fp);
|
fclose(log_fp);
|
||||||
free(log_filename);
|
|
||||||
log_fp = NULL;
|
|
||||||
log_filename = NULL;
|
|
||||||
log_opened = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_write(int level, const char *file,
|
static void log_write(int level, const char* source_filename, const int line, const FILE* log_fp, const char *fmt, ...)
|
||||||
const int line, const char *fmt, ...)
|
|
||||||
{
|
{
|
||||||
if (log_opened == 0)
|
if (log_fp == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "log_open not called yet\n");
|
fprintf(stderr, "can not open log file");
|
||||||
exit(1);
|
return;
|
||||||
}
|
}
|
||||||
static char buffer[log_buffer_size];
|
static char buffer[log_buffer_size];
|
||||||
|
static char log_buffer[log_buffer_size];
|
||||||
static char datetime[100];
|
static char datetime[100];
|
||||||
static char line_str[20];
|
static char line_str[20];
|
||||||
static time_t now;
|
static time_t now;
|
||||||
@ -123,30 +67,24 @@ static void log_write(int level, const char *file,
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
size_t count = snprintf(buffer, log_buffer_size,
|
size_t count = snprintf(buffer, log_buffer_size,
|
||||||
"%s [%s] [%s:%d]%s %s\n",
|
"%s [%s] [%s:%d]%s\n",
|
||||||
LOG_LEVEL_NOTE[level], datetime, file, line, log_extra_info, log_buffer);
|
LOG_LEVEL_NOTE[level], datetime, source_filename, line, log_buffer);
|
||||||
fprintf(stdout, "%s", buffer);
|
fprintf(stdout, "%s", buffer);
|
||||||
int log_fd = log_fp->_fileno;
|
int log_fd = log_fp->_fileno;
|
||||||
if (flock(log_fd, LOCK_EX) == 0)
|
if (flock(log_fd, LOCK_EX) == 0)
|
||||||
{
|
{
|
||||||
if (write(log_fd, buffer, count) < 0)
|
if (write(log_fd, buffer, count) < 0)
|
||||||
{
|
{
|
||||||
perror("write error");
|
fprintf(stderr, "write error");
|
||||||
exit(1);
|
return;
|
||||||
}
|
}
|
||||||
flock(log_fd, LOCK_UN);
|
flock(log_fd, LOCK_UN);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
perror("flock error");
|
fprintf(stderr, "flock error");
|
||||||
exit(1);
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_add_info(const char *info)
|
|
||||||
{
|
|
||||||
int len = strlen(log_extra_info);
|
|
||||||
snprintf(log_extra_info + len, log_buffer_size - len, "\n [%s]", info);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
88
runner.c
88
runner.c
@ -21,7 +21,6 @@ int set_timer(int sec, int ms, int is_cpu_time) {
|
|||||||
time_val.it_value.tv_sec = sec;
|
time_val.it_value.tv_sec = sec;
|
||||||
time_val.it_value.tv_usec = ms * 1000;
|
time_val.it_value.tv_usec = ms * 1000;
|
||||||
if (setitimer(is_cpu_time ? ITIMER_VIRTUAL : ITIMER_REAL, &time_val, NULL)) {
|
if (setitimer(is_cpu_time ? ITIMER_VIRTUAL : ITIMER_REAL, &time_val, NULL)) {
|
||||||
LOG_FATAL("setitimer failed, errno %d", errno);
|
|
||||||
return SETITIMER_FAILED;
|
return SETITIMER_FAILED;
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
@ -35,6 +34,7 @@ void run(struct config *config, struct result *result) {
|
|||||||
struct rlimit memory_limit;
|
struct rlimit memory_limit;
|
||||||
int signal;
|
int signal;
|
||||||
int i;
|
int i;
|
||||||
|
FILE* log_fp;
|
||||||
struct passwd *passwd = getpwnam("nobody");
|
struct passwd *passwd = getpwnam("nobody");
|
||||||
FILE *in_file, *out_file;
|
FILE *in_file, *out_file;
|
||||||
int syscalls_whitelist[] = {SCMP_SYS(read), SCMP_SYS(fstat),
|
int syscalls_whitelist[] = {SCMP_SYS(read), SCMP_SYS(fstat),
|
||||||
@ -47,7 +47,11 @@ void run(struct config *config, struct result *result) {
|
|||||||
int syscalls_whitelist_length = sizeof(syscalls_whitelist) / sizeof(int);
|
int syscalls_whitelist_length = sizeof(syscalls_whitelist) / sizeof(int);
|
||||||
scmp_filter_ctx ctx = NULL;
|
scmp_filter_ctx ctx = NULL;
|
||||||
|
|
||||||
log_open(config->log_path);
|
log_fp = log_open(config->log_path);
|
||||||
|
if(log_fp == NULL){
|
||||||
|
result->flag = SYSTEM_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#warning "setrlimit with RLIMIT_AS to limit memory usage will not work on OSX"
|
#warning "setrlimit with RLIMIT_AS to limit memory usage will not work on OSX"
|
||||||
@ -56,21 +60,24 @@ void run(struct config *config, struct result *result) {
|
|||||||
gettimeofday(&start, NULL);
|
gettimeofday(&start, NULL);
|
||||||
|
|
||||||
if(config->max_memory < 1 && config->max_memory != MEMORY_UNLIMITED) {
|
if(config->max_memory < 1 && config->max_memory != MEMORY_UNLIMITED) {
|
||||||
LOG_FATAL("max_memory must > 1 or unlimited");
|
LOG_FATAL(log_fp, "max_memory must > 1 or unlimited");
|
||||||
result->flag = SYSTEM_ERROR;
|
result->flag = SYSTEM_ERROR;
|
||||||
|
log_close(log_fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(config->max_cpu_time < 1 && config->max_cpu_time != CPU_TIME_UNLIMITED) {
|
if(config->max_cpu_time < 1 && config->max_cpu_time != CPU_TIME_UNLIMITED) {
|
||||||
LOG_FATAL("max_cpu_time must > 1 or unlimited");
|
LOG_FATAL(log_fp, "max_cpu_time must > 1 or unlimited");
|
||||||
result->flag = SYSTEM_ERROR;
|
result->flag = SYSTEM_ERROR;
|
||||||
|
log_close(log_fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_file = fopen(config->in_file, "r");
|
in_file = fopen(config->in_file, "r");
|
||||||
out_file = fopen(config->out_file, "w");
|
out_file = fopen(config->out_file, "w");
|
||||||
if(in_file == NULL || out_file == NULL) {
|
if(in_file == NULL || out_file == NULL) {
|
||||||
LOG_FATAL("failed to open in/out redirect file");
|
LOG_FATAL(log_fp, "failed to open in/out redirect file");
|
||||||
result->flag = SYSTEM_ERROR;
|
result->flag = SYSTEM_ERROR;
|
||||||
|
log_close(log_fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,8 +85,9 @@ void run(struct config *config, struct result *result) {
|
|||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
|
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
LOG_FATAL("fork failed");
|
LOG_FATAL(log_fp, "fork failed");
|
||||||
result->flag = SYSTEM_ERROR;
|
result->flag = SYSTEM_ERROR;
|
||||||
|
log_close(log_fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,11 +97,12 @@ void run(struct config *config, struct result *result) {
|
|||||||
// on success, returns the process ID of the child whose state has changed;
|
// on success, returns the process ID of the child whose state has changed;
|
||||||
// On error, -1 is returned.
|
// On error, -1 is returned.
|
||||||
if (wait4(pid, &status, 0, &resource_usage) == -1) {
|
if (wait4(pid, &status, 0, &resource_usage) == -1) {
|
||||||
LOG_FATAL("wait4 failed");
|
LOG_FATAL(log_fp, "wait4 failed");
|
||||||
result->flag = SYSTEM_ERROR;
|
result->flag = SYSTEM_ERROR;
|
||||||
|
log_close(log_fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_DEBUG("exit status: %d", WEXITSTATUS(status));
|
LOG_DEBUG(log_fp, "exit status: %d", WEXITSTATUS(status));
|
||||||
result->exit_status = WEXITSTATUS(status);
|
result->exit_status = WEXITSTATUS(status);
|
||||||
result->cpu_time = (int) (resource_usage.ru_utime.tv_sec * 1000 +
|
result->cpu_time = (int) (resource_usage.ru_utime.tv_sec * 1000 +
|
||||||
resource_usage.ru_utime.tv_usec / 1000 +
|
resource_usage.ru_utime.tv_usec / 1000 +
|
||||||
@ -115,7 +124,7 @@ void run(struct config *config, struct result *result) {
|
|||||||
|
|
||||||
if (WIFSIGNALED(status) != 0) {
|
if (WIFSIGNALED(status) != 0) {
|
||||||
signal = WTERMSIG(status);
|
signal = WTERMSIG(status);
|
||||||
LOG_DEBUG("signal: %d", signal);
|
LOG_DEBUG(log_fp, "signal: %d", signal);
|
||||||
result->signal = signal;
|
result->signal = signal;
|
||||||
if (signal == SIGALRM) {
|
if (signal == SIGALRM) {
|
||||||
result->flag = REAL_TIME_LIMIT_EXCEEDED;
|
result->flag = REAL_TIME_LIMIT_EXCEEDED;
|
||||||
@ -157,20 +166,20 @@ void run(struct config *config, struct result *result) {
|
|||||||
if (config->max_memory != MEMORY_UNLIMITED) {
|
if (config->max_memory != MEMORY_UNLIMITED) {
|
||||||
memory_limit.rlim_cur = memory_limit.rlim_max = (rlim_t) (config->max_memory) * 2;
|
memory_limit.rlim_cur = memory_limit.rlim_max = (rlim_t) (config->max_memory) * 2;
|
||||||
if (setrlimit(RLIMIT_AS, &memory_limit) == -1) {
|
if (setrlimit(RLIMIT_AS, &memory_limit) == -1) {
|
||||||
LOG_FATAL("setrlimit failed, errno: %d", errno);
|
LOG_FATAL(log_fp, "setrlimit failed, errno: %d", errno);
|
||||||
ERROR(SETRLIMIT_FAILED);
|
ERROR(log_fp, SETRLIMIT_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (config->max_cpu_time != CPU_TIME_UNLIMITED) {
|
if (config->max_cpu_time != CPU_TIME_UNLIMITED) {
|
||||||
// cpu time
|
// cpu time
|
||||||
if (set_timer(config->max_cpu_time / 1000, config->max_cpu_time % 1000, 1) != SUCCESS) {
|
if (set_timer(config->max_cpu_time / 1000, config->max_cpu_time % 1000, 1) != SUCCESS) {
|
||||||
LOG_FATAL("set cpu time timer failed");
|
LOG_FATAL(log_fp, "set cpu time timer failed");
|
||||||
ERROR(SETITIMER_FAILED);
|
ERROR(log_fp, SETITIMER_FAILED);
|
||||||
}
|
}
|
||||||
// real time * 3
|
// real time * 3
|
||||||
if (set_timer(config->max_cpu_time / 1000 * 3, (config->max_cpu_time % 1000) * 3 % 1000, 0) != SUCCESS) {
|
if (set_timer(config->max_cpu_time / 1000 * 3, (config->max_cpu_time % 1000) * 3 % 1000, 0) != SUCCESS) {
|
||||||
LOG_FATAL("set real time timer failed");
|
LOG_FATAL(log_fp, "set real time timer failed");
|
||||||
ERROR(SETITIMER_FAILED);
|
ERROR(log_fp, SETITIMER_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,32 +187,32 @@ void run(struct config *config, struct result *result) {
|
|||||||
// On success, these system calls return the new descriptor.
|
// On success, these system calls return the new descriptor.
|
||||||
// On error, -1 is returned, and errno is set appropriately.
|
// On error, -1 is returned, and errno is set appropriately.
|
||||||
if (dup2(fileno(in_file), 0) == -1) {
|
if (dup2(fileno(in_file), 0) == -1) {
|
||||||
LOG_FATAL("dup2 stdin failed, errno: %d", errno);
|
LOG_FATAL(log_fp, "dup2 stdin failed, errno: %d", errno);
|
||||||
ERROR(DUP2_FAILED);
|
ERROR(log_fp, DUP2_FAILED);
|
||||||
}
|
}
|
||||||
// write stdout to out file
|
// write stdout to out file
|
||||||
if (dup2(fileno(out_file), 1) == -1) {
|
if (dup2(fileno(out_file), 1) == -1) {
|
||||||
LOG_FATAL("dup2 stdout failed, errno: %d", errno);
|
LOG_FATAL(log_fp, "dup2 stdout failed, errno: %d", errno);
|
||||||
ERROR(DUP2_FAILED);
|
ERROR(log_fp, DUP2_FAILED);
|
||||||
}
|
}
|
||||||
// redirect stderr to stdout
|
// redirect stderr to stdout
|
||||||
if (dup2(fileno(stdout), fileno(stderr)) == -1) {
|
if (dup2(fileno(stdout), fileno(stderr)) == -1) {
|
||||||
LOG_FATAL("dup2 stderr failed, errno: %d", errno);
|
LOG_FATAL(log_fp, "dup2 stderr failed, errno: %d", errno);
|
||||||
ERROR(DUP2_FAILED);
|
ERROR(log_fp, DUP2_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->use_nobody != 0) {
|
if (config->use_nobody != 0) {
|
||||||
if(passwd == NULL) {
|
if(passwd == NULL) {
|
||||||
LOG_FATAL("get nobody user info failed, errno: %d", errno);
|
LOG_FATAL(log_fp, "get nobody user info failed, errno: %d", errno);
|
||||||
ERROR(SET_UID_FAILED);
|
ERROR(log_fp, SET_UID_FAILED);
|
||||||
}
|
}
|
||||||
if (setgid(passwd->pw_gid) == -1) {
|
if (setgid(passwd->pw_gid) == -1) {
|
||||||
LOG_FATAL("setgid failed, errno: %d", errno);
|
LOG_FATAL(log_fp, "setgid failed, errno: %d", errno);
|
||||||
ERROR(SET_GID_FAILED);
|
ERROR(log_fp, SET_GID_FAILED);
|
||||||
}
|
}
|
||||||
if (setuid(passwd->pw_uid) == -1) {
|
if (setuid(passwd->pw_uid) == -1) {
|
||||||
LOG_FATAL("setuid failed, errno: %d", errno);
|
LOG_FATAL(log_fp, "setuid failed, errno: %d", errno);
|
||||||
ERROR(SET_UID_FAILED);
|
ERROR(log_fp, SET_UID_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,33 +220,34 @@ void run(struct config *config, struct result *result) {
|
|||||||
// load seccomp rules
|
// load seccomp rules
|
||||||
ctx = seccomp_init(SCMP_ACT_KILL);
|
ctx = seccomp_init(SCMP_ACT_KILL);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
LOG_FATAL("init seccomp failed");
|
LOG_FATAL(log_fp, "init seccomp failed");
|
||||||
ERROR(LOAD_SECCOMP_FAILED);
|
ERROR(log_fp, LOAD_SECCOMP_FAILED);
|
||||||
}
|
}
|
||||||
for (i = 0; i < syscalls_whitelist_length; i++) {
|
for (i = 0; i < syscalls_whitelist_length; i++) {
|
||||||
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls_whitelist[i], 0) != 0) {
|
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls_whitelist[i], 0) != 0) {
|
||||||
LOG_FATAL("load syscall white list failed");
|
LOG_FATAL(log_fp, "load syscall white list failed");
|
||||||
ERROR(LOAD_SECCOMP_FAILED);
|
ERROR(log_fp, LOAD_SECCOMP_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add extra rule for execve
|
// add extra rule for execve
|
||||||
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(execve), 1, SCMP_A0(SCMP_CMP_EQ, config->path)) != 0) {
|
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(execve), 1, SCMP_A0(SCMP_CMP_EQ, config->path)) != 0) {
|
||||||
LOG_FATAL("load execve rule failed");
|
LOG_FATAL(log_fp, "load execve rule failed");
|
||||||
ERROR(LOAD_SECCOMP_FAILED);
|
ERROR(log_fp, LOAD_SECCOMP_FAILED);
|
||||||
}
|
}
|
||||||
// only fd 0 1 2 are allowed
|
// only fd 0 1 2 are allowed
|
||||||
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_LE, 2)) != 0) {
|
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_LE, 2)) != 0) {
|
||||||
LOG_FATAL("load dup2 rule failed");
|
LOG_FATAL(log_fp, "load dup2 rule failed");
|
||||||
ERROR(LOAD_SECCOMP_FAILED);
|
ERROR(log_fp, LOAD_SECCOMP_FAILED);
|
||||||
}
|
}
|
||||||
if (seccomp_load(ctx) != 0) {
|
if (seccomp_load(ctx) != 0) {
|
||||||
LOG_FATAL("seccomp load failed");
|
LOG_FATAL(log_fp, "seccomp load failed");
|
||||||
ERROR(LOAD_SECCOMP_FAILED);
|
ERROR(log_fp, LOAD_SECCOMP_FAILED);
|
||||||
}
|
}
|
||||||
seccomp_release(ctx);
|
seccomp_release(ctx);
|
||||||
}
|
}
|
||||||
execve(config->path, config->args, config->env);
|
execve(config->path, config->args, config->env);
|
||||||
LOG_FATAL("execve failed, errno: %d", errno);
|
LOG_FATAL(log_fp, "execve failed, errno: %d", errno);
|
||||||
ERROR(EXCEVE_FAILED);
|
ERROR(log_fp, EXCEVE_FAILED);
|
||||||
}
|
}
|
||||||
|
log_close(log_fp);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user