aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-08-14 08:45:25 -0400
committerLibravatar GitHub <noreply@github.com>2016-08-14 08:45:25 -0400
commitfd47862fae009368641b1f64153e3184e7966f18 (patch)
tree9a924753bcfe368fcdef79207439aac716e59e6f /src
parentMerge pull request #711 from Fred-Barclay/sandy_shores (diff)
parentjoin fixes (diff)
downloadfirejail-fd47862fae009368641b1f64153e3184e7966f18.tar.gz
firejail-fd47862fae009368641b1f64153e3184e7966f18.tar.zst
firejail-fd47862fae009368641b1f64153e3184e7966f18.zip
Merge pull request #709 from manevich/shell
Gather shell selection code in one place
Diffstat (limited to 'src')
-rw-r--r--src/firejail/bandwidth.c8
-rw-r--r--src/firejail/env.c4
-rw-r--r--src/firejail/firejail.h3
-rw-r--r--src/firejail/fs.c15
-rw-r--r--src/firejail/fs_home.c5
-rw-r--r--src/firejail/join.c47
-rw-r--r--src/firejail/main.c79
-rw-r--r--src/firejail/sandbox.c17
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
222extern int arg_command; // -c 222extern int arg_command; // -c
223extern int arg_overlay; // overlay option 223extern int arg_overlay; // overlay option
224extern int arg_overlay_keep; // place overlay diff directory in ~/.firejail 224extern int arg_overlay_keep; // place overlay diff directory in ~/.firejail
225extern int arg_zsh; // use zsh as default shell
226extern int arg_csh; // use csh as default shell
227 225
228extern int arg_seccomp; // enable default seccomp filter 226extern int arg_seccomp; // enable default seccomp filter
229 227
@@ -277,6 +275,7 @@ extern int fullargc;
277 275
278// main.c 276// main.c
279void check_user_namespace(void); 277void check_user_namespace(void);
278char *guess_shell(void);
280 279
281// sandbox.c 280// sandbox.c
282int sandbox(void* sandbox_arg); 281int 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
33static void skel(const char *homedir, uid_t u, gid_t g) { 33static 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
60int arg_command = 0; // -c 60int arg_command = 0; // -c
61int arg_overlay = 0; // overlay option 61int arg_overlay = 0; // overlay option
62int arg_overlay_keep = 0; // place overlay diff directory in ~/.firejail 62int arg_overlay_keep = 0; // place overlay diff directory in ~/.firejail
63int arg_zsh = 0; // use zsh as default shell
64int arg_csh = 0; // use csh as default shell
65 63
66int arg_seccomp = 0; // enable default seccomp filter 64int 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
723char *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");