diff options
author | smitsohu <smitsohu@gmail.com> | 2022-07-11 21:16:44 +0200 |
---|---|---|
committer | smitsohu <smitsohu@gmail.com> | 2022-07-11 21:28:34 +0200 |
commit | 604cbd3afcb19a65ba9c0a53d49fc89cb661bffb (patch) | |
tree | abfe7f63fee81237ef165272d10f467223271a57 | |
parent | aria2c.profile: add comment to winetricks workaround (diff) | |
download | firejail-604cbd3afcb19a65ba9c0a53d49fc89cb661bffb.tar.gz firejail-604cbd3afcb19a65ba9c0a53d49fc89cb661bffb.tar.zst firejail-604cbd3afcb19a65ba9c0a53d49fc89cb661bffb.zip |
simplify put option
copy using file descriptors, similar
to implementation of get option
-rw-r--r-- | src/firejail/firejail.h | 1 | ||||
-rw-r--r-- | src/firejail/ls.c | 107 | ||||
-rw-r--r-- | src/firejail/util.c | 2 |
3 files changed, 36 insertions, 74 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index a403767fb..c5004ef8a 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -534,6 +534,7 @@ void logmsg(const char *msg); | |||
534 | void logargs(int argc, char **argv) ; | 534 | void logargs(int argc, char **argv) ; |
535 | void logerr(const char *msg); | 535 | void logerr(const char *msg); |
536 | void set_nice(int inc); | 536 | void set_nice(int inc); |
537 | int copy_file_by_fd(int src, int dst); | ||
537 | int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); | 538 | int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); |
538 | void copy_file_as_user(const char *srcname, const char *destname, mode_t mode); | 539 | void copy_file_as_user(const char *srcname, const char *destname, mode_t mode); |
539 | void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); | 540 | void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); |
diff --git a/src/firejail/ls.c b/src/firejail/ls.c index 5ffd468a4..6494372cb 100644 --- a/src/firejail/ls.c +++ b/src/firejail/ls.c | |||
@@ -309,33 +309,34 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) { | |||
309 | } | 309 | } |
310 | // create destination file if necessary | 310 | // create destination file if necessary |
311 | EUID_ASSERT(); | 311 | EUID_ASSERT(); |
312 | int fd = open(dest_fname, O_WRONLY|O_CREAT|O_CLOEXEC, S_IRUSR | S_IWUSR); | 312 | int dest = open(dest_fname, O_WRONLY|O_CREAT|O_CLOEXEC, S_IRUSR | S_IWUSR); |
313 | if (fd == -1) { | 313 | if (dest == -1) { |
314 | fprintf(stderr, "Error: cannot open %s for writing\n", dest_fname); | 314 | fprintf(stderr, "Error: cannot open %s for writing\n", dest_fname); |
315 | exit(1); | 315 | exit(1); |
316 | } | 316 | } |
317 | struct stat s; | 317 | struct stat s; |
318 | if (fstat(fd, &s) == -1) | 318 | if (fstat(dest, &s) == -1) |
319 | errExit("fstat"); | 319 | errExit("fstat"); |
320 | if (!S_ISREG(s.st_mode)) { | 320 | if (!S_ISREG(s.st_mode)) { |
321 | fprintf(stderr, "Error: %s is no regular file\n", dest_fname); | 321 | fprintf(stderr, "Error: %s is not a regular file\n", dest_fname); |
322 | exit(1); | 322 | exit(1); |
323 | } | 323 | } |
324 | if (ftruncate(fd, 0) == -1) | 324 | if (ftruncate(dest, 0) == -1) |
325 | errExit("ftruncate"); | 325 | errExit("ftruncate"); |
326 | // go quiet - messages on stdout will corrupt the file | 326 | // go quiet - messages on stdout will corrupt the file |
327 | arg_debug = 0; | 327 | arg_debug = 0; |
328 | arg_quiet = 1; | 328 | arg_quiet = 1; |
329 | // redirection | 329 | // redirection |
330 | if (dup2(fd, STDOUT_FILENO) == -1) | 330 | if (dup2(dest, STDOUT_FILENO) == -1) |
331 | errExit("dup2"); | 331 | errExit("dup2"); |
332 | close(fd); | 332 | close(dest); |
333 | op = SANDBOX_FS_CAT; | 333 | op = SANDBOX_FS_CAT; |
334 | } | 334 | } |
335 | 335 | ||
336 | if (op == SANDBOX_FS_LS || op == SANDBOX_FS_CAT) { | 336 | if (op == SANDBOX_FS_LS || op == SANDBOX_FS_CAT) { |
337 | // chroot into the sandbox | 337 | // chroot into the sandbox |
338 | process_rootfs_chroot(sandbox); | 338 | process_rootfs_chroot(sandbox); |
339 | unpin_process(sandbox); | ||
339 | 340 | ||
340 | // drop privileges | 341 | // drop privileges |
341 | drop_privs(0); | 342 | drop_privs(0); |
@@ -344,88 +345,48 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) { | |||
344 | ls(fname1); | 345 | ls(fname1); |
345 | else | 346 | else |
346 | cat(fname1); | 347 | cat(fname1); |
347 | |||
348 | __gcov_flush(); | ||
349 | } | 348 | } |
350 | // get file from host and store it in the sandbox | 349 | // get file from host and store it in the sandbox |
351 | else if (op == SANDBOX_FS_PUT && path2) { | 350 | else if (op == SANDBOX_FS_PUT && path2) { |
352 | char *src_fname =fname1; | 351 | char *src_fname = fname1; |
353 | char *dest_fname = fname2; | 352 | char *dest_fname = fname2; |
354 | 353 | ||
355 | EUID_ROOT(); | 354 | EUID_ASSERT(); |
356 | if (arg_debug) | 355 | int src = open(src_fname, O_RDONLY|O_CLOEXEC); |
357 | printf("copy %s to %s\n", src_fname, dest_fname); | 356 | if (src == -1) { |
358 | 357 | fprintf(stderr, "Error: cannot open %s for reading\n", src_fname); | |
359 | // create a user-owned temporary file in /run/firejail directory | ||
360 | char tmp_fname[] = "/run/firejail/tmpget-XXXXXX"; | ||
361 | int fd = mkstemp(tmp_fname); | ||
362 | if (fd == -1) { | ||
363 | fprintf(stderr, "Error: cannot create temporary file %s\n", tmp_fname); | ||
364 | exit(1); | 358 | exit(1); |
365 | } | 359 | } |
366 | SET_PERMS_FD(fd, getuid(), getgid(), 0600); | ||
367 | close(fd); | ||
368 | |||
369 | // copy the source file into the temporary file - we need to chroot | ||
370 | pid_t child = fork(); | ||
371 | if (child < 0) | ||
372 | errExit("fork"); | ||
373 | if (child == 0) { | ||
374 | // drop privileges | ||
375 | drop_privs(0); | ||
376 | 360 | ||
377 | // copy the file | 361 | // chroot into the sandbox |
378 | if (copy_file(src_fname, tmp_fname, getuid(), getgid(), 0600)) // already a regular user | 362 | process_rootfs_chroot(sandbox); |
379 | _exit(1); | 363 | unpin_process(sandbox); |
380 | |||
381 | __gcov_flush(); | ||
382 | 364 | ||
383 | _exit(0); | 365 | // drop privileges |
384 | } | 366 | drop_privs(0); |
385 | 367 | ||
386 | // wait for the child to finish | 368 | int dest = open(dest_fname, O_WRONLY|O_CREAT|O_CLOEXEC, S_IRUSR | S_IWUSR); |
387 | int status = 0; | 369 | if (dest == -1) { |
388 | waitpid(child, &status, 0); | 370 | fprintf(stderr, "Error: cannot open %s for writing\n", dest_fname); |
389 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0); | ||
390 | else { | ||
391 | unlink(tmp_fname); | ||
392 | exit(1); | 371 | exit(1); |
393 | } | 372 | } |
394 | 373 | struct stat s; | |
395 | // copy the temporary file into the destination file | 374 | if (fstat(dest, &s) == -1) |
396 | child = fork(); | 375 | errExit("fstat"); |
397 | if (child < 0) | 376 | if (!S_ISREG(s.st_mode)) { |
398 | errExit("fork"); | 377 | fprintf(stderr, "Error: %s is not a regular file\n", dest_fname); |
399 | if (child == 0) { | ||
400 | // chroot into the sandbox | ||
401 | process_rootfs_chroot(sandbox); | ||
402 | |||
403 | // drop privileges | ||
404 | drop_privs(0); | ||
405 | |||
406 | // copy the file | ||
407 | if (copy_file(tmp_fname, dest_fname, getuid(), getgid(), 0600)) // already a regular user | ||
408 | _exit(1); | ||
409 | |||
410 | __gcov_flush(); | ||
411 | |||
412 | _exit(0); | ||
413 | } | ||
414 | |||
415 | // wait for the child to finish | ||
416 | status = 0; | ||
417 | waitpid(child, &status, 0); | ||
418 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0); | ||
419 | else { | ||
420 | unlink(tmp_fname); | ||
421 | exit(1); | 378 | exit(1); |
422 | } | 379 | } |
380 | if (ftruncate(dest, 0) == -1) | ||
381 | errExit("ftruncate"); | ||
423 | 382 | ||
424 | // remove the temporary file | 383 | if (copy_file_by_fd(src, dest) != 0) |
425 | unlink(tmp_fname); | 384 | fwarning("an error occured during copying\n"); |
426 | EUID_USER(); | 385 | close(src); |
386 | close(dest); | ||
427 | } | 387 | } |
428 | 388 | ||
429 | unpin_process(sandbox); | 389 | __gcov_flush(); |
390 | |||
430 | exit(0); | 391 | exit(0); |
431 | } | 392 | } |
diff --git a/src/firejail/util.c b/src/firejail/util.c index a35ad469e..a01290cf2 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -406,7 +406,7 @@ void set_nice(int inc) { | |||
406 | } | 406 | } |
407 | 407 | ||
408 | 408 | ||
409 | static int copy_file_by_fd(int src, int dst) { | 409 | int copy_file_by_fd(int src, int dst) { |
410 | assert(src >= 0); | 410 | assert(src >= 0); |
411 | assert(dst >= 0); | 411 | assert(dst >= 0); |
412 | 412 | ||