--timeout, fix #1614

This commit is contained in:
netblue30 2017-10-25 09:32:34 -04:00
parent 215d748143
commit c9dbf64201
8 changed files with 55 additions and 2 deletions

View file

@ -255,6 +255,7 @@ typedef struct config_t {
long long unsigned rlimit_fsize;
long long unsigned rlimit_sigpending;
long long unsigned rlimit_as;
unsigned timeout; // maximum time elapsed before killing the sandbox
// cpu affinity, nice and control groups
uint32_t cpus;
@ -513,6 +514,7 @@ void create_empty_file_as_root(const char *dir, mode_t mode);
int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode);
void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid);
char *read_text_file_or_exit(const char *fname);
unsigned extract_timeout(const char *str);
// fs_var.c
void fs_var_log(void); // mounting /var/log

View file

@ -2156,6 +2156,8 @@ int main(int argc, char **argv) {
//*************************************
// command
//*************************************
else if (strncmp(argv[i], "--timeout=", 10) == 0)
cfg.timeout = extract_timeout(argv[i] + 10);
else if (strcmp(argv[i], "--audit") == 0) {
arg_audit_prog = LIBDIR "/firejail/faudit";
arg_audit = 1;

View file

@ -1054,7 +1054,12 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
return 0;
}
if (strncmp(ptr, "timeout ", 8) == 0) {
cfg.timeout = extract_timeout(ptr +8);
return 0;
}
if (strncmp(ptr, "join-or-start ", 14) == 0) {
// try to join by name only
pid_t pid;

View file

@ -201,6 +201,14 @@ static int monitor_application(pid_t app_pid) {
signal (SIGTERM, sandbox_handler);
EUID_USER();
// handle --timeout
int options = 0;;
unsigned timeout = 0;
if (cfg.timeout) {
options = WNOHANG;
timeout = cfg.timeout;
}
int status = 0;
while (monitored_pid) {
usleep(20000);
@ -214,9 +222,19 @@ static int monitor_application(pid_t app_pid) {
pid_t rv;
do {
rv = waitpid(-1, &status, 0);
rv = waitpid(-1, &status, options);
if (rv == -1)
break;
// handle --timeout
if (options && --timeout == 0) {
kill(-1, SIGTERM);
flush_stdin();
sleep(1);
_exit(1);
}
sleep(1);
}
while(rv != monitored_pid);
if (arg_debug)

View file

@ -200,6 +200,8 @@ void usage(void) {
printf(" --shell=none - run the program directly without a user shell.\n");
printf(" --shell=program - set default user shell.\n");
printf(" --shutdown=name|pid - shutdown the sandbox identified by name or PID.\n");
printf(" --timeout=hh:mm:ss - kill the sandbox automatically after the time\n");
printf("\thas elapsed.\n");
printf(" --tmpfs=dirname - mount a tmpfs filesystem on directory dirname.\n");
printf(" --top - monitor the most CPU-intensive sandboxes.\n");
printf(" --trace - trace open, access and connect system calls.\n");

View file

@ -949,3 +949,17 @@ errexit:
fprintf(stderr, "Error: cannot read %s\n", fname);
exit(1);
}
unsigned extract_timeout(const char *str) {
unsigned s;
unsigned m;
unsigned h;
int rv = sscanf(str, "%02u:%02u:%02u", &h, &m, &s);
if (rv != 3) {
fprintf(stderr, "Error: invalid timeout, please use a hh:mm:ss format\n");
exit(1);
}
return h * 3600 + m * 60 + s;
}

View file

@ -408,6 +408,9 @@ Set a nice value of -5 to all processes running inside the sandbox.
.TP
\fBcgroup /sys/fs/cgroup/g1/tasks
The sandbox is placed in g1 control group.
.TP
\fBtimeout hh:mm:ss
Kill the sandbox automatically after the time has elapsed. The time is specified in hours/minutes/seconds format.
.SH User Environment
.TP

View file

@ -1849,6 +1849,13 @@ $ firejail \-\-list
.br
$ firejail \-\-shutdown=3272
.TP
\fB\-\-timeout=hh:mm:ss
Kill the sandbox automatically after the time has elapsed. The time is specified in hours/minutes/seconds format.
.br
.br
$ firejail \-\-timeout=01:30:00 firefox
.TP
\fB\-\-tmpfs=dirname
Mount a tmpfs filesystem on directory dirname. This option is available only when running the sandbox as root.
File globbing is supported, see \fBFILE GLOBBING\fR section for more details.