aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--RELNOTES1
-rw-r--r--etc/firejail.config4
-rw-r--r--src/firejail/checkcfg.c14
-rw-r--r--src/firejail/firejail.h1
-rw-r--r--src/firejail/x11.c101
5 files changed, 105 insertions, 16 deletions
diff --git a/RELNOTES b/RELNOTES
index 33088dfe5..ccd841e27 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -34,6 +34,7 @@ firejail (0.9.46-rc1) baseline; urgency=low
34 * feature: --fix-sound support in firecfg 34 * feature: --fix-sound support in firecfg
35 * feature: added support for sandboxing Xpra, Xvfb and Xephyr in 35 * feature: added support for sandboxing Xpra, Xvfb and Xephyr in
36 independent sandboxes when started with firejail --x11 36 independent sandboxes when started with firejail --x11
37 * feature: support for Xpra extra params in firejail config file
37 * new profiles: xiphos, Tor Browser Bundle, display (imagemagick), Wire, 38 * new profiles: xiphos, Tor Browser Bundle, display (imagemagick), Wire,
38 * new profiles: mumble, zoom, Guayadeque, qemu, keypass2, xed, pluma, 39 * new profiles: mumble, zoom, Guayadeque, qemu, keypass2, xed, pluma,
39 * new profiles: Cryptocat, Bless, Gnome 2048, Gnome Calculator, 40 * new profiles: Cryptocat, Bless, Gnome 2048, Gnome Calculator,
diff --git a/etc/firejail.config b/etc/firejail.config
index 537ac9b38..1db33edda 100644
--- a/etc/firejail.config
+++ b/etc/firejail.config
@@ -100,6 +100,10 @@
100# xephyr-extra-params -keybd ephyr,,,xkbmodel=evdev 100# xephyr-extra-params -keybd ephyr,,,xkbmodel=evdev
101# xephyr-extra-params -grayscale 101# xephyr-extra-params -grayscale
102 102
103# Xpra server command extra parameters. None by default; this is an example.
104# xpra-extra-params --dpi 96
105
106
103# Screen size for --x11=xvfb, default 800x600x24. The third dimension is 107# Screen size for --x11=xvfb, default 800x600x24. The third dimension is
104# color depth; use 24 unless you know exactly what you're doing. 108# color depth; use 24 unless you know exactly what you're doing.
105# xvfb-screen 640x480x24 109# xvfb-screen 640x480x24
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c
index 24d8d0381..3c0c1b9ac 100644
--- a/src/firejail/checkcfg.c
+++ b/src/firejail/checkcfg.c
@@ -27,6 +27,7 @@ static int initialized = 0;
27static int cfg_val[CFG_MAX]; 27static int cfg_val[CFG_MAX];
28char *xephyr_screen = "800x600"; 28char *xephyr_screen = "800x600";
29char *xephyr_extra_params = ""; 29char *xephyr_extra_params = "";
30char *xpra_extra_params = "";
30char *xvfb_screen = "800x600x24"; 31char *xvfb_screen = "800x600x24";
31char *xvfb_extra_params = ""; 32char *xvfb_extra_params = "";
32char *netfilter_default = NULL; 33char *netfilter_default = NULL;
@@ -248,14 +249,23 @@ int checkcfg(int val) {
248 } 249 }
249 250
250 // Xephyr command extra parameters 251 // Xephyr command extra parameters
251 else if (strncmp(ptr, "xephyr-extra-params ", 19) == 0) { 252 else if (strncmp(ptr, "xephyr-extra-params ", 20) == 0) {
252 if (*xephyr_extra_params != '\0') 253 if (*xephyr_extra_params != '\0')
253 goto errout; 254 goto errout;
254 xephyr_extra_params = strdup(ptr + 19); 255 xephyr_extra_params = strdup(ptr + 20);
255 if (!xephyr_extra_params) 256 if (!xephyr_extra_params)
256 errExit("strdup"); 257 errExit("strdup");
257 } 258 }
258 259
260 // xpra server extra parameters
261 else if (strncmp(ptr, "xpra-extra-params ", 18) == 0) {
262 if (*xpra_extra_params != '\0')
263 goto errout;
264 xpra_extra_params = strdup(ptr + 18);
265 if (!xpra_extra_params)
266 errExit("strdup");
267 }
268
259 // Xvfb screen size 269 // Xvfb screen size
260 else if (strncmp(ptr, "xvfb-screen ", 12) == 0) { 270 else if (strncmp(ptr, "xvfb-screen ", 12) == 0) {
261 // expecting three numbers separated by x's 271 // expecting three numbers separated by x's
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 09fadcf34..6b1786a93 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -692,6 +692,7 @@ enum {
692}; 692};
693extern char *xephyr_screen; 693extern char *xephyr_screen;
694extern char *xephyr_extra_params; 694extern char *xephyr_extra_params;
695extern char *xpra_extra_params;
695extern char *xvfb_screen; 696extern char *xvfb_screen;
696extern char *xvfb_extra_params; 697extern char *xvfb_extra_params;
697extern char *netfilter_default; 698extern char *netfilter_default;
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index da881f344..0f7ea56b6 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -239,8 +239,8 @@ void x11_start_xvfb(int argc, char **argv) {
239 239
240 // parse xvfb_extra_params 240 // parse xvfb_extra_params
241 // very basic quoting support 241 // very basic quoting support
242 char *temp = strdup(xephyr_extra_params); 242 char *temp = strdup(xvfb_extra_params);
243 if (*xephyr_extra_params != '\0') { 243 if (*xvfb_extra_params != '\0') {
244 if (!temp) 244 if (!temp)
245 errExit("strdup"); 245 errExit("strdup");
246 bool dquote = false; 246 bool dquote = false;
@@ -267,6 +267,7 @@ void x11_start_xvfb(int argc, char **argv) {
267 exit(1); 267 exit(1);
268 } 268 }
269 269
270 server_argv[pos++] = temp;
270 for (i = 0; i < (int) strlen(xvfb_extra_params)-1; i++) { 271 for (i = 0; i < (int) strlen(xvfb_extra_params)-1; i++) {
271 if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) { 272 if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) {
272 fprintf(stderr, "Error: arg count limit exceeded while parsing xvfb_extra_params\n"); 273 fprintf(stderr, "Error: arg count limit exceeded while parsing xvfb_extra_params\n");
@@ -284,12 +285,12 @@ void x11_start_xvfb(int argc, char **argv) {
284 285
285 if (arg_debug) { 286 if (arg_debug) {
286 size_t i = 0; 287 size_t i = 0;
287 printf("xvfb server:"); 288 printf("\n*** Starting xvfb server:");
288 while (server_argv[i]!=NULL) { 289 while (server_argv[i]!=NULL) {
289 printf(" \"%s\"", server_argv[i]); 290 printf(" \"%s\"", server_argv[i]);
290 i++; 291 i++;
291 } 292 }
292 putchar('\n'); 293 printf(" ***\n\n");
293 } 294 }
294 295
295 // remove --x11 arg 296 // remove --x11 arg
@@ -307,12 +308,12 @@ void x11_start_xvfb(int argc, char **argv) {
307 308
308 if (arg_debug) { 309 if (arg_debug) {
309 size_t i = 0; 310 size_t i = 0;
310 printf("xvfb client:"); 311 printf("\n*** Stating xvfb client:");
311 while (jail_argv[i]!=NULL) { 312 while (jail_argv[i]!=NULL) {
312 printf(" \"%s\"", jail_argv[i]); 313 printf(" \"%s\"", jail_argv[i]);
313 i++; 314 i++;
314 } 315 }
315 putchar('\n'); 316 printf(" ***\n\n");
316 } 317 }
317 318
318 server = fork(); 319 server = fork();
@@ -471,13 +472,18 @@ void x11_start_xephyr(int argc, char **argv) {
471 exit(1); 472 exit(1);
472 } 473 }
473 474
475 server_argv[pos++] = temp;
474 for (i = 0; i < (int) strlen(xephyr_extra_params)-1; i++) { 476 for (i = 0; i < (int) strlen(xephyr_extra_params)-1; i++) {
475 if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) { 477 if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) {
476 fprintf(stderr, "Error: arg count limit exceeded while parsing xephyr_extra_params\n"); 478 fprintf(stderr, "Error: arg count limit exceeded while parsing xephyr_extra_params\n");
477 exit(1); 479 exit(1);
478 } 480 }
479 if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) server_argv[pos++] = temp + i + 2; 481 if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) {
480 else if (temp[i] == '\0' && temp[i+1] != '\0') server_argv[pos++] = temp + i + 1; 482 server_argv[pos++] = temp + i + 2;
483 }
484 else if (temp[i] == '\0' && temp[i+1] != '\0') {
485 server_argv[pos++] = temp + i + 1;
486 }
481 } 487 }
482 } 488 }
483 489
@@ -490,12 +496,12 @@ void x11_start_xephyr(int argc, char **argv) {
490 496
491 if (arg_debug) { 497 if (arg_debug) {
492 size_t i = 0; 498 size_t i = 0;
493 printf("xephyr server:"); 499 printf("\n*** Starting xephyr server:");
494 while (server_argv[i]!=NULL) { 500 while (server_argv[i]!=NULL) {
495 printf(" \"%s\"", server_argv[i]); 501 printf(" \"%s\"", server_argv[i]);
496 i++; 502 i++;
497 } 503 }
498 putchar('\n'); 504 printf(" ***\n\n");
499 } 505 }
500 506
501 // remove --x11 arg 507 // remove --x11 arg
@@ -513,12 +519,12 @@ void x11_start_xephyr(int argc, char **argv) {
513 519
514 if (arg_debug) { 520 if (arg_debug) {
515 size_t i = 0; 521 size_t i = 0;
516 printf("xephyr client:"); 522 printf("*** Starting xephyr client:");
517 while (jail_argv[i]!=NULL) { 523 while (jail_argv[i]!=NULL) {
518 printf(" \"%s\"", jail_argv[i]); 524 printf(" \"%s\"", jail_argv[i]);
519 i++; 525 i++;
520 } 526 }
521 putchar('\n'); 527 printf(" ***\n\n");
522 } 528 }
523 529
524 server = fork(); 530 server = fork();
@@ -631,7 +637,74 @@ void x11_start_xpra(int argc, char **argv) {
631 errExit("asprintf"); 637 errExit("asprintf");
632 638
633 // build the start command 639 // build the start command
634 char *server_argv[] = { "xpra", "start", display_str, "--no-daemon", NULL }; 640 char *server_argv[256] = { // rest initialyzed to NULL
641 "xpra", "start", display_str, "--no-daemon",
642 };
643 unsigned pos = 0;
644 while (server_argv[pos] != NULL) pos++;
645
646 assert(xpra_extra_params); // should be "" if empty
647
648 // parse xephyr_extra_params
649 // very basic quoting support
650 char *temp = strdup(xpra_extra_params);
651 if (*xpra_extra_params != '\0') {
652 if (!temp)
653 errExit("strdup");
654 bool dquote = false;
655 bool squote = false;
656 for (i = 0; i < (int) strlen(xpra_extra_params); i++) {
657 if (temp[i] == '\"') {
658 dquote = !dquote;
659 // replace closing quote by \0
660 if (dquote) temp[i] = '\0';
661 }
662 if (temp[i] == '\'') {
663 squote = !squote;
664 // replace closing quote by \0
665 if (squote) temp[i] = '\0';
666 }
667 if (!dquote && !squote && temp[i] == ' ') temp[i] = '\0';
668 if (dquote && squote) {
669 fprintf(stderr, "Error: mixed quoting found while parsing xpra_extra_params\n");
670 exit(1);
671 }
672 }
673 if (dquote) {
674 fprintf(stderr, "Error: unclosed quote found while parsing xpra_extra_params\n");
675 exit(1);
676 }
677
678 server_argv[pos++] = temp;
679 for (i = 0; i < (int) strlen(xpra_extra_params)-1; i++) {
680 if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) {
681 fprintf(stderr, "Error: arg count limit exceeded while parsing xpra_extra_params\n");
682 exit(1);
683 }
684 if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) {
685 server_argv[pos++] = temp + i + 2;
686 }
687 else if (temp[i] == '\0' && temp[i+1] != '\0') {
688 server_argv[pos++] = temp + i + 1;
689 }
690 }
691 }
692
693 server_argv[pos++] = NULL;
694
695 // no overrun
696 assert(pos < (sizeof(server_argv)/sizeof(*server_argv)));
697 assert(server_argv[pos-1] == NULL); // last element is null
698
699 if (arg_debug) {
700 size_t i = 0;
701 printf("\n*** Starting xpra server: ");
702 while (server_argv[i]!=NULL) {
703 printf(" \"%s\"", server_argv[i]);
704 i++;
705 }
706 printf(" ***\n\n");
707 }
635 708
636 int fd_null = -1; 709 int fd_null = -1;
637 if (arg_quiet) { 710 if (arg_quiet) {
@@ -716,7 +789,7 @@ void x11_start_xpra(int argc, char **argv) {
716 789
717 // build jail command 790 // build jail command
718 char *firejail_argv[argc+2]; 791 char *firejail_argv[argc+2];
719 int pos = 0; 792 pos = 0;
720 for (i = 0; i < argc; i++) { 793 for (i = 0; i < argc; i++) {
721 if (strncmp(argv[i], "--x11", 5) == 0) 794 if (strncmp(argv[i], "--x11", 5) == 0)
722 continue; 795 continue;