diff options
author | netblue30 <netblue30@protonmail.com> | 2022-01-16 08:50:55 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-16 08:50:55 -0500 |
commit | 59c4c3babe8438143c62895727c246ec25e25ff1 (patch) | |
tree | a6f39a208fd17d679cd6fb84c2ef50797719d384 /src | |
parent | Merge pull request #4851 from kmk3/groups-keep-vglusers (diff) | |
parent | keep-fd option (#4845) (diff) | |
download | firejail-59c4c3babe8438143c62895727c246ec25e25ff1.tar.gz firejail-59c4c3babe8438143c62895727c246ec25e25ff1.tar.zst firejail-59c4c3babe8438143c62895727c246ec25e25ff1.zip |
Merge pull request #4856 from smitsohu/fildes
keep-fd option (#4845)
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/dbus.c | 8 | ||||
-rw-r--r-- | src/firejail/firejail.h | 2 | ||||
-rw-r--r-- | src/firejail/join.c | 5 | ||||
-rw-r--r-- | src/firejail/main.c | 9 | ||||
-rw-r--r-- | src/firejail/profile.c | 9 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 43 | ||||
-rw-r--r-- | src/firejail/usage.c | 1 | ||||
-rw-r--r-- | src/include/common.h | 1 | ||||
-rw-r--r-- | src/lib/common.c | 50 | ||||
-rw-r--r-- | src/man/firejail-profile.txt | 5 | ||||
-rw-r--r-- | src/man/firejail.txt | 20 | ||||
-rw-r--r-- | src/zsh_completion/_firejail.in | 1 |
12 files changed, 137 insertions, 17 deletions
diff --git a/src/firejail/dbus.c b/src/firejail/dbus.c index 12256b833..66738bd4b 100644 --- a/src/firejail/dbus.c +++ b/src/firejail/dbus.c | |||
@@ -298,10 +298,10 @@ void dbus_proxy_start(void) { | |||
298 | errExit("fork"); | 298 | errExit("fork"); |
299 | if (dbus_proxy_pid == 0) { | 299 | if (dbus_proxy_pid == 0) { |
300 | // close open files | 300 | // close open files |
301 | int keep_list[2]; | 301 | int keep[2]; |
302 | keep_list[0] = status_pipe[1]; | 302 | keep[0] = status_pipe[1]; |
303 | keep_list[1] = args_pipe[0]; | 303 | keep[1] = args_pipe[0]; |
304 | close_all(keep_list, ARRAY_SIZE(keep_list)); | 304 | close_all(keep, ARRAY_SIZE(keep)); |
305 | 305 | ||
306 | if (arg_dbus_log_file != NULL) { | 306 | if (arg_dbus_log_file != NULL) { |
307 | int output_fd = creat(arg_dbus_log_file, 0666); | 307 | int output_fd = creat(arg_dbus_log_file, 0666); |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 7314c5350..b1f30bcda 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -161,6 +161,7 @@ typedef struct config_t { | |||
161 | 161 | ||
162 | #define MAX_PROFILE_IGNORE 32 | 162 | #define MAX_PROFILE_IGNORE 32 |
163 | char *profile_ignore[MAX_PROFILE_IGNORE]; | 163 | char *profile_ignore[MAX_PROFILE_IGNORE]; |
164 | char *keep_fd; // inherit file descriptors to sandbox | ||
164 | char *chrootdir; // chroot directory | 165 | char *chrootdir; // chroot directory |
165 | char *home_private; // private home directory | 166 | char *home_private; // private home directory |
166 | char *home_private_keep; // keep list for private home directory | 167 | char *home_private_keep; // keep list for private home directory |
@@ -352,6 +353,7 @@ extern int arg_nou2f; // --nou2f | |||
352 | extern int arg_noinput; // --noinput | 353 | extern int arg_noinput; // --noinput |
353 | extern int arg_deterministic_exit_code; // always exit with first child's exit status | 354 | extern int arg_deterministic_exit_code; // always exit with first child's exit status |
354 | extern int arg_deterministic_shutdown; // shut down the sandbox if first child dies | 355 | extern int arg_deterministic_shutdown; // shut down the sandbox if first child dies |
356 | extern int arg_keep_fd_all; // inherit all file descriptors to sandbox | ||
355 | 357 | ||
356 | typedef enum { | 358 | typedef enum { |
357 | DBUS_POLICY_ALLOW, // Allow unrestricted access to the bus | 359 | DBUS_POLICY_ALLOW, // Allow unrestricted access to the bus |
diff --git a/src/firejail/join.c b/src/firejail/join.c index 9fc80d85b..b62a1ca9d 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c | |||
@@ -569,11 +569,6 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
569 | dbus_set_system_bus_env(); | 569 | dbus_set_system_bus_env(); |
570 | #endif | 570 | #endif |
571 | 571 | ||
572 | // set nice and rlimits | ||
573 | if (arg_nice) | ||
574 | set_nice(cfg.nice); | ||
575 | set_rlimits(); | ||
576 | |||
577 | start_application(0, shfd, NULL); | 572 | start_application(0, shfd, NULL); |
578 | 573 | ||
579 | __builtin_unreachable(); | 574 | __builtin_unreachable(); |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 8278cb62b..21a289efb 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -149,6 +149,7 @@ int arg_nou2f = 0; // --nou2f | |||
149 | int arg_noinput = 0; // --noinput | 149 | int arg_noinput = 0; // --noinput |
150 | int arg_deterministic_exit_code = 0; // always exit with first child's exit status | 150 | int arg_deterministic_exit_code = 0; // always exit with first child's exit status |
151 | int arg_deterministic_shutdown = 0; // shut down the sandbox if first child dies | 151 | int arg_deterministic_shutdown = 0; // shut down the sandbox if first child dies |
152 | int arg_keep_fd_all = 0; // inherit all file descriptors to sandbox | ||
152 | DbusPolicy arg_dbus_user = DBUS_POLICY_ALLOW; // --dbus-user | 153 | DbusPolicy arg_dbus_user = DBUS_POLICY_ALLOW; // --dbus-user |
153 | DbusPolicy arg_dbus_system = DBUS_POLICY_ALLOW; // --dbus-system | 154 | DbusPolicy arg_dbus_system = DBUS_POLICY_ALLOW; // --dbus-system |
154 | const char *arg_dbus_log_file = NULL; | 155 | const char *arg_dbus_log_file = NULL; |
@@ -1862,6 +1863,14 @@ int main(int argc, char **argv, char **envp) { | |||
1862 | } | 1863 | } |
1863 | profile_add_ignore(argv[i] + 9); | 1864 | profile_add_ignore(argv[i] + 9); |
1864 | } | 1865 | } |
1866 | else if (strncmp(argv[i], "--keep-fd=", 10) == 0) { | ||
1867 | if (strcmp(argv[i] + 10, "all") == 0) | ||
1868 | arg_keep_fd_all = 1; | ||
1869 | else { | ||
1870 | const char *add = argv[i] + 10; | ||
1871 | profile_list_augment(&cfg.keep_fd, add); | ||
1872 | } | ||
1873 | } | ||
1865 | #ifdef HAVE_CHROOT | 1874 | #ifdef HAVE_CHROOT |
1866 | else if (strncmp(argv[i], "--chroot=", 9) == 0) { | 1875 | else if (strncmp(argv[i], "--chroot=", 9) == 0) { |
1867 | if (checkcfg(CFG_CHROOT)) { | 1876 | if (checkcfg(CFG_CHROOT)) { |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 5725100e4..794668dc6 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -290,6 +290,15 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
290 | return 0; | 290 | return 0; |
291 | } | 291 | } |
292 | 292 | ||
293 | if (strncmp(ptr, "keep-fd ", 8) == 0) { | ||
294 | if (strcmp(ptr + 8, "all") == 0) | ||
295 | arg_keep_fd_all = 1; | ||
296 | else { | ||
297 | const char *add = ptr + 8; | ||
298 | profile_list_augment(&cfg.keep_fd, add); | ||
299 | } | ||
300 | return 0; | ||
301 | } | ||
293 | if (strncmp(ptr, "xephyr-screen ", 14) == 0) { | 302 | if (strncmp(ptr, "xephyr-screen ", 14) == 0) { |
294 | #ifdef HAVE_X11 | 303 | #ifdef HAVE_X11 |
295 | if (checkcfg(CFG_X11)) { | 304 | if (checkcfg(CFG_X11)) { |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 61d6578a0..0e4e1a36e 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -399,12 +399,28 @@ static int monitor_application(pid_t app_pid) { | |||
399 | return arg_deterministic_exit_code ? app_status : status; | 399 | return arg_deterministic_exit_code ? app_status : status; |
400 | } | 400 | } |
401 | 401 | ||
402 | |||
402 | static void print_time(void) { | 403 | static void print_time(void) { |
403 | float delta = timetrace_end(); | 404 | float delta = timetrace_end(); |
404 | fmessage("Child process initialized in %.02f ms\n", delta); | 405 | fmessage("Child process initialized in %.02f ms\n", delta); |
405 | } | 406 | } |
406 | 407 | ||
407 | 408 | ||
409 | int *build_keep_fd_array(size_t *sz) { | ||
410 | if (!cfg.keep_fd) { | ||
411 | *sz = 0; | ||
412 | return NULL; | ||
413 | } | ||
414 | |||
415 | int *rv = str_to_int_array(cfg.keep_fd, sz); | ||
416 | if (!rv) { | ||
417 | fprintf(stderr, "Error: invalid keep-fd option\n"); | ||
418 | exit(1); | ||
419 | } | ||
420 | return rv; | ||
421 | } | ||
422 | |||
423 | |||
408 | // check execute permissions for the program | 424 | // check execute permissions for the program |
409 | // this is done typically by the shell | 425 | // this is done typically by the shell |
410 | // we are here because of --shell=none | 426 | // we are here because of --shell=none |
@@ -461,10 +477,27 @@ static int ok_to_run(const char *program) { | |||
461 | return 0; | 477 | return 0; |
462 | } | 478 | } |
463 | 479 | ||
480 | |||
464 | void start_application(int no_sandbox, int fd, char *set_sandbox_status) { | 481 | void start_application(int no_sandbox, int fd, char *set_sandbox_status) { |
465 | // set environment | 482 | if (no_sandbox == 0) { |
466 | if (no_sandbox == 0) | 483 | // don't leak open file descriptors |
484 | if (!arg_keep_fd_all) { | ||
485 | size_t sz; | ||
486 | int *keep = build_keep_fd_array(&sz); | ||
487 | close_all(keep, sz); | ||
488 | if (keep) | ||
489 | free(keep); | ||
490 | } | ||
491 | |||
492 | // set nice and rlimits | ||
493 | if (arg_nice) | ||
494 | set_nice(cfg.nice); | ||
495 | set_rlimits(); | ||
496 | |||
467 | env_defaults(); | 497 | env_defaults(); |
498 | } | ||
499 | |||
500 | // set environment | ||
468 | env_apply_all(); | 501 | env_apply_all(); |
469 | 502 | ||
470 | // restore original umask | 503 | // restore original umask |
@@ -1252,12 +1285,6 @@ int sandbox(void* sandbox_arg) { | |||
1252 | #ifdef HAVE_APPARMOR | 1285 | #ifdef HAVE_APPARMOR |
1253 | set_apparmor(); | 1286 | set_apparmor(); |
1254 | #endif | 1287 | #endif |
1255 | |||
1256 | // set nice and rlimits | ||
1257 | if (arg_nice) | ||
1258 | set_nice(cfg.nice); | ||
1259 | set_rlimits(); | ||
1260 | |||
1261 | start_application(0, -1, set_sandbox_status); | 1288 | start_application(0, -1, set_sandbox_status); |
1262 | } | 1289 | } |
1263 | 1290 | ||
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 24c8e3194..c903841c5 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -119,6 +119,7 @@ static char *usage_str = | |||
119 | " --join-or-start=name|pid - join the sandbox or start a new one.\n" | 119 | " --join-or-start=name|pid - join the sandbox or start a new one.\n" |
120 | " --keep-config-pulse - disable automatic ~/.config/pulse init.\n" | 120 | " --keep-config-pulse - disable automatic ~/.config/pulse init.\n" |
121 | " --keep-dev-shm - /dev/shm directory is untouched (even with --private-dev).\n" | 121 | " --keep-dev-shm - /dev/shm directory is untouched (even with --private-dev).\n" |
122 | " --keep-fd - inherit open file descriptors to sandbox.\n" | ||
122 | " --keep-var-tmp - /var/tmp directory is untouched.\n" | 123 | " --keep-var-tmp - /var/tmp directory is untouched.\n" |
123 | " --list - list all sandboxes.\n" | 124 | " --list - list all sandboxes.\n" |
124 | #ifdef HAVE_FILE_TRANSFER | 125 | #ifdef HAVE_FILE_TRANSFER |
diff --git a/src/include/common.h b/src/include/common.h index 24feab02a..f72ec9738 100644 --- a/src/include/common.h +++ b/src/include/common.h | |||
@@ -142,4 +142,5 @@ int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid); | |||
142 | int pid_hidepid(void); | 142 | int pid_hidepid(void); |
143 | void warn_dumpable(void); | 143 | void warn_dumpable(void); |
144 | const char *gnu_basename(const char *path); | 144 | const char *gnu_basename(const char *path); |
145 | int *str_to_int_array(const char *str, size_t *sz); | ||
145 | #endif | 146 | #endif |
diff --git a/src/lib/common.c b/src/lib/common.c index f46e7db1c..91d5125b1 100644 --- a/src/lib/common.c +++ b/src/lib/common.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <dirent.h> | 31 | #include <dirent.h> |
32 | #include <string.h> | 32 | #include <string.h> |
33 | #include <time.h> | 33 | #include <time.h> |
34 | #include <limits.h> | ||
34 | #include "../include/common.h" | 35 | #include "../include/common.h" |
35 | #define BUFLEN 4096 | 36 | #define BUFLEN 4096 |
36 | 37 | ||
@@ -320,6 +321,55 @@ const char *gnu_basename(const char *path) { | |||
320 | return last_slash+1; | 321 | return last_slash+1; |
321 | } | 322 | } |
322 | 323 | ||
324 | // takes string with comma separated int values, returns int array | ||
325 | int *str_to_int_array(const char *str, size_t *sz) { | ||
326 | assert(str && sz); | ||
327 | |||
328 | size_t curr_sz = 0; | ||
329 | size_t arr_sz = 16; | ||
330 | int *rv = malloc(arr_sz * sizeof(int)); | ||
331 | if (!rv) | ||
332 | errExit("malloc"); | ||
333 | |||
334 | char *dup = strdup(str); | ||
335 | if (!dup) | ||
336 | errExit("strdup"); | ||
337 | char *tok = strtok(dup, ","); | ||
338 | if (!tok) { | ||
339 | free(dup); | ||
340 | free(rv); | ||
341 | goto errout; | ||
342 | } | ||
343 | |||
344 | while (tok) { | ||
345 | char *end; | ||
346 | long val = strtol(tok, &end, 10); | ||
347 | if (end == tok || *end != '\0' || val < INT_MIN || val > INT_MAX) { | ||
348 | free(dup); | ||
349 | free(rv); | ||
350 | goto errout; | ||
351 | } | ||
352 | |||
353 | if (curr_sz == arr_sz) { | ||
354 | arr_sz *= 2; | ||
355 | rv = realloc(rv, arr_sz * sizeof(int)); | ||
356 | if (!rv) | ||
357 | errExit("realloc"); | ||
358 | } | ||
359 | rv[curr_sz++] = val; | ||
360 | |||
361 | tok = strtok(NULL, ","); | ||
362 | } | ||
363 | free(dup); | ||
364 | |||
365 | *sz = curr_sz; | ||
366 | return rv; | ||
367 | |||
368 | errout: | ||
369 | *sz = 0; | ||
370 | return NULL; | ||
371 | } | ||
372 | |||
323 | //************************** | 373 | //************************** |
324 | // time trace based on getticks function | 374 | // time trace based on getticks function |
325 | //************************** | 375 | //************************** |
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index 71dab18ba..29f0fe4e4 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt | |||
@@ -724,6 +724,11 @@ env CFLAGS="-W -Wall -Werror" | |||
724 | .TP | 724 | .TP |
725 | \fBipc-namespace | 725 | \fBipc-namespace |
726 | Enable IPC namespace. | 726 | Enable IPC namespace. |
727 | |||
728 | .TP | ||
729 | \fBkeep-fd | ||
730 | Inherit open file descriptors to sandbox. | ||
731 | |||
727 | .TP | 732 | .TP |
728 | \fBname sandboxname | 733 | \fBname sandboxname |
729 | Set sandbox name. Example: | 734 | Set sandbox name. Example: |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 80487a49d..a5704e995 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -1104,6 +1104,26 @@ Example: | |||
1104 | $ firejail --keep-dev-shm --private-dev | 1104 | $ firejail --keep-dev-shm --private-dev |
1105 | 1105 | ||
1106 | .TP | 1106 | .TP |
1107 | \fB\-\-keep-fd=all | ||
1108 | Inherit all open file descriptors to the sandbox. By default only file descriptors 0, 1 and 2 are inherited to the sandbox, and all other file descriptors are closed. | ||
1109 | .br | ||
1110 | |||
1111 | .br | ||
1112 | Example: | ||
1113 | .br | ||
1114 | $ firejail --keep-fd=all | ||
1115 | |||
1116 | .TP | ||
1117 | \fB\-\-keep-fd=file_descriptor | ||
1118 | Don't close specified open file descriptors. By default only file descriptors 0, 1 and 2 are inherited to the sandbox, and all other file descriptors are closed. | ||
1119 | .br | ||
1120 | |||
1121 | .br | ||
1122 | Example: | ||
1123 | .br | ||
1124 | $ firejail --keep-fd=3,4,5 | ||
1125 | |||
1126 | .TP | ||
1107 | \fB\-\-keep-var-tmp | 1127 | \fB\-\-keep-var-tmp |
1108 | /var/tmp directory is untouched. | 1128 | /var/tmp directory is untouched. |
1109 | .br | 1129 | .br |
diff --git a/src/zsh_completion/_firejail.in b/src/zsh_completion/_firejail.in index 334812dd6..f7cd3cdff 100644 --- a/src/zsh_completion/_firejail.in +++ b/src/zsh_completion/_firejail.in | |||
@@ -104,6 +104,7 @@ _firejail_args=( | |||
104 | '--join-or-start=-[join the sandbox or start a new one name|pid]: :_all_firejails' | 104 | '--join-or-start=-[join the sandbox or start a new one name|pid]: :_all_firejails' |
105 | '--keep-config-pulse[disable automatic ~/.config/pulse init]' | 105 | '--keep-config-pulse[disable automatic ~/.config/pulse init]' |
106 | '--keep-dev-shm[/dev/shm directory is untouched (even with --private-dev)]' | 106 | '--keep-dev-shm[/dev/shm directory is untouched (even with --private-dev)]' |
107 | '--keep-fd[inherit open file descriptors to sandbox]' | ||
107 | '--keep-var-tmp[/var/tmp directory is untouched]' | 108 | '--keep-var-tmp[/var/tmp directory is untouched]' |
108 | '--machine-id[spoof /etc/machine-id with a random id]' | 109 | '--machine-id[spoof /etc/machine-id with a random id]' |
109 | '--memory-deny-write-execute[seccomp filter to block attempts to create memory mappings that are both writable and executable]' | 110 | '--memory-deny-write-execute[seccomp filter to block attempts to create memory mappings that are both writable and executable]' |