From 9614b8ac4bf2661f6378abc7db18169fb867d6bb Mon Sep 17 00:00:00 2001 From: Aleksey Manevich Date: Sat, 13 Aug 2016 21:12:22 +0300 Subject: shell selection --- src/firejail/bandwidth.c | 8 +++--- src/firejail/env.c | 4 --- src/firejail/firejail.h | 1 + src/firejail/fs.c | 15 +++++------ src/firejail/join.c | 59 +++++++++++++++++------------------------ src/firejail/main.c | 69 ++++++++++++++++++++++++++++++++++-------------- src/firejail/sandbox.c | 17 +++--------- 7 files changed, 90 insertions(+), 83 deletions(-) (limited to 'src') 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 if (setregid(0, 0)) errExit("setregid"); + assert(cfg.shell); + char *arg[4]; - arg[0] = "/bin/bash"; + arg[0] = cfg.shell; arg[1] = "-c"; arg[2] = cmd; arg[3] = NULL; - execvp("/bin/bash", arg); + execvp(arg[0], arg); // it will never get here - exit(0); + errExit("execvp"); } 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) { errExit("setenv"); if (setenv("container", "firejail", 1) < 0) // LXC sets container=lxc, errExit("setenv"); - if (arg_zsh && setenv("SHELL", "/usr/bin/zsh", 1) < 0) - errExit("setenv"); - if (arg_csh && setenv("SHELL", "/bin/csh", 1) < 0) - errExit("setenv"); if (cfg.shell && setenv("SHELL", cfg.shell, 1) < 0) errExit("setenv"); // 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; // main.c void check_user_namespace(void); +char *guess_shell(void); // sandbox.c 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) { } free(name); - // check /bin/bash -// if (asprintf(&name, "%s/bin/bash", rootdir) == -1) -// errExit("asprintf"); -// if (stat(name, &s) == -1) { -// fprintf(stderr, "Error: cannot find /bin/bash in chroot directory\n"); -// return 1; -// } -// free(name); + // check shell + if (!arg_shell_none) { + if (stat(cfg.shell, &s) == -1) { + fprintf(stderr, "Error: cannot find %s in chroot directory\n", cfg.shell); + return 1; + } + } // check x11 socket directory 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) { } } - // run cmdline trough /bin/bash + // run cmdline trough shell if (cfg.command_line == NULL) { + cfg.shell = guess_shell(); + if (!cfg.shell) { + fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); + exit(1); + } + if (arg_debug) + printf("Autoselecting %s as shell\n", cfg.shell); // replace the process with a shell - if (cfg.shell) - execlp(cfg.shell, cfg.shell, NULL); - else if (arg_zsh) - execlp("/usr/bin/zsh", "/usr/bin/zsh", NULL); - else if (arg_csh) - execlp("/bin/csh", "/bin/csh", NULL); - else { - struct stat s; - if (stat("/bin/bash", &s) == 0) - execlp("/bin/bash", "/bin/bash", NULL); - else if (stat("/usr/bin/zsh", &s) == 0) - execlp("/usr/bin/zsh", "/usr/bin/zsh", NULL); - else if (stat("/bin/csh", &s) == 0) - execlp("/bin/csh", "/bin/csh", NULL); - else if (stat("/bin/sh", &s) == 0) - execlp("/bin/sh", "/bin/sh", NULL); - } + execlp(cfg.shell, cfg.shell, NULL); - // no shell found, print an error and exit - fprintf(stderr, "Error: no POSIX shell found\n"); - sleep(5); - exit(1); + // it should never get here + errExit("execlp"); } else { // run the command supplied by the user @@ -398,19 +387,16 @@ void join(pid_t pid, int argc, char **argv, int index) { execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); exit(1); } else { - // choose the shell requested by the user, or use bash as default - char *sh; - if (cfg.shell) - sh = cfg.shell; - else if (arg_zsh) - sh = "/usr/bin/zsh"; - else if (arg_csh) - sh = "/bin/csh"; - else - sh = "/bin/bash"; - +// assert(cfg.shell); + cfg.shell = guess_shell(); + if (!cfg.shell) { + fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); + exit(1); + } + if (arg_debug) + printf("Autoselecting %s as shell\n", cfg.shell); char *arg[5]; - arg[0] = sh; + arg[0] = cfg.shell; arg[1] = "-c"; if (arg_debug) printf("Starting %s\n", cfg.command_line); @@ -423,7 +409,10 @@ void join(pid_t pid, int argc, char **argv, int index) { arg[3] = cfg.command_line; arg[4] = NULL; } - execvp("/bin/bash", arg); + execvp(arg[0], arg); + + // it should never get here + errExit("execvp"); } } 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) { } } +char *guess_shell(void) { + char *shell; + // shells in order of preference + char *shells[] = {"/bin/bash", "/bin/csh", "/usr/bin/zsh", "/bin/sh", "/bin/ash", NULL }; + + int i = 0; + while (shells[i] != NULL) { + struct stat s; + // access call checks as real UID/GID, not as effective UID/GID + if (stat(shells[i], &s) == 0 && access(shells[i], R_OK) == 0) { + shell = shells[i]; + break; + } + i++; + } + + + // FIXME get rid of arg_csh and arg_zsh completely + if (strcmp(shell,"/bin/csh")) + arg_csh = 1; + if (strcmp(shell,"/usr/bin/zsh") || strcmp(shell,"/bin/zsh")) + arg_zsh = 1; + + return shell; +} + //******************************************* // Main program //******************************************* @@ -1857,26 +1883,28 @@ int main(int argc, char **argv) { fprintf(stderr, "Error: --shell=none was already specified.\n"); return 1; } - if (arg_zsh || cfg.shell ) { + if (cfg.shell) { fprintf(stderr, "Error: only one default user shell can be specified\n"); return 1; } arg_csh = 1; + cfg.shell = "/bin/csh"; } else if (strcmp(argv[i], "--zsh") == 0) { if (arg_shell_none) { fprintf(stderr, "Error: --shell=none was already specified.\n"); return 1; } - if (arg_csh || cfg.shell ) { + if (cfg.shell) { fprintf(stderr, "Error: only one default user shell can be specified\n"); return 1; } arg_zsh = 1; + cfg.shell = "/bin/zsh"; } else if (strcmp(argv[i], "--shell=none") == 0) { arg_shell_none = 1; - if (arg_csh || arg_zsh || cfg.shell) { + if (cfg.shell) { fprintf(stderr, "Error: a shell was already specified\n"); return 1; } @@ -1888,7 +1916,7 @@ int main(int argc, char **argv) { } invalid_filename(argv[i] + 8); - if (arg_csh || arg_zsh || cfg.shell) { + if (cfg.shell) { fprintf(stderr, "Error: only one user shell can be specified\n"); return 1; } @@ -1970,27 +1998,24 @@ int main(int argc, char **argv) { free(msg); } - // build the sandbox command - if (prog_index == -1 && arg_zsh) { - cfg.command_line = "/usr/bin/zsh"; - cfg.window_title = "/usr/bin/zsh"; - cfg.command_name = "zsh"; - } - else if (prog_index == -1 && arg_csh) { - cfg.command_line = "/bin/csh"; - cfg.window_title = "/bin/csh"; - cfg.command_name = "csh"; + // guess shell if unspecified +// if (!arg_shell_none && !cfg.shell) { + if (prog_index == -1 && !cfg.shell) { + cfg.shell = guess_shell(); + if (!cfg.shell) { + fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); + exit(1); + } + if (arg_debug) + printf("Autoselecting %s as shell\n", cfg.shell); } - else if (prog_index == -1 && cfg.shell) { + + // build the sandbox command + if (prog_index == -1 && cfg.shell) { cfg.command_line = cfg.shell; cfg.window_title = cfg.shell; cfg.command_name = cfg.shell; } - else if (prog_index == -1) { - cfg.command_line = "/bin/bash"; - cfg.window_title = "/bin/bash"; - cfg.command_name = "bash"; - } else if (arg_appimage) { if (arg_debug) printf("Configuring appimage environment\n"); @@ -2000,6 +2025,10 @@ int main(int argc, char **argv) { else { build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index); } +/* else { + fprintf(stderr, "Error: command must be specified when --shell=none used.\n"); + exit(1); + }*/ assert(cfg.command_name); 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) { // start the program using a shell //**************************************** else { - // choose the shell requested by the user, or use bash as default - char *sh; - if (cfg.shell) - sh = cfg.shell; - else if (arg_zsh) - sh = "/usr/bin/zsh"; - else if (arg_csh) - sh = "/bin/csh"; - else - sh = "/bin/bash"; - + assert(cfg.shell); + char *arg[5]; int index = 0; - arg[index++] = sh; + arg[index++] = cfg.shell; arg[index++] = "-c"; assert(cfg.command_line); if (arg_debug) @@ -368,7 +359,7 @@ static void start_application(void) { if (!arg_command && !arg_quiet) printf("Child process initialized\n"); - execvp(sh, arg); + execvp(arg[0], arg); } perror("execvp"); -- cgit v1.2.3-70-g09d2 From ba27a763ad86978857a8c50bdd83a9bf894e74d7 Mon Sep 17 00:00:00 2001 From: Aleksey Manevich Date: Sat, 13 Aug 2016 22:54:29 +0300 Subject: small fix --- src/firejail/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/firejail/main.c b/src/firejail/main.c index 8a4d627f3..87c8389ad 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -1999,8 +1999,7 @@ int main(int argc, char **argv) { } // guess shell if unspecified -// if (!arg_shell_none && !cfg.shell) { - if (prog_index == -1 && !cfg.shell) { + if (!arg_shell_none && !cfg.shell) { cfg.shell = guess_shell(); if (!cfg.shell) { fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); -- cgit v1.2.3-70-g09d2 From 9f5dfa5964f82fa03b5b86c705b1f599c9887316 Mon Sep 17 00:00:00 2001 From: Aleksey Manevich Date: Sun, 14 Aug 2016 13:33:22 +0300 Subject: join fixes --- src/firejail/firejail.h | 2 -- src/firejail/fs_home.c | 5 +++-- src/firejail/join.c | 18 +++--------------- src/firejail/main.c | 25 +++++++++++++------------ 4 files changed, 19 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 0de2a354d..c45b324fc 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -222,8 +222,6 @@ extern int arg_nonetwork; // --net=none extern int arg_command; // -c extern int arg_overlay; // overlay option extern int arg_overlay_keep; // place overlay diff directory in ~/.firejail -extern int arg_zsh; // use zsh as default shell -extern int arg_csh; // use csh as default shell extern int arg_seccomp; // enable default seccomp filter 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 @@ static void skel(const char *homedir, uid_t u, gid_t g) { char *fname; + // zsh - if (arg_zsh) { + if (!arg_shell_none && (strcmp(cfg.shell,"/usr/bin/zsh") == 0 || strcmp(cfg.shell,"/bin/zsh") == 0)) { // copy skel files if (asprintf(&fname, "%s/.zshrc", homedir) == -1) errExit("asprintf"); @@ -63,7 +64,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) { free(fname); } // csh - else if (arg_csh) { + else if (!arg_shell_none && strcmp(cfg.shell,"/bin/csh") == 0) { // copy skel files if (asprintf(&fname, "%s/.cshrc", homedir) == -1) errExit("asprintf"); diff --git a/src/firejail/join.c b/src/firejail/join.c index 80ed1dc51..632715fea 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c @@ -332,13 +332,7 @@ void join(pid_t pid, int argc, char **argv, int index) { // run cmdline trough shell if (cfg.command_line == NULL) { - cfg.shell = guess_shell(); - if (!cfg.shell) { - fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); - exit(1); - } - if (arg_debug) - printf("Autoselecting %s as shell\n", cfg.shell); + assert(cfg.shell); // replace the process with a shell execlp(cfg.shell, cfg.shell, NULL); @@ -387,14 +381,8 @@ void join(pid_t pid, int argc, char **argv, int index) { execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); exit(1); } else { -// assert(cfg.shell); - cfg.shell = guess_shell(); - if (!cfg.shell) { - fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); - exit(1); - } - if (arg_debug) - printf("Autoselecting %s as shell\n", cfg.shell); + assert(cfg.shell); + char *arg[5]; arg[0] = cfg.shell; arg[1] = "-c"; diff --git a/src/firejail/main.c b/src/firejail/main.c index 87c8389ad..e0f2a676c 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -60,8 +60,6 @@ int arg_nonetwork = 0; // --net=none int arg_command = 0; // -c int arg_overlay = 0; // overlay option int arg_overlay_keep = 0; // place overlay diff directory in ~/.firejail -int arg_zsh = 0; // use zsh as default shell -int arg_csh = 0; // use csh as default shell int arg_seccomp = 0; // enable default seccomp filter @@ -565,7 +563,18 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { #endif else if (strncmp(argv[i], "--join=", 7) == 0) { logargs(argc, argv); - + + if (arg_shell_none) { + if (argc <= (i+1)) { + fprintf(stderr, "Error: --shell=none set, but no command specified\n"); + exit(1); + } + cfg.original_program_index = i + 1; + } + + if (!cfg.shell && !arg_shell_none) + cfg.shell = guess_shell(); + // join sandbox by pid or by name pid_t pid; if (read_pid(argv[i] + 7, &pid) == 0) @@ -573,6 +582,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { else join_name(argv[i] + 7, argc, argv, i + 1); exit(0); + } #ifdef HAVE_NETWORK else if (strncmp(argv[i], "--join-network=", 15) == 0) { @@ -725,13 +735,6 @@ char *guess_shell(void) { i++; } - - // FIXME get rid of arg_csh and arg_zsh completely - if (strcmp(shell,"/bin/csh")) - arg_csh = 1; - if (strcmp(shell,"/usr/bin/zsh") || strcmp(shell,"/bin/zsh")) - arg_zsh = 1; - return shell; } @@ -1887,7 +1890,6 @@ int main(int argc, char **argv) { fprintf(stderr, "Error: only one default user shell can be specified\n"); return 1; } - arg_csh = 1; cfg.shell = "/bin/csh"; } else if (strcmp(argv[i], "--zsh") == 0) { @@ -1899,7 +1901,6 @@ int main(int argc, char **argv) { fprintf(stderr, "Error: only one default user shell can be specified\n"); return 1; } - arg_zsh = 1; cfg.shell = "/bin/zsh"; } else if (strcmp(argv[i], "--shell=none") == 0) { -- cgit v1.2.3-70-g09d2