From 89535f782c19fd8396fd013d4b38d746f3faed95 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Wed, 24 Feb 2016 12:55:06 -0500 Subject: x11 work --- src/firejail/firejail.h | 2 ++ src/firejail/fs.c | 11 +++++++++ src/firejail/main.c | 36 +++++++++++++++++++++++++++++ src/firejail/x11.c | 19 ++++++++++++---- src/firemon/firemon.c | 6 +++++ src/firemon/x11.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ src/man/firejail.txt | 15 +++++++++++++ src/man/firemon.txt | 4 ++++ 8 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 src/firemon/x11.c diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index acb49d246..b37c3aba8 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -27,6 +27,7 @@ #define RUN_FIREJAIL_BASEDIR "/run" #define RUN_FIREJAIL_DIR "/run/firejail" #define RUN_FIREJAIL_NAME_DIR "/run/firejail/name" +#define RUN_FIREJAIL_X11_DIR "/run/firejail/x11" #define RUN_FIREJAIL_NETWORK_DIR "/run/firejail/network" #define RUN_FIREJAIL_BANDWIDTH_DIR "/run/firejail/bandwidth" #define RUN_NETWORK_LOCK_FILE "/run/firejail/firejail.lock" @@ -524,6 +525,7 @@ void fs_mkdir(const char *name); // x11.c void fs_x11(void); void x11_start(int argc, char **argv); +int x11_display(void); #endif diff --git a/src/firejail/fs.c b/src/firejail/fs.c index df5e8410b..6505177d0 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c @@ -127,6 +127,17 @@ void fs_build_firejail_dir(void) { errExit("chmod"); } + if (stat(RUN_FIREJAIL_X11_DIR, &s)) { + if (arg_debug) + printf("Creating %s directory\n", RUN_FIREJAIL_X11_DIR); + if (mkdir(RUN_FIREJAIL_X11_DIR, 0755) == -1) + errExit("mkdir"); + if (chown(RUN_FIREJAIL_X11_DIR, 0, 0) < 0) + errExit("chown"); + if (chmod(RUN_FIREJAIL_X11_DIR, 0755) < 0) + errExit("chmod"); + } + create_empty_dir(); create_empty_file(); } diff --git a/src/firejail/main.c b/src/firejail/main.c index 5a8f564f4..9e0be7bfa 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -106,6 +106,8 @@ pid_t sandbox_pid; static void set_name_file(uid_t pid); static void delete_name_file(uid_t pid); +static void set_x11_file(uid_t pid, int display); +static void delete_x11_file(uid_t pid); static void myexit(int rv) { logmsg("exiting..."); @@ -116,6 +118,7 @@ static void myexit(int rv) { bandwidth_shm_del_file(sandbox_pid); // bandwidth file network_shm_del_file(sandbox_pid); // network map file delete_name_file(sandbox_pid); + delete_x11_file(sandbox_pid); exit(rv); } @@ -511,6 +514,36 @@ static void delete_name_file(uid_t pid) { (void) rv; } +static void set_x11_file(uid_t pid, int display) { + char *fname; + if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_X11_DIR, pid) == -1) + errExit("asprintf"); + + // the file is deleted first + FILE *fp = fopen(fname, "w"); + if (!fp) { + fprintf(stderr, "Error: cannot create %s\n", fname); + exit(1); + } + fprintf(fp, "%d\n", display); + fclose(fp); + + // mode and ownership + if (chown(fname, 0, 0) == -1) + errExit("chown"); + if (chmod(fname, 0644) == -1) + errExit("chmod"); + +} + +static void delete_x11_file(uid_t pid) { + char *fname; + if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_X11_DIR, pid) == -1) + errExit("asprintf"); + int rv = unlink(fname); + (void) rv; +} + //******************************************* // Main program //******************************************* @@ -1554,6 +1587,9 @@ int main(int argc, char **argv) { EUID_ROOT(); if (cfg.name) set_name_file(sandbox_pid); + int display = x11_display(); + if (display > 0) + set_x11_file(sandbox_pid, display); EUID_USER(); // clone environment diff --git a/src/firejail/x11.c b/src/firejail/x11.c index c3515cc82..980a4dbca 100644 --- a/src/firejail/x11.c +++ b/src/firejail/x11.c @@ -26,12 +26,12 @@ #include #include -void fs_x11(void) { -#ifdef HAVE_X11 +// return display number, -1 if not configured +int x11_display(void) { // extract display char *d = getenv("DISPLAY"); if (!d) - return; + return - 1; int display; int rv = sscanf(d, ":%d", &display); @@ -39,6 +39,15 @@ void fs_x11(void) { return; if (arg_debug) printf("DISPLAY %s, %d\n", d, display); + + return display; +} + +void fs_x11(void) { +#ifdef HAVE_X11 + int display = x11_display(); + if (display <= 0) + return; char *x11file; if (asprintf(&x11file, "/tmp/.X11-unix/X%d", display) == -1) @@ -48,7 +57,7 @@ void fs_x11(void) { return; // keep a copy of real /tmp/.X11-unix directory in WHITELIST_TMP_DIR - rv = mkdir(RUN_WHITELIST_X11_DIR, 1777); + int rv = mkdir(RUN_WHITELIST_X11_DIR, 1777); if (rv == -1) errExit("mkdir"); if (chown(RUN_WHITELIST_X11_DIR, 0, 0) < 0) @@ -178,6 +187,7 @@ void x11_start(int argc, char **argv) { exit(1); } sleep(1); + if (arg_debug) { printf("X11 sockets: "); fflush(0); int rv = system("ls /tmp/.X11-unix"); @@ -213,6 +223,7 @@ void x11_start(int argc, char **argv) { if (!arg_quiet) printf("Xpra server pid %d, client pid %d\n", server, client); + exit(0); } #endif diff --git a/src/firemon/firemon.c b/src/firemon/firemon.c index 679c5a3e9..c19c344b0 100644 --- a/src/firemon/firemon.c +++ b/src/firemon/firemon.c @@ -33,6 +33,7 @@ static int arg_seccomp = 0; static int arg_caps = 0; static int arg_cpu = 0; static int arg_cgroup = 0; +static int arg_x11 = 0; int arg_nowrap = 0; static struct termios tlocal; // startup terminal setting @@ -141,6 +142,9 @@ int main(int argc, char **argv) { // cumulative options with or without a pid argument + else if (strcmp(argv[i], "--x11") == 0) { + arg_x11 = 1; + } else if (strcmp(argv[i], "--cgroup") == 0) { arg_cgroup = 1; } @@ -217,6 +221,8 @@ int main(int argc, char **argv) { cpu((pid_t) pid); if (arg_cgroup) cgroup((pid_t) pid); + if (arg_x11) + x11((pid_t) pid); if (!arg_route && !arg_arp && !arg_interface && !arg_tree && !arg_caps && !arg_seccomp) procevent((pid_t) pid); // never to return diff --git a/src/firemon/x11.c b/src/firemon/x11.c new file mode 100644 index 000000000..e30c2d78b --- /dev/null +++ b/src/firemon/x11.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014-2016 netblue30 (netblue30@yahoo.com) + * + * This file is part of firejail project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "firemon.h" +#include +#include +#include + +void x11(pid_t pid) { + if (getuid() == 0) + firemon_drop_privs(); + + pid_read(pid); + + // print processes + int i; + for (i = 0; i < max_pids; i++) { + if (pids[i].level == 1) { + pid_print_list(i, 0); + + char *x11file; + // todo: use macro from src/firejail/firejail.h for /run/firejail/x11 directory + if (asprintf(&x11file, "/run/firejail/x11/%d", i) == -1) + errExit("asprintf"); + + struct stat s; + if (stat(x11file, &s) == 0) { + FILE *fp = fopen(x11file, "r"); + if (!fp) { + free(x11file); + continue; + } + int display; + int rv = fscanf(fp, "%d", &display); + if (rv == 1) + printf(" DISPLAY :%d\n", display); + fclose(fp); + } + + free(x11file); + } + } +} + diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 681a105af..c6931af12 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt @@ -1505,6 +1505,20 @@ $ firejail \-\-whitelist=~/.mozilla \-\-whitelist=~/Downloads $ firejail \-\-whitelist=/tmp/.X11-unix --whitelist=/dev/null .br $ firejail "\-\-whitelist=/home/username/My Virtual Machines" + +.TP +\fB\-\-x11 +Start a new X11 server using Xpra (http://xpra.org) and attach the sandbox to this server. +Xpra is a persistent remote display server and client for forwarding X11 applications and desktop screens. +The regular X11 server (display 0) is not visible in the sandbox. This prevents screenshot and keylogger +applications started in the sandbox from accessing display 0. +.br + +.br +Example: +.br +$ firejail \-\-x11 firefox + .TP \fB\-\-zsh Use /usr/bin/zsh as default user shell. @@ -1514,6 +1528,7 @@ Use /usr/bin/zsh as default user shell. Example: .br $ firejail \-\-zsh + .SH TRAFFIC SHAPING Network bandwidth is an expensive resource shared among all sandboxes running on a system. Traffic shaping allows the user to increase network performance by controlling diff --git a/src/man/firemon.txt b/src/man/firemon.txt index 2a69b1de5..88b2ce59f 100644 --- a/src/man/firemon.txt +++ b/src/man/firemon.txt @@ -51,6 +51,10 @@ Print a tree of all sandboxed processes. \fB\-\-version Print program version and exit. +.TP +\fB\-\-x11 +Print X11 display number. + .PP Option \-\-list prints a list of all sandboxes. The format for each entry is as follows: -- cgit v1.2.3-70-g09d2