diff options
author | 2016-08-14 08:45:25 -0400 | |
---|---|---|
committer | 2016-08-14 08:45:25 -0400 | |
commit | fd47862fae009368641b1f64153e3184e7966f18 (patch) | |
tree | 9a924753bcfe368fcdef79207439aac716e59e6f | |
parent | Merge pull request #711 from Fred-Barclay/sandy_shores (diff) | |
parent | join fixes (diff) | |
download | firejail-fd47862fae009368641b1f64153e3184e7966f18.tar.gz firejail-fd47862fae009368641b1f64153e3184e7966f18.tar.zst firejail-fd47862fae009368641b1f64153e3184e7966f18.zip |
Merge pull request #709 from manevich/shell
Gather shell selection code in one place
-rw-r--r-- | src/firejail/bandwidth.c | 8 | ||||
-rw-r--r-- | src/firejail/env.c | 4 | ||||
-rw-r--r-- | src/firejail/firejail.h | 3 | ||||
-rw-r--r-- | src/firejail/fs.c | 15 | ||||
-rw-r--r-- | src/firejail/fs_home.c | 5 | ||||
-rw-r--r-- | src/firejail/join.c | 47 | ||||
-rw-r--r-- | src/firejail/main.c | 79 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 17 |
8 files changed, 86 insertions, 92 deletions
diff --git a/src/firejail/bandwidth.c b/src/firejail/bandwidth.c index 34c5ca509..5ff67b644 100644 --- a/src/firejail/bandwidth.c +++ b/src/firejail/bandwidth.c | |||
@@ -459,13 +459,15 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in | |||
459 | if (setregid(0, 0)) | 459 | if (setregid(0, 0)) |
460 | errExit("setregid"); | 460 | errExit("setregid"); |
461 | 461 | ||
462 | assert(cfg.shell); | ||
463 | |||
462 | char *arg[4]; | 464 | char *arg[4]; |
463 | arg[0] = "/bin/bash"; | 465 | arg[0] = cfg.shell; |
464 | arg[1] = "-c"; | 466 | arg[1] = "-c"; |
465 | arg[2] = cmd; | 467 | arg[2] = cmd; |
466 | arg[3] = NULL; | 468 | arg[3] = NULL; |
467 | execvp("/bin/bash", arg); | 469 | execvp(arg[0], arg); |
468 | 470 | ||
469 | // it will never get here | 471 | // it will never get here |
470 | exit(0); | 472 | errExit("execvp"); |
471 | } | 473 | } |
diff --git a/src/firejail/env.c b/src/firejail/env.c index dd51b0a78..328b19c5b 100644 --- a/src/firejail/env.c +++ b/src/firejail/env.c | |||
@@ -121,10 +121,6 @@ void env_defaults(void) { | |||
121 | errExit("setenv"); | 121 | errExit("setenv"); |
122 | if (setenv("container", "firejail", 1) < 0) // LXC sets container=lxc, | 122 | if (setenv("container", "firejail", 1) < 0) // LXC sets container=lxc, |
123 | errExit("setenv"); | 123 | errExit("setenv"); |
124 | if (arg_zsh && setenv("SHELL", "/usr/bin/zsh", 1) < 0) | ||
125 | errExit("setenv"); | ||
126 | if (arg_csh && setenv("SHELL", "/bin/csh", 1) < 0) | ||
127 | errExit("setenv"); | ||
128 | if (cfg.shell && setenv("SHELL", cfg.shell, 1) < 0) | 124 | if (cfg.shell && setenv("SHELL", cfg.shell, 1) < 0) |
129 | errExit("setenv"); | 125 | errExit("setenv"); |
130 | // set prompt color to green | 126 | // set prompt color to green |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 16b9d468f..c45b324fc 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -222,8 +222,6 @@ extern int arg_nonetwork; // --net=none | |||
222 | extern int arg_command; // -c | 222 | extern int arg_command; // -c |
223 | extern int arg_overlay; // overlay option | 223 | extern int arg_overlay; // overlay option |
224 | extern int arg_overlay_keep; // place overlay diff directory in ~/.firejail | 224 | extern int arg_overlay_keep; // place overlay diff directory in ~/.firejail |
225 | extern int arg_zsh; // use zsh as default shell | ||
226 | extern int arg_csh; // use csh as default shell | ||
227 | 225 | ||
228 | extern int arg_seccomp; // enable default seccomp filter | 226 | extern int arg_seccomp; // enable default seccomp filter |
229 | 227 | ||
@@ -277,6 +275,7 @@ extern int fullargc; | |||
277 | 275 | ||
278 | // main.c | 276 | // main.c |
279 | void check_user_namespace(void); | 277 | void check_user_namespace(void); |
278 | char *guess_shell(void); | ||
280 | 279 | ||
281 | // sandbox.c | 280 | // sandbox.c |
282 | int sandbox(void* sandbox_arg); | 281 | int sandbox(void* sandbox_arg); |
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index bf78a2e3b..5fe31cec8 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -1110,14 +1110,13 @@ int fs_check_chroot_dir(const char *rootdir) { | |||
1110 | } | 1110 | } |
1111 | free(name); | 1111 | free(name); |
1112 | 1112 | ||
1113 | // check /bin/bash | 1113 | // check shell |
1114 | // if (asprintf(&name, "%s/bin/bash", rootdir) == -1) | 1114 | if (!arg_shell_none) { |
1115 | // errExit("asprintf"); | 1115 | if (stat(cfg.shell, &s) == -1) { |
1116 | // if (stat(name, &s) == -1) { | 1116 | fprintf(stderr, "Error: cannot find %s in chroot directory\n", cfg.shell); |
1117 | // fprintf(stderr, "Error: cannot find /bin/bash in chroot directory\n"); | 1117 | return 1; |
1118 | // return 1; | 1118 | } |
1119 | // } | 1119 | } |
1120 | // free(name); | ||
1121 | 1120 | ||
1122 | // check x11 socket directory | 1121 | // check x11 socket directory |
1123 | if (getenv("FIREJAIL_X11")) { | 1122 | if (getenv("FIREJAIL_X11")) { |
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index c1e983c16..d328d5f1c 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c | |||
@@ -32,8 +32,9 @@ | |||
32 | 32 | ||
33 | static void skel(const char *homedir, uid_t u, gid_t g) { | 33 | static void skel(const char *homedir, uid_t u, gid_t g) { |
34 | char *fname; | 34 | char *fname; |
35 | |||
35 | // zsh | 36 | // zsh |
36 | if (arg_zsh) { | 37 | if (!arg_shell_none && (strcmp(cfg.shell,"/usr/bin/zsh") == 0 || strcmp(cfg.shell,"/bin/zsh") == 0)) { |
37 | // copy skel files | 38 | // copy skel files |
38 | if (asprintf(&fname, "%s/.zshrc", homedir) == -1) | 39 | if (asprintf(&fname, "%s/.zshrc", homedir) == -1) |
39 | errExit("asprintf"); | 40 | errExit("asprintf"); |
@@ -63,7 +64,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) { | |||
63 | free(fname); | 64 | free(fname); |
64 | } | 65 | } |
65 | // csh | 66 | // csh |
66 | else if (arg_csh) { | 67 | else if (!arg_shell_none && strcmp(cfg.shell,"/bin/csh") == 0) { |
67 | // copy skel files | 68 | // copy skel files |
68 | if (asprintf(&fname, "%s/.cshrc", homedir) == -1) | 69 | if (asprintf(&fname, "%s/.cshrc", homedir) == -1) |
69 | errExit("asprintf"); | 70 | errExit("asprintf"); |
diff --git a/src/firejail/join.c b/src/firejail/join.c index 0b5b6a34a..632715fea 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c | |||
@@ -330,32 +330,15 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
330 | } | 330 | } |
331 | } | 331 | } |
332 | 332 | ||
333 | // run cmdline trough /bin/bash | 333 | // run cmdline trough shell |
334 | if (cfg.command_line == NULL) { | 334 | if (cfg.command_line == NULL) { |
335 | assert(cfg.shell); | ||
335 | 336 | ||
336 | // replace the process with a shell | 337 | // replace the process with a shell |
337 | if (cfg.shell) | 338 | execlp(cfg.shell, cfg.shell, NULL); |
338 | execlp(cfg.shell, cfg.shell, NULL); | ||
339 | else if (arg_zsh) | ||
340 | execlp("/usr/bin/zsh", "/usr/bin/zsh", NULL); | ||
341 | else if (arg_csh) | ||
342 | execlp("/bin/csh", "/bin/csh", NULL); | ||
343 | else { | ||
344 | struct stat s; | ||
345 | if (stat("/bin/bash", &s) == 0) | ||
346 | execlp("/bin/bash", "/bin/bash", NULL); | ||
347 | else if (stat("/usr/bin/zsh", &s) == 0) | ||
348 | execlp("/usr/bin/zsh", "/usr/bin/zsh", NULL); | ||
349 | else if (stat("/bin/csh", &s) == 0) | ||
350 | execlp("/bin/csh", "/bin/csh", NULL); | ||
351 | else if (stat("/bin/sh", &s) == 0) | ||
352 | execlp("/bin/sh", "/bin/sh", NULL); | ||
353 | } | ||
354 | 339 | ||
355 | // no shell found, print an error and exit | 340 | // it should never get here |
356 | fprintf(stderr, "Error: no POSIX shell found\n"); | 341 | errExit("execlp"); |
357 | sleep(5); | ||
358 | exit(1); | ||
359 | } | 342 | } |
360 | else { | 343 | else { |
361 | // run the command supplied by the user | 344 | // run the command supplied by the user |
@@ -398,19 +381,10 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
398 | execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); | 381 | execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); |
399 | exit(1); | 382 | exit(1); |
400 | } else { | 383 | } else { |
401 | // choose the shell requested by the user, or use bash as default | 384 | assert(cfg.shell); |
402 | char *sh; | 385 | |
403 | if (cfg.shell) | ||
404 | sh = cfg.shell; | ||
405 | else if (arg_zsh) | ||
406 | sh = "/usr/bin/zsh"; | ||
407 | else if (arg_csh) | ||
408 | sh = "/bin/csh"; | ||
409 | else | ||
410 | sh = "/bin/bash"; | ||
411 | |||
412 | char *arg[5]; | 386 | char *arg[5]; |
413 | arg[0] = sh; | 387 | arg[0] = cfg.shell; |
414 | arg[1] = "-c"; | 388 | arg[1] = "-c"; |
415 | if (arg_debug) | 389 | if (arg_debug) |
416 | printf("Starting %s\n", cfg.command_line); | 390 | printf("Starting %s\n", cfg.command_line); |
@@ -423,7 +397,10 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
423 | arg[3] = cfg.command_line; | 397 | arg[3] = cfg.command_line; |
424 | arg[4] = NULL; | 398 | arg[4] = NULL; |
425 | } | 399 | } |
426 | execvp("/bin/bash", arg); | 400 | execvp(arg[0], arg); |
401 | |||
402 | // it should never get here | ||
403 | errExit("execvp"); | ||
427 | } | 404 | } |
428 | } | 405 | } |
429 | 406 | ||
diff --git a/src/firejail/main.c b/src/firejail/main.c index 7b8b770ab..7cc9f9bf6 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -60,8 +60,6 @@ int arg_nonetwork = 0; // --net=none | |||
60 | int arg_command = 0; // -c | 60 | int arg_command = 0; // -c |
61 | int arg_overlay = 0; // overlay option | 61 | int arg_overlay = 0; // overlay option |
62 | int arg_overlay_keep = 0; // place overlay diff directory in ~/.firejail | 62 | int arg_overlay_keep = 0; // place overlay diff directory in ~/.firejail |
63 | int arg_zsh = 0; // use zsh as default shell | ||
64 | int arg_csh = 0; // use csh as default shell | ||
65 | 63 | ||
66 | int arg_seccomp = 0; // enable default seccomp filter | 64 | int arg_seccomp = 0; // enable default seccomp filter |
67 | 65 | ||
@@ -566,7 +564,18 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
566 | #endif | 564 | #endif |
567 | else if (strncmp(argv[i], "--join=", 7) == 0) { | 565 | else if (strncmp(argv[i], "--join=", 7) == 0) { |
568 | logargs(argc, argv); | 566 | logargs(argc, argv); |
569 | 567 | ||
568 | if (arg_shell_none) { | ||
569 | if (argc <= (i+1)) { | ||
570 | fprintf(stderr, "Error: --shell=none set, but no command specified\n"); | ||
571 | exit(1); | ||
572 | } | ||
573 | cfg.original_program_index = i + 1; | ||
574 | } | ||
575 | |||
576 | if (!cfg.shell && !arg_shell_none) | ||
577 | cfg.shell = guess_shell(); | ||
578 | |||
570 | // join sandbox by pid or by name | 579 | // join sandbox by pid or by name |
571 | pid_t pid; | 580 | pid_t pid; |
572 | if (read_pid(argv[i] + 7, &pid) == 0) | 581 | if (read_pid(argv[i] + 7, &pid) == 0) |
@@ -574,6 +583,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
574 | else | 583 | else |
575 | join_name(argv[i] + 7, argc, argv, i + 1); | 584 | join_name(argv[i] + 7, argc, argv, i + 1); |
576 | exit(0); | 585 | exit(0); |
586 | |||
577 | } | 587 | } |
578 | #ifdef HAVE_NETWORK | 588 | #ifdef HAVE_NETWORK |
579 | else if (strncmp(argv[i], "--join-network=", 15) == 0) { | 589 | else if (strncmp(argv[i], "--join-network=", 15) == 0) { |
@@ -710,6 +720,25 @@ static void detect_quiet(int argc, char **argv) { | |||
710 | } | 720 | } |
711 | } | 721 | } |
712 | 722 | ||
723 | char *guess_shell(void) { | ||
724 | char *shell; | ||
725 | // shells in order of preference | ||
726 | char *shells[] = {"/bin/bash", "/bin/csh", "/usr/bin/zsh", "/bin/sh", "/bin/ash", NULL }; | ||
727 | |||
728 | int i = 0; | ||
729 | while (shells[i] != NULL) { | ||
730 | struct stat s; | ||
731 | // access call checks as real UID/GID, not as effective UID/GID | ||
732 | if (stat(shells[i], &s) == 0 && access(shells[i], R_OK) == 0) { | ||
733 | shell = shells[i]; | ||
734 | break; | ||
735 | } | ||
736 | i++; | ||
737 | } | ||
738 | |||
739 | return shell; | ||
740 | } | ||
741 | |||
713 | //******************************************* | 742 | //******************************************* |
714 | // Main program | 743 | // Main program |
715 | //******************************************* | 744 | //******************************************* |
@@ -1859,26 +1888,26 @@ int main(int argc, char **argv) { | |||
1859 | fprintf(stderr, "Error: --shell=none was already specified.\n"); | 1888 | fprintf(stderr, "Error: --shell=none was already specified.\n"); |
1860 | return 1; | 1889 | return 1; |
1861 | } | 1890 | } |
1862 | if (arg_zsh || cfg.shell ) { | 1891 | if (cfg.shell) { |
1863 | fprintf(stderr, "Error: only one default user shell can be specified\n"); | 1892 | fprintf(stderr, "Error: only one default user shell can be specified\n"); |
1864 | return 1; | 1893 | return 1; |
1865 | } | 1894 | } |
1866 | arg_csh = 1; | 1895 | cfg.shell = "/bin/csh"; |
1867 | } | 1896 | } |
1868 | else if (strcmp(argv[i], "--zsh") == 0) { | 1897 | else if (strcmp(argv[i], "--zsh") == 0) { |
1869 | if (arg_shell_none) { | 1898 | if (arg_shell_none) { |
1870 | fprintf(stderr, "Error: --shell=none was already specified.\n"); | 1899 | fprintf(stderr, "Error: --shell=none was already specified.\n"); |
1871 | return 1; | 1900 | return 1; |
1872 | } | 1901 | } |
1873 | if (arg_csh || cfg.shell ) { | 1902 | if (cfg.shell) { |
1874 | fprintf(stderr, "Error: only one default user shell can be specified\n"); | 1903 | fprintf(stderr, "Error: only one default user shell can be specified\n"); |
1875 | return 1; | 1904 | return 1; |
1876 | } | 1905 | } |
1877 | arg_zsh = 1; | 1906 | cfg.shell = "/bin/zsh"; |
1878 | } | 1907 | } |
1879 | else if (strcmp(argv[i], "--shell=none") == 0) { | 1908 | else if (strcmp(argv[i], "--shell=none") == 0) { |
1880 | arg_shell_none = 1; | 1909 | arg_shell_none = 1; |
1881 | if (arg_csh || arg_zsh || cfg.shell) { | 1910 | if (cfg.shell) { |
1882 | fprintf(stderr, "Error: a shell was already specified\n"); | 1911 | fprintf(stderr, "Error: a shell was already specified\n"); |
1883 | return 1; | 1912 | return 1; |
1884 | } | 1913 | } |
@@ -1890,7 +1919,7 @@ int main(int argc, char **argv) { | |||
1890 | } | 1919 | } |
1891 | invalid_filename(argv[i] + 8); | 1920 | invalid_filename(argv[i] + 8); |
1892 | 1921 | ||
1893 | if (arg_csh || arg_zsh || cfg.shell) { | 1922 | if (cfg.shell) { |
1894 | fprintf(stderr, "Error: only one user shell can be specified\n"); | 1923 | fprintf(stderr, "Error: only one user shell can be specified\n"); |
1895 | return 1; | 1924 | return 1; |
1896 | } | 1925 | } |
@@ -1974,27 +2003,23 @@ int main(int argc, char **argv) { | |||
1974 | free(msg); | 2003 | free(msg); |
1975 | } | 2004 | } |
1976 | 2005 | ||
1977 | // build the sandbox command | 2006 | // guess shell if unspecified |
1978 | if (prog_index == -1 && arg_zsh) { | 2007 | if (!arg_shell_none && !cfg.shell) { |
1979 | cfg.command_line = "/usr/bin/zsh"; | 2008 | cfg.shell = guess_shell(); |
1980 | cfg.window_title = "/usr/bin/zsh"; | 2009 | if (!cfg.shell) { |
1981 | cfg.command_name = "zsh"; | 2010 | fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); |
1982 | } | 2011 | exit(1); |
1983 | else if (prog_index == -1 && arg_csh) { | 2012 | } |
1984 | cfg.command_line = "/bin/csh"; | 2013 | if (arg_debug) |
1985 | cfg.window_title = "/bin/csh"; | 2014 | printf("Autoselecting %s as shell\n", cfg.shell); |
1986 | cfg.command_name = "csh"; | ||
1987 | } | 2015 | } |
1988 | else if (prog_index == -1 && cfg.shell) { | 2016 | |
2017 | // build the sandbox command | ||
2018 | if (prog_index == -1 && cfg.shell) { | ||
1989 | cfg.command_line = cfg.shell; | 2019 | cfg.command_line = cfg.shell; |
1990 | cfg.window_title = cfg.shell; | 2020 | cfg.window_title = cfg.shell; |
1991 | cfg.command_name = cfg.shell; | 2021 | cfg.command_name = cfg.shell; |
1992 | } | 2022 | } |
1993 | else if (prog_index == -1) { | ||
1994 | cfg.command_line = "/bin/bash"; | ||
1995 | cfg.window_title = "/bin/bash"; | ||
1996 | cfg.command_name = "bash"; | ||
1997 | } | ||
1998 | else if (arg_appimage) { | 2023 | else if (arg_appimage) { |
1999 | if (arg_debug) | 2024 | if (arg_debug) |
2000 | printf("Configuring appimage environment\n"); | 2025 | printf("Configuring appimage environment\n"); |
@@ -2004,6 +2029,10 @@ int main(int argc, char **argv) { | |||
2004 | else { | 2029 | else { |
2005 | build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index); | 2030 | build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index); |
2006 | } | 2031 | } |
2032 | /* else { | ||
2033 | fprintf(stderr, "Error: command must be specified when --shell=none used.\n"); | ||
2034 | exit(1); | ||
2035 | }*/ | ||
2007 | 2036 | ||
2008 | assert(cfg.command_name); | 2037 | assert(cfg.command_name); |
2009 | if (arg_debug) | 2038 | if (arg_debug) |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index a131d9e91..5451c6d6c 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -325,20 +325,11 @@ static void start_application(void) { | |||
325 | // start the program using a shell | 325 | // start the program using a shell |
326 | //**************************************** | 326 | //**************************************** |
327 | else { | 327 | else { |
328 | // choose the shell requested by the user, or use bash as default | 328 | assert(cfg.shell); |
329 | char *sh; | 329 | |
330 | if (cfg.shell) | ||
331 | sh = cfg.shell; | ||
332 | else if (arg_zsh) | ||
333 | sh = "/usr/bin/zsh"; | ||
334 | else if (arg_csh) | ||
335 | sh = "/bin/csh"; | ||
336 | else | ||
337 | sh = "/bin/bash"; | ||
338 | |||
339 | char *arg[5]; | 330 | char *arg[5]; |
340 | int index = 0; | 331 | int index = 0; |
341 | arg[index++] = sh; | 332 | arg[index++] = cfg.shell; |
342 | arg[index++] = "-c"; | 333 | arg[index++] = "-c"; |
343 | assert(cfg.command_line); | 334 | assert(cfg.command_line); |
344 | if (arg_debug) | 335 | if (arg_debug) |
@@ -368,7 +359,7 @@ static void start_application(void) { | |||
368 | 359 | ||
369 | if (!arg_command && !arg_quiet) | 360 | if (!arg_command && !arg_quiet) |
370 | printf("Child process initialized\n"); | 361 | printf("Child process initialized\n"); |
371 | execvp(sh, arg); | 362 | execvp(arg[0], arg); |
372 | } | 363 | } |
373 | 364 | ||
374 | perror("execvp"); | 365 | perror("execvp"); |