feat: allow to set write file limit

This commit is contained in:
Paul Pan 2024-04-27 21:22:04 +08:00
parent 57ea5e13c8
commit 667e7f35bc
6 changed files with 38 additions and 5 deletions

View File

@ -23,6 +23,7 @@ void print_help(char *self) {
LOG_WARN(" --memory_limit memory limit in MB"); LOG_WARN(" --memory_limit memory limit in MB");
LOG_WARN(" --nproc_limit number of processes limit"); LOG_WARN(" --nproc_limit number of processes limit");
LOG_WARN(" --time_limit time limit in ms"); LOG_WARN(" --time_limit time limit in ms");
LOG_WARN(" --fsize_limit write file size limit in MB");
LOG_WARN(" --sandbox_template sandbox template"); LOG_WARN(" --sandbox_template sandbox template");
LOG_WARN(" --sandbox_action sandbox action"); LOG_WARN(" --sandbox_action sandbox action");
LOG_WARN(" --uid user id"); LOG_WARN(" --uid user id");
@ -40,6 +41,7 @@ void parse(int argc, char *argv[]) {
[CFG_MEMORY_LIMIT] = {"memory_limit", required_argument, NULL, 0}, [CFG_MEMORY_LIMIT] = {"memory_limit", required_argument, NULL, 0},
[CFG_NPROC_LIMIT] = {"nproc_limit", required_argument, NULL, 0}, [CFG_NPROC_LIMIT] = {"nproc_limit", required_argument, NULL, 0},
[CFG_TIME_LIMIT] = {"time_limit", required_argument, NULL, 0}, [CFG_TIME_LIMIT] = {"time_limit", required_argument, NULL, 0},
[CFG_FSIZE_LIMIT] = {"fsize_limit", required_argument, NULL, 0},
[CFG_SANDBOX_TEMPLATE] = {"sandbox_template", required_argument, NULL, 0}, [CFG_SANDBOX_TEMPLATE] = {"sandbox_template", required_argument, NULL, 0},
[CFG_SANDBOX_ACTION] = {"sandbox_action", required_argument, NULL, 0}, [CFG_SANDBOX_ACTION] = {"sandbox_action", required_argument, NULL, 0},
[CFG_UID] = {"uid", optional_argument, NULL, 0}, [CFG_UID] = {"uid", optional_argument, NULL, 0},
@ -57,9 +59,10 @@ void parse(int argc, char *argv[]) {
while ((c = getopt_long_only(argc, argv, "", options, &idx)) != -1) { while ((c = getopt_long_only(argc, argv, "", options, &idx)) != -1) {
if (c != 0) break; if (c != 0) break;
if (idx < CFG_IS_VALID) if (idx < CFG_IS_VALID) {
config[idx] = optarg; config[idx] = optarg;
else if (idx == CFG_IS_VALID) { LOG_INFO("c = %d, x = %d, optarg = %s", c, idx, optarg);
} else if (idx == CFG_IS_VALID) {
print_help(argv[0]); print_help(argv[0]);
exit(0); exit(0);
} }

View File

@ -5,6 +5,7 @@ enum ConfigIndex {
CFG_MEMORY_LIMIT = 0, CFG_MEMORY_LIMIT = 0,
CFG_NPROC_LIMIT, CFG_NPROC_LIMIT,
CFG_TIME_LIMIT, CFG_TIME_LIMIT,
CFG_FSIZE_LIMIT,
CFG_SANDBOX_TEMPLATE, CFG_SANDBOX_TEMPLATE,
CFG_SANDBOX_ACTION, CFG_SANDBOX_ACTION,
CFG_UID, CFG_UID,

View File

@ -27,6 +27,7 @@ void setup_all(void) {
config[CFG_MEMORY_LIMIT] = getenv(LIMIT_MEMORY); config[CFG_MEMORY_LIMIT] = getenv(LIMIT_MEMORY);
config[CFG_NPROC_LIMIT] = getenv(LIMIT_NPROC); config[CFG_NPROC_LIMIT] = getenv(LIMIT_NPROC);
config[CFG_TIME_LIMIT] = getenv(LIMIT_TIME); config[CFG_TIME_LIMIT] = getenv(LIMIT_TIME);
config[CFG_FSIZE_LIMIT] = getenv(LIMIT_FSIZE);
config[CFG_SANDBOX_TEMPLATE] = getenv(SANDBOX_TEMPLATE); config[CFG_SANDBOX_TEMPLATE] = getenv(SANDBOX_TEMPLATE);
config[CFG_SANDBOX_ACTION] = getenv(SANDBOX_ACTION); config[CFG_SANDBOX_ACTION] = getenv(SANDBOX_ACTION);

View File

@ -21,12 +21,13 @@ void setup_rlimit(char *config[CFG_IS_VALID + 1]) {
char *mem_limit_str = config[CFG_MEMORY_LIMIT]; // in mb char *mem_limit_str = config[CFG_MEMORY_LIMIT]; // in mb
char *nproc_limit_str = config[CFG_NPROC_LIMIT]; char *nproc_limit_str = config[CFG_NPROC_LIMIT];
char *time_limit_str = config[CFG_TIME_LIMIT]; // in ms char *time_limit_str = config[CFG_TIME_LIMIT]; // in ms
char *fsize_limit_str = config[CFG_FSIZE_LIMIT]; // in mb
long mem_limit = 0, nproc_limit = 0, time_limit = 0; long mem_limit = 0, nproc_limit = 0, time_limit = 0, fsize_limit = 0;
if (mem_limit_str) { if (mem_limit_str) {
// convert to bytes and double the memory limit // convert to bytes
mem_limit = strtol(mem_limit_str, NULL, 10) * 1024 * 1024; mem_limit = strtol(mem_limit_str, NULL, 10) * 1024 * 1024;
} }
@ -39,7 +40,15 @@ void setup_rlimit(char *config[CFG_IS_VALID + 1]) {
time_limit = limit ? (limit + 1000) / 1000 : 0; time_limit = limit ? (limit + 1000) / 1000 : 0;
} }
if (fsize_limit_str) {
// convert to bytes
fsize_limit = strtol(fsize_limit_str, NULL, 10) * 1024 * 1024;
}
SET_LIMIT(RLIMIT_AS, mem_limit, "memory", "bytes"); SET_LIMIT(RLIMIT_AS, mem_limit, "memory", "bytes");
SET_LIMIT(RLIMIT_NPROC, nproc_limit, "nproc", "processes"); // per user, **not** subprocess SET_LIMIT(RLIMIT_NPROC, nproc_limit, "nproc", "processes"); // per user, **not** subprocess
SET_LIMIT(RLIMIT_CPU, time_limit, "time", "seconds"); // except blocked time SET_LIMIT(RLIMIT_CPU, time_limit, "time", "seconds"); // except blocked time
SET_LIMIT(RLIMIT_FSIZE, fsize_limit, "fsize", "bytes");
SET_LIMIT(RLIMIT_CORE, 0, "coredump", "bytes"); // disable core dump
} }

View File

@ -7,6 +7,7 @@
#define LIMIT_MEMORY "LIMIT_MEMORY" #define LIMIT_MEMORY "LIMIT_MEMORY"
#define LIMIT_TIME "LIMIT_TIME" #define LIMIT_TIME "LIMIT_TIME"
#define LIMIT_NPROC "LIMIT_NPROC" #define LIMIT_NPROC "LIMIT_NPROC"
#define LIMIT_FSIZE "LIMIT_FSIZE"
void setup_rlimit(char *config[CFG_IS_VALID + 1]); void setup_rlimit(char *config[CFG_IS_VALID + 1]);

18
test.c
View File

@ -64,6 +64,23 @@ void do_nproc() {
} }
} }
void do_fsize() {
FILE *fp = fopen("test.dat", "w");
if (fp == NULL) {
LOG_ERR("FAIL: fopen failed");
return;
}
for (int i = 0; i < 1 << 30; i++) {
if (fputc('a', fp) == EOF) {
LOG_INFO("OK: fputc failed: i=%d", i);
break;
}
}
fclose(fp);
}
#pragma GCC pop_options #pragma GCC pop_options
int main() { int main() {
@ -79,6 +96,7 @@ int main() {
case 6: LOG_AND_EXECUTE(block1); break; case 6: LOG_AND_EXECUTE(block1); break;
case 7: LOG_AND_EXECUTE(block2); break; case 7: LOG_AND_EXECUTE(block2); break;
case 8: LOG_AND_EXECUTE(nproc); break; case 8: LOG_AND_EXECUTE(nproc); break;
case 9: LOG_AND_EXECUTE(fsize); break;
default: { default: {
LOG_INFO("NO TEST SPECIFIED"); LOG_INFO("NO TEST SPECIFIED");
break; break;