From cf91175fec779ab431ef2fa31248b47a8da7196e Mon Sep 17 00:00:00 2001 From: Chiraag Nataraj Date: Sun, 30 Jul 2017 01:53:18 -0400 Subject: Tentative implementation for #1405 --- src/firejail/x11.c | 313 ++++++++++++++++++++++++++++------------------------- 1 file 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) { // build the start command char *server_argv[256] = { // rest initialyzed to NULL - "xpra", "start", display_str, "--no-daemon", + "xpra", "start", display_str, "--daemon=no", "--attach=yes", "--exit-with-children=yes" }; - unsigned pos = 0; - while (server_argv[pos] != NULL) pos++; + unsigned spos = 0; + unsigned fpos = 0; + while (server_argv[spos] != NULL) spos++; + + // build jail command + char *firejail_argv[argc+2]; + size_t total_length = 0; + for (i = 0; i < argc; i++) { + if (strncmp(argv[i], "--x11", 5) == 0) + continue; + firejail_argv[fpos] = argv[i]; + fpos++; + total_length += strlen(argv[i]); + } + + char *start_child_prefix = "--start-child="; + char *start_child; + start_child = malloc(total_length + strlen(start_child_prefix) + fpos + 2); + printf("START_CHILD: %s\n", start_child); + printf("START_CHILD_PREFIX: %s\n", start_child_prefix); + strcpy(start_child,start_child_prefix); + printf("START_CHILD: %s\n", start_child); + for(i = 0; i < fpos; i++) { + printf("%s\n",firejail_argv[i]); + strncat(start_child,firejail_argv[i],strlen(firejail_argv[i])); + if(i != fpos - 1) + strncat(start_child," ",strlen(" ")); + } + + /* strncat(start_child,"\'",strlen("\'")); */ + + printf("START_CHILD: %s\n", start_child); + + server_argv[spos++] = start_child; + + server_argv[spos++] = NULL; + firejail_argv[fpos] = NULL; assert(xpra_extra_params); // should be "" if empty @@ -702,26 +737,28 @@ void x11_start_xpra(int argc, char **argv) { exit(1); } - server_argv[pos++] = temp; + server_argv[spos++] = temp; for (i = 0; i < (int) strlen(xpra_extra_params)-1; i++) { - if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) { + if (spos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) { fprintf(stderr, "Error: arg count limit exceeded while parsing xpra_extra_params\n"); exit(1); } if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) { - server_argv[pos++] = temp + i + 2; + server_argv[spos++] = temp + i + 2; } else if (temp[i] == '\0' && temp[i+1] != '\0') { - server_argv[pos++] = temp + i + 1; + server_argv[spos++] = temp + i + 1; } } } - server_argv[pos++] = NULL; - + assert((int) fpos < (argc+2)); + assert(!firejail_argv[fpos]); // no overrun - assert(pos < (sizeof(server_argv)/sizeof(*server_argv))); - assert(server_argv[pos-1] == NULL); // last element is null + assert(spos < (sizeof(server_argv)/sizeof(*server_argv))); + assert(server_argv[spos-1] == NULL); // last element is null + + if (arg_debug) { size_t i = 0; @@ -761,142 +798,128 @@ void x11_start_xpra(int argc, char **argv) { _exit(1); } - // add a small delay, on some systems it takes some time for the server to start - sleep(5); - - // check X11 socket - char *fname; - if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1) - errExit("asprintf"); - int n = 0; - // wait for x11 server to start - while (++n < 10) { - sleep(1); - if (stat(fname, &s) == 0) - break; - } - - if (n == 10) { - fprintf(stderr, "Error: failed to start xpra\n"); - exit(1); - } - free(fname); - - if (arg_debug) { - printf("X11 sockets: "); fflush(0); - int rv = system("ls /tmp/.X11-unix"); - (void) rv; - } - - // build attach command - char *attach_argv[] = { "xpra", "--title=\"firejail x11 sandbox\"", "attach", display_str, NULL }; - - // run attach command - client = fork(); - if (client < 0) - errExit("fork"); - if (client == 0) { - if (arg_quiet && fd_null != -1) { - dup2(fd_null,0); - dup2(fd_null,1); - dup2(fd_null,2); - } - - if (!arg_quiet) - printf("\n*** Attaching to xpra display %d ***\n\n", display); - - // running without privileges - see drop_privs call above - assert(getenv("LD_PRELOAD") == NULL); - execvp(attach_argv[0], attach_argv); - perror("execvp"); - _exit(1); - } - - assert(display_str); - setenv("DISPLAY", display_str, 1); - - // build jail command - char *firejail_argv[argc+2]; - pos = 0; - for (i = 0; i < argc; i++) { - if (strncmp(argv[i], "--x11", 5) == 0) - continue; - firejail_argv[pos] = argv[i]; - pos++; - } - firejail_argv[pos] = NULL; - - assert((int) pos < (argc+2)); - assert(!firejail_argv[pos]); - - // start jail - pid_t jail = fork(); - if (jail < 0) - errExit("fork"); - if (jail == 0) { - // running without privileges - see drop_privs call above - assert(getenv("LD_PRELOAD") == NULL); - if (firejail_argv[0]) // shut up llvm scan-build - execvp(firejail_argv[0], firejail_argv); - perror("execvp"); - exit(1); - } - - if (!arg_quiet) - printf("Xpra server pid %d, xpra client pid %d, jail %d\n", server, client, jail); - - sleep(1); // adding a delay in order to let the server start + /* // add a small delay, on some systems it takes some time for the server to start */ + /* sleep(5); */ + + /* // check X11 socket */ + /* char *fname; */ + /* if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1) */ + /* errExit("asprintf"); */ + /* int n = 0; */ + /* // wait for x11 server to start */ + /* while (++n < 10) { */ + /* sleep(1); */ + /* if (stat(fname, &s) == 0) */ + /* break; */ + /* } */ + + /* if (n == 10) { */ + /* fprintf(stderr, "Error: failed to start xpra\n"); */ + /* exit(1); */ + /* } */ + /* free(fname); */ + + /* if (arg_debug) { */ + /* printf("X11 sockets: "); fflush(0); */ + /* int rv = system("ls /tmp/.X11-unix"); */ + /* (void) rv; */ + /* } */ + + /* // build attach command */ + /* char *attach_argv[] = { "xpra", "--title=\"firejail x11 sandbox\"", "attach", display_str, NULL }; */ + + /* // run attach command */ + /* client = fork(); */ + /* if (client < 0) */ + /* errExit("fork"); */ + /* if (client == 0) { */ + /* if (arg_quiet && fd_null != -1) { */ + /* dup2(fd_null,0); */ + /* dup2(fd_null,1); */ + /* dup2(fd_null,2); */ + /* } */ + + /* if (!arg_quiet) */ + /* printf("\n*** Attaching to xpra display %d ***\n\n", display); */ + + /* // running without privileges - see drop_privs call above */ + /* assert(getenv("LD_PRELOAD") == NULL); */ + /* execvp(attach_argv[0], attach_argv); */ + /* perror("execvp"); */ + /* _exit(1); */ + /* } */ + + /* assert(display_str); */ + /* setenv("DISPLAY", display_str, 1); */ + + /* // start jail */ + /* pid_t jail = fork(); */ + /* if (jail < 0) */ + /* errExit("fork"); */ + /* if (jail == 0) { */ + /* // running without privileges - see drop_privs call above */ + /* assert(getenv("LD_PRELOAD") == NULL); */ + /* if (firejail_argv[0]) // shut up llvm scan-build */ + /* execvp(firejail_argv[0], firejail_argv); */ + /* perror("execvp"); */ + /* exit(1); */ + /* } */ + + /* if (!arg_quiet) */ + /* printf("Xpra server pid %d, xpra client pid %d, jail %d\n", server, client, jail); */ + + /* sleep(1); // adding a delay in order to let the server start */ // wait for jail or server to end - while (1) { - pid_t pid = wait(NULL); - - if (pid == jail) { - char *stop_argv[] = { "xpra", "stop", display_str, NULL }; - pid_t stop = fork(); - if (stop < 0) - errExit("fork"); - if (stop == 0) { - if (arg_quiet && fd_null != -1) { - dup2(fd_null,0); - dup2(fd_null,1); - dup2(fd_null,2); - } - // running without privileges - see drop_privs call above - assert(getenv("LD_PRELOAD") == NULL); - execvp(stop_argv[0], stop_argv); - perror("execvp"); - _exit(1); - } - - // wait for xpra server to stop, 10 seconds limit - while (++n < 10) { - sleep(1); - pid = waitpid(server, NULL, WNOHANG); - if (pid == server) - break; - } - - if (arg_debug) { - if (n == 10) - printf("failed to stop xpra server gratefully\n"); - else - printf("xpra server successfully stopped in %d secs\n", n); - } - - // kill xpra server and xpra client - kill(client, SIGTERM); - kill(server, SIGTERM); - exit(0); - } - else if (pid == server) { - // kill firejail process - kill(jail, SIGTERM); - // kill xpra client (should die with server, but...) - kill(client, SIGTERM); - exit(0); - } - } + /* while (1) { */ + /* pid_t pid = wait(NULL); */ + + /* if (pid == jail) { */ + /* char *stop_argv[] = { "xpra", "stop", display_str, NULL }; */ + /* pid_t stop = fork(); */ + /* if (stop < 0) */ + /* errExit("fork"); */ + /* if (stop == 0) { */ + /* if (arg_quiet && fd_null != -1) { */ + /* dup2(fd_null,0); */ + /* dup2(fd_null,1); */ + /* dup2(fd_null,2); */ + /* } */ + /* // running without privileges - see drop_privs call above */ + /* assert(getenv("LD_PRELOAD") == NULL); */ + /* execvp(stop_argv[0], stop_argv); */ + /* perror("execvp"); */ + /* _exit(1); */ + /* } */ + + /* // wait for xpra server to stop, 10 seconds limit */ + /* while (++n < 10) { */ + /* sleep(1); */ + /* pid = waitpid(server, NULL, WNOHANG); */ + /* if (pid == server) */ + /* break; */ + /* } */ + + /* if (arg_debug) { */ + /* if (n == 10) */ + /* printf("failed to stop xpra server gratefully\n"); */ + /* else */ + /* printf("xpra server successfully stopped in %d secs\n", n); */ + /* } */ + + /* // kill xpra server and xpra client */ + /* kill(client, SIGTERM); */ + /* kill(server, SIGTERM); */ + /* exit(0); */ + /* } */ + /* else if (pid == server) { */ + /* // kill firejail process */ + /* kill(jail, SIGTERM); */ + /* // kill xpra client (should die with server, but...) */ + /* kill(client, SIGTERM); */ + /* exit(0); */ + /* } */ + /* } */ } -- cgit v1.2.3-70-g09d2