diff options
-rw-r--r-- | src/firejail/main.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/src/firejail/main.c b/src/firejail/main.c index 958374c43..79e39b669 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -361,6 +361,24 @@ static void init_cfg(int argc, char **argv) { | |||
361 | cfg.seccomp_error_action = "EPERM"; | 361 | cfg.seccomp_error_action = "EPERM"; |
362 | } | 362 | } |
363 | 363 | ||
364 | static void fix_single_std_fd(int fd, const char *file, int flags) { | ||
365 | struct stat s; | ||
366 | if (fstat(fd, &s) == -1 && errno == EBADF) { | ||
367 | // something is wrong with fd, probably it is not opened | ||
368 | int nfd = open(file, flags); | ||
369 | if (nfd != fd || fstat(fd, &s) != 0) | ||
370 | _exit(1); // no further attempts to fix the situation | ||
371 | } | ||
372 | } | ||
373 | |||
374 | // glibc does this automatically if Firejail was started by a regular user | ||
375 | // run this for root user and as a fallback | ||
376 | static void fix_std_streams(void) { | ||
377 | fix_single_std_fd(0, "/dev/full", O_RDONLY|O_NOFOLLOW); | ||
378 | fix_single_std_fd(1, "/dev/null", O_WRONLY|O_NOFOLLOW); | ||
379 | fix_single_std_fd(2, "/dev/null", O_WRONLY|O_NOFOLLOW); | ||
380 | } | ||
381 | |||
364 | static void check_network(Bridge *br) { | 382 | static void check_network(Bridge *br) { |
365 | assert(br); | 383 | assert(br); |
366 | if (br->macvlan == 0) // for bridge devices check network range or arp-scan and assign address | 384 | if (br->macvlan == 0) // for bridge devices check network range or arp-scan and assign address |
@@ -1017,16 +1035,19 @@ int main(int argc, char **argv, char **envp) { | |||
1017 | int arg_caps_cmdline = 0; // caps requested on command line (used to break out of --chroot) | 1035 | int arg_caps_cmdline = 0; // caps requested on command line (used to break out of --chroot) |
1018 | char **ptr; | 1036 | char **ptr; |
1019 | 1037 | ||
1038 | // sanitize the umask | ||
1039 | orig_umask = umask(022); | ||
1040 | |||
1041 | // check standard streams before printing anything | ||
1042 | fix_std_streams(); | ||
1043 | |||
1020 | // drop permissions by default and rise them when required | 1044 | // drop permissions by default and rise them when required |
1021 | EUID_INIT(); | 1045 | EUID_INIT(); |
1022 | EUID_USER(); | 1046 | EUID_USER(); |
1023 | 1047 | ||
1024 | // sanitize the umask | ||
1025 | orig_umask = umask(022); | ||
1026 | |||
1027 | // argument count should be larger than 0 | 1048 | // argument count should be larger than 0 |
1028 | if (argc == 0 || !argv || strlen(argv[0]) == 0) { | 1049 | if (argc == 0 || !argv || strlen(argv[0]) == 0) { |
1029 | fprintf(stderr, "Error: argv[0] is NULL\n"); | 1050 | fprintf(stderr, "Error: argv is invalid\n"); |
1030 | exit(1); | 1051 | exit(1); |
1031 | } else if (argc >= MAX_ARGS) { | 1052 | } else if (argc >= MAX_ARGS) { |
1032 | fprintf(stderr, "Error: too many arguments\n"); | 1053 | fprintf(stderr, "Error: too many arguments\n"); |