diff options
-rw-r--r-- | src/firejail/x11.c | 313 |
1 files changed, 168 insertions, 145 deletions
diff --git a/src/firejail/x11.c b/src/firejail/x11.c index c6bb7e1e3..01a40383d 100644 --- a/src/firejail/x11.c +++ b/src/firejail/x11.c | |||
@@ -665,10 +665,45 @@ void x11_start_xpra(int argc, char **argv) { | |||
665 | 665 | ||
666 | // build the start command | 666 | // build the start command |
667 | char *server_argv[256] = { // rest initialyzed to NULL | 667 | char *server_argv[256] = { // rest initialyzed to NULL |
668 | "xpra", "start", display_str, "--no-daemon", | 668 | "xpra", "start", display_str, "--daemon=no", "--attach=yes", "--exit-with-children=yes" |
669 | }; | 669 | }; |
670 | unsigned pos = 0; | 670 | unsigned spos = 0; |
671 | while (server_argv[pos] != NULL) pos++; | 671 | unsigned fpos = 0; |
672 | while (server_argv[spos] != NULL) spos++; | ||
673 | |||
674 | // build jail command | ||
675 | char *firejail_argv[argc+2]; | ||
676 | size_t total_length = 0; | ||
677 | for (i = 0; i < argc; i++) { | ||
678 | if (strncmp(argv[i], "--x11", 5) == 0) | ||
679 | continue; | ||
680 | firejail_argv[fpos] = argv[i]; | ||
681 | fpos++; | ||
682 | total_length += strlen(argv[i]); | ||
683 | } | ||
684 | |||
685 | char *start_child_prefix = "--start-child="; | ||
686 | char *start_child; | ||
687 | start_child = malloc(total_length + strlen(start_child_prefix) + fpos + 2); | ||
688 | printf("START_CHILD: %s\n", start_child); | ||
689 | printf("START_CHILD_PREFIX: %s\n", start_child_prefix); | ||
690 | strcpy(start_child,start_child_prefix); | ||
691 | printf("START_CHILD: %s\n", start_child); | ||
692 | for(i = 0; i < fpos; i++) { | ||
693 | printf("%s\n",firejail_argv[i]); | ||
694 | strncat(start_child,firejail_argv[i],strlen(firejail_argv[i])); | ||
695 | if(i != fpos - 1) | ||
696 | strncat(start_child," ",strlen(" ")); | ||
697 | } | ||
698 | |||
699 | /* strncat(start_child,"\'",strlen("\'")); */ | ||
700 | |||
701 | printf("START_CHILD: %s\n", start_child); | ||
702 | |||
703 | server_argv[spos++] = start_child; | ||
704 | |||
705 | server_argv[spos++] = NULL; | ||
706 | firejail_argv[fpos] = NULL; | ||
672 | 707 | ||
673 | assert(xpra_extra_params); // should be "" if empty | 708 | assert(xpra_extra_params); // should be "" if empty |
674 | 709 | ||
@@ -702,26 +737,28 @@ void x11_start_xpra(int argc, char **argv) { | |||
702 | exit(1); | 737 | exit(1); |
703 | } | 738 | } |
704 | 739 | ||
705 | server_argv[pos++] = temp; | 740 | server_argv[spos++] = temp; |
706 | for (i = 0; i < (int) strlen(xpra_extra_params)-1; i++) { | 741 | for (i = 0; i < (int) strlen(xpra_extra_params)-1; i++) { |
707 | if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) { | 742 | if (spos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) { |
708 | fprintf(stderr, "Error: arg count limit exceeded while parsing xpra_extra_params\n"); | 743 | fprintf(stderr, "Error: arg count limit exceeded while parsing xpra_extra_params\n"); |
709 | exit(1); | 744 | exit(1); |
710 | } | 745 | } |
711 | if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) { | 746 | if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) { |
712 | server_argv[pos++] = temp + i + 2; | 747 | server_argv[spos++] = temp + i + 2; |
713 | } | 748 | } |
714 | else if (temp[i] == '\0' && temp[i+1] != '\0') { | 749 | else if (temp[i] == '\0' && temp[i+1] != '\0') { |
715 | server_argv[pos++] = temp + i + 1; | 750 | server_argv[spos++] = temp + i + 1; |
716 | } | 751 | } |
717 | } | 752 | } |
718 | } | 753 | } |
719 | 754 | ||
720 | server_argv[pos++] = NULL; | 755 | assert((int) fpos < (argc+2)); |
721 | 756 | assert(!firejail_argv[fpos]); | |
722 | // no overrun | 757 | // no overrun |
723 | assert(pos < (sizeof(server_argv)/sizeof(*server_argv))); | 758 | assert(spos < (sizeof(server_argv)/sizeof(*server_argv))); |
724 | assert(server_argv[pos-1] == NULL); // last element is null | 759 | assert(server_argv[spos-1] == NULL); // last element is null |
760 | |||
761 | |||
725 | 762 | ||
726 | if (arg_debug) { | 763 | if (arg_debug) { |
727 | size_t i = 0; | 764 | size_t i = 0; |
@@ -761,142 +798,128 @@ void x11_start_xpra(int argc, char **argv) { | |||
761 | _exit(1); | 798 | _exit(1); |
762 | } | 799 | } |
763 | 800 | ||
764 | // add a small delay, on some systems it takes some time for the server to start | 801 | /* // add a small delay, on some systems it takes some time for the server to start */ |
765 | sleep(5); | 802 | /* sleep(5); */ |
766 | 803 | ||
767 | // check X11 socket | 804 | /* // check X11 socket */ |
768 | char *fname; | 805 | /* char *fname; */ |
769 | if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1) | 806 | /* if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1) */ |
770 | errExit("asprintf"); | 807 | /* errExit("asprintf"); */ |
771 | int n = 0; | 808 | /* int n = 0; */ |
772 | // wait for x11 server to start | 809 | /* // wait for x11 server to start */ |
773 | while (++n < 10) { | 810 | /* while (++n < 10) { */ |
774 | sleep(1); | 811 | /* sleep(1); */ |
775 | if (stat(fname, &s) == 0) | 812 | /* if (stat(fname, &s) == 0) */ |
776 | break; | 813 | /* break; */ |
777 | } | 814 | /* } */ |
778 | 815 | ||
779 | if (n == 10) { | 816 | /* if (n == 10) { */ |
780 | fprintf(stderr, "Error: failed to start xpra\n"); | 817 | /* fprintf(stderr, "Error: failed to start xpra\n"); */ |
781 | exit(1); | 818 | /* exit(1); */ |
782 | } | 819 | /* } */ |
783 | free(fname); | 820 | /* free(fname); */ |
784 | 821 | ||
785 | if (arg_debug) { | 822 | /* if (arg_debug) { */ |
786 | printf("X11 sockets: "); fflush(0); | 823 | /* printf("X11 sockets: "); fflush(0); */ |
787 | int rv = system("ls /tmp/.X11-unix"); | 824 | /* int rv = system("ls /tmp/.X11-unix"); */ |
788 | (void) rv; | 825 | /* (void) rv; */ |
789 | } | 826 | /* } */ |
790 | 827 | ||
791 | // build attach command | 828 | /* // build attach command */ |
792 | char *attach_argv[] = { "xpra", "--title=\"firejail x11 sandbox\"", "attach", display_str, NULL }; | 829 | /* char *attach_argv[] = { "xpra", "--title=\"firejail x11 sandbox\"", "attach", display_str, NULL }; */ |
793 | 830 | ||
794 | // run attach command | 831 | /* // run attach command */ |
795 | client = fork(); | 832 | /* client = fork(); */ |
796 | if (client < 0) | 833 | /* if (client < 0) */ |
797 | errExit("fork"); | 834 | /* errExit("fork"); */ |
798 | if (client == 0) { | 835 | /* if (client == 0) { */ |
799 | if (arg_quiet && fd_null != -1) { | 836 | /* if (arg_quiet && fd_null != -1) { */ |
800 | dup2(fd_null,0); | 837 | /* dup2(fd_null,0); */ |
801 | dup2(fd_null,1); | 838 | /* dup2(fd_null,1); */ |
802 | dup2(fd_null,2); | 839 | /* dup2(fd_null,2); */ |
803 | } | 840 | /* } */ |
804 | 841 | ||
805 | if (!arg_quiet) | 842 | /* if (!arg_quiet) */ |
806 | printf("\n*** Attaching to xpra display %d ***\n\n", display); | 843 | /* printf("\n*** Attaching to xpra display %d ***\n\n", display); */ |
807 | 844 | ||
808 | // running without privileges - see drop_privs call above | 845 | /* // running without privileges - see drop_privs call above */ |
809 | assert(getenv("LD_PRELOAD") == NULL); | 846 | /* assert(getenv("LD_PRELOAD") == NULL); */ |
810 | execvp(attach_argv[0], attach_argv); | 847 | /* execvp(attach_argv[0], attach_argv); */ |
811 | perror("execvp"); | 848 | /* perror("execvp"); */ |
812 | _exit(1); | 849 | /* _exit(1); */ |
813 | } | 850 | /* } */ |
814 | 851 | ||
815 | assert(display_str); | 852 | /* assert(display_str); */ |
816 | setenv("DISPLAY", display_str, 1); | 853 | /* setenv("DISPLAY", display_str, 1); */ |
817 | 854 | ||
818 | // build jail command | 855 | /* // start jail */ |
819 | char *firejail_argv[argc+2]; | 856 | /* pid_t jail = fork(); */ |
820 | pos = 0; | 857 | /* if (jail < 0) */ |
821 | for (i = 0; i < argc; i++) { | 858 | /* errExit("fork"); */ |
822 | if (strncmp(argv[i], "--x11", 5) == 0) | 859 | /* if (jail == 0) { */ |
823 | continue; | 860 | /* // running without privileges - see drop_privs call above */ |
824 | firejail_argv[pos] = argv[i]; | 861 | /* assert(getenv("LD_PRELOAD") == NULL); */ |
825 | pos++; | 862 | /* if (firejail_argv[0]) // shut up llvm scan-build */ |
826 | } | 863 | /* execvp(firejail_argv[0], firejail_argv); */ |
827 | firejail_argv[pos] = NULL; | 864 | /* perror("execvp"); */ |
828 | 865 | /* exit(1); */ | |
829 | assert((int) pos < (argc+2)); | 866 | /* } */ |
830 | assert(!firejail_argv[pos]); | 867 | |
831 | 868 | /* if (!arg_quiet) */ | |
832 | // start jail | 869 | /* printf("Xpra server pid %d, xpra client pid %d, jail %d\n", server, client, jail); */ |
833 | pid_t jail = fork(); | 870 | |
834 | if (jail < 0) | 871 | /* sleep(1); // adding a delay in order to let the server start */ |
835 | errExit("fork"); | ||
836 | if (jail == 0) { | ||
837 | // running without privileges - see drop_privs call above | ||
838 | assert(getenv("LD_PRELOAD") == NULL); | ||
839 | if (firejail_argv[0]) // shut up llvm scan-build | ||
840 | execvp(firejail_argv[0], firejail_argv); | ||
841 | perror("execvp"); | ||
842 | exit(1); | ||
843 | } | ||
844 | |||
845 | if (!arg_quiet) | ||
846 | printf("Xpra server pid %d, xpra client pid %d, jail %d\n", server, client, jail); | ||
847 | |||
848 | sleep(1); // adding a delay in order to let the server start | ||
849 | 872 | ||
850 | // wait for jail or server to end | 873 | // wait for jail or server to end |
851 | while (1) { | 874 | /* while (1) { */ |
852 | pid_t pid = wait(NULL); | 875 | /* pid_t pid = wait(NULL); */ |
853 | 876 | ||
854 | if (pid == jail) { | 877 | /* if (pid == jail) { */ |
855 | char *stop_argv[] = { "xpra", "stop", display_str, NULL }; | 878 | /* char *stop_argv[] = { "xpra", "stop", display_str, NULL }; */ |
856 | pid_t stop = fork(); | 879 | /* pid_t stop = fork(); */ |
857 | if (stop < 0) | 880 | /* if (stop < 0) */ |
858 | errExit("fork"); | 881 | /* errExit("fork"); */ |
859 | if (stop == 0) { | 882 | /* if (stop == 0) { */ |
860 | if (arg_quiet && fd_null != -1) { | 883 | /* if (arg_quiet && fd_null != -1) { */ |
861 | dup2(fd_null,0); | 884 | /* dup2(fd_null,0); */ |
862 | dup2(fd_null,1); | 885 | /* dup2(fd_null,1); */ |
863 | dup2(fd_null,2); | 886 | /* dup2(fd_null,2); */ |
864 | } | 887 | /* } */ |
865 | // running without privileges - see drop_privs call above | 888 | /* // running without privileges - see drop_privs call above */ |
866 | assert(getenv("LD_PRELOAD") == NULL); | 889 | /* assert(getenv("LD_PRELOAD") == NULL); */ |
867 | execvp(stop_argv[0], stop_argv); | 890 | /* execvp(stop_argv[0], stop_argv); */ |
868 | perror("execvp"); | 891 | /* perror("execvp"); */ |
869 | _exit(1); | 892 | /* _exit(1); */ |
870 | } | 893 | /* } */ |
871 | 894 | ||
872 | // wait for xpra server to stop, 10 seconds limit | 895 | /* // wait for xpra server to stop, 10 seconds limit */ |
873 | while (++n < 10) { | 896 | /* while (++n < 10) { */ |
874 | sleep(1); | 897 | /* sleep(1); */ |
875 | pid = waitpid(server, NULL, WNOHANG); | 898 | /* pid = waitpid(server, NULL, WNOHANG); */ |
876 | if (pid == server) | 899 | /* if (pid == server) */ |
877 | break; | 900 | /* break; */ |
878 | } | 901 | /* } */ |
879 | 902 | ||
880 | if (arg_debug) { | 903 | /* if (arg_debug) { */ |
881 | if (n == 10) | 904 | /* if (n == 10) */ |
882 | printf("failed to stop xpra server gratefully\n"); | 905 | /* printf("failed to stop xpra server gratefully\n"); */ |
883 | else | 906 | /* else */ |
884 | printf("xpra server successfully stopped in %d secs\n", n); | 907 | /* printf("xpra server successfully stopped in %d secs\n", n); */ |
885 | } | 908 | /* } */ |
886 | 909 | ||
887 | // kill xpra server and xpra client | 910 | /* // kill xpra server and xpra client */ |
888 | kill(client, SIGTERM); | 911 | /* kill(client, SIGTERM); */ |
889 | kill(server, SIGTERM); | 912 | /* kill(server, SIGTERM); */ |
890 | exit(0); | 913 | /* exit(0); */ |
891 | } | 914 | /* } */ |
892 | else if (pid == server) { | 915 | /* else if (pid == server) { */ |
893 | // kill firejail process | 916 | /* // kill firejail process */ |
894 | kill(jail, SIGTERM); | 917 | /* kill(jail, SIGTERM); */ |
895 | // kill xpra client (should die with server, but...) | 918 | /* // kill xpra client (should die with server, but...) */ |
896 | kill(client, SIGTERM); | 919 | /* kill(client, SIGTERM); */ |
897 | exit(0); | 920 | /* exit(0); */ |
898 | } | 921 | /* } */ |
899 | } | 922 | /* } */ |
900 | } | 923 | } |
901 | 924 | ||
902 | 925 | ||