diff options
Diffstat (limited to 'src/firejail')
-rw-r--r-- | src/firejail/firejail.h | 4 | ||||
-rw-r--r-- | src/firejail/fs_hostname.c | 55 | ||||
-rw-r--r-- | src/firejail/main.c | 3 | ||||
-rw-r--r-- | src/firejail/profile.c | 6 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 21 | ||||
-rw-r--r-- | src/firejail/usage.c | 1 |
6 files changed, 79 insertions, 11 deletions
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 { | |||
213 | // networking | 213 | // networking |
214 | char *name; // sandbox name | 214 | char *name; // sandbox name |
215 | char *hostname; // host name | 215 | char *hostname; // host name |
216 | char *hosts_file; // hosts file to be installed in the sandbox | ||
216 | uint32_t defaultgw; // default gateway | 217 | uint32_t defaultgw; // default gateway |
217 | Bridge bridge0; | 218 | Bridge bridge0; |
218 | Bridge bridge1; | 219 | Bridge bridge1; |
@@ -537,6 +538,9 @@ void fs_trace(void); | |||
537 | // fs_hostname.c | 538 | // fs_hostname.c |
538 | void fs_hostname(const char *hostname); | 539 | void fs_hostname(const char *hostname); |
539 | void fs_resolvconf(void); | 540 | void fs_resolvconf(void); |
541 | char *fs_check_hosts_fiile(const char *fname); | ||
542 | void fs_store_hosts_file(void); | ||
543 | void fs_mount_hosts_file(void); | ||
540 | 544 | ||
541 | // rlimit.c | 545 | // rlimit.c |
542 | void set_rlimits(void); | 546 | 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) { | |||
42 | } | 42 | } |
43 | 43 | ||
44 | // create a new /etc/hosts | 44 | // create a new /etc/hosts |
45 | if (stat("/etc/hosts", &s) == 0) { | 45 | if (cfg.hosts_file == NULL && stat("/etc/hosts", &s) == 0) { |
46 | if (arg_debug) | 46 | if (arg_debug) |
47 | printf("Creating a new /etc/hosts file\n"); | 47 | printf("Creating a new /etc/hosts file\n"); |
48 | // copy /etc/host into our new file, and modify it on the fly | 48 | // copy /etc/host into our new file, and modify it on the fly |
@@ -79,9 +79,7 @@ void fs_hostname(const char *hostname) { | |||
79 | fclose(fp2); | 79 | fclose(fp2); |
80 | 80 | ||
81 | // bind-mount the file on top of /etc/hostname | 81 | // bind-mount the file on top of /etc/hostname |
82 | if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0) | 82 | fs_mount_hosts_file(); |
83 | errExit("mount bind /etc/hosts"); | ||
84 | fs_logger("create /etc/hosts"); | ||
85 | } | 83 | } |
86 | return; | 84 | return; |
87 | 85 | ||
@@ -129,4 +127,53 @@ void fs_resolvconf(void) { | |||
129 | } | 127 | } |
130 | } | 128 | } |
131 | 129 | ||
130 | char *fs_check_hosts_fiile(const char *fname) { | ||
131 | assert(fname); | ||
132 | invalid_filename(fname); | ||
133 | char *rv = expand_home(fname, cfg.homedir); | ||
134 | |||
135 | // no a link | ||
136 | if (is_link(rv)) | ||
137 | goto errexit; | ||
138 | |||
139 | // file owned by the user | ||
140 | struct stat s; | ||
141 | if (stat(rv, &s) == -1) | ||
142 | goto errexit; | ||
132 | 143 | ||
144 | if (s.st_uid != getuid()) | ||
145 | goto errexit; | ||
146 | |||
147 | return rv; | ||
148 | errexit: | ||
149 | fprintf(stderr, "Error: invalid file %s\n", fname); | ||
150 | exit(1); | ||
151 | } | ||
152 | |||
153 | void fs_store_hosts_file(void) { | ||
154 | copy_file(cfg.hosts_file, RUN_HOSTS_FILE, 0, 0, 0644); // root needed | ||
155 | } | ||
156 | |||
157 | void fs_mount_hosts_file(void) { | ||
158 | // check /etc/hosts file | ||
159 | struct stat s; | ||
160 | if (stat("/etc/hosts", &s) == -1) | ||
161 | goto errexit; | ||
162 | // not a link | ||
163 | if (is_link("/etc/hosts")) | ||
164 | goto errexit; | ||
165 | // owned by root | ||
166 | if (s.st_uid != 0) | ||
167 | goto errexit; | ||
168 | |||
169 | // bind-mount the file on top of /etc/hostname | ||
170 | if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0) | ||
171 | errExit("mount bind /etc/hosts"); | ||
172 | fs_logger("create /etc/hosts"); | ||
173 | return; | ||
174 | |||
175 | errexit: | ||
176 | fprintf(stderr, "Error: invalid /etc/hosts file\n"); | ||
177 | exit(1); | ||
178 | } | ||
179 | |||
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) { | |||
1947 | return 1; | 1947 | return 1; |
1948 | } | 1948 | } |
1949 | } | 1949 | } |
1950 | |||
1951 | else if (strncmp(argv[i], "--hosts-file=", 13) == 0) | ||
1952 | cfg.hosts_file = fs_check_hosts_fiile(argv[i] + 13); | ||
1950 | 1953 | ||
1951 | #ifdef HAVE_NETWORK | 1954 | #ifdef HAVE_NETWORK |
1952 | else if (strcmp(argv[i], "--netfilter") == 0) { | 1955 | 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) { | |||
602 | return 0; | 602 | return 0; |
603 | } | 603 | } |
604 | 604 | ||
605 | // hosts-file | ||
606 | if (strncmp(ptr, "hosts-file ", 11) == 0) { | ||
607 | cfg.hosts_file = fs_check_hosts_fiile(ptr + 11); | ||
608 | return 0; | ||
609 | } | ||
610 | |||
605 | // dns | 611 | // dns |
606 | if (strncmp(ptr, "dns ", 4) == 0) { | 612 | if (strncmp(ptr, "dns ", 4) == 0) { |
607 | uint32_t dns; | 613 | 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) { | |||
587 | if (arg_trace || arg_tracelog || mask_x11_abstract_socket) | 587 | if (arg_trace || arg_tracelog || mask_x11_abstract_socket) |
588 | fs_trace_preload(); | 588 | fs_trace_preload(); |
589 | 589 | ||
590 | // store hosts file | ||
591 | if (cfg.hosts_file) | ||
592 | fs_store_hosts_file(); | ||
593 | |||
590 | //**************************** | 594 | //**************************** |
591 | // configure filesystem | 595 | // configure filesystem |
592 | //**************************** | 596 | //**************************** |
@@ -631,13 +635,6 @@ int sandbox(void* sandbox_arg) { | |||
631 | fs_basic_fs(); | 635 | fs_basic_fs(); |
632 | 636 | ||
633 | //**************************** | 637 | //**************************** |
634 | // set hostname in /etc/hostname | ||
635 | //**************************** | ||
636 | if (cfg.hostname) { | ||
637 | fs_hostname(cfg.hostname); | ||
638 | } | ||
639 | |||
640 | //**************************** | ||
641 | // private mode | 638 | // private mode |
642 | //**************************** | 639 | //**************************** |
643 | if (arg_private) { | 640 | if (arg_private) { |
@@ -735,6 +732,16 @@ int sandbox(void* sandbox_arg) { | |||
735 | } | 732 | } |
736 | } | 733 | } |
737 | 734 | ||
735 | |||
736 | //**************************** | ||
737 | // hosts and hostname | ||
738 | //**************************** | ||
739 | if (cfg.hostname) | ||
740 | fs_hostname(cfg.hostname); | ||
741 | |||
742 | if (cfg.hosts_file) | ||
743 | fs_mount_hosts_file(); | ||
744 | |||
738 | //**************************** | 745 | //**************************** |
739 | // /etc overrides from the network namespace | 746 | // /etc overrides from the network namespace |
740 | //**************************** | 747 | //**************************** |
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) { | |||
78 | printf(" --get=name|pid filename - get a file from sandbox container.\n"); | 78 | printf(" --get=name|pid filename - get a file from sandbox container.\n"); |
79 | printf(" --help, -? - this help screen.\n"); | 79 | printf(" --help, -? - this help screen.\n"); |
80 | printf(" --hostname=name - set sandbox hostname.\n"); | 80 | printf(" --hostname=name - set sandbox hostname.\n"); |
81 | printf(" --hosts-file=file - use file as /etc/hosts.\n"); | ||
81 | printf(" --ignore=command - ignore command in profile files.\n"); | 82 | printf(" --ignore=command - ignore command in profile files.\n"); |
82 | #ifdef HAVE_NETWORK | 83 | #ifdef HAVE_NETWORK |
83 | printf(" --interface=name - move interface in sandbox.\n"); | 84 | printf(" --interface=name - move interface in sandbox.\n"); |