diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/x11.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/src/firejail/x11.c b/src/firejail/x11.c index 6cba95501..ecab8880a 100644 --- a/src/firejail/x11.c +++ b/src/firejail/x11.c | |||
@@ -312,6 +312,7 @@ void x11_start_xephyr(int argc, char **argv) { | |||
312 | if (arg_debug) | 312 | if (arg_debug) |
313 | printf("Starting xephyr...\n"); | 313 | printf("Starting xephyr...\n"); |
314 | 314 | ||
315 | // running without privileges - see drop_privs call above | ||
315 | assert(getenv("LD_PRELOAD") == NULL); | 316 | assert(getenv("LD_PRELOAD") == NULL); |
316 | execvp(server_argv[0], server_argv); | 317 | execvp(server_argv[0], server_argv); |
317 | perror("execvp"); | 318 | perror("execvp"); |
@@ -354,6 +355,7 @@ void x11_start_xephyr(int argc, char **argv) { | |||
354 | if (!arg_quiet) | 355 | if (!arg_quiet) |
355 | printf("\n*** Attaching to Xephyr display %d ***\n\n", display); | 356 | printf("\n*** Attaching to Xephyr display %d ***\n\n", display); |
356 | 357 | ||
358 | // running without privileges - see drop_privs call above | ||
357 | assert(getenv("LD_PRELOAD") == NULL); | 359 | assert(getenv("LD_PRELOAD") == NULL); |
358 | execvp(jail_argv[0], jail_argv); | 360 | execvp(jail_argv[0], jail_argv); |
359 | perror("execvp"); | 361 | perror("execvp"); |
@@ -434,6 +436,7 @@ void x11_start_xpra(int argc, char **argv) { | |||
434 | dup2(fd_null,2); | 436 | dup2(fd_null,2); |
435 | } | 437 | } |
436 | 438 | ||
439 | // running without privileges - see drop_privs call above | ||
437 | assert(getenv("LD_PRELOAD") == NULL); | 440 | assert(getenv("LD_PRELOAD") == NULL); |
438 | execvp(server_argv[0], server_argv); | 441 | execvp(server_argv[0], server_argv); |
439 | perror("execvp"); | 442 | perror("execvp"); |
@@ -481,6 +484,7 @@ void x11_start_xpra(int argc, char **argv) { | |||
481 | if (!arg_quiet) | 484 | if (!arg_quiet) |
482 | printf("\n*** Attaching to xpra display %d ***\n\n", display); | 485 | printf("\n*** Attaching to xpra display %d ***\n\n", display); |
483 | 486 | ||
487 | // running without privileges - see drop_privs call above | ||
484 | assert(getenv("LD_PRELOAD") == NULL); | 488 | assert(getenv("LD_PRELOAD") == NULL); |
485 | execvp(attach_argv[0], attach_argv); | 489 | execvp(attach_argv[0], attach_argv); |
486 | perror("execvp"); | 490 | perror("execvp"); |
@@ -512,6 +516,7 @@ void x11_start_xpra(int argc, char **argv) { | |||
512 | if (jail < 0) | 516 | if (jail < 0) |
513 | errExit("fork"); | 517 | errExit("fork"); |
514 | if (jail == 0) { | 518 | if (jail == 0) { |
519 | // running without privileges - see drop_privs call above | ||
515 | assert(getenv("LD_PRELOAD") == NULL); | 520 | assert(getenv("LD_PRELOAD") == NULL); |
516 | if (firejail_argv[0]) // shut up llvm scan-build | 521 | if (firejail_argv[0]) // shut up llvm scan-build |
517 | execvp(firejail_argv[0], firejail_argv); | 522 | execvp(firejail_argv[0], firejail_argv); |
@@ -539,6 +544,7 @@ void x11_start_xpra(int argc, char **argv) { | |||
539 | dup2(fd_null,1); | 544 | dup2(fd_null,1); |
540 | dup2(fd_null,2); | 545 | dup2(fd_null,2); |
541 | } | 546 | } |
547 | // running without privileges - see drop_privs call above | ||
542 | assert(getenv("LD_PRELOAD") == NULL); | 548 | assert(getenv("LD_PRELOAD") == NULL); |
543 | execvp(stop_argv[0], stop_argv); | 549 | execvp(stop_argv[0], stop_argv); |
544 | perror("execvp"); | 550 | perror("execvp"); |
@@ -638,7 +644,7 @@ void x11_block(void) { | |||
638 | 644 | ||
639 | void x11_xorg(void) { | 645 | void x11_xorg(void) { |
640 | #ifdef HAVE_X11 | 646 | #ifdef HAVE_X11 |
641 | // destination | 647 | // destination - create an empty ~/.Xauthotrity file if it doesn't exist already, and use it as a mount point |
642 | char *dest; | 648 | char *dest; |
643 | if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) | 649 | if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) |
644 | errExit("asprintf"); | 650 | errExit("asprintf"); |
@@ -652,47 +658,67 @@ void x11_xorg(void) { | |||
652 | fclose(fp); | 658 | fclose(fp); |
653 | } | 659 | } |
654 | 660 | ||
661 | // check xauth utility is present in the system | ||
655 | if (stat("/usr/bin/xauth", &s) == -1) { | 662 | if (stat("/usr/bin/xauth", &s) == -1) { |
656 | fprintf(stderr, "Error: cannot find /usr/bin/xauth executable\n"); | 663 | fprintf(stderr, "Error: cannot find /usr/bin/xauth executable\n"); |
657 | exit(1); | 664 | exit(1); |
658 | } | 665 | } |
659 | 666 | ||
667 | // create a temporary .Xauthority file | ||
668 | char tmpfname[] = "/tmp/.tmpXauth-XXXXXX"; | ||
669 | int fd = mkstemp(tmpfname); | ||
670 | if (fd == -1) { | ||
671 | fprintf(stderr, "Error: cannot create .Xauthority file\n"); | ||
672 | exit(1); | ||
673 | } | ||
674 | close(fd); | ||
675 | if (chown(tmpfname, getuid(), getgid()) == -1) | ||
676 | errExit("chown"); | ||
677 | |||
660 | pid_t child = fork(); | 678 | pid_t child = fork(); |
661 | if (child < 0) | 679 | if (child < 0) |
662 | errExit("fork"); | 680 | errExit("fork"); |
663 | if (child == 0) { | 681 | if (child == 0) { |
664 | // generate a new .Xauthority file | 682 | // generate the new .Xauthority file using xauth utility |
665 | if (arg_debug) | 683 | if (arg_debug) |
666 | printf("Generating a new .Xauthority file\n"); | 684 | printf("Generating a new .Xauthority file\n"); |
667 | 685 | drop_privs(1); | |
668 | // elevate privileges - files in /run/firejail/mnt directory belong to root | ||
669 | if (setreuid(0, 0) < 0) | ||
670 | errExit("setreuid"); | ||
671 | if (setregid(0, 0) < 0) | ||
672 | errExit("setregid"); | ||
673 | 686 | ||
674 | char *display = getenv("DISPLAY"); | 687 | char *display = getenv("DISPLAY"); |
675 | if (!display) | 688 | if (!display) |
676 | display = ":0.0"; | 689 | display = ":0.0"; |
677 | 690 | ||
678 | assert(getenv("LD_PRELOAD") == NULL); | 691 | clearenv(); |
679 | execlp("/usr/bin/xauth", "/usr/bin/xauth", "-f", RUN_XAUTHORITY_SEC_FILE, | 692 | execlp("/usr/bin/xauth", "/usr/bin/xauth", "-f", tmpfname, |
680 | "generate", display, "MIT-MAGIC-COOKIE-1", "untrusted", NULL); | 693 | "generate", display, "MIT-MAGIC-COOKIE-1", "untrusted", NULL); |
681 | 694 | ||
682 | _exit(0); | 695 | _exit(0); |
683 | } | 696 | } |
697 | |||
684 | // wait for the child to finish | 698 | // wait for the child to finish |
685 | waitpid(child, NULL, 0); | 699 | waitpid(child, NULL, 0); |
686 | 700 | ||
687 | // check the file was created and set mode and ownership | 701 | // check the file was created and set mode and ownership |
688 | if (stat(RUN_XAUTHORITY_SEC_FILE, &s) == -1) { | 702 | if (stat(tmpfname, &s) == -1) { |
689 | fprintf(stderr, "Error: cannot create the new .Xauthority file\n"); | 703 | fprintf(stderr, "Error: cannot create the new .Xauthority file\n"); |
690 | exit(1); | 704 | exit(1); |
691 | } | 705 | } |
706 | if (chown(tmpfname, getuid(), getgid()) == -1) | ||
707 | errExit("chown"); | ||
708 | if (chmod(tmpfname, 0600) == -1) | ||
709 | errExit("chmod"); | ||
710 | |||
711 | // move the temporary file in RUN_XAUTHORITY_SEC_FILE in order to have it deleted | ||
712 | // automatically when the sandbox is closed | ||
713 | if (copy_file(tmpfname, RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600)) { | ||
714 | fprintf(stderr, "asdfdsfError: cannot create the new .Xauthority file\n"); | ||
715 | exit(1); | ||
716 | } | ||
692 | if (chown(RUN_XAUTHORITY_SEC_FILE, getuid(), getgid()) == -1) | 717 | if (chown(RUN_XAUTHORITY_SEC_FILE, getuid(), getgid()) == -1) |
693 | errExit("chown"); | 718 | errExit("chown"); |
694 | if (chmod(RUN_XAUTHORITY_SEC_FILE, 0600) == -1) | 719 | if (chmod(RUN_XAUTHORITY_SEC_FILE, 0600) == -1) |
695 | errExit("chmod"); | 720 | errExit("chmod"); |
721 | unlink(tmpfname); | ||
696 | 722 | ||
697 | // mount | 723 | // mount |
698 | if (mount(RUN_XAUTHORITY_SEC_FILE, dest, "none", MS_BIND, "mode=0600") == -1) { | 724 | if (mount(RUN_XAUTHORITY_SEC_FILE, dest, "none", MS_BIND, "mode=0600") == -1) { |