aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Chiraag Nataraj <chiraag.nataraj@gmail.com>2017-07-30 01:53:18 -0400
committerLibravatar Chiraag Nataraj <chiraag.nataraj@gmail.com>2017-07-30 01:53:18 -0400
commitcf91175fec779ab431ef2fa31248b47a8da7196e (patch)
treecb8a958720c3f38169641afb17caa472d001fff6
parentMerge branch 'master' of https://github.com/netblue30/firejail (diff)
downloadfirejail-cf91175fec779ab431ef2fa31248b47a8da7196e.tar.gz
firejail-cf91175fec779ab431ef2fa31248b47a8da7196e.tar.zst
firejail-cf91175fec779ab431ef2fa31248b47a8da7196e.zip
Tentative implementation for #1405
-rw-r--r--src/firejail/x11.c313
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