From e8685de73159e005a84d3e756767c6d2db943e2e Mon Sep 17 00:00:00 2001 From: startx2017 Date: Tue, 24 Oct 2017 12:41:42 -0400 Subject: implemented --rlimit-cpu - set max CPU time for processes running in the sandbox; for issue #1614, more to come... --- src/firejail/firejail.h | 2 ++ src/firejail/main.c | 6 ++++++ src/firejail/profile.c | 5 +++++ src/firejail/rlimit.c | 12 ++++++++++++ src/firejail/usage.c | 1 + src/man/firejail-profile.txt | 3 +++ src/man/firejail.txt | 9 +++++++++ 7 files changed, 38 insertions(+) diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 008f4ad08..1b399ba10 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -249,6 +249,7 @@ typedef struct config_t { char *protocol; // protocol list // rlimits + long long unsigned rlimit_cpu; long long unsigned rlimit_nofile; long long unsigned rlimit_nproc; long long unsigned rlimit_fsize; @@ -324,6 +325,7 @@ extern char *arg_caps_list; // optional caps list extern int arg_trace; // syscall tracing support extern int arg_tracelog; // blacklist tracing support +extern int arg_rlimit_cpu; // rlimit cpu extern int arg_rlimit_nofile; // rlimit nofile extern int arg_rlimit_nproc; // rlimit nproc extern int arg_rlimit_fsize; // rlimit fsize diff --git a/src/firejail/main.c b/src/firejail/main.c index fef333601..04900d6f9 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -67,6 +67,7 @@ char *arg_caps_list = NULL; // optional caps list int arg_trace = 0; // syscall tracing support int arg_tracelog = 0; // blacklist tracing support +int arg_rlimit_cpu = 0; // rlimit max cpu time int arg_rlimit_nofile = 0; // rlimit nofile int arg_rlimit_nproc = 0; // rlimit nproc int arg_rlimit_fsize = 0; // rlimit fsize @@ -1259,6 +1260,11 @@ int main(int argc, char **argv) { arg_trace = 1; else if (strcmp(argv[i], "--tracelog") == 0) arg_tracelog = 1; + else if (strncmp(argv[i], "--rlimit-cpu=", 13) == 0) { + check_unsigned(argv[i] + 13, "Error: invalid rlimit"); + sscanf(argv[i] + 13, "%llu", &cfg.rlimit_cpu); + arg_rlimit_cpu = 1; + } else if (strncmp(argv[i], "--rlimit-nofile=", 16) == 0) { check_unsigned(argv[i] + 16, "Error: invalid rlimit"); sscanf(argv[i] + 16, "%llu", &cfg.rlimit_nofile); diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 622306c22..9f49d7405 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -1022,6 +1022,11 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { sscanf(ptr + 14, "%llu", &cfg.rlimit_nofile); arg_rlimit_nofile = 1; } + else if (strncmp(ptr, "rlimit-cpu ", 11) == 0) { + check_unsigned(ptr + 11, "Error: invalid rlimit in profile file: "); + sscanf(ptr + 11, "%llu", &cfg.rlimit_cpu); + arg_rlimit_cpu = 1; + } else if (strncmp(ptr, "rlimit-nproc ", 13) == 0) { check_unsigned(ptr + 13, "Error: invalid rlimit in profile file: "); sscanf(ptr + 13, "%llu", &cfg.rlimit_nproc); diff --git a/src/firejail/rlimit.c b/src/firejail/rlimit.c index e5720a22b..7206c2cce 100644 --- a/src/firejail/rlimit.c +++ b/src/firejail/rlimit.c @@ -24,6 +24,18 @@ void set_rlimits(void) { // resource limits struct rlimit rl; + if (arg_rlimit_cpu) { + rl.rlim_cur = (rlim_t) cfg.rlimit_cpu; + rl.rlim_max = (rlim_t) cfg.rlimit_cpu; +#ifdef HAVE_GCOV + __gcov_dump(); +#endif + if (setrlimit(RLIMIT_CPU, &rl) == -1) + errExit("setrlimit"); + if (arg_debug) + printf("Config rlimit: max cpu time %llu\n", cfg.rlimit_cpu); + } + if (arg_rlimit_nofile) { rl.rlim_cur = (rlim_t) cfg.rlimit_nofile; rl.rlim_max = (rlim_t) cfg.rlimit_nofile; diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 567d3134e..4222d4d1c 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c @@ -172,6 +172,7 @@ void usage(void) { printf(" --read-write=filename - set directory or file read-write.\n"); printf(" --rlimit-as=number - set the maximum size of the process's virtual memory\n"); printf("\t(address space) in bytes.\n"); + printf(" --rlimit-cpu=number - set the maximum CPU time in seconds.\n"); printf(" --rlimit-fsize=number - set the maximum file size that can be created\n"); printf("\tby a process.\n"); printf(" --rlimit-nofile=number - set the maximum number of files that can be\n"); diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index 185420ba4..808fc7440 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt @@ -385,6 +385,9 @@ Examples: \fBrlimit-as 123456789012 Set he maximum size of the process's virtual memory to 123456789012 bytes. .TP +\fBrlimit-cpu 123 +Set he maximum CPU time in seconds. +.TP \fBrlimit-fsize 1024 Set the maximum file size that can be created by a process to 1024 bytes. .TP diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 2303a8bbd..d2e04675d 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt @@ -1546,6 +1546,15 @@ $ firejail --read-only=~/test --read-write=~/test/a \fB\-\-rlimit-as=number Set the maximum size of the process's virtual memory (address space) in bytes. +.TP +\fB\-\-rlimit-cpu=number +Set the maximum limit, in seconds, for the amount of CPU time each +sandboxed process can consume. When the limit is reached, the processes are killed. + +The CPU limit is a limit on CPU seconds rather than elapsed time. CPU seconds is basically how many seconds +the CPU has been in use and does not necessarily directly relate to the elapsed time. Linux kernel keeps +track of CPU seconds for each process independently. + .TP \fB\-\-rlimit-fsize=number Set the maximum file size that can be created by a process. -- cgit v1.2.3-54-g00ecf