From a6227240b273cceb13391f80b7eabc2b5929ac6e Mon Sep 17 00:00:00 2001 From: smitsohu Date: Wed, 18 Nov 2020 21:43:23 +0100 Subject: reimplement --get using --cat --- src/firejail/ls.c | 122 ++++++++++++++++-------------------------------------- 1 file changed, 36 insertions(+), 86 deletions(-) diff --git a/src/firejail/ls.c b/src/firejail/ls.c index 4d0a001b6..ebd65cdd3 100644 --- a/src/firejail/ls.c +++ b/src/firejail/ls.c @@ -26,6 +26,7 @@ #include #include #include +#include //#include //#include //#include @@ -291,6 +292,41 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) { printf("file2 %s\n", fname2 ? fname2 : "(null)"); } + // get file from sandbox and store it in the current directory + // implemented using --cat + if (op == SANDBOX_FS_GET) { + char *dest_fname = strrchr(fname1, '/'); + if (!dest_fname || *(++dest_fname) == '\0') { + fprintf(stderr, "Error: invalid file name %s\n", fname1); + exit(1); + } + // create destination file if necessary + EUID_ASSERT(); + int fd = open(dest_fname, O_WRONLY|O_CREAT|O_CLOEXEC, S_IRUSR | S_IWRITE); + if (fd == -1) { + fprintf(stderr, "Error: cannot open %s for writing\n", dest_fname); + exit(1); + } + struct stat s; + if (fstat(fd, &s) == -1) + errExit("fstat"); + if (!S_ISREG(s.st_mode)) { + fprintf(stderr, "Error: %s is no regular file\n", dest_fname); + exit(1); + } + if (ftruncate(fd, 0) == -1) + errExit("ftruncate"); + // go quiet - messages on stdout will corrupt the file + arg_debug = 0; + arg_quiet = 1; + // redirection + if (dup2(fd, STDOUT_FILENO) == -1) + errExit("dup2"); + assert(fd != STDOUT_FILENO); + close(fd); + op = SANDBOX_FS_CAT; + } + // sandbox root directory char *rootdir; if (asprintf(&rootdir, "/proc/%d/root", pid) == -1) @@ -327,92 +363,6 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) { else exit(1); } - - // get file from sandbox and store it in the current directory - else if (op == SANDBOX_FS_GET) { - char *src_fname =fname1; - char *dest_fname = strrchr(fname1, '/'); - if (!dest_fname || *(++dest_fname) == '\0') { - fprintf(stderr, "Error: invalid file name %s\n", fname1); - exit(1); - } - - EUID_ROOT(); - if (arg_debug) - printf("copy %s to %s\n", src_fname, dest_fname); - - // create a user-owned temporary file in /run/firejail directory - char tmp_fname[] = "/run/firejail/tmpget-XXXXXX"; - int fd = mkstemp(tmp_fname); - if (fd == -1) { - fprintf(stderr, "Error: cannot create temporary file %s\n", tmp_fname); - exit(1); - } - SET_PERMS_FD(fd, getuid(), getgid(), 0600); - close(fd); - - // copy the source file into the temporary file - we need to chroot - pid_t child = fork(); - if (child < 0) - errExit("fork"); - if (child == 0) { - // chroot - if (chroot(rootdir) < 0) - errExit("chroot"); - if (chdir("/") < 0) - errExit("chdir"); - - // drop privileges - drop_privs(0); - - // copy the file - if (copy_file(src_fname, tmp_fname, getuid(), getgid(), 0600)) // already a regular user - _exit(1); -#ifdef HAVE_GCOV - __gcov_flush(); -#endif - _exit(0); - } - - // wait for the child to finish - int status = 0; - waitpid(child, &status, 0); - if (WIFEXITED(status) && WEXITSTATUS(status) == 0); - else { - unlink(tmp_fname); - exit(1); - } - - // copy the temporary file into the destination file - child = fork(); - if (child < 0) - errExit("fork"); - if (child == 0) { - // drop privileges - drop_privs(0); - - // copy the file - if (copy_file(tmp_fname, dest_fname, getuid(), getgid(), 0600)) // already a regular user - _exit(1); -#ifdef HAVE_GCOV - __gcov_flush(); -#endif - _exit(0); - } - - // wait for the child to finish - status = 0; - waitpid(child, &status, 0); - if (WIFEXITED(status) && WEXITSTATUS(status) == 0); - else { - unlink(tmp_fname); - exit(1); - } - - // remove the temporary file - unlink(tmp_fname); - EUID_USER(); - } // get file from host and store it in the sandbox else if (op == SANDBOX_FS_PUT && path2) { char *src_fname =fname1; -- cgit v1.2.3-70-g09d2