summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-10-21 10:30:24 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2017-10-21 10:30:24 -0400
commit955bb591345a688d124b297154d9c1bc2fd05430 (patch)
tree4fc0882fe98547707b239d94c53d71eb20c21fff
parentadded whitelist support for /etc (diff)
downloadfirejail-955bb591345a688d124b297154d9c1bc2fd05430.tar.gz
firejail-955bb591345a688d124b297154d9c1bc2fd05430.tar.zst
firejail-955bb591345a688d124b297154d9c1bc2fd05430.zip
added whitelisting support for /usr/share
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/fs_whitelist.c68
2 files changed, 59 insertions, 11 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 387fc441c..008f4ad08 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -82,6 +82,7 @@
82#define RUN_WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt" 82#define RUN_WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt"
83#define RUN_WHITELIST_SRV_DIR "/run/firejail/mnt/orig-srv" 83#define RUN_WHITELIST_SRV_DIR "/run/firejail/mnt/orig-srv"
84#define RUN_WHITELIST_ETC_DIR "/run/firejail/mnt/orig-etc" 84#define RUN_WHITELIST_ETC_DIR "/run/firejail/mnt/orig-etc"
85#define RUN_WHITELIST_SHARE_DIR "/run/firejail/mnt/orig-share"
85 86
86#define RUN_XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority" 87#define RUN_XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority"
87#define RUN_XAUTHORITY_SEC_FILE "/run/firejail/mnt/sec.Xauthority" 88#define RUN_XAUTHORITY_SEC_FILE "/run/firejail/mnt/sec.Xauthority"
@@ -200,6 +201,7 @@ typedef struct profile_entry_t {
200 unsigned opt_dir:1; // whitelist in /opt directory 201 unsigned opt_dir:1; // whitelist in /opt directory
201 unsigned srv_dir:1; // whitelist in /srv directory 202 unsigned srv_dir:1; // whitelist in /srv directory
202 unsigned etc_dir:1; // whitelist in /etc directory 203 unsigned etc_dir:1; // whitelist in /etc directory
204 unsigned share_dir:1; // whitelist in /usr/share directory
203}ProfileEntry; 205}ProfileEntry;
204 206
205typedef struct config_t { 207typedef struct config_t {
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 0ae5a7155..7928aaf3d 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -202,7 +202,7 @@ static void whitelist_path(ProfileEntry *entry) {
202 errExit("asprintf"); 202 errExit("asprintf");
203 } 203 }
204 else if (entry->tmp_dir) { 204 else if (entry->tmp_dir) {
205 fname = path + 4; // strlen("/tmp") 205 fname = path + 5; // strlen("/tmp/")
206 if (*fname == '\0') 206 if (*fname == '\0')
207 goto errexit; 207 goto errexit;
208 208
@@ -210,7 +210,7 @@ static void whitelist_path(ProfileEntry *entry) {
210 errExit("asprintf"); 210 errExit("asprintf");
211 } 211 }
212 else if (entry->media_dir) { 212 else if (entry->media_dir) {
213 fname = path + 6; // strlen("/media") 213 fname = path + 7; // strlen("/media/")
214 if (*fname == '\0') 214 if (*fname == '\0')
215 goto errexit; 215 goto errexit;
216 216
@@ -218,7 +218,7 @@ static void whitelist_path(ProfileEntry *entry) {
218 errExit("asprintf"); 218 errExit("asprintf");
219 } 219 }
220 else if (entry->mnt_dir) { 220 else if (entry->mnt_dir) {
221 fname = path + 4; // strlen("/mnt") 221 fname = path + 5; // strlen("/mnt/")
222 if (*fname == '\0') 222 if (*fname == '\0')
223 goto errexit; 223 goto errexit;
224 224
@@ -226,7 +226,7 @@ static void whitelist_path(ProfileEntry *entry) {
226 errExit("asprintf"); 226 errExit("asprintf");
227 } 227 }
228 else if (entry->var_dir) { 228 else if (entry->var_dir) {
229 fname = path + 4; // strlen("/var") 229 fname = path + 5; // strlen("/var/")
230 if (*fname == '\0') 230 if (*fname == '\0')
231 goto errexit; 231 goto errexit;
232 232
@@ -234,7 +234,7 @@ static void whitelist_path(ProfileEntry *entry) {
234 errExit("asprintf"); 234 errExit("asprintf");
235 } 235 }
236 else if (entry->dev_dir) { 236 else if (entry->dev_dir) {
237 fname = path + 4; // strlen("/dev") 237 fname = path + 5; // strlen("/dev/")
238 if (*fname == '\0') 238 if (*fname == '\0')
239 goto errexit; 239 goto errexit;
240 240
@@ -242,7 +242,7 @@ static void whitelist_path(ProfileEntry *entry) {
242 errExit("asprintf"); 242 errExit("asprintf");
243 } 243 }
244 else if (entry->opt_dir) { 244 else if (entry->opt_dir) {
245 fname = path + 4; // strlen("/opt") 245 fname = path + 5; // strlen("/opt/")
246 if (*fname == '\0') 246 if (*fname == '\0')
247 goto errexit; 247 goto errexit;
248 248
@@ -250,7 +250,7 @@ static void whitelist_path(ProfileEntry *entry) {
250 errExit("asprintf"); 250 errExit("asprintf");
251 } 251 }
252 else if (entry->srv_dir) { 252 else if (entry->srv_dir) {
253 fname = path + 4; // strlen("/srv") 253 fname = path + 5; // strlen("/srv/")
254 if (*fname == '\0') 254 if (*fname == '\0')
255 goto errexit; 255 goto errexit;
256 256
@@ -258,23 +258,31 @@ static void whitelist_path(ProfileEntry *entry) {
258 errExit("asprintf"); 258 errExit("asprintf");
259 } 259 }
260 else if (entry->etc_dir) { 260 else if (entry->etc_dir) {
261 fname = path + 4; // strlen("/etc") 261 fname = path + 5; // strlen("/etc/")
262 if (*fname == '\0') 262 if (*fname == '\0')
263 goto errexit; 263 goto errexit;
264 264
265 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_ETC_DIR, fname) == -1) 265 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_ETC_DIR, fname) == -1)
266 errExit("asprintf"); 266 errExit("asprintf");
267 } 267 }
268 else if (entry->share_dir) {
269 fname = path + 11; // strlen("/usr/share/")
270 if (*fname == '\0')
271 goto errexit;
272
273 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_SHARE_DIR, fname) == -1)
274 errExit("asprintf");
275 }
268 276
269 // check if the file exists 277 // check if the file exists
278 assert(wfile);
270 struct stat s; 279 struct stat s;
271 if (wfile && stat(wfile, &s) == 0) { 280 if (stat(wfile, &s) == 0) {
272 if (arg_debug || arg_debug_whitelists) 281 if (arg_debug || arg_debug_whitelists)
273 printf("Whitelisting %s\n", path); 282 printf("Whitelisting %s\n", path);
274 } 283 }
275 else { 284 else
276 return; 285 return;
277 }
278 286
279 // create the path if necessary 287 // create the path if necessary
280 mkpath(path, s.st_mode); 288 mkpath(path, s.st_mode);
@@ -335,6 +343,7 @@ void fs_whitelist(void) {
335 int opt_dir = 0; // /opt directory flag 343 int opt_dir = 0; // /opt directory flag
336 int srv_dir = 0; // /srv directory flag 344 int srv_dir = 0; // /srv directory flag
337 int etc_dir = 0; // /etc directory flag 345 int etc_dir = 0; // /etc directory flag
346 int share_dir = 0; // /usr/share directory flag
338 347
339 size_t nowhitelist_c = 0; 348 size_t nowhitelist_c = 0;
340 size_t nowhitelist_m = 32; 349 size_t nowhitelist_m = 32;
@@ -426,6 +435,8 @@ void fs_whitelist(void) {
426 srv_dir = 1; 435 srv_dir = 1;
427 else if (strncmp(new_name, "/etc/", 5) == 0) 436 else if (strncmp(new_name, "/etc/", 5) == 0)
428 etc_dir = 1; 437 etc_dir = 1;
438 else if (strncmp(new_name, "/usr/share/", 11) == 0)
439 share_dir = 1;
429 } 440 }
430 441
431 entry->data = EMPTY_STRING; 442 entry->data = EMPTY_STRING;
@@ -558,6 +569,13 @@ void fs_whitelist(void) {
558 goto errexit; 569 goto errexit;
559 } 570 }
560 } 571 }
572 else if (strncmp(new_name, "/usr/share/", 11) == 0) {
573 entry->share_dir = 1;
574 share_dir = 1;
575 // both path and absolute path are under /etc
576 if (strncmp(fname, "/usr/share/", 11) != 0)
577 goto errexit;
578 }
561 else { 579 else {
562 goto errexit; 580 goto errexit;
563 } 581 }
@@ -764,6 +782,27 @@ void fs_whitelist(void) {
764 etc_dir = 0; 782 etc_dir = 0;
765 } 783 }
766 784
785 // /usr/share mountpoint
786 if (share_dir) {
787 // check if /usr/share directory exists
788 struct stat s;
789 if (stat("/usr/share", &s) == 0) {
790 // keep a copy of real /usr/share directory in RUN_WHITELIST_ETC_DIR
791 mkdir_attr(RUN_WHITELIST_SHARE_DIR, 0755, 0, 0);
792 if (mount("/usr/share", RUN_WHITELIST_SHARE_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
793 errExit("mount bind");
794
795 // mount tmpfs on /srv
796 if (arg_debug || arg_debug_whitelists)
797 printf("Mounting tmpfs on /usr/share directory\n");
798 if (mount("tmpfs", "/usr/share", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
799 errExit("mounting tmpfs on /usr/share");
800 fs_logger("tmpfs /usr/share");
801 }
802 else
803 share_dir = 0;
804 }
805
767 806
768 // go through profile rules again, and interpret whitelist commands 807 // go through profile rules again, and interpret whitelist commands
769 entry = cfg.profile; 808 entry = cfg.profile;
@@ -870,6 +909,13 @@ void fs_whitelist(void) {
870 fs_logger2("tmpfs", RUN_WHITELIST_ETC_DIR); 909 fs_logger2("tmpfs", RUN_WHITELIST_ETC_DIR);
871 } 910 }
872 911
912 // mask the real /usr/share directory, currently mounted on RUN_WHITELIST_SHARE_DIR
913 if (share_dir) {
914 if (mount("tmpfs", RUN_WHITELIST_SHARE_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
915 errExit("mount tmpfs");
916 fs_logger2("tmpfs", RUN_WHITELIST_SHARE_DIR);
917 }
918
873 if (new_name) 919 if (new_name)
874 free(new_name); 920 free(new_name);
875 921