diff options
-rw-r--r-- | RELNOTES | 57 | ||||
-rw-r--r-- | etc/firejail.config | 5 | ||||
-rw-r--r-- | src/firejail/checkcfg.c | 8 | ||||
-rw-r--r-- | src/firejail/env.c | 10 | ||||
-rw-r--r-- | src/firejail/firejail.h | 3 | ||||
-rw-r--r-- | src/firejail/fs.c | 140 | ||||
-rw-r--r-- | src/firejail/main.c | 9 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 107 | ||||
-rw-r--r-- | src/firejail/usage.c | 20 | ||||
-rw-r--r-- | src/man/firejail.txt | 18 |
10 files changed, 227 insertions, 150 deletions
@@ -1,35 +1,36 @@ | |||
1 | firejail (0.9.42~rc2) baseline; urgency=low | 1 | firejail (0.9.42~rc2) baseline; urgency=low |
2 | * security: --whitelist deleted files, submitted by Vasya Novikov | 2 | * security: --whitelist deleted files, submitted by Vasya Novikov |
3 | * security: disable x32 ABI, submitted by Jann Horn | 3 | * security: disable x32 ABI in seccomp, submitted by Jann Horn |
4 | * security: tighten --chroot, submitted by Jann Horn | 4 | * security: tighten --chroot, submitted by Jann Horn |
5 | * security: terminal sandbox escape, submitted by Stephan Sokolow | 5 | * security: terminal sandbox escape, submitted by Stephan Sokolow |
6 | * deprecated --user option, please use "sudo -u username firejail" instead | 6 | * modifs: deprecated --user option, please use "sudo -u username firejail" instead |
7 | * --read-write option rework | 7 | * modifs: allow symlinks in home directory for --whitelist option |
8 | * allow symlinks in home directory for --whitelist option | 8 | * modifs: Firejail prompt is enabled by env variable FIREJAIL_PROMPT="yes" |
9 | * --allow-debuggers option | 9 | * modifs: recursive mkdir |
10 | * --private-template (very simillar to the former --private-home) | 10 | * modifs: include /dev/snd in --private-dev |
11 | * AppImage support (--appimage) | 11 | * modifs: seccomp filter update |
12 | * AppArmor support (--apparmor) | 12 | * feature: AppImage support (--appimage) |
13 | * compile time support for Busybox | 13 | * feature: AppArmor support (--apparmor) |
14 | * Sandbox auditing support (--audit) | 14 | * feature: Ubuntu snap support (/etc/firejail/snap.profile) |
15 | * remove environment variable (--rmenv) | 15 | * feature: Sandbox auditing support (--audit) |
16 | * noexec support (--noexec) | 16 | * feature: remove environment variable (--rmenv) |
17 | * --overlay-clean option | 17 | * feature: noexec support (--noexec) |
18 | * --overlay-named=name option | 18 | * feature: clean local overlay storage directory (--overlay-clean) |
19 | * --overlay-path=path option | 19 | * feature: store and reuse overlay (--overlay-named) |
20 | * compile time and run time support to disable overlayfs | 20 | * feature: allow debugging inside the sandbox with gdb and strace (--allow-debuggers) |
21 | * Ubuntu snap support | 21 | * feature: mkfile profile command |
22 | * include /dev/snd in --private-dev | 22 | * feature: quiet profile command |
23 | * added mkfile profile command | 23 | * feature: x11 profile command |
24 | * added quiet profile command | 24 | * compile time: Busybox support (--enable-busybox-workaround) |
25 | * recursive mkdir | 25 | * compile time: disable overlayfs (--disable-overlayfs) |
26 | * seccomp filter updated | 26 | * compile time: disable whitlisting (--disable-whitelist) |
27 | * compile time and run time support to disable whitelists | 27 | * compile time: disable global config (--disable-globalcfg) |
28 | * compile time support to disable global configuration file | 28 | * run time: enable/disable overlayfs (overlayfs yes/no) |
29 | * run time support to disable remounting of /proc and /sys | 29 | * run time: enable/disable quiet as default (quiet-by-default yes/no) |
30 | * added quiet-by-default config option in /etc/firejail/firejail.config | 30 | * run time: user-defined network filter (netfilter-default) |
31 | * added netfilter-default config option in /etc/firejail/firejail.config | 31 | * run time: enable/disable whitelisting (whitelist yes/no) |
32 | * added x11 command for profile files | 32 | * run time: enable/disable remounting of /proc and /sys (remount-proc-sys yes/no) |
33 | * run time: enable/disable chroot desktop features (chroot-desktop yes/no) | ||
33 | * new profiles: Gitter, gThumb, mpv, Franz messenger, LibreOffice | 34 | * new profiles: Gitter, gThumb, mpv, Franz messenger, LibreOffice |
34 | * new profiles: pix, audacity, xz, xzdec, gzip, cpio, less | 35 | * new profiles: pix, audacity, xz, xzdec, gzip, cpio, less |
35 | * new profiles: Atom Beta, Atom, jitsi, eom, uudeview | 36 | * new profiles: Atom Beta, Atom, jitsi, eom, uudeview |
diff --git a/etc/firejail.config b/etc/firejail.config index 275bba8e2..6b6ba7fdf 100644 --- a/etc/firejail.config +++ b/etc/firejail.config | |||
@@ -9,6 +9,11 @@ | |||
9 | # Enable or disable chroot support, default enabled. | 9 | # Enable or disable chroot support, default enabled. |
10 | # chroot yes | 10 | # chroot yes |
11 | 11 | ||
12 | # Use chroot for desktop programs, default enabled. The sandbox will have full | ||
13 | # access to system's /dev directory in order to allow video acceleration, | ||
14 | # and it will harden the rest of the chroot tree. | ||
15 | # chroot-desktop yes | ||
16 | |||
12 | # Enable or disable file transfer support, default enabled. | 17 | # Enable or disable file transfer support, default enabled. |
13 | # file-transfer yes | 18 | # file-transfer yes |
14 | 19 | ||
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index fed934434..5bc859f8d 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c | |||
@@ -241,6 +241,14 @@ int checkcfg(int val) { | |||
241 | else | 241 | else |
242 | goto errout; | 242 | goto errout; |
243 | } | 243 | } |
244 | else if (strncmp(ptr, "chroot-desktop ", 15) == 0) { | ||
245 | if (strcmp(ptr + 15, "yes") == 0) | ||
246 | cfg_val[CFG_CHROOT_DESKTOP] = 1; | ||
247 | else if (strcmp(ptr + 15, "no") == 0) | ||
248 | cfg_val[CFG_CHROOT_DESKTOP] = 0; | ||
249 | else | ||
250 | goto errout; | ||
251 | } | ||
244 | else | 252 | else |
245 | goto errout; | 253 | goto errout; |
246 | 254 | ||
diff --git a/src/firejail/env.c b/src/firejail/env.c index c05abadca..2c8be3852 100644 --- a/src/firejail/env.c +++ b/src/firejail/env.c | |||
@@ -123,10 +123,14 @@ void env_defaults(void) { | |||
123 | errExit("setenv"); | 123 | errExit("setenv"); |
124 | if (cfg.shell && setenv("SHELL", cfg.shell, 1) < 0) | 124 | if (cfg.shell && setenv("SHELL", cfg.shell, 1) < 0) |
125 | errExit("setenv"); | 125 | errExit("setenv"); |
126 | |||
126 | // set prompt color to green | 127 | // set prompt color to green |
127 | //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' | 128 | char *prompt = getenv("FIREJAIL_PROMPT"); |
128 | // if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0) | 129 | if (prompt && strcmp(prompt, "yes") == 0) { |
129 | // errExit("setenv"); | 130 | //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' |
131 | if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0) | ||
132 | errExit("setenv"); | ||
133 | } | ||
130 | 134 | ||
131 | // set the window title | 135 | // set the window title |
132 | printf("\033]0;firejail %s\007", cfg.window_title); | 136 | printf("\033]0;firejail %s\007", cfg.window_title); |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 4bc953e24..a3b573acc 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -614,7 +614,8 @@ void sandboxfs(int op, pid_t pid, const char *patqh); | |||
614 | #define CFG_XEPHYR_WINDOW_TITLE 10 | 614 | #define CFG_XEPHYR_WINDOW_TITLE 10 |
615 | #define CFG_REMOUNT_PROC_SYS 11 | 615 | #define CFG_REMOUNT_PROC_SYS 11 |
616 | #define CFG_OVERLAYFS 12 | 616 | #define CFG_OVERLAYFS 12 |
617 | #define CFG_MAX 13 // this should always be the last entry | 617 | #define CFG_CHROOT_DESKTOP 13 |
618 | #define CFG_MAX 14 // this should always be the last entry | ||
618 | extern char *xephyr_screen; | 619 | extern char *xephyr_screen; |
619 | extern char *xephyr_extra_params; | 620 | extern char *xephyr_extra_params; |
620 | extern char *netfilter_default; | 621 | extern char *netfilter_default; |
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index ddb25c2dd..6c87df1e9 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -817,9 +817,10 @@ void fs_basic_fs(void) { | |||
817 | 817 | ||
818 | #ifdef HAVE_OVERLAYFS | 818 | #ifdef HAVE_OVERLAYFS |
819 | char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) { | 819 | char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) { |
820 | // create ~/.firejail directory | ||
821 | struct stat s; | 820 | struct stat s; |
822 | char *dirname; | 821 | char *dirname; |
822 | |||
823 | // create ~/.firejail directory | ||
823 | if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1) | 824 | if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1) |
824 | errExit("asprintf"); | 825 | errExit("asprintf"); |
825 | if (stat(dirname, &s) == -1) { | 826 | if (stat(dirname, &s) == -1) { |
@@ -835,12 +836,15 @@ char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) { | |||
835 | fprintf(stderr, "Error: invalid ~/.firejail directory\n"); | 836 | fprintf(stderr, "Error: invalid ~/.firejail directory\n"); |
836 | exit(1); | 837 | exit(1); |
837 | } | 838 | } |
838 | |||
839 | free(dirname); | 839 | free(dirname); |
840 | 840 | ||
841 | // check overlay directory | 841 | // check overlay directory |
842 | if (asprintf(&dirname, "%s/.firejail/%s", cfg.homedir, subdirname) == -1) | 842 | if (asprintf(&dirname, "%s/.firejail/%s", cfg.homedir, subdirname) == -1) |
843 | errExit("asprintf"); | 843 | errExit("asprintf"); |
844 | if (is_link(dirname)) { | ||
845 | fprintf(stderr, "Error: overlay directory is a symbolic link\n"); | ||
846 | exit(1); | ||
847 | } | ||
844 | if (allow_reuse == 0) { | 848 | if (allow_reuse == 0) { |
845 | if (stat(dirname, &s) == 0) { | 849 | if (stat(dirname, &s) == 0) { |
846 | fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname); | 850 | fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname); |
@@ -1207,56 +1211,58 @@ int fs_check_chroot_dir(const char *rootdir) { | |||
1207 | void fs_chroot(const char *rootdir) { | 1211 | void fs_chroot(const char *rootdir) { |
1208 | assert(rootdir); | 1212 | assert(rootdir); |
1209 | 1213 | ||
1210 | // mount-bind a /dev in rootdir | 1214 | if (checkcfg(CFG_CHROOT_DESKTOP)) { |
1211 | char *newdev; | 1215 | // mount-bind a /dev in rootdir |
1212 | if (asprintf(&newdev, "%s/dev", rootdir) == -1) | 1216 | char *newdev; |
1213 | errExit("asprintf"); | 1217 | if (asprintf(&newdev, "%s/dev", rootdir) == -1) |
1214 | if (arg_debug) | ||
1215 | printf("Mounting /dev on %s\n", newdev); | ||
1216 | if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
1217 | errExit("mounting /dev"); | ||
1218 | free(newdev); | ||
1219 | |||
1220 | // x11 | ||
1221 | if (getenv("FIREJAIL_X11")) { | ||
1222 | char *newx11; | ||
1223 | if (asprintf(&newx11, "%s/tmp/.X11-unix", rootdir) == -1) | ||
1224 | errExit("asprintf"); | 1218 | errExit("asprintf"); |
1225 | if (arg_debug) | 1219 | if (arg_debug) |
1226 | printf("Mounting /tmp/.X11-unix on %s\n", newx11); | 1220 | printf("Mounting /dev on %s\n", newdev); |
1227 | if (mount("/tmp/.X11-unix", newx11, NULL, MS_BIND|MS_REC, NULL) < 0) | 1221 | if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0) |
1228 | errExit("mounting /tmp/.X11-unix"); | 1222 | errExit("mounting /dev"); |
1229 | free(newx11); | 1223 | free(newdev); |
1230 | } | 1224 | |
1231 | 1225 | // x11 | |
1232 | // some older distros don't have a /run directory | 1226 | if (getenv("FIREJAIL_X11")) { |
1233 | // create one by default | 1227 | char *newx11; |
1234 | // no exit on error, let the user deal with any problems | 1228 | if (asprintf(&newx11, "%s/tmp/.X11-unix", rootdir) == -1) |
1235 | char *rundir; | 1229 | errExit("asprintf"); |
1236 | if (asprintf(&rundir, "%s/run", rootdir) == -1) | 1230 | if (arg_debug) |
1237 | errExit("asprintf"); | 1231 | printf("Mounting /tmp/.X11-unix on %s\n", newx11); |
1238 | if (!is_dir(rundir)) { | 1232 | if (mount("/tmp/.X11-unix", newx11, NULL, MS_BIND|MS_REC, NULL) < 0) |
1239 | int rv = mkdir(rundir, 0755); | 1233 | errExit("mounting /tmp/.X11-unix"); |
1240 | (void) rv; | 1234 | free(newx11); |
1241 | rv = chown(rundir, 0, 0); | 1235 | } |
1242 | (void) rv; | 1236 | |
1237 | // some older distros don't have a /run directory | ||
1238 | // create one by default | ||
1239 | // no exit on error, let the user deal with any problems | ||
1240 | char *rundir; | ||
1241 | if (asprintf(&rundir, "%s/run", rootdir) == -1) | ||
1242 | errExit("asprintf"); | ||
1243 | if (!is_dir(rundir)) { | ||
1244 | int rv = mkdir(rundir, 0755); | ||
1245 | (void) rv; | ||
1246 | rv = chown(rundir, 0, 0); | ||
1247 | (void) rv; | ||
1248 | } | ||
1249 | |||
1250 | // copy /etc/resolv.conf in chroot directory | ||
1251 | // if resolv.conf in chroot is a symbolic link, this will fail | ||
1252 | // no exit on error, let the user deal with the problem | ||
1253 | char *fname; | ||
1254 | if (asprintf(&fname, "%s/etc/resolv.conf", rootdir) == -1) | ||
1255 | errExit("asprintf"); | ||
1256 | if (arg_debug) | ||
1257 | printf("Updating /etc/resolv.conf in %s\n", fname); | ||
1258 | if (is_link(fname)) { | ||
1259 | fprintf(stderr, "Error: invalid %s file\n", fname); | ||
1260 | exit(1); | ||
1261 | } | ||
1262 | if (copy_file("/etc/resolv.conf", fname) == -1) | ||
1263 | fprintf(stderr, "Warning: /etc/resolv.conf not initialized\n"); | ||
1243 | } | 1264 | } |
1244 | 1265 | ||
1245 | // copy /etc/resolv.conf in chroot directory | ||
1246 | // if resolv.conf in chroot is a symbolic link, this will fail | ||
1247 | // no exit on error, let the user deal with the problem | ||
1248 | char *fname; | ||
1249 | if (asprintf(&fname, "%s/etc/resolv.conf", rootdir) == -1) | ||
1250 | errExit("asprintf"); | ||
1251 | if (arg_debug) | ||
1252 | printf("Updating /etc/resolv.conf in %s\n", fname); | ||
1253 | if (is_link(fname)) { | ||
1254 | fprintf(stderr, "Error: invalid %s file\n", fname); | ||
1255 | exit(1); | ||
1256 | } | ||
1257 | if (copy_file("/etc/resolv.conf", fname) == -1) | ||
1258 | fprintf(stderr, "Warning: /etc/resolv.conf not initialized\n"); | ||
1259 | |||
1260 | // chroot into the new directory | 1266 | // chroot into the new directory |
1261 | if (arg_debug) | 1267 | if (arg_debug) |
1262 | printf("Chrooting into %s\n", rootdir); | 1268 | printf("Chrooting into %s\n", rootdir); |
@@ -1265,24 +1271,26 @@ void fs_chroot(const char *rootdir) { | |||
1265 | // mount a new tmpfs in /run/firejail/mnt - the old one was lost in chroot | 1271 | // mount a new tmpfs in /run/firejail/mnt - the old one was lost in chroot |
1266 | fs_build_remount_mnt_dir(); | 1272 | fs_build_remount_mnt_dir(); |
1267 | 1273 | ||
1268 | // update /var directory in order to support multiple sandboxes running on the same root directory | 1274 | if (checkcfg(CFG_CHROOT_DESKTOP)) { |
1269 | if (!arg_private_dev) | 1275 | // update /var directory in order to support multiple sandboxes running on the same root directory |
1270 | fs_dev_shm(); | 1276 | if (!arg_private_dev) |
1271 | fs_var_lock(); | 1277 | fs_dev_shm(); |
1272 | fs_var_tmp(); | 1278 | fs_var_lock(); |
1273 | fs_var_log(); | 1279 | fs_var_tmp(); |
1274 | fs_var_lib(); | 1280 | fs_var_log(); |
1275 | fs_var_cache(); | 1281 | fs_var_lib(); |
1276 | fs_var_utmp(); | 1282 | fs_var_cache(); |
1277 | 1283 | fs_var_utmp(); | |
1278 | // don't leak user information | 1284 | |
1279 | restrict_users(); | 1285 | // don't leak user information |
1280 | 1286 | restrict_users(); | |
1281 | // when starting as root, firejail config is not disabled; | 1287 | |
1282 | // this mode could be used to install and test new software by chaining | 1288 | // when starting as root, firejail config is not disabled; |
1283 | // firejail sandboxes (firejail --force) | 1289 | // this mode could be used to install and test new software by chaining |
1284 | if (getuid() != 0) | 1290 | // firejail sandboxes (firejail --force) |
1285 | disable_config(); | 1291 | if (getuid() != 0) |
1292 | disable_config(); | ||
1293 | } | ||
1286 | } | 1294 | } |
1287 | #endif | 1295 | #endif |
1288 | 1296 | ||
diff --git a/src/firejail/main.c b/src/firejail/main.c index bdb8e0df5..27e2a7f1a 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -1365,6 +1365,13 @@ int main(int argc, char **argv) { | |||
1365 | fprintf(stderr, "Error: invalid overlay option\n"); | 1365 | fprintf(stderr, "Error: invalid overlay option\n"); |
1366 | exit(1); | 1366 | exit(1); |
1367 | } | 1367 | } |
1368 | |||
1369 | // check name | ||
1370 | invalid_filename(subdirname); | ||
1371 | if (strstr(subdirname, "..") || strstr(subdirname, "/")) { | ||
1372 | fprintf(stderr, "Error: invalid overlay name\n"); | ||
1373 | exit(1); | ||
1374 | } | ||
1368 | cfg.overlay_dir = fs_check_overlay_dir(subdirname, arg_overlay_reuse); | 1375 | cfg.overlay_dir = fs_check_overlay_dir(subdirname, arg_overlay_reuse); |
1369 | } | 1376 | } |
1370 | else { | 1377 | else { |
@@ -1373,6 +1380,7 @@ int main(int argc, char **argv) { | |||
1373 | } | 1380 | } |
1374 | 1381 | ||
1375 | } | 1382 | } |
1383 | #if 0 // disabled for now, it could be used to overwrite system directories | ||
1376 | else if (strncmp(argv[i], "--overlay-path=", 15) == 0) { | 1384 | else if (strncmp(argv[i], "--overlay-path=", 15) == 0) { |
1377 | if (checkcfg(CFG_OVERLAYFS)) { | 1385 | if (checkcfg(CFG_OVERLAYFS)) { |
1378 | if (cfg.chrootdir) { | 1386 | if (cfg.chrootdir) { |
@@ -1400,6 +1408,7 @@ int main(int argc, char **argv) { | |||
1400 | exit(1); | 1408 | exit(1); |
1401 | } | 1409 | } |
1402 | } | 1410 | } |
1411 | #endif | ||
1403 | else if (strcmp(argv[i], "--overlay-tmpfs") == 0) { | 1412 | else if (strcmp(argv[i], "--overlay-tmpfs") == 0) { |
1404 | if (checkcfg(CFG_OVERLAYFS)) { | 1413 | if (checkcfg(CFG_OVERLAYFS)) { |
1405 | if (cfg.chrootdir) { | 1414 | if (cfg.chrootdir) { |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 0818bf450..40df00a98 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -378,7 +378,30 @@ void start_application(void) { | |||
378 | exit(1); // it should never get here!!! | 378 | exit(1); // it should never get here!!! |
379 | } | 379 | } |
380 | 380 | ||
381 | 381 | static void enforce_filters(void) { | |
382 | // force default seccomp inside the chroot, no keep or drop list | ||
383 | // the list build on top of the default drop list is kept intact | ||
384 | arg_seccomp = 1; | ||
385 | if (cfg.seccomp_list_drop) { | ||
386 | free(cfg.seccomp_list_drop); | ||
387 | cfg.seccomp_list_drop = NULL; | ||
388 | } | ||
389 | if (cfg.seccomp_list_keep) { | ||
390 | free(cfg.seccomp_list_keep); | ||
391 | cfg.seccomp_list_keep = NULL; | ||
392 | } | ||
393 | |||
394 | // disable all capabilities | ||
395 | if (arg_caps_default_filter || arg_caps_list) | ||
396 | fprintf(stderr, "Warning: all capabilities disabled for a regular user in chroot\n"); | ||
397 | arg_caps_drop_all = 1; | ||
398 | |||
399 | // drop all supplementary groups; /etc/group file inside chroot | ||
400 | // is controlled by a regular usr | ||
401 | arg_nogroups = 1; | ||
402 | if (!arg_quiet) | ||
403 | printf("Dropping all Linux capabilities and enforcing default seccomp filter\n"); | ||
404 | } | ||
382 | 405 | ||
383 | int sandbox(void* sandbox_arg) { | 406 | int sandbox(void* sandbox_arg) { |
384 | // Get rid of unused parameter warning | 407 | // Get rid of unused parameter warning |
@@ -463,37 +486,13 @@ int sandbox(void* sandbox_arg) { | |||
463 | #ifdef HAVE_CHROOT | 486 | #ifdef HAVE_CHROOT |
464 | if (cfg.chrootdir) { | 487 | if (cfg.chrootdir) { |
465 | fs_chroot(cfg.chrootdir); | 488 | fs_chroot(cfg.chrootdir); |
466 | |||
467 | // // redo cp command | ||
468 | // fs_build_cp_command(); | ||
469 | 489 | ||
470 | // force caps and seccomp if not started as root | 490 | // force caps and seccomp if not started as root |
471 | if (getuid() != 0) { | 491 | if (getuid() != 0) { |
472 | // force default seccomp inside the chroot, no keep or drop list | 492 | enforce_filters(); |
473 | // the list build on top of the default drop list is kept intact | ||
474 | arg_seccomp = 1; | ||
475 | #ifdef HAVE_SECCOMP | 493 | #ifdef HAVE_SECCOMP |
476 | enforce_seccomp = 1; | 494 | enforce_seccomp = 1; |
477 | #endif | 495 | #endif |
478 | if (cfg.seccomp_list_drop) { | ||
479 | free(cfg.seccomp_list_drop); | ||
480 | cfg.seccomp_list_drop = NULL; | ||
481 | } | ||
482 | if (cfg.seccomp_list_keep) { | ||
483 | free(cfg.seccomp_list_keep); | ||
484 | cfg.seccomp_list_keep = NULL; | ||
485 | } | ||
486 | |||
487 | // disable all capabilities | ||
488 | if (arg_caps_default_filter || arg_caps_list) | ||
489 | fprintf(stderr, "Warning: all capabilities disabled for a regular user in chroot\n"); | ||
490 | arg_caps_drop_all = 1; | ||
491 | |||
492 | // drop all supplementary groups; /etc/group file inside chroot | ||
493 | // is controlled by a regular usr | ||
494 | arg_nogroups = 1; | ||
495 | if (!arg_quiet) | ||
496 | printf("Dropping all Linux capabilities and enforcing default seccomp filter\n"); | ||
497 | } | 496 | } |
498 | else | 497 | else |
499 | arg_seccomp = 1; | 498 | arg_seccomp = 1; |
@@ -507,8 +506,18 @@ int sandbox(void* sandbox_arg) { | |||
507 | else | 506 | else |
508 | #endif | 507 | #endif |
509 | #ifdef HAVE_OVERLAYFS | 508 | #ifdef HAVE_OVERLAYFS |
510 | if (arg_overlay) | 509 | if (arg_overlay) { |
511 | fs_overlayfs(); | 510 | fs_overlayfs(); |
511 | // force caps and seccomp if not started as root | ||
512 | if (getuid() != 0) { | ||
513 | enforce_filters(); | ||
514 | #ifdef HAVE_SECCOMP | ||
515 | enforce_seccomp = 1; | ||
516 | #endif | ||
517 | } | ||
518 | else | ||
519 | arg_seccomp = 1; | ||
520 | } | ||
512 | else | 521 | else |
513 | #endif | 522 | #endif |
514 | fs_basic_fs(); | 523 | fs_basic_fs(); |
@@ -524,8 +533,14 @@ int sandbox(void* sandbox_arg) { | |||
524 | // private mode | 533 | // private mode |
525 | //**************************** | 534 | //**************************** |
526 | if (arg_private) { | 535 | if (arg_private) { |
527 | if (cfg.home_private) // --private= | 536 | if (cfg.home_private) { // --private= |
528 | fs_private_homedir(); | 537 | if (cfg.chrootdir) |
538 | fprintf(stderr, "Warning: private=directory feature is disabled in chroot\n"); | ||
539 | else if (arg_overlay) | ||
540 | fprintf(stderr, "Warning: private=directory feature is disabled in overlay\n"); | ||
541 | else | ||
542 | fs_private_homedir(); | ||
543 | } | ||
529 | else // --private | 544 | else // --private |
530 | fs_private(); | 545 | fs_private(); |
531 | } | 546 | } |
@@ -533,11 +548,20 @@ int sandbox(void* sandbox_arg) { | |||
533 | if (arg_private_template) | 548 | if (arg_private_template) |
534 | fs_private_template(); | 549 | fs_private_template(); |
535 | 550 | ||
536 | if (arg_private_dev) | 551 | if (arg_private_dev) { |
537 | fs_private_dev(); | 552 | if (cfg.chrootdir) |
553 | fprintf(stderr, "Warning: private-dev feature is disabled in chroot\n"); | ||
554 | else if (arg_overlay) | ||
555 | fprintf(stderr, "Warning: private-dev feature is disabled in overlay\n"); | ||
556 | else | ||
557 | fs_private_dev(); | ||
558 | } | ||
559 | |||
538 | if (arg_private_etc) { | 560 | if (arg_private_etc) { |
539 | if (cfg.chrootdir) | 561 | if (cfg.chrootdir) |
540 | fprintf(stderr, "Warning: private-etc feature is disabled in chroot\n"); | 562 | fprintf(stderr, "Warning: private-etc feature is disabled in chroot\n"); |
563 | else if (arg_overlay) | ||
564 | fprintf(stderr, "Warning: private-etc feature is disabled in overlay\n"); | ||
541 | else { | 565 | else { |
542 | fs_private_etc_list(); | 566 | fs_private_etc_list(); |
543 | // create /etc/ld.so.preload file again | 567 | // create /etc/ld.so.preload file again |
@@ -545,14 +569,24 @@ int sandbox(void* sandbox_arg) { | |||
545 | fs_trace_preload(); | 569 | fs_trace_preload(); |
546 | } | 570 | } |
547 | } | 571 | } |
572 | |||
548 | if (arg_private_bin) { | 573 | if (arg_private_bin) { |
549 | if (cfg.chrootdir) | 574 | if (cfg.chrootdir) |
550 | fprintf(stderr, "Warning: private-bin feature is disabled in chroot\n"); | 575 | fprintf(stderr, "Warning: private-bin feature is disabled in chroot\n"); |
576 | else if (arg_overlay) | ||
577 | fprintf(stderr, "Warning: private-bin feature is disabled in overlay\n"); | ||
551 | else | 578 | else |
552 | fs_private_bin_list(); | 579 | fs_private_bin_list(); |
553 | } | 580 | } |
554 | if (arg_private_tmp) | 581 | |
555 | fs_private_tmp(); | 582 | if (arg_private_tmp) { |
583 | if (cfg.chrootdir) | ||
584 | fprintf(stderr, "Warning: private-tmp feature is disabled in chroot\n"); | ||
585 | else if (arg_overlay) | ||
586 | fprintf(stderr, "Warning: private-tmp feature is disabled in overlay\n"); | ||
587 | else | ||
588 | fs_private_tmp(); | ||
589 | } | ||
556 | 590 | ||
557 | //**************************** | 591 | //**************************** |
558 | // update /proc, /sys, /dev, /boot directorymy | 592 | // update /proc, /sys, /dev, /boot directorymy |
@@ -565,7 +599,12 @@ int sandbox(void* sandbox_arg) { | |||
565 | //**************************** | 599 | //**************************** |
566 | if (cfg.profile) { | 600 | if (cfg.profile) { |
567 | // apply all whitelist commands ... | 601 | // apply all whitelist commands ... |
568 | fs_whitelist(); | 602 | if (cfg.chrootdir) |
603 | fprintf(stderr, "Warning: whitelist feature is disabled in chroot\n"); | ||
604 | else if (arg_overlay) | ||
605 | fprintf(stderr, "Warning: whitelist feature is disabled in overlay\n"); | ||
606 | else | ||
607 | fs_whitelist(); | ||
569 | 608 | ||
570 | // ... followed by blacklist commands | 609 | // ... followed by blacklist commands |
571 | fs_blacklist(); | 610 | fs_blacklist(); |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index ebe1c8830..d4eab7802 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -185,10 +185,30 @@ void usage(void) { | |||
185 | printf("\t$HOME/.firejail/<NAME> directory. (OverlayFS support is required in\n"); | 185 | printf("\t$HOME/.firejail/<NAME> directory. (OverlayFS support is required in\n"); |
186 | printf("\tLinux kernel for this option to work). \n\n"); | 186 | printf("\tLinux kernel for this option to work). \n\n"); |
187 | 187 | ||
188 | #if 0 // disabled for now, it could be used to overwrite system directories | ||
188 | printf(" --overlay-path=path - mount a filesystem overlay on top of the current\n"); | 189 | printf(" --overlay-path=path - mount a filesystem overlay on top of the current\n"); |
189 | printf("\tfilesystem. The upper filesystem layer is persistent, and stored in\n"); | 190 | printf("\tfilesystem. The upper filesystem layer is persistent, and stored in\n"); |
190 | printf("\tthe specified path. (OverlayFS support is required in Linux kernel for\n"); | 191 | printf("\tthe specified path. (OverlayFS support is required in Linux kernel for\n"); |
191 | printf("\tthis option to work). \n\n"); | 192 | printf("\tthis option to work). \n\n"); |
193 | |||
194 | .TP | ||
195 | \fB\-\-overlay-path=path | ||
196 | Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, | ||
197 | the system directories are mounted read-write. All filesystem modifications go into the overlay. | ||
198 | The overlay is stored in the specified path. The created overlay can be reused between multiple sessions. | ||
199 | .br | ||
200 | |||
201 | .br | ||
202 | OverlayFS support is required in Linux kernel for this option to work. | ||
203 | OverlayFS was officially introduced in Linux kernel version 3.18. | ||
204 | This option is not available on Grsecurity systems. | ||
205 | .br | ||
206 | |||
207 | .br | ||
208 | Example: | ||
209 | .br | ||
210 | $ firejail \-\-overlay-path=~/jails/jail1 firefox | ||
211 | #endif | ||
192 | 212 | ||
193 | printf(" --overlay-tmpfs - mount a filesystem overlay on top of the current\n"); | 213 | printf(" --overlay-tmpfs - mount a filesystem overlay on top of the current\n"); |
194 | printf("\tfilesystem. The upper layer is stored in a tmpfs filesystem,\n"); | 214 | printf("\tfilesystem. The upper layer is stored in a tmpfs filesystem,\n"); |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index b258c3d20..19fca9854 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -1037,24 +1037,6 @@ Example: | |||
1037 | $ firejail \-\-overlay-named=jail1 firefox | 1037 | $ firejail \-\-overlay-named=jail1 firefox |
1038 | 1038 | ||
1039 | .TP | 1039 | .TP |
1040 | \fB\-\-overlay-path=path | ||
1041 | Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, | ||
1042 | the system directories are mounted read-write. All filesystem modifications go into the overlay. | ||
1043 | The overlay is stored in the specified path. The created overlay can be reused between multiple sessions. | ||
1044 | .br | ||
1045 | |||
1046 | .br | ||
1047 | OverlayFS support is required in Linux kernel for this option to work. | ||
1048 | OverlayFS was officially introduced in Linux kernel version 3.18. | ||
1049 | This option is not available on Grsecurity systems. | ||
1050 | .br | ||
1051 | |||
1052 | .br | ||
1053 | Example: | ||
1054 | .br | ||
1055 | $ firejail \-\-overlay-path=~/jails/jail1 firefox | ||
1056 | |||
1057 | .TP | ||
1058 | \fB\-\-overlay-tmpfs | 1040 | \fB\-\-overlay-tmpfs |
1059 | Mount a filesystem overlay on top of the current filesystem. All filesystem modifications go into the overlay, | 1041 | Mount a filesystem overlay on top of the current filesystem. All filesystem modifications go into the overlay, |
1060 | and are discarded when the sandbox is closed. | 1042 | and are discarded when the sandbox is closed. |