aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-07-31 07:09:41 -0400
committerLibravatar GitHub <noreply@github.com>2017-07-31 07:09:41 -0400
commitafe4b1dada830895aac46f1a51d235ce893b9571 (patch)
tree81534aee83bfd0c5cfc1b09410e48842540bde1b
parentFixes for the private-lib and memory-deny-write-execute features (diff)
parentEnsure malloc was successful (diff)
downloadfirejail-afe4b1dada830895aac46f1a51d235ce893b9571.tar.gz
firejail-afe4b1dada830895aac46f1a51d235ce893b9571.tar.zst
firejail-afe4b1dada830895aac46f1a51d235ce893b9571.zip
Merge pull request #1415 from chiraag-nataraj/master
Tentative implementation for #1405
-rw-r--r--src/firejail/x11.c320
1 files changed, 175 insertions, 145 deletions
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index c6bb7e1e3..7b21c2209 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -665,10 +665,43 @@ 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 if (start_child == NULL)
689 {
690 fprintf(stderr, "Error: unable to allocate start_child to assemble command\n");
691 exit(1);
692 }
693
694 strcpy(start_child,start_child_prefix);
695 for(i = 0; i < fpos; i++) {
696 strncat(start_child,firejail_argv[i],strlen(firejail_argv[i]));
697 if(i != fpos - 1)
698 strncat(start_child," ",strlen(" "));
699 }
700
701 server_argv[spos++] = start_child;
702
703 server_argv[spos++] = NULL;
704 firejail_argv[fpos] = NULL;
672 705
673 assert(xpra_extra_params); // should be "" if empty 706 assert(xpra_extra_params); // should be "" if empty
674 707
@@ -702,26 +735,28 @@ void x11_start_xpra(int argc, char **argv) {
702 exit(1); 735 exit(1);
703 } 736 }
704 737
705 server_argv[pos++] = temp; 738 server_argv[spos++] = temp;
706 for (i = 0; i < (int) strlen(xpra_extra_params)-1; i++) { 739 for (i = 0; i < (int) strlen(xpra_extra_params)-1; i++) {
707 if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) { 740 if (spos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) {
708 fprintf(stderr, "Error: arg count limit exceeded while parsing xpra_extra_params\n"); 741 fprintf(stderr, "Error: arg count limit exceeded while parsing xpra_extra_params\n");
709 exit(1); 742 exit(1);
710 } 743 }
711 if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) { 744 if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) {
712 server_argv[pos++] = temp + i + 2; 745 server_argv[spos++] = temp + i + 2;
713 } 746 }
714 else if (temp[i] == '\0' && temp[i+1] != '\0') { 747 else if (temp[i] == '\0' && temp[i+1] != '\0') {
715 server_argv[pos++] = temp + i + 1; 748 server_argv[spos++] = temp + i + 1;
716 } 749 }
717 } 750 }
718 } 751 }
719 752
720 server_argv[pos++] = NULL; 753 assert((int) fpos < (argc+2));
721 754 assert(!firejail_argv[fpos]);
722 // no overrun 755 // no overrun
723 assert(pos < (sizeof(server_argv)/sizeof(*server_argv))); 756 assert(spos < (sizeof(server_argv)/sizeof(*server_argv)));
724 assert(server_argv[pos-1] == NULL); // last element is null 757 assert(server_argv[spos-1] == NULL); // last element is null
758
759
725 760
726 if (arg_debug) { 761 if (arg_debug) {
727 size_t i = 0; 762 size_t i = 0;
@@ -761,142 +796,137 @@ void x11_start_xpra(int argc, char **argv) {
761 _exit(1); 796 _exit(1);
762 } 797 }
763 798
764 // add a small delay, on some systems it takes some time for the server to start 799 /* // add a small delay, on some systems it takes some time for the server to start */
765 sleep(5); 800 /* sleep(5); */
766 801
767 // check X11 socket 802 /* // check X11 socket */
768 char *fname; 803 /* char *fname; */
769 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1) 804 /* if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1) */
770 errExit("asprintf"); 805 /* errExit("asprintf"); */
771 int n = 0; 806 /* int n = 0; */
772 // wait for x11 server to start 807 /* // wait for x11 server to start */
773 while (++n < 10) { 808 /* while (++n < 10) { */
774 sleep(1); 809 /* sleep(1); */
775 if (stat(fname, &s) == 0) 810 /* if (stat(fname, &s) == 0) */
776 break; 811 /* break; */
777 } 812 /* } */
778 813
779 if (n == 10) { 814 /* if (n == 10) { */
780 fprintf(stderr, "Error: failed to start xpra\n"); 815 /* fprintf(stderr, "Error: failed to start xpra\n"); */
781 exit(1); 816 /* exit(1); */
782 } 817 /* } */
783 free(fname); 818 /* free(fname); */
784 819
785 if (arg_debug) { 820 /* if (arg_debug) { */
786 printf("X11 sockets: "); fflush(0); 821 /* printf("X11 sockets: "); fflush(0); */
787 int rv = system("ls /tmp/.X11-unix"); 822 /* int rv = system("ls /tmp/.X11-unix"); */
788 (void) rv; 823 /* (void) rv; */
789 } 824 /* } */
790 825
791 // build attach command 826 /* // build attach command */
792 char *attach_argv[] = { "xpra", "--title=\"firejail x11 sandbox\"", "attach", display_str, NULL }; 827 /* char *attach_argv[] = { "xpra", "--title=\"firejail x11 sandbox\"", "attach", display_str, NULL }; */
793 828
794 // run attach command 829 /* // run attach command */
795 client = fork(); 830 /* client = fork(); */
796 if (client < 0) 831 /* if (client < 0) */
797 errExit("fork"); 832 /* errExit("fork"); */
798 if (client == 0) { 833 /* if (client == 0) { */
799 if (arg_quiet && fd_null != -1) { 834 /* if (arg_quiet && fd_null != -1) { */
800 dup2(fd_null,0); 835 /* dup2(fd_null,0); */
801 dup2(fd_null,1); 836 /* dup2(fd_null,1); */
802 dup2(fd_null,2); 837 /* dup2(fd_null,2); */
803 } 838 /* } */
804 839
805 if (!arg_quiet) 840 /* if (!arg_quiet) */
806 printf("\n*** Attaching to xpra display %d ***\n\n", display); 841 /* printf("\n*** Attaching to xpra display %d ***\n\n", display); */
807 842
808 // running without privileges - see drop_privs call above 843 /* // running without privileges - see drop_privs call above */
809 assert(getenv("LD_PRELOAD") == NULL); 844 /* assert(getenv("LD_PRELOAD") == NULL); */
810 execvp(attach_argv[0], attach_argv); 845 /* execvp(attach_argv[0], attach_argv); */
811 perror("execvp"); 846 /* perror("execvp"); */
812 _exit(1); 847 /* _exit(1); */
813 } 848 /* } */
814 849
815 assert(display_str); 850 /* assert(display_str); */
816 setenv("DISPLAY", display_str, 1); 851 /* setenv("DISPLAY", display_str, 1); */
817 852
818 // build jail command 853 /* // start jail */
819 char *firejail_argv[argc+2]; 854 /* pid_t jail = fork(); */
820 pos = 0; 855 /* if (jail < 0) */
821 for (i = 0; i < argc; i++) { 856 /* errExit("fork"); */
822 if (strncmp(argv[i], "--x11", 5) == 0) 857 /* if (jail == 0) { */
823 continue; 858 /* // running without privileges - see drop_privs call above */
824 firejail_argv[pos] = argv[i]; 859 /* assert(getenv("LD_PRELOAD") == NULL); */
825 pos++; 860 /* if (firejail_argv[0]) // shut up llvm scan-build */
826 } 861 /* execvp(firejail_argv[0], firejail_argv); */
827 firejail_argv[pos] = NULL; 862 /* perror("execvp"); */
828 863 /* exit(1); */
829 assert((int) pos < (argc+2)); 864 /* } */
830 assert(!firejail_argv[pos]); 865
831 866 /* if (!arg_quiet) */
832 // start jail 867 /* printf("Xpra server pid %d, xpra client pid %d, jail %d\n", server, client, jail); */
833 pid_t jail = fork(); 868
834 if (jail < 0) 869 /* sleep(1); // adding a delay in order to let the server start */
835 errExit("fork"); 870
836 if (jail == 0) { 871 // wait for server to end
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
850 // wait for jail or server to end
851 while (1) { 872 while (1) {
852 pid_t pid = wait(NULL); 873 pid_t pid = wait(NULL);
853 874 if (pid == server) {
854 if (pid == jail) { 875 free(start_child);
855 char *stop_argv[] = { "xpra", "stop", display_str, NULL }; 876 exit(0);
856 pid_t stop = fork(); 877 }
857 if (stop < 0)
858 errExit("fork");
859 if (stop == 0) {
860 if (arg_quiet && fd_null != -1) {
861 dup2(fd_null,0);
862 dup2(fd_null,1);
863 dup2(fd_null,2);
864 }
865 // running without privileges - see drop_privs call above
866 assert(getenv("LD_PRELOAD") == NULL);
867 execvp(stop_argv[0], stop_argv);
868 perror("execvp");
869 _exit(1);
870 }
871
872 // wait for xpra server to stop, 10 seconds limit
873 while (++n < 10) {
874 sleep(1);
875 pid = waitpid(server, NULL, WNOHANG);
876 if (pid == server)
877 break;
878 }
879
880 if (arg_debug) {
881 if (n == 10)
882 printf("failed to stop xpra server gratefully\n");
883 else
884 printf("xpra server successfully stopped in %d secs\n", n);
885 }
886
887 // kill xpra server and xpra client
888 kill(client, SIGTERM);
889 kill(server, SIGTERM);
890 exit(0);
891 }
892 else if (pid == server) {
893 // kill firejail process
894 kill(jail, SIGTERM);
895 // kill xpra client (should die with server, but...)
896 kill(client, SIGTERM);
897 exit(0);
898 }
899 } 878 }
879
880 // wait for jail or server to end
881 /* while (1) { */
882 /* pid_t pid = wait(NULL); */
883
884 /* if (pid == jail) { */
885 /* char *stop_argv[] = { "xpra", "stop", display_str, NULL }; */
886 /* pid_t stop = fork(); */
887 /* if (stop < 0) */
888 /* errExit("fork"); */
889 /* if (stop == 0) { */
890 /* if (arg_quiet && fd_null != -1) { */
891 /* dup2(fd_null,0); */
892 /* dup2(fd_null,1); */
893 /* dup2(fd_null,2); */
894 /* } */
895 /* // running without privileges - see drop_privs call above */
896 /* assert(getenv("LD_PRELOAD") == NULL); */
897 /* execvp(stop_argv[0], stop_argv); */
898 /* perror("execvp"); */
899 /* _exit(1); */
900 /* } */
901
902 /* // wait for xpra server to stop, 10 seconds limit */
903 /* while (++n < 10) { */
904 /* sleep(1); */
905 /* pid = waitpid(server, NULL, WNOHANG); */
906 /* if (pid == server) */
907 /* break; */
908 /* } */
909
910 /* if (arg_debug) { */
911 /* if (n == 10) */
912 /* printf("failed to stop xpra server gratefully\n"); */
913 /* else */
914 /* printf("xpra server successfully stopped in %d secs\n", n); */
915 /* } */
916
917 /* // kill xpra server and xpra client */
918 /* kill(client, SIGTERM); */
919 /* kill(server, SIGTERM); */
920 /* exit(0); */
921 /* } */
922 /* else if (pid == server) { */
923 /* // kill firejail process */
924 /* kill(jail, SIGTERM); */
925 /* // kill xpra client (should die with server, but...) */
926 /* kill(client, SIGTERM); */
927 /* exit(0); */
928 /* } */
929 /* } */
900} 930}
901 931
902 932