diff options
-rw-r--r-- | src/firejail/firejail.h | 4 | ||||
-rw-r--r-- | src/firejail/fs_whitelist.c | 41 | ||||
-rw-r--r-- | src/man/firejail.txt | 2 |
3 files changed, 44 insertions, 3 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 25a39d0c4..9ba3b78ab 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -46,6 +46,7 @@ | |||
46 | #define WHITELIST_MEDIA_DIR "/run/firejail/mnt/orig-media" | 46 | #define WHITELIST_MEDIA_DIR "/run/firejail/mnt/orig-media" |
47 | #define WHITELIST_VAR_DIR "/run/firejail/mnt/orig-var" | 47 | #define WHITELIST_VAR_DIR "/run/firejail/mnt/orig-var" |
48 | #define WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev" | 48 | #define WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev" |
49 | #define WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt" | ||
49 | 50 | ||
50 | #define XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority" | 51 | #define XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority" |
51 | #define HOSTNAME_FILE "/run/firejail/mnt/hostname" | 52 | #define HOSTNAME_FILE "/run/firejail/mnt/hostname" |
@@ -103,7 +104,8 @@ typedef struct profile_entry_t { | |||
103 | unsigned tmp_dir:1; // whitelist in /tmp directory | 104 | unsigned tmp_dir:1; // whitelist in /tmp directory |
104 | unsigned media_dir:1; // whitelist in /media directory | 105 | unsigned media_dir:1; // whitelist in /media directory |
105 | unsigned var_dir:1; // whitelist in /var directory | 106 | unsigned var_dir:1; // whitelist in /var directory |
106 | unsigned dev_dir:1; // whitelist in /tmp directory | 107 | unsigned dev_dir:1; // whitelist in /dev directory |
108 | unsigned opt_dir:1; // whitelist in /opt directory | ||
107 | }ProfileEntry; | 109 | }ProfileEntry; |
108 | 110 | ||
109 | typedef struct config_t { | 111 | typedef struct config_t { |
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index 8b5444ebc..9016e3923 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c | |||
@@ -126,6 +126,16 @@ static void whitelist_path(ProfileEntry *entry) { | |||
126 | if (asprintf(&wfile, "%s/%s", WHITELIST_DEV_DIR, fname) == -1) | 126 | if (asprintf(&wfile, "%s/%s", WHITELIST_DEV_DIR, fname) == -1) |
127 | errExit("asprintf"); | 127 | errExit("asprintf"); |
128 | } | 128 | } |
129 | else if (entry->opt_dir) { | ||
130 | fname = path + 4; // strlen("/opt") | ||
131 | if (*fname == '\0') { | ||
132 | fprintf(stderr, "Error: file %s is not in /opt directory, exiting...\n", path); | ||
133 | exit(1); | ||
134 | } | ||
135 | |||
136 | if (asprintf(&wfile, "%s/%s", WHITELIST_OPT_DIR, fname) == -1) | ||
137 | errExit("asprintf"); | ||
138 | } | ||
129 | 139 | ||
130 | // check if the file exists | 140 | // check if the file exists |
131 | struct stat s; | 141 | struct stat s; |
@@ -191,6 +201,7 @@ void fs_whitelist(void) { | |||
191 | int media_dir = 0; // /media directory flag | 201 | int media_dir = 0; // /media directory flag |
192 | int var_dir = 0; // /var directory flag | 202 | int var_dir = 0; // /var directory flag |
193 | int dev_dir = 0; // /dev directory flag | 203 | int dev_dir = 0; // /dev directory flag |
204 | int opt_dir = 0; // /opt directory flag | ||
194 | 205 | ||
195 | // verify whitelist files, extract symbolic links, etc. | 206 | // verify whitelist files, extract symbolic links, etc. |
196 | while (entry) { | 207 | while (entry) { |
@@ -269,6 +280,13 @@ void fs_whitelist(void) { | |||
269 | if (strncmp(fname, "/dev/", 5) != 0) | 280 | if (strncmp(fname, "/dev/", 5) != 0) |
270 | goto errexit; | 281 | goto errexit; |
271 | } | 282 | } |
283 | else if (strncmp(new_name, "/opt/", 5) == 0) { | ||
284 | entry->opt_dir = 1; | ||
285 | opt_dir = 1; | ||
286 | // both path and absolute path are under /dev | ||
287 | if (strncmp(fname, "/opt/", 5) != 0) | ||
288 | goto errexit; | ||
289 | } | ||
272 | else | 290 | else |
273 | goto errexit; | 291 | goto errexit; |
274 | 292 | ||
@@ -390,13 +408,34 @@ void fs_whitelist(void) { | |||
390 | if (mount("/dev", WHITELIST_DEV_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) | 408 | if (mount("/dev", WHITELIST_DEV_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) |
391 | errExit("mount bind"); | 409 | errExit("mount bind"); |
392 | 410 | ||
393 | // mount tmpfs on /var | 411 | // mount tmpfs on /dev |
394 | if (arg_debug) | 412 | if (arg_debug) |
395 | printf("Mounting tmpfs on /dev directory\n"); | 413 | printf("Mounting tmpfs on /dev directory\n"); |
396 | if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | 414 | if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) |
397 | errExit("mounting tmpfs on /dev"); | 415 | errExit("mounting tmpfs on /dev"); |
398 | } | 416 | } |
399 | 417 | ||
418 | // /opt mountpoint | ||
419 | if (opt_dir) { | ||
420 | // keep a copy of real /opt directory in WHITELIST_DEV_DIR | ||
421 | int rv = mkdir(WHITELIST_OPT_DIR, S_IRWXU | S_IRWXG | S_IRWXO); | ||
422 | if (rv == -1) | ||
423 | errExit("mkdir"); | ||
424 | if (chown(WHITELIST_OPT_DIR, 0, 0) < 0) | ||
425 | errExit("chown"); | ||
426 | if (chmod(WHITELIST_OPT_DIR, 0755) < 0) | ||
427 | errExit("chmod"); | ||
428 | |||
429 | if (mount("/opt", WHITELIST_OPT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
430 | errExit("mount bind"); | ||
431 | |||
432 | // mount tmpfs on /opt | ||
433 | if (arg_debug) | ||
434 | printf("Mounting tmpfs on /opt directory\n"); | ||
435 | if (mount("tmpfs", "/opt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
436 | errExit("mounting tmpfs on /opt"); | ||
437 | } | ||
438 | |||
400 | // go through profile rules again, and interpret whitelist commands | 439 | // go through profile rules again, and interpret whitelist commands |
401 | entry = cfg.profile; | 440 | entry = cfg.profile; |
402 | while (entry) { | 441 | while (entry) { |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index d144fac10..39e0dbaf7 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -1291,7 +1291,7 @@ $ firejail \-\-version | |||
1291 | firejail version 0.9.27 | 1291 | firejail version 0.9.27 |
1292 | .TP | 1292 | .TP |
1293 | \fB\-\-whitelist=dirname_or_filename | 1293 | \fB\-\-whitelist=dirname_or_filename |
1294 | Whitelist directory or file. This feature is implemented only for user home, /dev, /media, /var, and /tmp directories. | 1294 | Whitelist directory or file. This feature is implemented only for user home, /dev, /media, /opt, /var, and /tmp directories. |
1295 | .br | 1295 | .br |
1296 | 1296 | ||
1297 | .br | 1297 | .br |