From edcd62d7523365165e23695d7daabc94f1e9f48d Mon Sep 17 00:00:00 2001 From: netblue30 Date: Wed, 16 Nov 2016 11:10:32 -0500 Subject: fcopy part 1 --- test/fcopy/cmdline.exp | 56 ++++++++++++++++++++++++++++++ test/fcopy/dircopy.exp | 86 ++++++++++++++++++++++++++++++++++++++++++++++ test/fcopy/fcopy.sh | 23 +++++++++++++ test/fcopy/filecopy.exp | 54 +++++++++++++++++++++++++++++ test/fcopy/linkcopy.exp | 86 ++++++++++++++++++++++++++++++++++++++++++++++ test/fcopy/src/a/b/file4 | 11 ++++++ test/fcopy/src/a/file3 | 0 test/fcopy/src/dircopy.exp | 1 + test/fcopy/src/file1 | 0 test/fcopy/src/file2 | 0 10 files changed, 317 insertions(+) create mode 100755 test/fcopy/cmdline.exp create mode 100755 test/fcopy/dircopy.exp create mode 100755 test/fcopy/fcopy.sh create mode 100755 test/fcopy/filecopy.exp create mode 100755 test/fcopy/linkcopy.exp create mode 100644 test/fcopy/src/a/b/file4 create mode 100644 test/fcopy/src/a/file3 create mode 120000 test/fcopy/src/dircopy.exp create mode 100755 test/fcopy/src/file1 create mode 100644 test/fcopy/src/file2 (limited to 'test/fcopy') diff --git a/test/fcopy/cmdline.exp b/test/fcopy/cmdline.exp new file mode 100755 index 000000000..95e221321 --- /dev/null +++ b/test/fcopy/cmdline.exp @@ -0,0 +1,56 @@ +#!/usr/bin/expect -f +# This file is part of Firejail project +# Copyright (C) 2014-2016 Firejail Authors +# License GPL v2 + +set timeout 10 +spawn $env(SHELL) +match_max 100000 + +send -- "/usr/lib/firejail/fcopy\r" +expect { + timeout {puts "TESTING ERROR 0\n";exit} + "files missing" +} +expect { + timeout {puts "TESTING ERROR 1\n";exit} + "Usage:" +} +after 100 + +send -- "/usr/lib/firejail/fcopy foo\r" +expect { + timeout {puts "TESTING ERROR 2\n";exit} + "files missing" +} +expect { + timeout {puts "TESTING ERROR 3\n";exit} + "Usage:" +} +after 100 + +send -- "/usr/lib/firejail/fcopy f%oo1 foo2\r" +expect { + timeout {puts "TESTING ERROR 4\n";exit} + "invalid file name" +} +after 100 + +send -- "/usr/lib/firejail/fcopy foo1 f,oo2\r" +expect { + timeout {puts "TESTING ERROR 5\n";exit} + "invalid file name" +} +after 100 + +send -- "/usr/lib/firejail/fcopy foo1 foo2\r" +expect { + timeout {puts "TESTING ERROR 6\n";exit} + "cannot find destination directory" +} +after 100 + + + + +puts "\nall done\n" diff --git a/test/fcopy/dircopy.exp b/test/fcopy/dircopy.exp new file mode 100755 index 000000000..b87f24a59 --- /dev/null +++ b/test/fcopy/dircopy.exp @@ -0,0 +1,86 @@ +#!/usr/bin/expect -f +# This file is part of Firejail project +# Copyright (C) 2014-2016 Firejail Authors +# License GPL v2 + +# +# copy directory src to dest +# +set timeout 10 +spawn $env(SHELL) +match_max 100000 + +send -- "rm -fr dest/*\r" +after 100 + +send -- "/usr/lib/firejail/fcopy src dest\r" +after 100 + +send -- "find dest\r" +expect { + timeout {puts "TESTING ERROR 0\n";exit} + "dest/" +} +expect { + timeout {puts "TESTING ERROR 1\n";exit} + "dest/a" +} +expect { + timeout {puts "TESTING ERROR 2\n";exit} + "dest/a/b" +} +expect { + timeout {puts "TESTING ERROR 3\n";exit} + "dest/a/b/file4" +} +expect { + timeout {puts "TESTING ERROR 4\n";exit} + "dest/a/file3" +} +expect { + timeout {puts "TESTING ERROR 5\n";exit} + "dest/dircopy.exp" +} +expect { + timeout {puts "TESTING ERROR 6\n";exit} + "dest/file2" +} +expect { + timeout {puts "TESTING ERROR 7\n";exit} + "dest/file1" +} +after 100 + + +send -- "ls -al dest\r" +expect { + timeout {puts "TESTING ERROR 8\n";exit} + "drwx--x--x" +} +expect { + timeout {puts "TESTING ERROR 9\n";exit} + "rwxrwxrwx" +} +expect { + timeout {puts "TESTING ERROR 10\n";exit} + "rw-r--r--" +} +after 100 + +send -- "diff -q src/a/b/file4 dest/a/b/file4; echo done\r" +expect { + timeout {puts "TESTING ERROR 11\n";exit} + "differ" {puts "TESTING ERROR 12\n";exit} + "done" +} + +send -- "file dest/dircopy.exp\r" +expect { + timeout {puts "TESTING ERROR 13\n";exit} + "symbolic link" +} + +send -- "rm -fr dest/*\r" +after 100 + +puts "\nall done\n" diff --git a/test/fcopy/fcopy.sh b/test/fcopy/fcopy.sh new file mode 100755 index 000000000..9961d6317 --- /dev/null +++ b/test/fcopy/fcopy.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# This file is part of Firejail project +# Copyright (C) 2014-2016 Firejail Authors +# License GPL v2 + +export MALLOC_CHECK_=3 +export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) + +rm -fr dest/* + +echo "TESTING: fcopy cmdline (test/fcopy/cmdline.exp)" +./cmdline.exp + +echo "TESTING: fcopy directory (test/fcopy/dircopy.exp)" +./dircopy.exp + +echo "TESTING: fcopy file (test/fcopy/filecopy.exp)" +./filecopy.exp + +echo "TESTING: fcopy link (test/fcopy/linkcopy.exp)" +./linkcopy.exp + +rm -fr dest/* diff --git a/test/fcopy/filecopy.exp b/test/fcopy/filecopy.exp new file mode 100755 index 000000000..9927e18fe --- /dev/null +++ b/test/fcopy/filecopy.exp @@ -0,0 +1,54 @@ +#!/usr/bin/expect -f +# This file is part of Firejail project +# Copyright (C) 2014-2016 Firejail Authors +# License GPL v2 + +# +# copy directory src to dest +# +set timeout 10 +spawn $env(SHELL) +match_max 100000 + +send -- "rm -fr dest/*\r" +after 100 + +send -- "/usr/lib/firejail/fcopy src/dircopy.exp dest\r" +after 100 + +send -- "find dest\r" +expect { + timeout {puts "TESTING ERROR 0\n";exit} + "dest/" +} +expect { + timeout {puts "TESTING ERROR 1\n";exit} + "dest/dircopy.exp" +} +after 100 + + +send -- "ls -al dest\r" +expect { + timeout {puts "TESTING ERROR 2\n";exit} + "lrwxrwxrwx" +} +after 100 + +send -- "diff -q dircopy.exp dest/dircopy.exp; echo done\r" +expect { + timeout {puts "TESTING ERROR 3\n";exit} + "differ" {puts "TESTING ERROR 4\n";exit} + "done" +} + +send -- "file dest/dircopy.exp\r" +expect { + timeout {puts "TESTING ERROR 5\n";exit} + "symbolic link" +} + +send -- "rm -fr dest/*\r" +after 100 + +puts "\nall done\n" diff --git a/test/fcopy/linkcopy.exp b/test/fcopy/linkcopy.exp new file mode 100755 index 000000000..b87f24a59 --- /dev/null +++ b/test/fcopy/linkcopy.exp @@ -0,0 +1,86 @@ +#!/usr/bin/expect -f +# This file is part of Firejail project +# Copyright (C) 2014-2016 Firejail Authors +# License GPL v2 + +# +# copy directory src to dest +# +set timeout 10 +spawn $env(SHELL) +match_max 100000 + +send -- "rm -fr dest/*\r" +after 100 + +send -- "/usr/lib/firejail/fcopy src dest\r" +after 100 + +send -- "find dest\r" +expect { + timeout {puts "TESTING ERROR 0\n";exit} + "dest/" +} +expect { + timeout {puts "TESTING ERROR 1\n";exit} + "dest/a" +} +expect { + timeout {puts "TESTING ERROR 2\n";exit} + "dest/a/b" +} +expect { + timeout {puts "TESTING ERROR 3\n";exit} + "dest/a/b/file4" +} +expect { + timeout {puts "TESTING ERROR 4\n";exit} + "dest/a/file3" +} +expect { + timeout {puts "TESTING ERROR 5\n";exit} + "dest/dircopy.exp" +} +expect { + timeout {puts "TESTING ERROR 6\n";exit} + "dest/file2" +} +expect { + timeout {puts "TESTING ERROR 7\n";exit} + "dest/file1" +} +after 100 + + +send -- "ls -al dest\r" +expect { + timeout {puts "TESTING ERROR 8\n";exit} + "drwx--x--x" +} +expect { + timeout {puts "TESTING ERROR 9\n";exit} + "rwxrwxrwx" +} +expect { + timeout {puts "TESTING ERROR 10\n";exit} + "rw-r--r--" +} +after 100 + +send -- "diff -q src/a/b/file4 dest/a/b/file4; echo done\r" +expect { + timeout {puts "TESTING ERROR 11\n";exit} + "differ" {puts "TESTING ERROR 12\n";exit} + "done" +} + +send -- "file dest/dircopy.exp\r" +expect { + timeout {puts "TESTING ERROR 13\n";exit} + "symbolic link" +} + +send -- "rm -fr dest/*\r" +after 100 + +puts "\nall done\n" diff --git a/test/fcopy/src/a/b/file4 b/test/fcopy/src/a/b/file4 new file mode 100644 index 000000000..ac318d7ab --- /dev/null +++ b/test/fcopy/src/a/b/file4 @@ -0,0 +1,11 @@ + + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam interdum at massa non aliquam. Maecenas molestie id orci volutpat porta. Praesent aliquam nunc quis mi tristique, ac feugiat enim rutrum. Nulla vitae metus sodales, pellentesque risus sit amet, volutpat nisl. Curabitur accumsan arcu congue lacus porta laoreet. Nulla facilisi. Integer nec augue id magna gravida tincidunt id vitae lorem. Curabitur facilisis, tellus vel pellentesque pretium, odio dolor efficitur lorem, et tincidunt dui enim cursus lacus. Cras a orci ac magna semper dapibus nec et velit. Nullam aliquam sollicitudin auctor. + +Mauris ac quam vel purus volutpat semper eget a ante. Curabitur arcu nisl, dapibus ac lectus ac, porttitor fermentum metus. Aliquam et sem aliquam magna interdum ultricies at eu orci. Aenean tortor augue, volutpat nec magna nec, rutrum bibendum justo. Vivamus ex quam, auctor ut pellentesque mattis, aliquet a eros. Etiam ac lacus ac ante ullamcorper sollicitudin a quis orci. Suspendisse quis justo ac mauris cursus finibus quis at elit. Vestibulum elementum finibus diam, eget convallis purus aliquet et. Fusce fermentum ornare urna, non ornare nisl tincidunt consectetur. Donec et lacus vitae ex eleifend porttitor id ut odio. Quisque luctus eget lorem et sollicitudin. + +Aliquam libero elit, finibus a nisl a, commodo viverra turpis. Nam pulvinar in est sit amet fermentum. Praesent scelerisque tempus lectus, ac porta elit sodales rutrum. Duis faucibus faucibus urna eget accumsan. Vivamus in turpis ut massa rhoncus pretium nec et lorem. Aenean at tellus eget metus porta ornare. Aliquam erat volutpat. Donec hendrerit a massa vel malesuada. Integer varius sapien et orci viverra pretium. In at velit aliquet, vulputate nisi lobortis, aliquam augue. + +Ut aliquam turpis ut lorem aliquam, in faucibus elit pulvinar. Vivamus viverra tortor ornare, lacinia leo sit amet, auctor arcu. Sed erat leo, pellentesque vel nibh a, malesuada vehicula purus. Vivamus est dolor, aliquet quis facilisis fermentum, varius in dolor. Nunc quis libero feugiat, imperdiet est vitae, mollis risus. Vestibulum elementum mattis lorem vitae gravida. Nullam id tellus interdum, aliquam erat eu, laoreet nunc. Aliquam ut felis vel mauris maximus pellentesque. + +Vestibulum tempus mauris eget ex interdum, vitae vehicula tortor sollicitudin. Pellentesque et dolor cursus dui vulputate laoreet. Morbi eu bibendum quam, at ultrices elit. Vestibulum dictum enim sit amet ultricies imperdiet. Praesent congue magna ac mauris mattis, a iaculis ante aliquet. Vivamus at egestas ex. Suspendisse orci dolor, pharetra at aliquam a, faucibus facilisis leo. Quisque semper lorem eget elit commodo pretium. Aenean posuere augue quis arcu finibus, sit amet fringilla risus congue. Pellentesque rutrum nunc leo, aliquam lobortis lacus molestie nec. Donec convallis congue diam, ullamcorper vestibulum dui varius nec. Praesent pellentesque nisi risus. In aliquam molestie malesuada. Nulla facilisis a risus eu tristique. Morbi molestie et arcu quis efficitur. Curabitur cursus vestibulum luctus. diff --git a/test/fcopy/src/a/file3 b/test/fcopy/src/a/file3 new file mode 100644 index 000000000..e69de29bb diff --git a/test/fcopy/src/dircopy.exp b/test/fcopy/src/dircopy.exp new file mode 120000 index 000000000..2acf88f7b --- /dev/null +++ b/test/fcopy/src/dircopy.exp @@ -0,0 +1 @@ +../dircopy.exp \ No newline at end of file diff --git a/test/fcopy/src/file1 b/test/fcopy/src/file1 new file mode 100755 index 000000000..e69de29bb diff --git a/test/fcopy/src/file2 b/test/fcopy/src/file2 new file mode 100644 index 000000000..e69de29bb -- cgit v1.2.3-54-g00ecf From 98159c098b6afedfed20eecdc80719dae1f914ff Mon Sep 17 00:00:00 2001 From: netblue30 Date: Wed, 16 Nov 2016 16:40:12 -0500 Subject: fcopy part 2 --- gcov.sh | 28 +++-- src/fcopy/main.c | 36 +++---- src/firejail/firejail.h | 4 +- src/firejail/fs_etc.c | 31 ------ src/firejail/fs_home.c | 269 ++++++++++-------------------------------------- src/firejail/main.c | 2 - src/firejail/profile.c | 2 - src/firejail/util.c | 7 +- test/fcopy/cmdline.exp | 10 -- test/fcopy/filecopy.exp | 6 +- test/fcopy/linkcopy.exp | 46 ++------- 11 files changed, 101 insertions(+), 340 deletions(-) (limited to 'test/fcopy') diff --git a/gcov.sh b/gcov.sh index 6f668d65f..900b7ca41 100755 --- a/gcov.sh +++ b/gcov.sh @@ -1,22 +1,28 @@ #!/bin/bash +gcov_init() { + USER=`whoami` + firejail --help + firemon --help + /usr/lib/firejail/fnet --help + /usr/lib/firejail/fseccomp --help + /usr/lib/firejail/ftee --help + /usr/lib/firejail/fcopy --help + firecfg --help + sudo chown $USER:$USER `find .` +} + generate() { - lcov --capture -d src/firejail -d src/firemon -d src/fseccomp -d src/fnet -d src/ftee -d src/lib -d src/firecfg --output-file gcov-file + lcov --capture -d src/firejail -d src/firemon -d src/fcopy -d src/fseccomp -d src/fnet -d src/ftee -d src/lib -d src/firecfg --output-file gcov-file rm -fr gcov-dir genhtml gcov-file --output-directory gcov-dir } -# init -USER=`whoami` -firejail --help -firemon --help -/usr/lib/firejail/fnet --help -/usr/lib/firejail/fseccomp --help -/usr/lib/firejail/ftee --help -/usr/lib/firejail/fcopy --help -firecfg --help -sudo chown $USER:$USER `find .` +gcov_init generate +echo "press any key to continue, or Ctrl-C to exit" +read text + # running tests make test-root diff --git a/src/fcopy/main.c b/src/fcopy/main.c index 4437b90e5..82d829bba 100644 --- a/src/fcopy/main.c +++ b/src/fcopy/main.c @@ -130,10 +130,16 @@ static int fs_copydir(const char *infname, const struct stat *st, int ftype, str if (size_limit_reached) return 0; + char *outfname; if (asprintf(&outfname, "%s%s", outpath, infname + strlen(inpath)) == -1) errExit("asprintf"); +//printf("outpaht %s\n", outpath); +//printf("inpath %s\n", inpath); +//printf("infname %s\n", infname); +//printf("outfname %s\n\n", outfname); + // don't copy it if we already have the file struct stat s; if (stat(outfname, &s) == 0) { @@ -265,7 +271,7 @@ static void duplicate_link(const char *src, const char *dest, struct stat *s) { static void usage(void) { printf("Usage: fcopy src dest\n"); printf("Copy src file in dest directory. If src is a directory, copy all the files in\n"); - printf("src recoursively\n"); + printf("src recoursively. If the destination directory does not exist, it will be created.\n"); } int main(int argc, char **argv) { @@ -276,25 +282,16 @@ int i; for (i = 0; i < argc; i++) printf("*%s* ", argv[i]); printf("\n"); -} -#endif +} +#endif if (argc != 3) { fprintf(stderr, "Error fcopy: files missing\n"); usage(); exit(1); } - int i; - int index = 1; - for (i = 1; i < (argc - 2); i++) { - if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) { - usage(); - return 0; - } - } - // check the two files; remove ending / - char *src = argv[index]; + char *src = argv[1]; int len = strlen(src); if (src[len - 1] == '/') src[len - 1] = '\0'; @@ -303,7 +300,7 @@ printf("\n"); exit(1); } - char *dest = argv[index + 1]; + char *dest = argv[2]; len = strlen(dest); if (dest[len - 1] == '/') dest[len - 1] = '\0'; @@ -313,14 +310,11 @@ printf("\n"); } - // the destination should be a directory; remove ending / + // the destination should be a directory; struct stat s; - if (stat(dest, &s) == -1) { - fprintf(stderr, "Error fcopy: cannot find destination directory\n"); - exit(1); - } - if (S_ISDIR(s.st_mode) == -1) { - fprintf(stderr, "Error fcopy: the destination should be a directory\n"); + if (stat(dest, &s) == -1 || + !S_ISDIR(s.st_mode)) { + fprintf(stderr, "Error fcopy: invalid destination directory\n"); exit(1); } diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index d7ba539e6..80627fda8 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -490,8 +490,6 @@ void fs_private_template(void); void fs_check_private_dir(void); // check new private template home directory (--private-template= option) exit if it fails void fs_check_private_template(void); -// check directory list specified by user (--private-home option) - exit if it fails -void fs_check_home_list(void); void fs_private_home_list(void); @@ -557,7 +555,6 @@ void network_del_run_file(pid_t pid); void network_set_run_file(pid_t pid); // fs_etc.c -void fs_check_etc_list(void); void fs_private_etc_list(void); // no_sandbox.c @@ -681,6 +678,7 @@ void build_cmdline(char **command_line, char **window_title, int argc, char **ar #define PATH_FNET (LIBDIR "/firejail/fnet") #define PATH_FIREMON (PREFIX "/bin/firemon") #define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp") +#define PATH_FCOPY (LIBDIR "/firejail/fcopy") // bitmapped filters for sbox_run #define SBOX_ROOT (1 << 0) // run the sandbox as root #define SBOX_USER (1 << 1) // run the sandbox as a regular user diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c index 7e18840fd..6a70d482c 100644 --- a/src/firejail/fs_etc.c +++ b/src/firejail/fs_etc.c @@ -62,37 +62,6 @@ errexit: exit(1); } -void fs_check_etc_list(void) { - EUID_ASSERT(); - if (strstr(cfg.etc_private_keep, "..")) { - fprintf(stderr, "Error: invalid private etc list\n"); - exit(1); - } - - char *dlist = strdup(cfg.etc_private_keep); - if (!dlist) - errExit("strdup"); - - // build a new list only with the files found - char *newlist = malloc(strlen(cfg.etc_private_keep) + 1); - if (!newlist) - errExit("malloc"); - *newlist = '\0'; - - char *ptr = strtok(dlist, ","); - if (check_dir_or_file(ptr)) - strcat(newlist, ptr); - while ((ptr = strtok(NULL, ",")) != NULL) { - if (check_dir_or_file(ptr)) { - strcat(newlist, ","); - strcat(newlist, ptr); - } - } - cfg.etc_private_keep = newlist; - - free(dlist); -} - static void duplicate(char *fname) { // copy the file if (arg_debug) diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index 242482d26..d8cd9ce4d 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c @@ -28,7 +28,7 @@ #include #include #include -#include +//#include static void skel(const char *homedir, uid_t u, gid_t g) { char *fname; @@ -349,106 +349,6 @@ void fs_check_private_dir(void) { //*********************************************************************************** // --private-home //*********************************************************************************** -#define PRIVATE_COPY_LIMIT (500 * 1024 *1024) -static int size_limit_reached = 0; -static unsigned file_cnt = 0; -static unsigned size_cnt = 0; -static char *check_dir_or_file(const char *name); - -int fs_copydir(const char *path, const struct stat *st, int ftype, struct FTW *sftw) { - (void) st; - (void) sftw; - if (size_limit_reached) - return 0; - - struct stat s; - char *dest; - if (asprintf(&dest, "%s%s", RUN_HOME_DIR, path + strlen(cfg.homedir)) == -1) - errExit("asprintf"); - - // don't copy it if we already have the file - if (stat(dest, &s) == 0) { - free(dest); - return 0; - } - - // extract mode and ownership - if (stat(path, &s) != 0) { - free(dest); - return 0; - } - - // check uid - if (s.st_uid != firejail_uid || s.st_gid != firejail_gid) { - free(dest); - return 0; - } - - if ((s.st_size + size_cnt) > PRIVATE_COPY_LIMIT) { - size_limit_reached = 1; - free(dest); - return 0; - } - - file_cnt++; - size_cnt += s.st_size; - - if(ftype == FTW_F) - copy_file(path, dest, firejail_uid, firejail_gid, s.st_mode); - else if (ftype == FTW_D) { - if (mkdir(dest, s.st_mode) == -1) - errExit("mkdir"); - if (set_perms(dest, firejail_uid, firejail_gid, s.st_mode)) - errExit("set_perms"); -#if 0 -struct stat s2; -if (stat(dest, &s2) == 0) { - printf("%s\t", dest); - printf((S_ISDIR(s.st_mode)) ? "d" : "-"); - printf((s.st_mode & S_IRUSR) ? "r" : "-"); - printf((s.st_mode & S_IWUSR) ? "w" : "-"); - printf((s.st_mode & S_IXUSR) ? "x" : "-"); - printf((s.st_mode & S_IRGRP) ? "r" : "-"); - printf((s.st_mode & S_IWGRP) ? "w" : "-"); - printf((s.st_mode & S_IXGRP) ? "x" : "-"); - printf((s.st_mode & S_IROTH) ? "r" : "-"); - printf((s.st_mode & S_IWOTH) ? "w" : "-"); - printf((s.st_mode & S_IXOTH) ? "x" : "-"); - printf("\n"); -} -#endif - - fs_logger2("clone", path); - } - - free(dest); - return(0); -} - -static void duplicate(char *name) { - char *fname = check_dir_or_file(name); - - if (arg_debug) - printf("Private home: duplicating %s\n", fname); - assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0); - - struct stat s; - if (stat(fname, &s) == -1) { - free(fname); - return; - } - - if(nftw(fname, fs_copydir, 1, FTW_PHYS) != 0) { - fprintf(stderr, "Error: unable to copy template dir\n"); - exit(1); - } - fs_logger_print(); // save the current log - - free(fname); -} - - - static char *check_dir_or_file(const char *name) { assert(name); struct stat s; @@ -461,10 +361,7 @@ static char *check_dir_or_file(const char *name) { // expand home directory char *fname = expand_home(name, cfg.homedir); - if (!fname) { - fprintf(stderr, "Error: file %s not found.\n", name); - exit(1); - } + assert(fname); // If it doesn't start with '/', it must be relative to homedir if (fname[0] != '/') { @@ -475,31 +372,19 @@ static char *check_dir_or_file(const char *name) { fname = tmp; } - // check the file is in user home directory + // check the file is in user home directory, a full home directory is not allowed char *rname = realpath(fname, NULL); - if (!rname) { + if (!rname || + strncmp(rname, cfg.homedir, strlen(cfg.homedir)) != 0 || + strcmp(rname, cfg.homedir) == 0) { fprintf(stderr, "Error: invalid file %s\n", name); exit(1); } - if (strncmp(rname, cfg.homedir, strlen(cfg.homedir)) != 0) { - fprintf(stderr, "Error: file %s is not in user home directory\n", name); - exit(1); - } - - // a full home directory is not allowed - if (strcmp(rname, cfg.homedir) == 0) { - fprintf(stderr, "Error: invalid directory %s\n", rname); - exit(1); - } // only top files and directories in user home are allowed char *ptr = rname + strlen(cfg.homedir); - if (*ptr == '\0') { - fprintf(stderr, "Error: invalid file %s\n", name); - exit(1); - } - ptr++; - ptr = strchr(ptr, '/'); + assert(*ptr != '\0'); + ptr = strchr(++ptr, '/'); if (ptr) { if (*ptr != '\0') { fprintf(stderr, "Error: only top files and directories in user home are allowed\n"); @@ -507,55 +392,42 @@ static char *check_dir_or_file(const char *name) { } } - if (stat(fname, &s) == -1) { - fprintf(stderr, "Error: file %s not found.\n", fname); - exit(1); - } - - // check uid - uid_t uid = getuid(); - gid_t gid = getgid(); - if (s.st_uid != uid || s.st_gid != gid) { - fprintf(stderr, "Error: only files or directories created by the current user are allowed.\n"); - exit(1); - } - - // dir or regular file - if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { - free(fname); - return rname; // regular exit from the function - } - - fprintf(stderr, "Error: invalid file type, %s.\n", fname); - exit(1); + free(fname); + return rname; } +static void duplicate(char *name) { + char *fname = check_dir_or_file(name); + char *dest = RUN_HOME_DIR; -// check directory list specified by user (--private-home option) - exit if it fails -void fs_check_home_list(void) { - if (strstr(cfg.home_private_keep, "..")) { - fprintf(stderr, "Error: invalid private-home list\n"); - exit(1); - } - - char *dlist = strdup(cfg.home_private_keep); - if (!dlist) - errExit("strdup"); - - char *ptr = strtok(dlist, ","); - char *tmp = check_dir_or_file(ptr); - free(tmp); + if (arg_debug) + printf("Private home: duplicating %s\n", fname); + assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0); - while ((ptr = strtok(NULL, ",")) != NULL) { - tmp = check_dir_or_file(ptr); - free(tmp); + struct stat s; + if (stat(fname, &s) == -1) { + free(fname); + return; + } + else if (S_ISDIR(s.st_mode)) { + // create the directory in RUN_HOME_DIR + char *name; + char *ptr = strrchr(fname, '/'); + ptr++; + if (asprintf(&name, "%s/%s", RUN_HOME_DIR, ptr) == -1) + errExit("asprintf"); + mkdir_attr(name, 0755, getuid(), getgid()); + sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, name); + free(name); } + else + sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, RUN_HOME_DIR); + fs_logger2("clone", fname); + fs_logger_print(); // save the current log - free(dlist); + free(fname); } - - // private mode (--private-home=list): // mount homedir on top of /home/user, // tmpfs on top of /root in nonroot mode, @@ -571,8 +443,8 @@ void fs_private_home_list(void) { int xflag = store_xauthority(); int aflag = store_asoundrc(); - uid_t u = firejail_uid; - gid_t g = firejail_gid; + uid_t uid = getuid(); + gid_t gid = getgid(); struct stat s; if (stat(homedir, &s) == -1) { fprintf(stderr, "Error: cannot find user home directory\n"); @@ -580,59 +452,24 @@ void fs_private_home_list(void) { } // create /run/firejail/mnt/home directory - int rv = mkdir(RUN_HOME_DIR, 0755); - if (rv == -1) - errExit("mkdir"); - if (set_perms(RUN_HOME_DIR, u, g, 0755)) - errExit("set_perms"); - ASSERT_PERMS(RUN_HOME_DIR, u, g, 0755); - + mkdir_attr(RUN_HOME_DIR, 0755, uid, gid); fs_logger_print(); // save the current log + if (arg_debug) + printf("Copying files in the new home:\n"); + // copy the list of files in the new home directory - // using a new child process without root privileges - pid_t child = fork(); - if (child < 0) - errExit("fork"); - if (child == 0) { - if (arg_debug) - printf("Copying files in the new home:\n"); - - // drop privileges - if (setgroups(0, NULL) < 0) - errExit("setgroups"); - if (setgid(getgid()) < 0) - errExit("setgid/getgid"); - if (setuid(getuid()) < 0) - errExit("setuid/getuid"); - - // copy the list of files in the new home directory - char *dlist = strdup(cfg.home_private_keep); - if (!dlist) - errExit("strdup"); - - char *ptr = strtok(dlist, ","); + char *dlist = strdup(cfg.home_private_keep); + if (!dlist) + errExit("strdup"); + + char *ptr = strtok(dlist, ","); + duplicate(ptr); + while ((ptr = strtok(NULL, ",")) != NULL) duplicate(ptr); - while ((ptr = strtok(NULL, ",")) != NULL) - duplicate(ptr); - - if (!arg_quiet) { - if (size_limit_reached) - fprintf(stderr, "Warning: private-home copy limit of %u MB reached, not all the files were copied\n", - PRIVATE_COPY_LIMIT / (1024 *1024)); - else - printf("Private home: %u files, total size %u bytes\n", file_cnt, size_cnt); - } - fs_logger_print(); // save the current log - free(dlist); -#ifdef HAVE_GCOV - __gcov_flush(); -#endif - _exit(0); - } - // wait for the child to finish - waitpid(child, NULL, 0); + fs_logger_print(); // save the current log + free(dlist); if (arg_debug) printf("Mount-bind %s on top of %s\n", RUN_HOME_DIR, homedir); @@ -640,7 +477,7 @@ void fs_private_home_list(void) { if (mount(RUN_HOME_DIR, homedir, NULL, MS_BIND|MS_REC, NULL) < 0) errExit("mount bind"); - if (u != 0) { + if (uid != 0) { // mask /root if (arg_debug) printf("Mounting a new /root directory\n"); @@ -655,7 +492,7 @@ void fs_private_home_list(void) { errExit("mounting home directory"); } - skel(homedir, u, g); + skel(homedir, uid, gid); if (xflag) copy_xauthority(); if (aflag) diff --git a/src/firejail/main.c b/src/firejail/main.c index ec0c31285..5bfa04cc9 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -1601,7 +1601,6 @@ int main(int argc, char **argv) { // extract private home dirname cfg.home_private_keep = argv[i] + 15; - fs_check_home_list(); arg_private = 1; } else { @@ -1625,7 +1624,6 @@ int main(int argc, char **argv) { fprintf(stderr, "Error: invalid private-etc option\n"); exit(1); } - fs_check_etc_list(); arg_private_etc = 1; } else if (strncmp(argv[i], "--private-bin=", 14) == 0) { diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 0fd45d1ef..693b1dc30 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -173,7 +173,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { #ifdef HAVE_PRIVATE_HOME if (checkcfg(CFG_PRIVATE_HOME)) { cfg.home_private_keep = ptr + 13; - fs_check_home_list(); arg_private = 1; } else @@ -737,7 +736,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { exit(1); } cfg.etc_private_keep = ptr + 12; - fs_check_etc_list(); arg_private_etc = 1; return 0; diff --git a/src/firejail/util.c b/src/firejail/util.c index 027f1cd47..c56380ca1 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c @@ -562,7 +562,10 @@ char *expand_home(const char *path, const char* homedir) { return new_name; } - return strdup(path); + char *rv = strdup(path); + if (!rv) + errExit("strdup"); + return rv; } @@ -625,7 +628,7 @@ uid_t pid_get_uid(pid_t pid) { void invalid_filename(const char *fname) { - EUID_ASSERT(); +// EUID_ASSERT(); assert(fname); const char *ptr = fname; diff --git a/test/fcopy/cmdline.exp b/test/fcopy/cmdline.exp index 95e221321..24bb19351 100755 --- a/test/fcopy/cmdline.exp +++ b/test/fcopy/cmdline.exp @@ -43,14 +43,4 @@ expect { } after 100 -send -- "/usr/lib/firejail/fcopy foo1 foo2\r" -expect { - timeout {puts "TESTING ERROR 6\n";exit} - "cannot find destination directory" -} -after 100 - - - - puts "\nall done\n" diff --git a/test/fcopy/filecopy.exp b/test/fcopy/filecopy.exp index 9927e18fe..d1f0a4424 100755 --- a/test/fcopy/filecopy.exp +++ b/test/fcopy/filecopy.exp @@ -13,7 +13,7 @@ match_max 100000 send -- "rm -fr dest/*\r" after 100 -send -- "/usr/lib/firejail/fcopy src/dircopy.exp dest\r" +send -- "/usr/lib/firejail/fcopy dircopy.exp dest\r" after 100 send -- "find dest\r" @@ -31,7 +31,7 @@ after 100 send -- "ls -al dest\r" expect { timeout {puts "TESTING ERROR 2\n";exit} - "lrwxrwxrwx" + "rwxr-xr-x" } after 100 @@ -45,7 +45,7 @@ expect { send -- "file dest/dircopy.exp\r" expect { timeout {puts "TESTING ERROR 5\n";exit} - "symbolic link" + "ASCII text" } send -- "rm -fr dest/*\r" diff --git a/test/fcopy/linkcopy.exp b/test/fcopy/linkcopy.exp index b87f24a59..9927e18fe 100755 --- a/test/fcopy/linkcopy.exp +++ b/test/fcopy/linkcopy.exp @@ -13,7 +13,7 @@ match_max 100000 send -- "rm -fr dest/*\r" after 100 -send -- "/usr/lib/firejail/fcopy src dest\r" +send -- "/usr/lib/firejail/fcopy src/dircopy.exp dest\r" after 100 send -- "find dest\r" @@ -23,60 +23,28 @@ expect { } expect { timeout {puts "TESTING ERROR 1\n";exit} - "dest/a" -} -expect { - timeout {puts "TESTING ERROR 2\n";exit} - "dest/a/b" -} -expect { - timeout {puts "TESTING ERROR 3\n";exit} - "dest/a/b/file4" -} -expect { - timeout {puts "TESTING ERROR 4\n";exit} - "dest/a/file3" -} -expect { - timeout {puts "TESTING ERROR 5\n";exit} "dest/dircopy.exp" } -expect { - timeout {puts "TESTING ERROR 6\n";exit} - "dest/file2" -} -expect { - timeout {puts "TESTING ERROR 7\n";exit} - "dest/file1" -} after 100 send -- "ls -al dest\r" expect { - timeout {puts "TESTING ERROR 8\n";exit} - "drwx--x--x" -} -expect { - timeout {puts "TESTING ERROR 9\n";exit} - "rwxrwxrwx" -} -expect { - timeout {puts "TESTING ERROR 10\n";exit} - "rw-r--r--" + timeout {puts "TESTING ERROR 2\n";exit} + "lrwxrwxrwx" } after 100 -send -- "diff -q src/a/b/file4 dest/a/b/file4; echo done\r" +send -- "diff -q dircopy.exp dest/dircopy.exp; echo done\r" expect { - timeout {puts "TESTING ERROR 11\n";exit} - "differ" {puts "TESTING ERROR 12\n";exit} + timeout {puts "TESTING ERROR 3\n";exit} + "differ" {puts "TESTING ERROR 4\n";exit} "done" } send -- "file dest/dircopy.exp\r" expect { - timeout {puts "TESTING ERROR 13\n";exit} + timeout {puts "TESTING ERROR 5\n";exit} "symbolic link" } -- cgit v1.2.3-54-g00ecf From fe8ed9b3abb32ec8b6dff8a0ae36038504ebc0e8 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Sat, 19 Nov 2016 11:12:38 -0500 Subject: fix vivaldi profile, more testing --- etc/vivaldi.profile | 1 - test/fcopy/dircopy.exp | 30 +++++++++++++++++++++++++----- test/fcopy/fcopy.sh | 2 +- 3 files changed, 26 insertions(+), 7 deletions(-) (limited to 'test/fcopy') diff --git a/etc/vivaldi.profile b/etc/vivaldi.profile index 3c608dccb..08b046847 100644 --- a/etc/vivaldi.profile +++ b/etc/vivaldi.profile @@ -6,7 +6,6 @@ include /etc/firejail/disable-programs.inc include /etc/firejail/disable-devel.inc netfilter -nonewprivs whitelist ${DOWNLOADS} mkdir ~/.config/vivaldi diff --git a/test/fcopy/dircopy.exp b/test/fcopy/dircopy.exp index b87f24a59..00b0204ae 100755 --- a/test/fcopy/dircopy.exp +++ b/test/fcopy/dircopy.exp @@ -55,28 +55,48 @@ after 100 send -- "ls -al dest\r" expect { timeout {puts "TESTING ERROR 8\n";exit} - "drwx--x--x" + "drwxr-xr-x" } expect { timeout {puts "TESTING ERROR 9\n";exit} - "rwxrwxrwx" + "a" } expect { timeout {puts "TESTING ERROR 10\n";exit} + "lrwxrwxrwx" +} +expect { + timeout {puts "TESTING ERROR 11\n";exit} + "dircopy.exp" +} +expect { + timeout {puts "TESTING ERROR 12\n";exit} + "rwxr-xr-x" +} +expect { + timeout {puts "TESTING ERROR 13\n";exit} + "file1" +} +expect { + timeout {puts "TESTING ERROR 14\n";exit} "rw-r--r--" } +expect { + timeout {puts "TESTING ERROR 15\n";exit} + "file2" +} after 100 send -- "diff -q src/a/b/file4 dest/a/b/file4; echo done\r" expect { - timeout {puts "TESTING ERROR 11\n";exit} - "differ" {puts "TESTING ERROR 12\n";exit} + timeout {puts "TESTING ERROR 16\n";exit} + "differ" {puts "TESTING ERROR 17\n";exit} "done" } send -- "file dest/dircopy.exp\r" expect { - timeout {puts "TESTING ERROR 13\n";exit} + timeout {puts "TESTING ERROR 18\n";exit} "symbolic link" } diff --git a/test/fcopy/fcopy.sh b/test/fcopy/fcopy.sh index 9961d6317..dcda5ca31 100755 --- a/test/fcopy/fcopy.sh +++ b/test/fcopy/fcopy.sh @@ -6,7 +6,7 @@ export MALLOC_CHECK_=3 export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) -rm -fr dest/* +mkdir dest echo "TESTING: fcopy cmdline (test/fcopy/cmdline.exp)" ./cmdline.exp -- cgit v1.2.3-54-g00ecf