Compare commits

...

2 Commits

Author SHA1 Message Date
667e7f35bc feat: allow to set write file limit 2024-04-27 21:22:04 +08:00
57ea5e13c8 feat: add support for go 2024-04-27 21:21:47 +08:00
10 changed files with 44 additions and 8 deletions

2
.idea/.gitignore vendored
View File

@ -6,3 +6,5 @@
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# GitHub Copilot persisted chat sessions
/copilot/chatSessions

View File

@ -5,9 +5,8 @@ if [ -d ./libseccomp ]; then exit 0; fi
set -x
git clone https://github.com/seccomp/libseccomp.git >/dev/null 2>&1 || exit 1
git clone -b "$VERSION" https://github.com/seccomp/libseccomp.git >/dev/null 2>&1 || exit 1
cd libseccomp || exit 1
git checkout $VERSION >/dev/null 2>&1
./autogen.sh >/dev/null 2>&1 || exit 1
./configure --enable-shared=no >/dev/null 2>&1 || exit 1
make -j >/dev/null 2>&1 || exit 1

View File

@ -23,6 +23,7 @@ void print_help(char *self) {
LOG_WARN(" --memory_limit memory limit in MB");
LOG_WARN(" --nproc_limit number of processes limit");
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_action sandbox action");
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_NPROC_LIMIT] = {"nproc_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_ACTION] = {"sandbox_action", required_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) {
if (c != 0) break;
if (idx < CFG_IS_VALID)
if (idx < CFG_IS_VALID) {
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]);
exit(0);
}

View File

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

View File

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

View File

@ -22,11 +22,12 @@ void setup_rlimit(char *config[CFG_IS_VALID + 1]) {
char *mem_limit_str = config[CFG_MEMORY_LIMIT]; // in mb
char *nproc_limit_str = config[CFG_NPROC_LIMIT];
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) {
// convert to bytes and double the memory limit
// convert to bytes
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;
}
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_NPROC, nproc_limit, "nproc", "processes"); // per user, **not** subprocess
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_TIME "LIMIT_TIME"
#define LIMIT_NPROC "LIMIT_NPROC"
#define LIMIT_FSIZE "LIMIT_FSIZE"
void setup_rlimit(char *config[CFG_IS_VALID + 1]);

View File

@ -8,8 +8,11 @@ void setup_lang_go(scmp_filter_ctx ctx) {
SCMP_SYS(rt_sigprocmask), // 14
SCMP_SYS(madvise), // 28
SCMP_SYS(clone), // 56
SCMP_SYS(fcntl), // 72
SCMP_SYS(getrlimit), // 97
SCMP_SYS(sigaltstack), // 131
SCMP_SYS(gettid), // 186
SCMP_SYS(futex), // 202
SCMP_SYS(sched_getaffinity), // 204
};
ADD_RULE_LIST(white, SCMP_ACT_ALLOW);

View File

@ -46,7 +46,6 @@ void setup_common(scmp_filter_ctx ctx, const char *exe_path) {
SCMP_SYS(exit_group), // 231
SCMP_SYS(newfstatat), // 262
SCMP_SYS(getrandom), // 318
};
ADD_RULE_LIST(white, SCMP_ACT_ALLOW);
}

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
int main() {
@ -79,6 +96,7 @@ int main() {
case 6: LOG_AND_EXECUTE(block1); break;
case 7: LOG_AND_EXECUTE(block2); break;
case 8: LOG_AND_EXECUTE(nproc); break;
case 9: LOG_AND_EXECUTE(fsize); break;
default: {
LOG_INFO("NO TEST SPECIFIED");
break;