From b1b1e774a175fe2ee35aa22d02c097e13873a5a9 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Wed, 8 Nov 2017 08:30:10 -0500 Subject: private-bin and private-lib fixes --- src/firejail/firejail.h | 1 + src/firejail/fs_bin.c | 58 ++++++++++++++++++++----------------------------- src/firejail/fs_lib.c | 19 +++++++--------- src/firejail/main.c | 3 +++ src/firejail/usage.c | 1 + src/man/firejail.txt | 3 +++ 6 files changed, 39 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index b0b7e4e77..5d6d94d16 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -310,6 +310,7 @@ extern int arg_debug; // print debug messages extern int arg_debug_check_filename; // print debug messages for filename checking extern int arg_debug_blacklists; // print debug messages for blacklists extern int arg_debug_whitelists; // print debug messages for whitelists +extern int arg_debug_private_lib; // print debug messages for private-lib extern int arg_nonetwork; // --net=none extern int arg_command; // -c extern int arg_overlay; // overlay option diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c index a17c8dac0..364431077 100644 --- a/src/firejail/fs_bin.c +++ b/src/firejail/fs_bin.c @@ -99,16 +99,23 @@ static char *check_dir_or_file(const char *name) { static int valid_full_path_file(const char *name) { assert(name); - char *real_path = realpath(name, NULL); - if (!real_path) - goto errexit; - char *fname = strrchr(real_path, '/'); - if (!fname) - goto errexit; - if (*(++fname) == '\0') - goto errexit; - - int found = 0; + if (*name != '/') + return 0; + if (strstr(name, "..")) + return 0; + + // do we have a file? + struct stat s; + if (stat(name, &s) == -1) + return 0; + // directories not allowed + if (S_ISDIR(s.st_mode)) + return 0; + // checking access + if (access(name, X_OK) == -1) + return 0; + + // check standard paths int i = 0; while (paths[i]) { // private-bin-no-local can be disabled in /etc/firejail/firejail.config @@ -117,34 +124,13 @@ static int valid_full_path_file(const char *name) { continue; } - // check file - char *path; - if (asprintf(&path, "%s/%s", paths[i], fname) == -1) - errExit("asprintf"); - - if (strcmp(real_path, path) == 0) { - free(path); - // checking access - if (access(real_path, X_OK) == 0) - found = 1; - break; - } - - free(path); + int len = strlen(paths[i]); + if (strncmp(name, paths[i], len) == 0 && name[len] == '/' && name[len + 1] != '\0') + return 1; i++; } - - if (!found) - goto errexit; - - free(real_path); - return 1; - -errexit: if (arg_debug) - fwarning("file %s not found\n", name); - if (real_path) - free(real_path); + printf("file %s not found\n", name); return 0; } @@ -205,6 +191,7 @@ static void duplicate(char *fname, FILE *fplist) { char *actual_path = realpath(full_path, NULL); if (actual_path) { if (valid_full_path_file(actual_path)) { + // solving problems such as /bin/sh -> /bin/dash // copy the real file pointed by symlink sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, actual_path, RUN_BIN_DIR); char *f = strrchr(actual_path, '/'); @@ -214,6 +201,7 @@ static void duplicate(char *fname, FILE *fplist) { free(actual_path); } } + // copy a file or a symlink sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, full_path, RUN_BIN_DIR); } diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c index 59c0c5261..23fdb8a6a 100644 --- a/src/firejail/fs_lib.c +++ b/src/firejail/fs_lib.c @@ -23,7 +23,6 @@ #include #include #include - #define MAXBUF 4096 static const char * const lib_paths[] = { @@ -69,8 +68,6 @@ static char *build_dest_dir(const char *full_path) { // copy fname in private_run_dir void fslib_duplicate(const char *full_path) { assert(full_path); - if (arg_debug) - printf("fslib_duplicate %s\n", full_path); struct stat s; if (stat(full_path, &s) != 0 || s.st_uid != 0 || access(full_path, R_OK)) @@ -95,7 +92,7 @@ void fslib_duplicate(const char *full_path) { } free(name); - if (arg_debug) + if (arg_debug || arg_debug_private_lib) printf("copying %s to private %s\n", full_path, dest_dir); sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", full_path, dest_dir); @@ -109,13 +106,13 @@ void fslib_duplicate(const char *full_path) { // lib is not copied, only libraries used by it void fslib_copy_libs(const char *full_path) { assert(full_path); - if (arg_debug) + if (arg_debug || arg_debug_private_lib) printf("fslib_copy_libs %s\n", full_path); // if library/executable does not exist or the user does not have read access to it // print a warning and exit the function. if (access(full_path, R_OK)) { - if (arg_debug) + if (arg_debug || arg_debug_private_lib) printf("cannot find %s for private-lib, skipping...\n", full_path); return; } @@ -127,7 +124,7 @@ void fslib_copy_libs(const char *full_path) { errExit("chown"); // run fldd to extact the list of files - if (arg_debug) + if (arg_debug || arg_debug_private_lib) printf("runing fldd %s\n", full_path); sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, full_path, RUN_LIB_FILE); @@ -150,7 +147,7 @@ void fslib_copy_libs(const char *full_path) { void fslib_copy_dir(const char *full_path) { assert(full_path); - if (arg_debug) + if (arg_debug || arg_debug_private_lib) printf("fslib_copy_dir %s\n", full_path); // do nothing if the directory does not exist or is not owned by root @@ -216,7 +213,7 @@ static char *valid_file(const char *lib) { static void mount_directories(void) { - if (arg_debug) + if (arg_debug || arg_debug_private_lib) printf("Mount-bind %s on top of /lib /lib64 /usr/lib\n", RUN_LIB_DIR); if (is_dir("/lib")) { @@ -262,7 +259,7 @@ void fs_private_lib(void) { return; #endif char *private_list = cfg.lib_private_keep; - if (arg_debug) + if (arg_debug || arg_debug_private_lib) printf("Starting private-lib processing: program %s, shell %s\n", (cfg.original_program_index > 0)? cfg.original_argv[cfg.original_program_index]: "none", (arg_shell_none)? "none": cfg.shell); @@ -288,7 +285,7 @@ void fs_private_lib(void) { // for the listed libs if (private_list && *private_list != '\0') { - if (arg_debug) + if (arg_debug || arg_debug_private_lib) printf("Copying extra files (%s) in the new lib directory\n", private_list); char *dlist = strdup(private_list); diff --git a/src/firejail/main.c b/src/firejail/main.c index 7730e8384..c8b347b5f 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -49,6 +49,7 @@ int arg_debug = 0; // print debug messages int arg_debug_check_filename = 0; // print debug messages for filename checking int arg_debug_blacklists = 0; // print debug messages for blacklists int arg_debug_whitelists = 0; // print debug messages for whitelists +int arg_debug_private_lib = 0; // print debug messages for private-lib int arg_nonetwork = 0; // --net=none int arg_command = 0; // -c int arg_overlay = 0; // overlay option @@ -1125,6 +1126,8 @@ int main(int argc, char **argv) { arg_debug_blacklists = 1; else if (strcmp(argv[i], "--debug-whitelists") == 0) arg_debug_whitelists = 1; + else if (strcmp(argv[i], "--debug-private-lib") == 0) + arg_debug_private_lib = 1; else if (strcmp(argv[i], "--quiet") == 0) { arg_quiet = 1; arg_debug = 0; diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 0bc3b20fd..38de99471 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c @@ -64,6 +64,7 @@ void usage(void) { printf(" --debug-caps - print all recognized capabilities.\n"); printf(" --debug-check-filename - debug filename checking.\n"); printf(" --debug-errnos - print all recognized error numbers.\n"); + printf(" --debug-private-lib - debug for --private-lib option.\n"); printf(" --debug-protocols - print all recognized protocols.\n"); printf(" --debug-syscalls - print all recognized system calls.\n"); #ifdef HAVE_WHITELIST diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 476050d9c..9f6da87ee 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt @@ -356,6 +356,9 @@ Example: .br $ firejail \-\-debug-errnos .TP +\fB\-\-debug-private-lib +Debug messages for --private-lib option. +.TP \fB\-\-debug-protocols Print all recognized protocols in the current Firejail software build and exit. .br -- cgit v1.2.3-54-g00ecf