diff options
author | 2020-11-22 12:47:44 -0500 | |
---|---|---|
committer | 2020-11-22 12:47:44 -0500 | |
commit | c5a021c8ef49ad502c693f894f32c96ae6d5ffa6 (patch) | |
tree | 63c0708e0d1c56e51650cc4af70df4dd146fb3b1 /src | |
parent | drop deprecated path (diff) | |
parent | reimplement --get using --cat (diff) | |
download | firejail-c5a021c8ef49ad502c693f894f32c96ae6d5ffa6.tar.gz firejail-c5a021c8ef49ad502c693f894f32c96ae6d5ffa6.tar.zst firejail-c5a021c8ef49ad502c693f894f32c96ae6d5ffa6.zip |
Merge pull request #3752 from smitsohu/smitsohu-get-to-cat
reimplement --get using --cat
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/ls.c | 122 |
1 files changed, 36 insertions, 86 deletions
diff --git a/src/firejail/ls.c b/src/firejail/ls.c index 1a65c9ff0..e61edf427 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> |
@@ -293,6 +294,41 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) { | |||
293 | printf("file2 %s\n", fname2 ? fname2 : "(null)"); | 294 | printf("file2 %s\n", fname2 ? fname2 : "(null)"); |
294 | } | 295 | } |
295 | 296 | ||
297 | // get file from sandbox and store it in the current directory | ||
298 | // implemented using --cat | ||
299 | if (op == SANDBOX_FS_GET) { | ||
300 | char *dest_fname = strrchr(fname1, '/'); | ||
301 | if (!dest_fname || *(++dest_fname) == '\0') { | ||
302 | fprintf(stderr, "Error: invalid file name %s\n", fname1); | ||
303 | exit(1); | ||
304 | } | ||
305 | // create destination file if necessary | ||
306 | EUID_ASSERT(); | ||
307 | int fd = open(dest_fname, O_WRONLY|O_CREAT|O_CLOEXEC, S_IRUSR | S_IWRITE); | ||
308 | if (fd == -1) { | ||
309 | fprintf(stderr, "Error: cannot open %s for writing\n", dest_fname); | ||
310 | exit(1); | ||
311 | } | ||
312 | struct stat s; | ||
313 | if (fstat(fd, &s) == -1) | ||
314 | errExit("fstat"); | ||
315 | if (!S_ISREG(s.st_mode)) { | ||
316 | fprintf(stderr, "Error: %s is no regular file\n", dest_fname); | ||
317 | exit(1); | ||
318 | } | ||
319 | if (ftruncate(fd, 0) == -1) | ||
320 | errExit("ftruncate"); | ||
321 | // go quiet - messages on stdout will corrupt the file | ||
322 | arg_debug = 0; | ||
323 | arg_quiet = 1; | ||
324 | // redirection | ||
325 | if (dup2(fd, STDOUT_FILENO) == -1) | ||
326 | errExit("dup2"); | ||
327 | assert(fd != STDOUT_FILENO); | ||
328 | close(fd); | ||
329 | op = SANDBOX_FS_CAT; | ||
330 | } | ||
331 | |||
296 | // sandbox root directory | 332 | // sandbox root directory |
297 | char *rootdir; | 333 | char *rootdir; |
298 | if (asprintf(&rootdir, "/proc/%d/root", pid) == -1) | 334 | if (asprintf(&rootdir, "/proc/%d/root", pid) == -1) |
@@ -317,92 +353,6 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) { | |||
317 | __gcov_flush(); | 353 | __gcov_flush(); |
318 | #endif | 354 | #endif |
319 | } | 355 | } |
320 | |||
321 | // get file from sandbox and store it in the current directory | ||
322 | else if (op == SANDBOX_FS_GET) { | ||
323 | char *src_fname =fname1; | ||
324 | char *dest_fname = strrchr(fname1, '/'); | ||
325 | if (!dest_fname || *(++dest_fname) == '\0') { | ||
326 | fprintf(stderr, "Error: invalid file name %s\n", fname1); | ||
327 | exit(1); | ||
328 | } | ||
329 | |||
330 | EUID_ROOT(); | ||
331 | if (arg_debug) | ||
332 | printf("copy %s to %s\n", src_fname, dest_fname); | ||
333 | |||
334 | // create a user-owned temporary file in /run/firejail directory | ||
335 | char tmp_fname[] = "/run/firejail/tmpget-XXXXXX"; | ||
336 | int fd = mkstemp(tmp_fname); | ||
337 | if (fd == -1) { | ||
338 | fprintf(stderr, "Error: cannot create temporary file %s\n", tmp_fname); | ||
339 | exit(1); | ||
340 | } | ||
341 | SET_PERMS_FD(fd, getuid(), getgid(), 0600); | ||
342 | close(fd); | ||
343 | |||
344 | // copy the source file into the temporary file - we need to chroot | ||
345 | pid_t child = fork(); | ||
346 | if (child < 0) | ||
347 | errExit("fork"); | ||
348 | if (child == 0) { | ||
349 | // chroot | ||
350 | if (chroot(rootdir) < 0) | ||
351 | errExit("chroot"); | ||
352 | if (chdir("/") < 0) | ||
353 | errExit("chdir"); | ||
354 | |||
355 | // drop privileges | ||
356 | drop_privs(0); | ||
357 | |||
358 | // copy the file | ||
359 | if (copy_file(src_fname, tmp_fname, getuid(), getgid(), 0600)) // already a regular user | ||
360 | _exit(1); | ||
361 | #ifdef HAVE_GCOV | ||
362 | __gcov_flush(); | ||
363 | #endif | ||
364 | _exit(0); | ||
365 | } | ||
366 | |||
367 | // wait for the child to finish | ||
368 | int status = 0; | ||
369 | waitpid(child, &status, 0); | ||
370 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0); | ||
371 | else { | ||
372 | unlink(tmp_fname); | ||
373 | exit(1); | ||
374 | } | ||
375 | |||
376 | // copy the temporary file into the destination file | ||
377 | child = fork(); | ||
378 | if (child < 0) | ||
379 | errExit("fork"); | ||
380 | if (child == 0) { | ||
381 | // drop privileges | ||
382 | drop_privs(0); | ||
383 | |||
384 | // copy the file | ||
385 | if (copy_file(tmp_fname, dest_fname, getuid(), getgid(), 0600)) // already a regular user | ||
386 | _exit(1); | ||
387 | #ifdef HAVE_GCOV | ||
388 | __gcov_flush(); | ||
389 | #endif | ||
390 | _exit(0); | ||
391 | } | ||
392 | |||
393 | // wait for the child to finish | ||
394 | status = 0; | ||
395 | waitpid(child, &status, 0); | ||
396 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0); | ||
397 | else { | ||
398 | unlink(tmp_fname); | ||
399 | exit(1); | ||
400 | } | ||
401 | |||
402 | // remove the temporary file | ||
403 | unlink(tmp_fname); | ||
404 | EUID_USER(); | ||
405 | } | ||
406 | // get file from host and store it in the sandbox | 356 | // get file from host and store it in the sandbox |
407 | else if (op == SANDBOX_FS_PUT && path2) { | 357 | else if (op == SANDBOX_FS_PUT && path2) { |
408 | char *src_fname =fname1; | 358 | char *src_fname =fname1; |