diff options
author | Aleksey Manevich <manevich.aleksey@gmail.com> | 2016-08-13 21:12:22 +0300 |
---|---|---|
committer | Aleksey Manevich <manevich.aleksey@gmail.com> | 2016-08-13 21:12:22 +0300 |
commit | 9614b8ac4bf2661f6378abc7db18169fb867d6bb (patch) | |
tree | 3bbfe8094cc721f3f9843cbe280b5cdec9ea6c0d /src | |
parent | removed /bin/bash check for chroot (diff) | |
download | firejail-9614b8ac4bf2661f6378abc7db18169fb867d6bb.tar.gz firejail-9614b8ac4bf2661f6378abc7db18169fb867d6bb.tar.zst firejail-9614b8ac4bf2661f6378abc7db18169fb867d6bb.zip |
shell selection
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/bandwidth.c | 8 | ||||
-rw-r--r-- | src/firejail/env.c | 4 | ||||
-rw-r--r-- | src/firejail/firejail.h | 1 | ||||
-rw-r--r-- | src/firejail/fs.c | 15 | ||||
-rw-r--r-- | src/firejail/join.c | 59 | ||||
-rw-r--r-- | src/firejail/main.c | 69 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 17 |
7 files changed, 90 insertions, 83 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 79d6b81e3..fdfa80ea8 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..0de2a354d 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -277,6 +277,7 @@ extern int fullargc; | |||
277 | 277 | ||
278 | // main.c | 278 | // main.c |
279 | void check_user_namespace(void); | 279 | void check_user_namespace(void); |
280 | char *guess_shell(void); | ||
280 | 281 | ||
281 | // sandbox.c | 282 | // sandbox.c |
282 | int sandbox(void* sandbox_arg); | 283 | 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/join.c b/src/firejail/join.c index 0b5b6a34a..80ed1dc51 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c | |||
@@ -330,32 +330,21 @@ 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 | cfg.shell = guess_shell(); | ||
336 | if (!cfg.shell) { | ||
337 | fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); | ||
338 | exit(1); | ||
339 | } | ||
340 | if (arg_debug) | ||
341 | printf("Autoselecting %s as shell\n", cfg.shell); | ||
335 | 342 | ||
336 | // replace the process with a shell | 343 | // replace the process with a shell |
337 | if (cfg.shell) | 344 | 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 | 345 | ||
355 | // no shell found, print an error and exit | 346 | // it should never get here |
356 | fprintf(stderr, "Error: no POSIX shell found\n"); | 347 | errExit("execlp"); |
357 | sleep(5); | ||
358 | exit(1); | ||
359 | } | 348 | } |
360 | else { | 349 | else { |
361 | // run the command supplied by the user | 350 | // run the command supplied by the user |
@@ -398,19 +387,16 @@ 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]); | 387 | execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); |
399 | exit(1); | 388 | exit(1); |
400 | } else { | 389 | } else { |
401 | // choose the shell requested by the user, or use bash as default | 390 | // assert(cfg.shell); |
402 | char *sh; | 391 | cfg.shell = guess_shell(); |
403 | if (cfg.shell) | 392 | if (!cfg.shell) { |
404 | sh = cfg.shell; | 393 | fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); |
405 | else if (arg_zsh) | 394 | exit(1); |
406 | sh = "/usr/bin/zsh"; | 395 | } |
407 | else if (arg_csh) | 396 | if (arg_debug) |
408 | sh = "/bin/csh"; | 397 | printf("Autoselecting %s as shell\n", cfg.shell); |
409 | else | ||
410 | sh = "/bin/bash"; | ||
411 | |||
412 | char *arg[5]; | 398 | char *arg[5]; |
413 | arg[0] = sh; | 399 | arg[0] = cfg.shell; |
414 | arg[1] = "-c"; | 400 | arg[1] = "-c"; |
415 | if (arg_debug) | 401 | if (arg_debug) |
416 | printf("Starting %s\n", cfg.command_line); | 402 | printf("Starting %s\n", cfg.command_line); |
@@ -423,7 +409,10 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
423 | arg[3] = cfg.command_line; | 409 | arg[3] = cfg.command_line; |
424 | arg[4] = NULL; | 410 | arg[4] = NULL; |
425 | } | 411 | } |
426 | execvp("/bin/bash", arg); | 412 | execvp(arg[0], arg); |
413 | |||
414 | // it should never get here | ||
415 | errExit("execvp"); | ||
427 | } | 416 | } |
428 | } | 417 | } |
429 | 418 | ||
diff --git a/src/firejail/main.c b/src/firejail/main.c index acae7c3dd..8a4d627f3 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -709,6 +709,32 @@ static void detect_quiet(int argc, char **argv) { | |||
709 | } | 709 | } |
710 | } | 710 | } |
711 | 711 | ||
712 | char *guess_shell(void) { | ||
713 | char *shell; | ||
714 | // shells in order of preference | ||
715 | char *shells[] = {"/bin/bash", "/bin/csh", "/usr/bin/zsh", "/bin/sh", "/bin/ash", NULL }; | ||
716 | |||
717 | int i = 0; | ||
718 | while (shells[i] != NULL) { | ||
719 | struct stat s; | ||
720 | // access call checks as real UID/GID, not as effective UID/GID | ||
721 | if (stat(shells[i], &s) == 0 && access(shells[i], R_OK) == 0) { | ||
722 | shell = shells[i]; | ||
723 | break; | ||
724 | } | ||
725 | i++; | ||
726 | } | ||
727 | |||
728 | |||
729 | // FIXME get rid of arg_csh and arg_zsh completely | ||
730 | if (strcmp(shell,"/bin/csh")) | ||
731 | arg_csh = 1; | ||
732 | if (strcmp(shell,"/usr/bin/zsh") || strcmp(shell,"/bin/zsh")) | ||
733 | arg_zsh = 1; | ||
734 | |||
735 | return shell; | ||
736 | } | ||
737 | |||
712 | //******************************************* | 738 | //******************************************* |
713 | // Main program | 739 | // Main program |
714 | //******************************************* | 740 | //******************************************* |
@@ -1857,26 +1883,28 @@ int main(int argc, char **argv) { | |||
1857 | fprintf(stderr, "Error: --shell=none was already specified.\n"); | 1883 | fprintf(stderr, "Error: --shell=none was already specified.\n"); |
1858 | return 1; | 1884 | return 1; |
1859 | } | 1885 | } |
1860 | if (arg_zsh || cfg.shell ) { | 1886 | if (cfg.shell) { |
1861 | fprintf(stderr, "Error: only one default user shell can be specified\n"); | 1887 | fprintf(stderr, "Error: only one default user shell can be specified\n"); |
1862 | return 1; | 1888 | return 1; |
1863 | } | 1889 | } |
1864 | arg_csh = 1; | 1890 | arg_csh = 1; |
1891 | cfg.shell = "/bin/csh"; | ||
1865 | } | 1892 | } |
1866 | else if (strcmp(argv[i], "--zsh") == 0) { | 1893 | else if (strcmp(argv[i], "--zsh") == 0) { |
1867 | if (arg_shell_none) { | 1894 | if (arg_shell_none) { |
1868 | fprintf(stderr, "Error: --shell=none was already specified.\n"); | 1895 | fprintf(stderr, "Error: --shell=none was already specified.\n"); |
1869 | return 1; | 1896 | return 1; |
1870 | } | 1897 | } |
1871 | if (arg_csh || cfg.shell ) { | 1898 | if (cfg.shell) { |
1872 | fprintf(stderr, "Error: only one default user shell can be specified\n"); | 1899 | fprintf(stderr, "Error: only one default user shell can be specified\n"); |
1873 | return 1; | 1900 | return 1; |
1874 | } | 1901 | } |
1875 | arg_zsh = 1; | 1902 | arg_zsh = 1; |
1903 | cfg.shell = "/bin/zsh"; | ||
1876 | } | 1904 | } |
1877 | else if (strcmp(argv[i], "--shell=none") == 0) { | 1905 | else if (strcmp(argv[i], "--shell=none") == 0) { |
1878 | arg_shell_none = 1; | 1906 | arg_shell_none = 1; |
1879 | if (arg_csh || arg_zsh || cfg.shell) { | 1907 | if (cfg.shell) { |
1880 | fprintf(stderr, "Error: a shell was already specified\n"); | 1908 | fprintf(stderr, "Error: a shell was already specified\n"); |
1881 | return 1; | 1909 | return 1; |
1882 | } | 1910 | } |
@@ -1888,7 +1916,7 @@ int main(int argc, char **argv) { | |||
1888 | } | 1916 | } |
1889 | invalid_filename(argv[i] + 8); | 1917 | invalid_filename(argv[i] + 8); |
1890 | 1918 | ||
1891 | if (arg_csh || arg_zsh || cfg.shell) { | 1919 | if (cfg.shell) { |
1892 | fprintf(stderr, "Error: only one user shell can be specified\n"); | 1920 | fprintf(stderr, "Error: only one user shell can be specified\n"); |
1893 | return 1; | 1921 | return 1; |
1894 | } | 1922 | } |
@@ -1970,27 +1998,24 @@ int main(int argc, char **argv) { | |||
1970 | free(msg); | 1998 | free(msg); |
1971 | } | 1999 | } |
1972 | 2000 | ||
1973 | // build the sandbox command | 2001 | // guess shell if unspecified |
1974 | if (prog_index == -1 && arg_zsh) { | 2002 | // if (!arg_shell_none && !cfg.shell) { |
1975 | cfg.command_line = "/usr/bin/zsh"; | 2003 | if (prog_index == -1 && !cfg.shell) { |
1976 | cfg.window_title = "/usr/bin/zsh"; | 2004 | cfg.shell = guess_shell(); |
1977 | cfg.command_name = "zsh"; | 2005 | if (!cfg.shell) { |
1978 | } | 2006 | fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); |
1979 | else if (prog_index == -1 && arg_csh) { | 2007 | exit(1); |
1980 | cfg.command_line = "/bin/csh"; | 2008 | } |
1981 | cfg.window_title = "/bin/csh"; | 2009 | if (arg_debug) |
1982 | cfg.command_name = "csh"; | 2010 | printf("Autoselecting %s as shell\n", cfg.shell); |
1983 | } | 2011 | } |
1984 | else if (prog_index == -1 && cfg.shell) { | 2012 | |
2013 | // build the sandbox command | ||
2014 | if (prog_index == -1 && cfg.shell) { | ||
1985 | cfg.command_line = cfg.shell; | 2015 | cfg.command_line = cfg.shell; |
1986 | cfg.window_title = cfg.shell; | 2016 | cfg.window_title = cfg.shell; |
1987 | cfg.command_name = cfg.shell; | 2017 | cfg.command_name = cfg.shell; |
1988 | } | 2018 | } |
1989 | else if (prog_index == -1) { | ||
1990 | cfg.command_line = "/bin/bash"; | ||
1991 | cfg.window_title = "/bin/bash"; | ||
1992 | cfg.command_name = "bash"; | ||
1993 | } | ||
1994 | else if (arg_appimage) { | 2019 | else if (arg_appimage) { |
1995 | if (arg_debug) | 2020 | if (arg_debug) |
1996 | printf("Configuring appimage environment\n"); | 2021 | printf("Configuring appimage environment\n"); |
@@ -2000,6 +2025,10 @@ int main(int argc, char **argv) { | |||
2000 | else { | 2025 | else { |
2001 | build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index); | 2026 | build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index); |
2002 | } | 2027 | } |
2028 | /* else { | ||
2029 | fprintf(stderr, "Error: command must be specified when --shell=none used.\n"); | ||
2030 | exit(1); | ||
2031 | }*/ | ||
2003 | 2032 | ||
2004 | assert(cfg.command_name); | 2033 | assert(cfg.command_name); |
2005 | if (arg_debug) | 2034 | 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"); |