From 7d11cf62ca175696c8f5998de42c510924c6dcc3 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Sun, 22 Jan 2017 10:26:05 -0500 Subject: --hosts-file option --- README.md | 16 +++++++++---- RELNOTES | 11 +++++---- src/firejail/firejail.h | 4 ++++ src/firejail/fs_hostname.c | 55 ++++++++++++++++++++++++++++++++++++++++---- src/firejail/main.c | 3 +++ src/firejail/profile.c | 6 +++++ src/firejail/sandbox.c | 21 +++++++++++------ src/firejail/usage.c | 1 + src/man/firejail-profile.txt | 4 ++++ src/man/firejail.txt | 10 ++++++++ 10 files changed, 111 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index dcc9d8ca4..e480361c4 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,9 @@ Use this issue to request new profiles: https://github.com/netblue30/firejail/is ````` ````` -## AppImage type 2 support +## AppImage + +Added AppImage type 2 support, and support for passing command line arguments to appimages. ````` ````` @@ -75,9 +77,9 @@ Use this issue to request new profiles: https://github.com/netblue30/firejail/is Example: # firejail --private-srv=www /etc/init.d/apache2 start - --machine-id - Preserve id number in /etc/machine-id file. By default a new - random id is generated inside the sandbox. + --machine-id + Spoof id number in /etc/machine-id file - a new random id is + generated inside the sandbox. Example: $ firejail --machine-id @@ -89,6 +91,12 @@ Use this issue to request new profiles: https://github.com/netblue30/firejail/is Example: $ firejail --allow-private-blacklist --private=~/priv-dir --blacklist=~/.mozilla + + --hosts-file=file + Use file as /etc/hosts. + + Example: + $ firejail --hosts-file=~/myhosts firefox ````` ## New Profiles diff --git a/RELNOTES b/RELNOTES index bb71d1723..90e65f973 100644 --- a/RELNOTES +++ b/RELNOTES @@ -14,16 +14,17 @@ firejail (0.9.45) baseline; urgency=low * security: split file copying in private option in a separate executable * security: root exploit found by Sebastian Krahmer (CVE-2017-5180) * feature: disable gnupg and systemd directories under /run/user - * feature: allow root user access to /dev/shm (--noblacklist=/dev/shm) - * feature: AppImage type 2 support * feature: test coverage (gcov) support + * feature: allow root user access to /dev/shm (--noblacklist=/dev/shm) * feature: private /opt directory (--private-opt, profile support) * feature: private /srv directory (--private-srv, profile support) - * feature: spoof machine-id + * feature: spoof machine-id (--machine-id, profile support) + * feature: allow blacklists under --private (--allow-private-blacklist) - more work to come + * feature: user-defined /etc/hosts file (--hosts-file, profile support) * feature: config support for firejail prompt in terminals + * feature: AppImage type 2 support * feature: pass command line arguments to appimages - * feature: --allow-private-blacklist option - * feature: allow non-seccomp setup for OverlayFS sandboxes + * feature: allow non-seccomp setup for OverlayFS sandboxes - more work to come * feature: added a number o Python scripts for handling sandboxes * feature: allow local customization using .local files under /etc/firejail * new profiles: xiphos, Tor Browser Bundle, display (imagemagik), Wire, diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 94e66920b..0f836f1db 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -213,6 +213,7 @@ typedef struct config_t { // networking char *name; // sandbox name char *hostname; // host name + char *hosts_file; // hosts file to be installed in the sandbox uint32_t defaultgw; // default gateway Bridge bridge0; Bridge bridge1; @@ -537,6 +538,9 @@ void fs_trace(void); // fs_hostname.c void fs_hostname(const char *hostname); void fs_resolvconf(void); +char *fs_check_hosts_fiile(const char *fname); +void fs_store_hosts_file(void); +void fs_mount_hosts_file(void); // rlimit.c void set_rlimits(void); diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c index b2e1b4a99..ac831f6b9 100644 --- a/src/firejail/fs_hostname.c +++ b/src/firejail/fs_hostname.c @@ -42,7 +42,7 @@ void fs_hostname(const char *hostname) { } // create a new /etc/hosts - if (stat("/etc/hosts", &s) == 0) { + if (cfg.hosts_file == NULL && stat("/etc/hosts", &s) == 0) { if (arg_debug) printf("Creating a new /etc/hosts file\n"); // copy /etc/host into our new file, and modify it on the fly @@ -79,9 +79,7 @@ void fs_hostname(const char *hostname) { fclose(fp2); // bind-mount the file on top of /etc/hostname - if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0) - errExit("mount bind /etc/hosts"); - fs_logger("create /etc/hosts"); + fs_mount_hosts_file(); } return; @@ -129,4 +127,53 @@ void fs_resolvconf(void) { } } +char *fs_check_hosts_fiile(const char *fname) { + assert(fname); + invalid_filename(fname); + char *rv = expand_home(fname, cfg.homedir); + + // no a link + if (is_link(rv)) + goto errexit; + + // file owned by the user + struct stat s; + if (stat(rv, &s) == -1) + goto errexit; + if (s.st_uid != getuid()) + goto errexit; + + return rv; +errexit: + fprintf(stderr, "Error: invalid file %s\n", fname); + exit(1); +} + +void fs_store_hosts_file(void) { + copy_file(cfg.hosts_file, RUN_HOSTS_FILE, 0, 0, 0644); // root needed +} + +void fs_mount_hosts_file(void) { + // check /etc/hosts file + struct stat s; + if (stat("/etc/hosts", &s) == -1) + goto errexit; + // not a link + if (is_link("/etc/hosts")) + goto errexit; + // owned by root + if (s.st_uid != 0) + goto errexit; + + // bind-mount the file on top of /etc/hostname + if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0) + errExit("mount bind /etc/hosts"); + fs_logger("create /etc/hosts"); + return; + +errexit: + fprintf(stderr, "Error: invalid /etc/hosts file\n"); + exit(1); +} + diff --git a/src/firejail/main.c b/src/firejail/main.c index 9c6b6e001..8fea98950 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -1947,6 +1947,9 @@ int main(int argc, char **argv) { return 1; } } + + else if (strncmp(argv[i], "--hosts-file=", 13) == 0) + cfg.hosts_file = fs_check_hosts_fiile(argv[i] + 13); #ifdef HAVE_NETWORK else if (strcmp(argv[i], "--netfilter") == 0) { diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 33b6eab91..2d49b60c0 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -602,6 +602,12 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { return 0; } + // hosts-file + if (strncmp(ptr, "hosts-file ", 11) == 0) { + cfg.hosts_file = fs_check_hosts_fiile(ptr + 11); + return 0; + } + // dns if (strncmp(ptr, "dns ", 4) == 0) { uint32_t dns; diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 69cb8331e..812112b51 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c @@ -587,6 +587,10 @@ int sandbox(void* sandbox_arg) { if (arg_trace || arg_tracelog || mask_x11_abstract_socket) fs_trace_preload(); + // store hosts file + if (cfg.hosts_file) + fs_store_hosts_file(); + //**************************** // configure filesystem //**************************** @@ -630,13 +634,6 @@ int sandbox(void* sandbox_arg) { #endif fs_basic_fs(); - //**************************** - // set hostname in /etc/hostname - //**************************** - if (cfg.hostname) { - fs_hostname(cfg.hostname); - } - //**************************** // private mode //**************************** @@ -735,6 +732,16 @@ int sandbox(void* sandbox_arg) { } } + + //**************************** + // hosts and hostname + //**************************** + if (cfg.hostname) + fs_hostname(cfg.hostname); + + if (cfg.hosts_file) + fs_mount_hosts_file(); + //**************************** // /etc overrides from the network namespace //**************************** diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 9f4dfd44c..6f16a5868 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c @@ -78,6 +78,7 @@ void usage(void) { printf(" --get=name|pid filename - get a file from sandbox container.\n"); printf(" --help, -? - this help screen.\n"); printf(" --hostname=name - set sandbox hostname.\n"); + printf(" --hosts-file=file - use file as /etc/hosts.\n"); printf(" --ignore=command - ignore command in profile files.\n"); #ifdef HAVE_NETWORK printf(" --interface=name - move interface in sandbox.\n"); diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index ecb8be139..034f1beac 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt @@ -391,6 +391,10 @@ Set a DNS server for the sandbox. Up to three DNS servers can be defined. \fBhostname name Set a hostname for the sandbox. +.TP +\fBhosts-file file +Use file as /etc/hosts. + .TP \fBip address Assign IP addresses to the last network interface defined by a net command. A diff --git a/src/man/firejail.txt b/src/man/firejail.txt index afd8e1e4e..b836fd738 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt @@ -468,6 +468,16 @@ Example: .br $ firejail \-\-hostname=officepc firefox +.TP +\fB\-\-hosts-file=file +Use file as /etc/hosts. +.br + +.br +Example: +.br +$ firejail \-\-hosts-file=~/myhosts firefox + .TP \fB\-\-ignore=command Ignore command in profile file. -- cgit v1.2.3-70-g09d2