From 369458e299696f7badf7d0d72ec0e90cdd91f201 Mon Sep 17 00:00:00 2001 From: startx2017 Date: Tue, 15 Aug 2017 09:34:47 -0400 Subject: fix #1462 --- src/firejail/firejail.h | 9 +++++++++ src/firejail/join.c | 37 +++++++++++++++++++++++++++++++++++++ src/firejail/x11.c | 6 +----- 3 files changed, 47 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 5f16d1a5d..b31d1365c 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -670,6 +670,15 @@ void fs_mkdir(const char *name); void fs_mkfile(const char *name); // x11.c + +// X11 display range as assigned by --x11 options +// We try display numbers in the range 21 through 1000. +// Normal X servers typically use displays in the 0-10 range; +// ssh's X11 forwarding uses 10-20, and login screens +// (e.g. gdm3) may use displays above 1000. +#define X11_DISPLAY_START 21 +#define X11_DISPLAY_END 1000 + void fs_x11(void); int x11_display(void); void x11_start(int argc, char **argv); diff --git a/src/firejail/join.c b/src/firejail/join.c index 4c0537413..84bd80364 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c @@ -28,6 +28,7 @@ static int apply_caps = 0; static uint64_t caps = 0; static int apply_seccomp = 0; +static unsigned display = 0; #define BUFLEN 4096 static void signal_handler(int sig){ @@ -36,6 +37,30 @@ static void signal_handler(int sig){ exit(sig); } + + +static void extract_x11_display(pid_t pid) { + char *fname; + if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_X11_DIR, pid) == -1) + errExit("asprintf"); + + FILE *fp = fopen(fname, "r"); + free(fname); + if (!fp) + return; + + if (1 != fscanf(fp, "%d", &display)) { + fprintf(stderr, "Error: cannot read X11 display file\n"); + return; + } + + // check display range + if (display < X11_DISPLAY_START || display > X11_DISPLAY_END) { + fprintf(stderr, "Error: invalid X11 display range\n"); + return; + } +} + static void extract_command(int argc, char **argv, int index) { EUID_ASSERT(); if (index >= argc) @@ -176,6 +201,7 @@ static void extract_user_namespace(pid_t pid) { void join(pid_t pid, int argc, char **argv, int index) { EUID_ASSERT(); char *homedir = cfg.homedir; + pid_t parent = pid; extract_command(argc, argv, index); signal (SIGTERM, signal_handler); @@ -206,6 +232,8 @@ void join(pid_t pid, int argc, char **argv, int index) { } } + extract_x11_display(parent); + EUID_ROOT(); // in user mode set caps seccomp, cpu, cgroup, etc if (getuid() != 0) { @@ -316,7 +344,16 @@ void join(pid_t pid, int argc, char **argv, int index) { } } + // set environment, add x11 display env_defaults(); + if (display) { + char *display_str; + if (asprintf(&display_str, ":%d", display) == -1) + errExit("asprintf"); + setenv("DISPLAY", display_str, 1); + free(display_str); + } + if (cfg.command_line == NULL) { assert(cfg.shell); cfg.command_line = cfg.shell; diff --git a/src/firejail/x11.c b/src/firejail/x11.c index 74b8d5b5c..d41f46d93 100644 --- a/src/firejail/x11.c +++ b/src/firejail/x11.c @@ -134,11 +134,7 @@ static int random_display_number(void) { errExit("socket"); for (i = 0; i < 100; i++) { - // We try display numbers in the range 21 through 1000. - // Normal X servers typically use displays in the 0-10 range; - // ssh's X11 forwarding uses 10-20, and login screens - // (e.g. gdm3) may use displays above 1000. - display = rand() % 979 + 21; + display = rand() % (X11_DISPLAY_END - X11_DISPLAY_START) + X11_DISPLAY_START; // The display number might be claimed by a server listening // in _either_ the normal or the abstract namespace; they -- cgit v1.2.3-54-g00ecf