aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2020-11-18 21:43:23 +0100
committerLibravatar smitsohu <smitsohu@gmail.com>2020-11-18 21:43:23 +0100
commita6227240b273cceb13391f80b7eabc2b5929ac6e (patch)
treeca35cf178d37bc8272f3dd21498f7d0afa9f1c37
parentwhitelist-var-common.inc: fix certificate verification (diff)
downloadfirejail-a6227240b273cceb13391f80b7eabc2b5929ac6e.tar.gz
firejail-a6227240b273cceb13391f80b7eabc2b5929ac6e.tar.zst
firejail-a6227240b273cceb13391f80b7eabc2b5929ac6e.zip
reimplement --get using --cat
-rw-r--r--src/firejail/ls.c122
1 files 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 @@
26#include <dirent.h> 26#include <dirent.h>
27#include <pwd.h> 27#include <pwd.h>
28#include <grp.h> 28#include <grp.h>
29#include <fcntl.h>
29//#include <dirent.h> 30//#include <dirent.h>
30//#include <stdio.h> 31//#include <stdio.h>
31//#include <stdlib.h> 32//#include <stdlib.h>
@@ -291,6 +292,41 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
291 printf("file2 %s\n", fname2 ? fname2 : "(null)"); 292 printf("file2 %s\n", fname2 ? fname2 : "(null)");
292 } 293 }
293 294
295 // get file from sandbox and store it in the current directory
296 // implemented using --cat
297 if (op == SANDBOX_FS_GET) {
298 char *dest_fname = strrchr(fname1, '/');
299 if (!dest_fname || *(++dest_fname) == '\0') {
300 fprintf(stderr, "Error: invalid file name %s\n", fname1);
301 exit(1);
302 }
303 // create destination file if necessary
304 EUID_ASSERT();
305 int fd = open(dest_fname, O_WRONLY|O_CREAT|O_CLOEXEC, S_IRUSR | S_IWRITE);
306 if (fd == -1) {
307 fprintf(stderr, "Error: cannot open %s for writing\n", dest_fname);
308 exit(1);
309 }
310 struct stat s;
311 if (fstat(fd, &s) == -1)
312 errExit("fstat");
313 if (!S_ISREG(s.st_mode)) {
314 fprintf(stderr, "Error: %s is no regular file\n", dest_fname);
315 exit(1);
316 }
317 if (ftruncate(fd, 0) == -1)
318 errExit("ftruncate");
319 // go quiet - messages on stdout will corrupt the file
320 arg_debug = 0;
321 arg_quiet = 1;
322 // redirection
323 if (dup2(fd, STDOUT_FILENO) == -1)
324 errExit("dup2");
325 assert(fd != STDOUT_FILENO);
326 close(fd);
327 op = SANDBOX_FS_CAT;
328 }
329
294 // sandbox root directory 330 // sandbox root directory
295 char *rootdir; 331 char *rootdir;
296 if (asprintf(&rootdir, "/proc/%d/root", pid) == -1) 332 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) {
327 else 363 else
328 exit(1); 364 exit(1);
329 } 365 }
330
331 // get file from sandbox and store it in the current directory
332 else if (op == SANDBOX_FS_GET) {
333 char *src_fname =fname1;
334 char *dest_fname = strrchr(fname1, '/');
335 if (!dest_fname || *(++dest_fname) == '\0') {
336 fprintf(stderr, "Error: invalid file name %s\n", fname1);
337 exit(1);
338 }
339
340 EUID_ROOT();
341 if (arg_debug)
342 printf("copy %s to %s\n", src_fname, dest_fname);
343
344 // create a user-owned temporary file in /run/firejail directory
345 char tmp_fname[] = "/run/firejail/tmpget-XXXXXX";
346 int fd = mkstemp(tmp_fname);
347 if (fd == -1) {
348 fprintf(stderr, "Error: cannot create temporary file %s\n", tmp_fname);
349 exit(1);
350 }
351 SET_PERMS_FD(fd, getuid(), getgid(), 0600);
352 close(fd);
353
354 // copy the source file into the temporary file - we need to chroot
355 pid_t child = fork();
356 if (child < 0)
357 errExit("fork");
358 if (child == 0) {
359 // chroot
360 if (chroot(rootdir) < 0)
361 errExit("chroot");
362 if (chdir("/") < 0)
363 errExit("chdir");
364
365 // drop privileges
366 drop_privs(0);
367
368 // copy the file
369 if (copy_file(src_fname, tmp_fname, getuid(), getgid(), 0600)) // already a regular user
370 _exit(1);
371#ifdef HAVE_GCOV
372 __gcov_flush();
373#endif
374 _exit(0);
375 }
376
377 // wait for the child to finish
378 int status = 0;
379 waitpid(child, &status, 0);
380 if (WIFEXITED(status) && WEXITSTATUS(status) == 0);
381 else {
382 unlink(tmp_fname);
383 exit(1);
384 }
385
386 // copy the temporary file into the destination file
387 child = fork();
388 if (child < 0)
389 errExit("fork");
390 if (child == 0) {
391 // drop privileges
392 drop_privs(0);
393
394 // copy the file
395 if (copy_file(tmp_fname, dest_fname, getuid(), getgid(), 0600)) // already a regular user
396 _exit(1);
397#ifdef HAVE_GCOV
398 __gcov_flush();
399#endif
400 _exit(0);
401 }
402
403 // wait for the child to finish
404 status = 0;
405 waitpid(child, &status, 0);
406 if (WIFEXITED(status) && WEXITSTATUS(status) == 0);
407 else {
408 unlink(tmp_fname);
409 exit(1);
410 }
411
412 // remove the temporary file
413 unlink(tmp_fname);
414 EUID_USER();
415 }
416 // get file from host and store it in the sandbox 366 // get file from host and store it in the sandbox
417 else if (op == SANDBOX_FS_PUT && path2) { 367 else if (op == SANDBOX_FS_PUT && path2) {
418 char *src_fname =fname1; 368 char *src_fname =fname1;