aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2022-07-11 21:16:44 +0200
committerLibravatar smitsohu <smitsohu@gmail.com>2022-07-11 21:28:34 +0200
commit604cbd3afcb19a65ba9c0a53d49fc89cb661bffb (patch)
treeabfe7f63fee81237ef165272d10f467223271a57
parentaria2c.profile: add comment to winetricks workaround (diff)
downloadfirejail-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.h1
-rw-r--r--src/firejail/ls.c107
-rw-r--r--src/firejail/util.c2
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);
534void logargs(int argc, char **argv) ; 534void logargs(int argc, char **argv) ;
535void logerr(const char *msg); 535void logerr(const char *msg);
536void set_nice(int inc); 536void set_nice(int inc);
537int copy_file_by_fd(int src, int dst);
537int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); 538int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode);
538void copy_file_as_user(const char *srcname, const char *destname, mode_t mode); 539void copy_file_as_user(const char *srcname, const char *destname, mode_t mode);
539void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); 540void 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
409static int copy_file_by_fd(int src, int dst) { 409int 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