diff options
-rw-r--r-- | src/firejail/firejail.h | 2 | ||||
-rw-r--r-- | src/firejail/main.c | 2 | ||||
-rw-r--r-- | src/firejail/profile.c | 7 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 20 | ||||
-rw-r--r-- | src/firejail/usage.c | 2 | ||||
-rw-r--r-- | src/firejail/util.c | 14 | ||||
-rw-r--r-- | src/man/firejail-profile.txt | 3 | ||||
-rw-r--r-- | src/man/firejail.txt | 7 |
8 files changed, 55 insertions, 2 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 1b399ba10..a6b57f263 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -255,6 +255,7 @@ typedef struct config_t { | |||
255 | long long unsigned rlimit_fsize; | 255 | long long unsigned rlimit_fsize; |
256 | long long unsigned rlimit_sigpending; | 256 | long long unsigned rlimit_sigpending; |
257 | long long unsigned rlimit_as; | 257 | long long unsigned rlimit_as; |
258 | unsigned timeout; // maximum time elapsed before killing the sandbox | ||
258 | 259 | ||
259 | // cpu affinity, nice and control groups | 260 | // cpu affinity, nice and control groups |
260 | uint32_t cpus; | 261 | uint32_t cpus; |
@@ -513,6 +514,7 @@ void create_empty_file_as_root(const char *dir, mode_t mode); | |||
513 | int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode); | 514 | int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode); |
514 | void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid); | 515 | void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid); |
515 | char *read_text_file_or_exit(const char *fname); | 516 | char *read_text_file_or_exit(const char *fname); |
517 | unsigned extract_timeout(const char *str); | ||
516 | 518 | ||
517 | // fs_var.c | 519 | // fs_var.c |
518 | void fs_var_log(void); // mounting /var/log | 520 | void fs_var_log(void); // mounting /var/log |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 04900d6f9..67b40f9c2 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -2156,6 +2156,8 @@ int main(int argc, char **argv) { | |||
2156 | //************************************* | 2156 | //************************************* |
2157 | // command | 2157 | // command |
2158 | //************************************* | 2158 | //************************************* |
2159 | else if (strncmp(argv[i], "--timeout=", 10) == 0) | ||
2160 | cfg.timeout = extract_timeout(argv[i] + 10); | ||
2159 | else if (strcmp(argv[i], "--audit") == 0) { | 2161 | else if (strcmp(argv[i], "--audit") == 0) { |
2160 | arg_audit_prog = LIBDIR "/firejail/faudit"; | 2162 | arg_audit_prog = LIBDIR "/firejail/faudit"; |
2161 | arg_audit = 1; | 2163 | arg_audit = 1; |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 9f49d7405..dc1333988 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -1054,7 +1054,12 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
1054 | 1054 | ||
1055 | return 0; | 1055 | return 0; |
1056 | } | 1056 | } |
1057 | 1057 | ||
1058 | if (strncmp(ptr, "timeout ", 8) == 0) { | ||
1059 | cfg.timeout = extract_timeout(ptr +8); | ||
1060 | return 0; | ||
1061 | } | ||
1062 | |||
1058 | if (strncmp(ptr, "join-or-start ", 14) == 0) { | 1063 | if (strncmp(ptr, "join-or-start ", 14) == 0) { |
1059 | // try to join by name only | 1064 | // try to join by name only |
1060 | pid_t pid; | 1065 | pid_t pid; |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index abdbbfecd..b92483c66 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -201,6 +201,14 @@ static int monitor_application(pid_t app_pid) { | |||
201 | signal (SIGTERM, sandbox_handler); | 201 | signal (SIGTERM, sandbox_handler); |
202 | EUID_USER(); | 202 | EUID_USER(); |
203 | 203 | ||
204 | // handle --timeout | ||
205 | int options = 0;; | ||
206 | unsigned timeout = 0; | ||
207 | if (cfg.timeout) { | ||
208 | options = WNOHANG; | ||
209 | timeout = cfg.timeout; | ||
210 | } | ||
211 | |||
204 | int status = 0; | 212 | int status = 0; |
205 | while (monitored_pid) { | 213 | while (monitored_pid) { |
206 | usleep(20000); | 214 | usleep(20000); |
@@ -214,9 +222,19 @@ static int monitor_application(pid_t app_pid) { | |||
214 | 222 | ||
215 | pid_t rv; | 223 | pid_t rv; |
216 | do { | 224 | do { |
217 | rv = waitpid(-1, &status, 0); | 225 | rv = waitpid(-1, &status, options); |
218 | if (rv == -1) | 226 | if (rv == -1) |
219 | break; | 227 | break; |
228 | |||
229 | // handle --timeout | ||
230 | if (options && --timeout == 0) { | ||
231 | kill(-1, SIGTERM); | ||
232 | flush_stdin(); | ||
233 | sleep(1); | ||
234 | _exit(1); | ||
235 | } | ||
236 | |||
237 | sleep(1); | ||
220 | } | 238 | } |
221 | while(rv != monitored_pid); | 239 | while(rv != monitored_pid); |
222 | if (arg_debug) | 240 | if (arg_debug) |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 4222d4d1c..0bc3b20fd 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -200,6 +200,8 @@ void usage(void) { | |||
200 | printf(" --shell=none - run the program directly without a user shell.\n"); | 200 | printf(" --shell=none - run the program directly without a user shell.\n"); |
201 | printf(" --shell=program - set default user shell.\n"); | 201 | printf(" --shell=program - set default user shell.\n"); |
202 | printf(" --shutdown=name|pid - shutdown the sandbox identified by name or PID.\n"); | 202 | printf(" --shutdown=name|pid - shutdown the sandbox identified by name or PID.\n"); |
203 | printf(" --timeout=hh:mm:ss - kill the sandbox automatically after the time\n"); | ||
204 | printf("\thas elapsed.\n"); | ||
203 | printf(" --tmpfs=dirname - mount a tmpfs filesystem on directory dirname.\n"); | 205 | printf(" --tmpfs=dirname - mount a tmpfs filesystem on directory dirname.\n"); |
204 | printf(" --top - monitor the most CPU-intensive sandboxes.\n"); | 206 | printf(" --top - monitor the most CPU-intensive sandboxes.\n"); |
205 | printf(" --trace - trace open, access and connect system calls.\n"); | 207 | printf(" --trace - trace open, access and connect system calls.\n"); |
diff --git a/src/firejail/util.c b/src/firejail/util.c index 559f7ee48..cea2b76e3 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -949,3 +949,17 @@ errexit: | |||
949 | fprintf(stderr, "Error: cannot read %s\n", fname); | 949 | fprintf(stderr, "Error: cannot read %s\n", fname); |
950 | exit(1); | 950 | exit(1); |
951 | } | 951 | } |
952 | |||
953 | |||
954 | unsigned extract_timeout(const char *str) { | ||
955 | unsigned s; | ||
956 | unsigned m; | ||
957 | unsigned h; | ||
958 | int rv = sscanf(str, "%02u:%02u:%02u", &h, &m, &s); | ||
959 | if (rv != 3) { | ||
960 | fprintf(stderr, "Error: invalid timeout, please use a hh:mm:ss format\n"); | ||
961 | exit(1); | ||
962 | } | ||
963 | |||
964 | return h * 3600 + m * 60 + s; | ||
965 | } | ||
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index 808fc7440..39680ab0a 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt | |||
@@ -408,6 +408,9 @@ Set a nice value of -5 to all processes running inside the sandbox. | |||
408 | .TP | 408 | .TP |
409 | \fBcgroup /sys/fs/cgroup/g1/tasks | 409 | \fBcgroup /sys/fs/cgroup/g1/tasks |
410 | The sandbox is placed in g1 control group. | 410 | The sandbox is placed in g1 control group. |
411 | .TP | ||
412 | \fBtimeout hh:mm:ss | ||
413 | Kill the sandbox automatically after the time has elapsed. The time is specified in hours/minutes/seconds format. | ||
411 | 414 | ||
412 | .SH User Environment | 415 | .SH User Environment |
413 | .TP | 416 | .TP |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index d2e04675d..d725bb883 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -1849,6 +1849,13 @@ $ firejail \-\-list | |||
1849 | .br | 1849 | .br |
1850 | $ firejail \-\-shutdown=3272 | 1850 | $ firejail \-\-shutdown=3272 |
1851 | .TP | 1851 | .TP |
1852 | \fB\-\-timeout=hh:mm:ss | ||
1853 | Kill the sandbox automatically after the time has elapsed. The time is specified in hours/minutes/seconds format. | ||
1854 | .br | ||
1855 | |||
1856 | .br | ||
1857 | $ firejail \-\-timeout=01:30:00 firefox | ||
1858 | .TP | ||
1852 | \fB\-\-tmpfs=dirname | 1859 | \fB\-\-tmpfs=dirname |
1853 | Mount a tmpfs filesystem on directory dirname. This option is available only when running the sandbox as root. | 1860 | Mount a tmpfs filesystem on directory dirname. This option is available only when running the sandbox as root. |
1854 | File globbing is supported, see \fBFILE GLOBBING\fR section for more details. | 1861 | File globbing is supported, see \fBFILE GLOBBING\fR section for more details. |