aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/dig.profile3
-rw-r--r--etc/disable-common.inc3
-rw-r--r--etc/firejail-default18
-rw-r--r--etc/k3b.profile13
-rw-r--r--etc/wine.profile7
-rw-r--r--src/firejail/fs.c6
-rw-r--r--src/firejail/fs_home.c63
-rw-r--r--src/firejail/main.c2
-rw-r--r--src/firejail/profile.c5
-rw-r--r--src/man/firejail-profile.txt2
10 files changed, 82 insertions, 40 deletions
diff --git a/etc/dig.profile b/etc/dig.profile
index e609105b4..af71ff17f 100644
--- a/etc/dig.profile
+++ b/etc/dig.profile
@@ -46,7 +46,8 @@ private
46private-bin bash,dig,sh 46private-bin bash,dig,sh
47private-cache 47private-cache
48private-dev 48private-dev
49private-lib 49# Uncomment the next line (or put 'private-lib' in your dig.local) on non Debian/Ubuntu OS (see issue #3038)
50#private-lib
50private-tmp 51private-tmp
51 52
52memory-deny-write-execute 53memory-deny-write-execute
diff --git a/etc/disable-common.inc b/etc/disable-common.inc
index 96957eeaf..b2837b443 100644
--- a/etc/disable-common.inc
+++ b/etc/disable-common.inc
@@ -315,6 +315,7 @@ blacklist ${HOME}/.config/keybase
315blacklist ${HOME}/.davfs2/secrets 315blacklist ${HOME}/.davfs2/secrets
316blacklist ${HOME}/.ecryptfs 316blacklist ${HOME}/.ecryptfs
317blacklist ${HOME}/.fetchmailrc 317blacklist ${HOME}/.fetchmailrc
318blacklist ${HOME}/.fscrypt
318blacklist ${HOME}/.git-credential-cache 319blacklist ${HOME}/.git-credential-cache
319blacklist ${HOME}/.git-credentials 320blacklist ${HOME}/.git-credentials
320blacklist ${HOME}/.gnome2/keyrings 321blacklist ${HOME}/.gnome2/keyrings
@@ -335,6 +336,7 @@ blacklist ${HOME}/.local/share/pki
335blacklist ${HOME}/.smbcredentials 336blacklist ${HOME}/.smbcredentials
336blacklist ${HOME}/.ssh 337blacklist ${HOME}/.ssh
337blacklist ${HOME}/.vaults 338blacklist ${HOME}/.vaults
339blacklist /.fscrypt
338blacklist /etc/davfs2/secrets 340blacklist /etc/davfs2/secrets
339blacklist /etc/group+ 341blacklist /etc/group+
340blacklist /etc/group- 342blacklist /etc/group-
@@ -348,6 +350,7 @@ blacklist /etc/shadow+
348blacklist /etc/shadow- 350blacklist /etc/shadow-
349blacklist /etc/ssh 351blacklist /etc/ssh
350blacklist /home/.ecryptfs 352blacklist /home/.ecryptfs
353blacklist /home/.fscrypt
351blacklist /var/backup 354blacklist /var/backup
352 355
353# cloud provider configuration 356# cloud provider configuration
diff --git a/etc/firejail-default b/etc/firejail-default
index e7831e145..a012f5440 100644
--- a/etc/firejail-default
+++ b/etc/firejail-default
@@ -22,12 +22,11 @@ dbus,
22 22
23########## 23##########
24# With ptrace it is possible to inspect and hijack running programs. 24# With ptrace it is possible to inspect and hijack running programs.
25# Some browsers are also using ptrace for their sandboxing.
26########## 25##########
27# Uncomment this line to allow all ptrace access 26# Uncomment this line to allow all ptrace access
28#ptrace, 27#ptrace,
29# Allow obtaining some process information, but not ptrace(2) 28# Allow obtaining some process information, but not ptrace(2)
30ptrace (read,readby) peer=firejail-default, 29ptrace (read,readby) peer=@{profile_name},
31 30
32########## 31##########
33# Allow read access to whole filesystem and control it from firejail. 32# Allow read access to whole filesystem and control it from firejail.
@@ -46,9 +45,6 @@ ptrace (read,readby) peer=firejail-default,
46########## 45##########
47owner /{,run/firejail/mnt/oroot/}{,var/}run/firejail/mnt/trace w, 46owner /{,run/firejail/mnt/oroot/}{,var/}run/firejail/mnt/trace w,
48owner /{,run/firejail/mnt/oroot/}{,var/}run/user/[0-9]*/** w, 47owner /{,run/firejail/mnt/oroot/}{,var/}run/user/[0-9]*/** w,
49owner /{,run/firejail/mnt/oroot/}{,var/}run/user/[0-9]*/*.slave-socket w,
50owner /{,run/firejail/mnt/oroot/}{,var/}run/user/[0-9]*/orcexec.* w,
51
52owner /{,run/firejail/mnt/oroot/}{run,dev}/shm/** w, 48owner /{,run/firejail/mnt/oroot/}{run,dev}/shm/** w,
53 49
54# Allow writing to removable media 50# Allow writing to removable media
@@ -58,9 +54,6 @@ owner /{,var/}run/media/** w,
58/{,var/}run/systemd/journal/socket w, 54/{,var/}run/systemd/journal/socket w,
59/{,var/}run/systemd/journal/dev-log w, 55/{,var/}run/systemd/journal/dev-log w,
60 56
61# Needed for wine
62/{,var/}run/firejail/profile/@{PID} w,
63
64# Allow access to cups printing socket. 57# Allow access to cups printing socket.
65/{,var/}run/cups/cups.sock w, 58/{,var/}run/cups/cups.sock w,
66 59
@@ -94,8 +87,10 @@ deny /proc/@{PID}/oom_score_adj w,
94########## 87##########
95# Blacklist specific sensitive paths. 88# Blacklist specific sensitive paths.
96########## 89##########
97# Common backup directory 90deny /**/.fscrypt/ rw,
98deny /**/.snapshots/ rwx, 91deny /**/.fscrypt/** rwklmx,
92deny /**/.snapshots/ rw,
93deny /**/.snapshots/** rwklmx,
99 94
100########## 95##########
101# Allow all networking functionality, and control it from Firejail. 96# Allow all networking functionality, and control it from Firejail.
@@ -111,7 +106,8 @@ network packet,
111########## 106##########
112# There is no equivalent in Firejail for filtering signals. 107# There is no equivalent in Firejail for filtering signals.
113########## 108##########
114signal, 109signal (send) peer=@{profile_name},
110signal (receive),
115 111
116########## 112##########
117# We let Firejail deal with capabilities, but ensure that 113# We let Firejail deal with capabilities, but ensure that
diff --git a/etc/k3b.profile b/etc/k3b.profile
index 60da458ab..0c1da7ae1 100644
--- a/etc/k3b.profile
+++ b/etc/k3b.profile
@@ -20,17 +20,18 @@ include disable-xdg.inc
20 20
21include whitelist-var-common.inc 21include whitelist-var-common.inc
22 22
23caps.drop all 23caps.keep ipc_lock,sys_nice,sys_rawio,sys_resource
24# net none
24netfilter 25netfilter
25no3d 26no3d
26nonewprivs 27# nonewprivs - breaks privileged helpers
27noroot 28# noroot - breaks privileged helpers
28nosound 29nosound
29notv 30notv
30novideo 31novideo
31protocol unix 32# protocol unix - breaks privileged helpers
32seccomp 33# seccomp - breaks privileged helpers
33shell none 34shell none
34tracelog
35 35
36private-dev
36# private-tmp 37# private-tmp
diff --git a/etc/wine.profile b/etc/wine.profile
index 192c375cd..29e79c3f5 100644
--- a/etc/wine.profile
+++ b/etc/wine.profile
@@ -15,13 +15,20 @@ noblacklist ${HOME}/.wine
15include disable-common.inc 15include disable-common.inc
16include disable-devel.inc 16include disable-devel.inc
17include disable-interpreters.inc 17include disable-interpreters.inc
18include disable-passwdmgr.inc
18include disable-programs.inc 19include disable-programs.inc
19 20
21# uncomment next line if seccomp breaks a program
22# allow-debuggers
20caps.drop all 23caps.drop all
24# net none
21netfilter 25netfilter
22nodvd 26nodvd
23nogroups 27nogroups
24nonewprivs 28nonewprivs
25noroot 29noroot
26notv 30notv
31# novideo
27seccomp 32seccomp
33
34private-dev
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 3df551d4c..3e802efb5 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -1191,15 +1191,15 @@ void fs_private_cache(void) {
1191 // check if ~/.cache is a valid destination 1191 // check if ~/.cache is a valid destination
1192 struct stat s; 1192 struct stat s;
1193 if (lstat(cache, &s) == -1) { 1193 if (lstat(cache, &s) == -1) {
1194 fwarning("cannot find %s, tmpfs not mounted\n", cache); 1194 fwarning("skipping private-cache: cannot find %s\n", cache);
1195 free(cache); 1195 free(cache);
1196 return; 1196 return;
1197 } 1197 }
1198 if (!S_ISDIR(s.st_mode)) { 1198 if (!S_ISDIR(s.st_mode)) {
1199 if (S_ISLNK(s.st_mode)) 1199 if (S_ISLNK(s.st_mode))
1200 fwarning("%s is a symbolic link, tmpfs not mounted\n", cache); 1200 fwarning("skipping private-cache: %s is a symbolic link\n", cache);
1201 else 1201 else
1202 fwarning("%s is not a directory; cannot mount a tmpfs on top of it\n", cache); 1202 fwarning("skipping private-cache: %s is not a directory\n", cache);
1203 free(cache); 1203 free(cache);
1204 return; 1204 return;
1205 } 1205 }
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index 25c167af1..2e8a8ad96 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -250,6 +250,9 @@ void fs_private_homedir(void) {
250 int xflag = store_xauthority(); 250 int xflag = store_xauthority();
251 int aflag = store_asoundrc(); 251 int aflag = store_asoundrc();
252 252
253 // home directory outside /home?
254 int oflag = (strncmp(homedir, "/home/", 6) != 0);
255
253 uid_t u = getuid(); 256 uid_t u = getuid();
254 gid_t g = getgid(); 257 gid_t g = getgid();
255 258
@@ -259,20 +262,33 @@ void fs_private_homedir(void) {
259 // get file descriptors for homedir and private_homedir, fails if there is any symlink 262 // get file descriptors for homedir and private_homedir, fails if there is any symlink
260 int src = safe_fd(private_homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); 263 int src = safe_fd(private_homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
261 if (src == -1) 264 if (src == -1)
262 errExit("safe_fd"); 265 errExit("opening private directory");
263 int dst = safe_fd(homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); 266 int dst = safe_fd(homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
264 if (dst == -1) 267 if (dst == -1)
265 errExit("safe_fd"); 268 errExit("opening home directory");
266 // check if new home directory is owned by the user 269 if (u != 0) {
267 struct stat s; 270 struct stat s;
268 if (fstat(src, &s) == -1) 271 // sometimes system users are assigned home directories like /, /proc, ...
269 errExit("fstat"); 272 // require that a home directory outside /home is owned by the user
270 if (s.st_uid != getuid()) { 273 if (oflag) {
271 fprintf(stderr, "Error: private directory is not owned by the current user\n"); 274 if (fstat(dst, &s) == -1)
272 exit(1); 275 errExit("fstat");
276 if (s.st_uid != u) {
277 fprintf(stderr, "Error: cannot mount private directory:\n"
278 "Home directory is not owned by the current user\n");
279 exit(1);
280 }
281 }
282 // check if new home directory is owned by the user
283 if (fstat(src, &s) == -1)
284 errExit("fstat");
285 if (s.st_uid != u) {
286 fprintf(stderr, "Error: private directory is not owned by the current user\n");
287 exit(1);
288 }
289 if ((S_IRWXU & s.st_mode) != S_IRWXU)
290 fwarning("no full permissions on private directory\n");
273 } 291 }
274 if ((S_IRWXU & s.st_mode) != S_IRWXU)
275 fwarning("no full permissions on private directory\n");
276 // mount via the links in /proc/self/fd 292 // mount via the links in /proc/self/fd
277 char *proc_src, *proc_dst; 293 char *proc_src, *proc_dst;
278 if (asprintf(&proc_src, "/proc/self/fd/%d", src) == -1) 294 if (asprintf(&proc_src, "/proc/self/fd/%d", src) == -1)
@@ -308,7 +324,7 @@ void fs_private_homedir(void) {
308 errExit("mounting home directory"); 324 errExit("mounting home directory");
309 fs_logger("tmpfs /root"); 325 fs_logger("tmpfs /root");
310 } 326 }
311 if (u == 0 || strncmp(homedir, "/home/", 6) != 0) { 327 if (oflag) {
312 // mask /home 328 // mask /home
313 if (arg_debug) 329 if (arg_debug)
314 printf("Mounting a new /home directory\n"); 330 printf("Mounting a new /home directory\n");
@@ -317,7 +333,6 @@ void fs_private_homedir(void) {
317 fs_logger("tmpfs /home"); 333 fs_logger("tmpfs /home");
318 } 334 }
319 335
320
321 skel(homedir, u, g); 336 skel(homedir, u, g);
322 if (xflag) 337 if (xflag)
323 copy_xauthority(); 338 copy_xauthority();
@@ -377,6 +392,7 @@ void fs_private(void) {
377 } 392 }
378 else 393 else
379 // user directory is outside /home, mask it as well 394 // user directory is outside /home, mask it as well
395 // check if directory is owned by the current user
380 fs_tmpfs(homedir, 1); 396 fs_tmpfs(homedir, 1);
381 } 397 }
382 398
@@ -385,7 +401,6 @@ void fs_private(void) {
385 copy_xauthority(); 401 copy_xauthority();
386 if (aflag) 402 if (aflag)
387 copy_asoundrc(); 403 copy_asoundrc();
388
389} 404}
390 405
391// check new private home directory (--private= option) - exit if it fails 406// check new private home directory (--private= option) - exit if it fails
@@ -531,6 +546,9 @@ void fs_private_home_list(void) {
531 int xflag = store_xauthority(); 546 int xflag = store_xauthority();
532 int aflag = store_asoundrc(); 547 int aflag = store_asoundrc();
533 548
549 // home directory outside /home?
550 int oflag = (strncmp(homedir, "/home/", 6) != 0);
551
534 uid_t uid = getuid(); 552 uid_t uid = getuid();
535 gid_t gid = getgid(); 553 gid_t gid = getgid();
536 554
@@ -563,7 +581,19 @@ void fs_private_home_list(void) {
563 581
564 int fd = safe_fd(homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); 582 int fd = safe_fd(homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
565 if (fd == -1) 583 if (fd == -1)
566 errExit("safe_fd"); 584 errExit("opening home directory");
585 if (uid != 0 && oflag) {
586 // home directory outside /home should be owned by the user
587 struct stat s;
588 if (fstat(fd, &s) == -1)
589 errExit("fstat");
590 if (s.st_uid != uid) {
591 fprintf(stderr, "Error: cannot mount private directory:\n"
592 "Home directory is not owned by the current user\n");
593 exit(1);
594 }
595 }
596 // mount using the file descriptor
567 char *proc; 597 char *proc;
568 if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) 598 if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1)
569 errExit("asprintf"); 599 errExit("asprintf");
@@ -584,7 +614,7 @@ void fs_private_home_list(void) {
584 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=700,gid=0") < 0) 614 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=700,gid=0") < 0)
585 errExit("mounting home directory"); 615 errExit("mounting home directory");
586 } 616 }
587 if (uid == 0 || strncmp(homedir, "/home/", 6) != 0) { 617 if (oflag) {
588 // mask /home 618 // mask /home
589 if (arg_debug) 619 if (arg_debug)
590 printf("Mounting a new /home directory\n"); 620 printf("Mounting a new /home directory\n");
@@ -600,5 +630,4 @@ void fs_private_home_list(void) {
600 630
601 if (!arg_quiet) 631 if (!arg_quiet)
602 fprintf(stderr, "Home directory installed in %0.2f ms\n", timetrace_end()); 632 fprintf(stderr, "Home directory installed in %0.2f ms\n", timetrace_end());
603
604} 633}
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 5b39dd491..1786cfac2 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -262,7 +262,7 @@ static int has_link(const char *dir) {
262 262
263static void check_homedir(void) { 263static void check_homedir(void) {
264 assert(cfg.homedir); 264 assert(cfg.homedir);
265 if (cfg.homedir[0] != '/' || cfg.homedir[1] == '\0') { // system users sometimes have root directory as home 265 if (cfg.homedir[0] != '/') {
266 fprintf(stderr, "Error: invalid user directory \"%s\"\n", cfg.homedir); 266 fprintf(stderr, "Error: invalid user directory \"%s\"\n", cfg.homedir);
267 exit(1); 267 exit(1);
268 } 268 }
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 03cd9dadb..9a724331b 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -143,6 +143,10 @@ static int check_appimage(void) {
143 return arg_appimage != 0; 143 return arg_appimage != 0;
144} 144}
145 145
146static int check_netoptions(void) {
147 return (arg_nonetwork || any_bridge_configured());
148}
149
146static int check_nodbus(void) { 150static int check_nodbus(void) {
147 return arg_nodbus != 0; 151 return arg_nodbus != 0;
148} 152}
@@ -161,6 +165,7 @@ static int check_allow_drm(void) {
161 165
162Cond conditionals[] = { 166Cond conditionals[] = {
163 {"HAS_APPIMAGE", check_appimage}, 167 {"HAS_APPIMAGE", check_appimage},
168 {"HAS_NET", check_netoptions},
164 {"HAS_NODBUS", check_nodbus}, 169 {"HAS_NODBUS", check_nodbus},
165 {"HAS_X11", check_x11}, 170 {"HAS_X11", check_x11},
166 {"BROWSER_DISABLE_U2F", check_disable_u2f}, 171 {"BROWSER_DISABLE_U2F", check_disable_u2f},
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt
index 4a84cc828..719a80c2c 100644
--- a/src/man/firejail-profile.txt
+++ b/src/man/firejail-profile.txt
@@ -103,7 +103,7 @@ Example: "?HAS_APPIMAGE: whitelist ${HOME}/special/appimage/dir"
103 103
104This example will load the whitelist profile line only if the \-\-appimage option has been specified on the command line. 104This example will load the whitelist profile line only if the \-\-appimage option has been specified on the command line.
105 105
106Currently the only conditionals supported this way are HAS_APPIMAGE, HAS_NODBUS and HAS_X11. The conditionals BROWSER_DISABLE_U2F and BROWSER_ALLOW_DRM 106Currently the only conditionals supported this way are HAS_APPIMAGE, HAS_NET, HAS_NODBUS and HAS_X11. The conditionals BROWSER_DISABLE_U2F and BROWSER_ALLOW_DRM
107can be enabled or disabled globally in Firejail's configuration file. 107can be enabled or disabled globally in Firejail's configuration file.
108 108
109The profile line may be any profile line that you would normally use in a profile \fBexcept\fR for "quiet" and "include" lines. 109The profile line may be any profile line that you would normally use in a profile \fBexcept\fR for "quiet" and "include" lines.