aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--RELNOTES5
-rw-r--r--etc/firejail.config4
-rw-r--r--etc/profile-a-l/cargo.profile1
-rw-r--r--etc/profile-a-l/chromium-common.profile3
-rw-r--r--etc/profile-a-l/firefox.profile3
-rw-r--r--etc/profile-a-l/librewolf.profile3
-rw-r--r--etc/templates/syscalls.txt2
-rw-r--r--src/firejail/appimage.c2
-rw-r--r--src/firejail/checkcfg.c5
-rw-r--r--src/firejail/chroot.c2
-rw-r--r--src/firejail/firejail.h5
-rw-r--r--src/firejail/fs.c2
-rw-r--r--src/firejail/fs_home.c99
-rw-r--r--src/firejail/fs_mkdir.c2
-rw-r--r--src/firejail/fs_whitelist.c8
-rw-r--r--src/firejail/ls.c2
-rw-r--r--src/firejail/main.c13
-rw-r--r--src/firejail/profile.c2
-rw-r--r--src/firejail/rlimit.c2
-rw-r--r--src/firejail/sandbox.c4
-rw-r--r--src/firejail/seccomp.c5
-rw-r--r--src/firejail/util.c9
-rw-r--r--src/firejail/x11.c6
-rw-r--r--src/firemon/interface.c2
-rw-r--r--src/firemon/netstats.c2
-rw-r--r--src/firemon/procevent.c2
-rw-r--r--src/firemon/top.c2
-rw-r--r--src/include/gcov_wrapper.h40
-rw-r--r--src/lib/syscall.c3
-rw-r--r--src/man/firejail.txt53
30 files changed, 202 insertions, 91 deletions
diff --git a/RELNOTES b/RELNOTES
index c989b00ff..6a629476d 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -1,6 +1,11 @@
1firejail (0.9.65) baseline; urgency=low 1firejail (0.9.65) baseline; urgency=low
2 * deprecated --audit options, relpaced by jailcheck utility 2 * deprecated --audit options, relpaced by jailcheck utility
3 * deprecated follow-symlink-as-user from firejail.config 3 * deprecated follow-symlink-as-user from firejail.config
4 * new firejail.config settings: private-bin, private-etc
5 * new firejail.config settings: private-opt, private-srv
6 * new firejail.config settings: whitelist-disable-topdir
7 * new firejail.config settings: seccomp-filter-add
8 * removed kcmp syscall from seccomp default filter
4 * rename --noautopulse to keep-config-pulse 9 * rename --noautopulse to keep-config-pulse
5 * filtering environment variables 10 * filtering environment variables
6 * zsh completion 11 * zsh completion
diff --git a/etc/firejail.config b/etc/firejail.config
index f5b3d5efa..43db49422 100644
--- a/etc/firejail.config
+++ b/etc/firejail.config
@@ -113,6 +113,10 @@
113# Enable or disable seccomp support, default enabled. 113# Enable or disable seccomp support, default enabled.
114# seccomp yes 114# seccomp yes
115 115
116# Add rules to the default seccomp filter. Same syntax as for --seccomp=
117# None by default; this is an example.
118# seccomp-filter-add !chroot,kcmp,mincore
119
116# Seccomp error action, kill, log or errno (EPERM, ENOSYS etc) 120# Seccomp error action, kill, log or errno (EPERM, ENOSYS etc)
117# seccomp-error-action EPERM 121# seccomp-error-action EPERM
118 122
diff --git a/etc/profile-a-l/cargo.profile b/etc/profile-a-l/cargo.profile
index 043fd6718..7cf04c550 100644
--- a/etc/profile-a-l/cargo.profile
+++ b/etc/profile-a-l/cargo.profile
@@ -34,6 +34,7 @@ include disable-xdg.inc
34#whitelist ${HOME}/.cargo 34#whitelist ${HOME}/.cargo
35#whitelist ${HOME}/.rustup 35#whitelist ${HOME}/.rustup
36#include whitelist-common.inc 36#include whitelist-common.inc
37whitelist /usr/share/pkgconfig
37include whitelist-runuser-common.inc 38include whitelist-runuser-common.inc
38include whitelist-usr-share-common.inc 39include whitelist-usr-share-common.inc
39include whitelist-var-common.inc 40include whitelist-var-common.inc
diff --git a/etc/profile-a-l/chromium-common.profile b/etc/profile-a-l/chromium-common.profile
index f7493aa82..b0e0254d4 100644
--- a/etc/profile-a-l/chromium-common.profile
+++ b/etc/profile-a-l/chromium-common.profile
@@ -37,8 +37,9 @@ include whitelist-var-common.inc
37# Add the next line to your chromium-common.local if your kernel allows unprivileged userns clone. 37# Add the next line to your chromium-common.local if your kernel allows unprivileged userns clone.
38#include chromium-common-hardened.inc.profile 38#include chromium-common-hardened.inc.profile
39 39
40# Add the next line to your chromium-common.local to allow screen sharing under wayland. 40# Add the next two lines to your chromium-common.local to allow screen sharing under wayland.
41#whitelist ${RUNUSER}/pipewire-0 41#whitelist ${RUNUSER}/pipewire-0
42#whitelist /usr/share/pipewire/client.conf
42 43
43apparmor 44apparmor
44caps.keep sys_admin,sys_chroot 45caps.keep sys_admin,sys_chroot
diff --git a/etc/profile-a-l/firefox.profile b/etc/profile-a-l/firefox.profile
index 7874c882f..3ad67734d 100644
--- a/etc/profile-a-l/firefox.profile
+++ b/etc/profile-a-l/firefox.profile
@@ -56,8 +56,9 @@ dbus-user.own org.mpris.MediaPlayer2.firefox.*
56#dbus-user.own org.mpris.MediaPlayer2.plasma-browser-integration 56#dbus-user.own org.mpris.MediaPlayer2.plasma-browser-integration
57#dbus-user.talk org.kde.JobViewServer 57#dbus-user.talk org.kde.JobViewServer
58#dbus-user.talk org.kde.kuiserver 58#dbus-user.talk org.kde.kuiserver
59# Add the next two lines to your firefox.local to allow screen sharing under wayland. 59# Add the next three lines to your firefox.local to allow screen sharing under wayland.
60#whitelist ${RUNUSER}/pipewire-0 60#whitelist ${RUNUSER}/pipewire-0
61#whitelist /usr/share/pipewire/client.conf
61#dbus-user.talk org.freedesktop.portal.* 62#dbus-user.talk org.freedesktop.portal.*
62# Add the next line to your firefox.local if screen sharing sharing still does not work 63# Add the next line to your firefox.local if screen sharing sharing still does not work
63# with the above lines (might depend on the portal implementation). 64# with the above lines (might depend on the portal implementation).
diff --git a/etc/profile-a-l/librewolf.profile b/etc/profile-a-l/librewolf.profile
index 8e3e58f19..da047357a 100644
--- a/etc/profile-a-l/librewolf.profile
+++ b/etc/profile-a-l/librewolf.profile
@@ -44,8 +44,9 @@ dbus-user filter
44#dbus-user.own org.mpris.MediaPlayer2.plasma-browser-integration 44#dbus-user.own org.mpris.MediaPlayer2.plasma-browser-integration
45#dbus-user.talk org.kde.JobViewServer 45#dbus-user.talk org.kde.JobViewServer
46#dbus-user.talk org.kde.kuiserver 46#dbus-user.talk org.kde.kuiserver
47# Add the next lines to your librewolf.local to allow screensharing under Wayland. 47# Add the next three lines to your librewolf.local to allow screensharing under Wayland.
48#whitelist ${RUNUSER}/pipewire-0 48#whitelist ${RUNUSER}/pipewire-0
49#whitelist /usr/share/pipewire/client.conf
49#dbus-user.talk org.freedesktop.portal.* 50#dbus-user.talk org.freedesktop.portal.*
50# Also add the next line to your librewolf.local if screensharing does not work with 51# Also add the next line to your librewolf.local if screensharing does not work with
51# the above lines (depends on the portal implementation). 52# the above lines (depends on the portal implementation).
diff --git a/etc/templates/syscalls.txt b/etc/templates/syscalls.txt
index 0775f60ff..3992c984a 100644
--- a/etc/templates/syscalls.txt
+++ b/etc/templates/syscalls.txt
@@ -33,7 +33,7 @@ Definition of groups
33@clock=adjtimex,clock_adjtime,clock_settime,settimeofday,stime 33@clock=adjtimex,clock_adjtime,clock_settime,settimeofday,stime
34@cpu-emulation=modify_ldt,subpage_prot,switch_endian,vm86,vm86old 34@cpu-emulation=modify_ldt,subpage_prot,switch_endian,vm86,vm86old
35@debug=lookup_dcookie,perf_event_open,process_vm_writev,rtas,s390_runtime_instr,sys_debug_setcontext 35@debug=lookup_dcookie,perf_event_open,process_vm_writev,rtas,s390_runtime_instr,sys_debug_setcontext
36@default=@clock,@cpu-emulation,@debug,@module,@mount,@obsolete,@raw-io,@reboot,@swap,open_by_handle_at,name_to_handle_at,ioprio_set,ni_syscall,syslog,fanotify_init,kcmp,add_key,request_key,mbind,migrate_pages,move_pages,keyctl,io_setup,io_destroy,io_getevents,io_submit,io_cancel,remap_file_pages,set_mempolicyvmsplice,userfaultfd,acct,bpf,nfsservctl,setdomainname,sethostname,vhangup 36@default=@clock,@cpu-emulation,@debug,@module,@mount,@obsolete,@raw-io,@reboot,@swap,open_by_handle_at,name_to_handle_at,ioprio_set,ni_syscall,syslog,fanotify_init,add_key,request_key,mbind,migrate_pages,move_pages,keyctl,io_setup,io_destroy,io_getevents,io_submit,io_cancel,remap_file_pages,set_mempolicyvmsplice,userfaultfd,acct,bpf,nfsservctl,setdomainname,sethostname,vhangup
37@default-nodebuggers=@default,ptrace,personality,process_vm_readv 37@default-nodebuggers=@default,ptrace,personality,process_vm_readv
38@default-keep=execveat,execve,prctl 38@default-keep=execveat,execve,prctl
39@file-system=access,chdir,chmod,close,creat,faccessat,faccessat2,fallocate,fchdir,fchmod,fchmodat,fcntl,fcntl64,fgetxattr,flistxattr,fremovexattr,fsetxattr,fstat,fstat64,fstatat64,fstatfs,fstatfs64,ftruncate,ftruncate64,futimesat,getcwd,getdents,getdents64,getxattr,inotify_add_watch,inotify_init,inotify_init1,inotify_rm_watch,lgetxattr,link,linkat,listxattr,llistxattr,lremovexattr,lsetxattr,lstat,lstat64,mkdir,mkdirat,mknod,mknodat,mmap,mmap2,munmap,newfstatat,oldfstat,oldlstat,oldstat,open,openat,readlink,readlinkat,removexattr,rename,renameat,renameat2,rmdir,setxattr,stat,stat64,statfs,statfs64,statx,symlink,symlinkat,truncate,truncate64,unlink,unlinkat,utime,utimensat,utimes 39@file-system=access,chdir,chmod,close,creat,faccessat,faccessat2,fallocate,fchdir,fchmod,fchmodat,fcntl,fcntl64,fgetxattr,flistxattr,fremovexattr,fsetxattr,fstat,fstat64,fstatat64,fstatfs,fstatfs64,ftruncate,ftruncate64,futimesat,getcwd,getdents,getdents64,getxattr,inotify_add_watch,inotify_init,inotify_init1,inotify_rm_watch,lgetxattr,link,linkat,listxattr,llistxattr,lremovexattr,lsetxattr,lstat,lstat64,mkdir,mkdirat,mknod,mknodat,mmap,mmap2,munmap,newfstatat,oldfstat,oldlstat,oldstat,open,openat,readlink,readlinkat,removexattr,rename,renameat,renameat2,rmdir,setxattr,stat,stat64,statfs,statfs64,statx,symlink,symlinkat,truncate,truncate64,unlink,unlinkat,utime,utimensat,utimes
diff --git a/src/firejail/appimage.c b/src/firejail/appimage.c
index a96415985..056640eec 100644
--- a/src/firejail/appimage.c
+++ b/src/firejail/appimage.c
@@ -29,7 +29,7 @@
29#include <errno.h> 29#include <errno.h>
30 30
31#ifdef HAVE_GCOV 31#ifdef HAVE_GCOV
32#include <gcov.h> 32#include "../include/gcov_wrapper.h"
33#endif 33#endif
34 34
35static char *devloop = NULL; // device file 35static char *devloop = NULL; // device file
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c
index f3ab0a6d8..1e9f4b641 100644
--- a/src/firejail/checkcfg.c
+++ b/src/firejail/checkcfg.c
@@ -35,6 +35,7 @@ char *xvfb_extra_params = "";
35char *netfilter_default = NULL; 35char *netfilter_default = NULL;
36unsigned long join_timeout = 5000000; // microseconds 36unsigned long join_timeout = 5000000; // microseconds
37char *config_seccomp_error_action_str = "EPERM"; 37char *config_seccomp_error_action_str = "EPERM";
38char *config_seccomp_filter_add = NULL;
38char **whitelist_reject_topdirs = NULL; 39char **whitelist_reject_topdirs = NULL;
39 40
40int checkcfg(int val) { 41int checkcfg(int val) {
@@ -225,6 +226,10 @@ int checkcfg(int val) {
225 else if (strncmp(ptr, "join-timeout ", 13) == 0) 226 else if (strncmp(ptr, "join-timeout ", 13) == 0)
226 join_timeout = strtoul(ptr + 13, NULL, 10) * 1000000; // seconds to microseconds 227 join_timeout = strtoul(ptr + 13, NULL, 10) * 1000000; // seconds to microseconds
227 228
229 // add rules to default seccomp filter
230 else if (strncmp(ptr, "seccomp-filter-add ", 19) == 0)
231 config_seccomp_filter_add = seccomp_check_list(ptr + 19);
232
228 // seccomp error action 233 // seccomp error action
229 else if (strncmp(ptr, "seccomp-error-action ", 21) == 0) { 234 else if (strncmp(ptr, "seccomp-error-action ", 21) == 0) {
230 if (strcmp(ptr + 21, "kill") == 0) 235 if (strcmp(ptr + 21, "kill") == 0)
diff --git a/src/firejail/chroot.c b/src/firejail/chroot.c
index edc31cdea..0d4baa618 100644
--- a/src/firejail/chroot.c
+++ b/src/firejail/chroot.c
@@ -30,7 +30,7 @@
30#endif 30#endif
31 31
32#ifdef HAVE_GCOV 32#ifdef HAVE_GCOV
33#include <gcov.h> 33#include "../include/gcov_wrapper.h"
34#endif 34#endif
35 35
36// exit if error 36// exit if error
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index c84965074..9971d30b6 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; eithe r version 2 of the License, or 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
@@ -508,7 +508,7 @@ void logargs(int argc, char **argv) ;
508void logerr(const char *msg); 508void logerr(const char *msg);
509void set_nice(int inc); 509void set_nice(int inc);
510int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); 510int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode);
511void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); 511void copy_file_as_user(const char *srcname, const char *destname, mode_t mode);
512void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); 512void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode);
513void touch_file_as_user(const char *fname, mode_t mode); 513void touch_file_as_user(const char *fname, mode_t mode);
514int is_dir(const char *fname); 514int is_dir(const char *fname);
@@ -810,6 +810,7 @@ extern char *xvfb_extra_params;
810extern char *netfilter_default; 810extern char *netfilter_default;
811extern unsigned long join_timeout; 811extern unsigned long join_timeout;
812extern char *config_seccomp_error_action_str; 812extern char *config_seccomp_error_action_str;
813extern char *config_seccomp_filter_add;
813extern char **whitelist_reject_topdirs; 814extern char **whitelist_reject_topdirs;
814 815
815int checkcfg(int val); 816int checkcfg(int val);
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 4ae7dbfa4..806fa9249 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -34,7 +34,7 @@
34#endif 34#endif
35 35
36#ifdef HAVE_GCOV 36#ifdef HAVE_GCOV
37#include <gcov.h> 37#include "../include/gcov_wrapper.h"
38#endif 38#endif
39 39
40#define MAX_BUF 4096 40#define MAX_BUF 4096
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index eab952eb8..0ed476063 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -34,12 +34,13 @@
34#define O_PATH 010000000 34#define O_PATH 010000000
35#endif 35#endif
36 36
37static void skel(const char *homedir, uid_t u, gid_t g) { 37static void skel(const char *homedir) {
38 char *fname; 38 EUID_ASSERT();
39 39
40 // zsh 40 // zsh
41 if (!arg_shell_none && (strcmp(cfg.shell,"/usr/bin/zsh") == 0 || strcmp(cfg.shell,"/bin/zsh") == 0)) { 41 if (!arg_shell_none && (strcmp(cfg.shell,"/usr/bin/zsh") == 0 || strcmp(cfg.shell,"/bin/zsh") == 0)) {
42 // copy skel files 42 // copy skel files
43 char *fname;
43 if (asprintf(&fname, "%s/.zshrc", homedir) == -1) 44 if (asprintf(&fname, "%s/.zshrc", homedir) == -1)
44 errExit("asprintf"); 45 errExit("asprintf");
45 // don't copy it if we already have the file 46 // don't copy it if we already have the file
@@ -50,7 +51,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
50 exit(1); 51 exit(1);
51 } 52 }
52 if (access("/etc/skel/.zshrc", R_OK) == 0) { 53 if (access("/etc/skel/.zshrc", R_OK) == 0) {
53 copy_file_as_user("/etc/skel/.zshrc", fname, u, g, 0644); // regular user 54 copy_file_as_user("/etc/skel/.zshrc", fname, 0644); // regular user
54 fs_logger("clone /etc/skel/.zshrc"); 55 fs_logger("clone /etc/skel/.zshrc");
55 fs_logger2("clone", fname); 56 fs_logger2("clone", fname);
56 } 57 }
@@ -64,6 +65,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
64 // csh 65 // csh
65 else if (!arg_shell_none && strcmp(cfg.shell,"/bin/csh") == 0) { 66 else if (!arg_shell_none && strcmp(cfg.shell,"/bin/csh") == 0) {
66 // copy skel files 67 // copy skel files
68 char *fname;
67 if (asprintf(&fname, "%s/.cshrc", homedir) == -1) 69 if (asprintf(&fname, "%s/.cshrc", homedir) == -1)
68 errExit("asprintf"); 70 errExit("asprintf");
69 // don't copy it if we already have the file 71 // don't copy it if we already have the file
@@ -74,7 +76,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
74 exit(1); 76 exit(1);
75 } 77 }
76 if (access("/etc/skel/.cshrc", R_OK) == 0) { 78 if (access("/etc/skel/.cshrc", R_OK) == 0) {
77 copy_file_as_user("/etc/skel/.cshrc", fname, u, g, 0644); // regular user 79 copy_file_as_user("/etc/skel/.cshrc", fname, 0644); // regular user
78 fs_logger("clone /etc/skel/.cshrc"); 80 fs_logger("clone /etc/skel/.cshrc");
79 fs_logger2("clone", fname); 81 fs_logger2("clone", fname);
80 } 82 }
@@ -88,6 +90,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
88 // bash etc. 90 // bash etc.
89 else { 91 else {
90 // copy skel files 92 // copy skel files
93 char *fname;
91 if (asprintf(&fname, "%s/.bashrc", homedir) == -1) 94 if (asprintf(&fname, "%s/.bashrc", homedir) == -1)
92 errExit("asprintf"); 95 errExit("asprintf");
93 // don't copy it if we already have the file 96 // don't copy it if we already have the file
@@ -98,7 +101,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
98 exit(1); 101 exit(1);
99 } 102 }
100 if (access("/etc/skel/.bashrc", R_OK) == 0) { 103 if (access("/etc/skel/.bashrc", R_OK) == 0) {
101 copy_file_as_user("/etc/skel/.bashrc", fname, u, g, 0644); // regular user 104 copy_file_as_user("/etc/skel/.bashrc", fname, 0644); // regular user
102 fs_logger("clone /etc/skel/.bashrc"); 105 fs_logger("clone /etc/skel/.bashrc");
103 fs_logger2("clone", fname); 106 fs_logger2("clone", fname);
104 } 107 }
@@ -108,6 +111,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
108} 111}
109 112
110static int store_xauthority(void) { 113static int store_xauthority(void) {
114 EUID_ASSERT();
111 if (arg_x11_block) 115 if (arg_x11_block)
112 return 0; 116 return 0;
113 117
@@ -118,7 +122,7 @@ static int store_xauthority(void) {
118 errExit("asprintf"); 122 errExit("asprintf");
119 123
120 struct stat s; 124 struct stat s;
121 if (lstat_as_user(src, &s) == 0) { 125 if (lstat(src, &s) == 0) {
122 if (S_ISLNK(s.st_mode)) { 126 if (S_ISLNK(s.st_mode)) {
123 fwarning("invalid .Xauthority file\n"); 127 fwarning("invalid .Xauthority file\n");
124 free(src); 128 free(src);
@@ -126,6 +130,7 @@ static int store_xauthority(void) {
126 } 130 }
127 131
128 // create an empty file as root, and change ownership to user 132 // create an empty file as root, and change ownership to user
133 EUID_ROOT();
129 FILE *fp = fopen(dest, "we"); 134 FILE *fp = fopen(dest, "we");
130 if (fp) { 135 if (fp) {
131 fprintf(fp, "\n"); 136 fprintf(fp, "\n");
@@ -134,10 +139,11 @@ static int store_xauthority(void) {
134 } 139 }
135 else 140 else
136 errExit("fopen"); 141 errExit("fopen");
142 EUID_USER();
137 143
138 copy_file_as_user(src, dest, getuid(), getgid(), 0600); // regular user 144 copy_file_as_user(src, dest, 0600); // regular user
139 fs_logger2("clone", dest);
140 selinux_relabel_path(dest, src); 145 selinux_relabel_path(dest, src);
146 fs_logger2("clone", dest);
141 free(src); 147 free(src);
142 return 1; // file copied 148 return 1; // file copied
143 } 149 }
@@ -147,6 +153,7 @@ static int store_xauthority(void) {
147} 153}
148 154
149static int store_asoundrc(void) { 155static int store_asoundrc(void) {
156 EUID_ASSERT();
150 if (arg_nosound) 157 if (arg_nosound)
151 return 0; 158 return 0;
152 159
@@ -157,11 +164,11 @@ static int store_asoundrc(void) {
157 errExit("asprintf"); 164 errExit("asprintf");
158 165
159 struct stat s; 166 struct stat s;
160 if (lstat_as_user(src, &s) == 0) { 167 if (lstat(src, &s) == 0) {
161 if (S_ISLNK(s.st_mode)) { 168 if (S_ISLNK(s.st_mode)) {
162 // make sure the real path of the file is inside the home directory 169 // make sure the real path of the file is inside the home directory
163 /* coverity[toctou] */ 170 /* coverity[toctou] */
164 char *rp = realpath_as_user(src); 171 char *rp = realpath(src, NULL);
165 if (!rp) { 172 if (!rp) {
166 fprintf(stderr, "Error: Cannot access %s\n", src); 173 fprintf(stderr, "Error: Cannot access %s\n", src);
167 exit(1); 174 exit(1);
@@ -174,6 +181,7 @@ static int store_asoundrc(void) {
174 } 181 }
175 182
176 // create an empty file as root, and change ownership to user 183 // create an empty file as root, and change ownership to user
184 EUID_ROOT();
177 FILE *fp = fopen(dest, "we"); 185 FILE *fp = fopen(dest, "we");
178 if (fp) { 186 if (fp) {
179 fprintf(fp, "\n"); 187 fprintf(fp, "\n");
@@ -182,10 +190,11 @@ static int store_asoundrc(void) {
182 } 190 }
183 else 191 else
184 errExit("fopen"); 192 errExit("fopen");
193 EUID_USER();
185 194
186 copy_file_as_user(src, dest, getuid(), getgid(), 0644); // regular user 195 copy_file_as_user(src, dest, 0644); // regular user
187 selinux_relabel_path(dest, src);
188 fs_logger2("clone", dest); 196 fs_logger2("clone", dest);
197 selinux_relabel_path(dest, src);
189 free(src); 198 free(src);
190 return 1; // file copied 199 return 1; // file copied
191 } 200 }
@@ -195,6 +204,7 @@ static int store_asoundrc(void) {
195} 204}
196 205
197static void copy_xauthority(void) { 206static void copy_xauthority(void) {
207 EUID_ASSERT();
198 // copy XAUTHORITY_FILE in the new home directory 208 // copy XAUTHORITY_FILE in the new home directory
199 char *src = RUN_XAUTHORITY_FILE ; 209 char *src = RUN_XAUTHORITY_FILE ;
200 char *dest; 210 char *dest;
@@ -207,16 +217,18 @@ static void copy_xauthority(void) {
207 exit(1); 217 exit(1);
208 } 218 }
209 219
210 copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); // regular user 220 copy_file_as_user(src, dest, S_IRUSR | S_IWUSR); // regular user
211 selinux_relabel_path(dest, src);
212 fs_logger2("clone", dest); 221 fs_logger2("clone", dest);
222 selinux_relabel_path(dest, dest);
213 free(dest); 223 free(dest);
214 224
215 // delete the temporary file 225 EUID_ROOT();
216 unlink(src); 226 unlink(src); // delete the temporary file
227 EUID_USER();
217} 228}
218 229
219static void copy_asoundrc(void) { 230static void copy_asoundrc(void) {
231 EUID_ASSERT();
220 // copy ASOUNDRC_FILE in the new home directory 232 // copy ASOUNDRC_FILE in the new home directory
221 char *src = RUN_ASOUNDRC_FILE ; 233 char *src = RUN_ASOUNDRC_FILE ;
222 char *dest; 234 char *dest;
@@ -229,13 +241,14 @@ static void copy_asoundrc(void) {
229 exit(1); 241 exit(1);
230 } 242 }
231 243
232 copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); // regular user 244 copy_file_as_user(src, dest, S_IRUSR | S_IWUSR); // regular user
233 selinux_relabel_path(dest, src);
234 fs_logger2("clone", dest); 245 fs_logger2("clone", dest);
246 selinux_relabel_path(dest, dest);
235 free(dest); 247 free(dest);
236 248
237 // delete the temporary file 249 EUID_ROOT();
238 unlink(src); 250 unlink(src); // delete the temporary file
251 EUID_USER();
239} 252}
240 253
241// private mode (--private=homedir): 254// private mode (--private=homedir):
@@ -248,18 +261,18 @@ void fs_private_homedir(void) {
248 char *private_homedir = cfg.home_private; 261 char *private_homedir = cfg.home_private;
249 assert(homedir); 262 assert(homedir);
250 assert(private_homedir); 263 assert(private_homedir);
264 EUID_ASSERT();
265
266 uid_t u = getuid();
267 // gid_t g = getgid();
251 268
252 int xflag = store_xauthority(); 269 int xflag = store_xauthority();
253 int aflag = store_asoundrc(); 270 int aflag = store_asoundrc();
254 271
255 uid_t u = getuid();
256 gid_t g = getgid();
257
258 // mount bind private_homedir on top of homedir 272 // mount bind private_homedir on top of homedir
259 if (arg_debug) 273 if (arg_debug)
260 printf("Mount-bind %s on top of %s\n", private_homedir, homedir); 274 printf("Mount-bind %s on top of %s\n", private_homedir, homedir);
261 // get file descriptors for homedir and private_homedir, fails if there is any symlink 275 // get file descriptors for homedir and private_homedir, fails if there is any symlink
262 EUID_USER();
263 int src = safer_openat(-1, private_homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); 276 int src = safer_openat(-1, private_homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
264 if (src == -1) 277 if (src == -1)
265 errExit("opening private directory"); 278 errExit("opening private directory");
@@ -287,6 +300,7 @@ void fs_private_homedir(void) {
287 EUID_ROOT(); 300 EUID_ROOT();
288 if (bind_mount_by_fd(src, dst)) 301 if (bind_mount_by_fd(src, dst))
289 errExit("mount bind"); 302 errExit("mount bind");
303 EUID_USER();
290 304
291 // check /proc/self/mountinfo to confirm the mount is ok 305 // check /proc/self/mountinfo to confirm the mount is ok
292 MountData *mptr = get_last_mount(); 306 MountData *mptr = get_last_mount();
@@ -305,6 +319,7 @@ void fs_private_homedir(void) {
305// if (chmod(homedir, s.st_mode) == -1) 319// if (chmod(homedir, s.st_mode) == -1)
306// errExit("mount-bind chmod"); 320// errExit("mount-bind chmod");
307 321
322 EUID_ROOT();
308 if (u != 0) { 323 if (u != 0) {
309 // mask /root 324 // mask /root
310 if (arg_debug) 325 if (arg_debug)
@@ -323,8 +338,9 @@ void fs_private_homedir(void) {
323 selinux_relabel_path("/home", "/home"); 338 selinux_relabel_path("/home", "/home");
324 fs_logger("tmpfs /home"); 339 fs_logger("tmpfs /home");
325 } 340 }
341 EUID_USER();
326 342
327 skel(homedir, u, g); 343 skel(homedir);
328 if (xflag) 344 if (xflag)
329 copy_xauthority(); 345 copy_xauthority();
330 if (aflag) 346 if (aflag)
@@ -339,12 +355,15 @@ void fs_private_homedir(void) {
339void fs_private(void) { 355void fs_private(void) {
340 char *homedir = cfg.homedir; 356 char *homedir = cfg.homedir;
341 assert(homedir); 357 assert(homedir);
358 EUID_ASSERT();
359
342 uid_t u = getuid(); 360 uid_t u = getuid();
343 gid_t g = getgid(); 361 gid_t g = getgid();
344 362
345 int xflag = store_xauthority(); 363 int xflag = store_xauthority();
346 int aflag = store_asoundrc(); 364 int aflag = store_asoundrc();
347 365
366 EUID_ROOT();
348 // mask /root 367 // mask /root
349 if (arg_debug) 368 if (arg_debug)
350 printf("Mounting a new /root directory\n"); 369 printf("Mounting a new /root directory\n");
@@ -387,8 +406,9 @@ void fs_private(void) {
387 406
388 selinux_relabel_path(homedir, homedir); 407 selinux_relabel_path(homedir, homedir);
389 } 408 }
409 EUID_USER();
390 410
391 skel(homedir, u, g); 411 skel(homedir);
392 if (xflag) 412 if (xflag)
393 copy_xauthority(); 413 copy_xauthority();
394 if (aflag) 414 if (aflag)
@@ -530,26 +550,29 @@ static void duplicate(char *name) {
530// set skel files, 550// set skel files,
531// restore .Xauthority 551// restore .Xauthority
532void fs_private_home_list(void) { 552void fs_private_home_list(void) {
533 timetrace_start();
534
535 char *homedir = cfg.homedir; 553 char *homedir = cfg.homedir;
536 char *private_list = cfg.home_private_keep; 554 char *private_list = cfg.home_private_keep;
537 assert(homedir); 555 assert(homedir);
538 assert(private_list); 556 assert(private_list);
557 EUID_ASSERT();
539 558
540 int xflag = store_xauthority(); 559 timetrace_start();
541 int aflag = store_asoundrc();
542 560
543 uid_t uid = getuid(); 561 uid_t uid = getuid();
544 gid_t gid = getgid(); 562 gid_t gid = getgid();
545 563
564 int xflag = store_xauthority();
565 int aflag = store_asoundrc();
566
546 // create /run/firejail/mnt/home directory 567 // create /run/firejail/mnt/home directory
568 EUID_ROOT();
547 mkdir_attr(RUN_HOME_DIR, 0755, uid, gid); 569 mkdir_attr(RUN_HOME_DIR, 0755, uid, gid);
548 selinux_relabel_path(RUN_HOME_DIR, homedir); 570 selinux_relabel_path(RUN_HOME_DIR, homedir);
571
549 fs_logger_print(); // save the current log 572 fs_logger_print(); // save the current log
573 EUID_USER();
550 574
551 // copy the list of files in the new home directory 575 // copy the list of files in the new home directory
552 EUID_USER();
553 if (arg_debug) 576 if (arg_debug)
554 printf("Copying files in the new home:\n"); 577 printf("Copying files in the new home:\n");
555 char *dlist = strdup(cfg.home_private_keep); 578 char *dlist = strdup(cfg.home_private_keep);
@@ -587,6 +610,7 @@ void fs_private_home_list(void) {
587 EUID_ROOT(); 610 EUID_ROOT();
588 if (bind_mount_path_to_fd(RUN_HOME_DIR, fd)) 611 if (bind_mount_path_to_fd(RUN_HOME_DIR, fd))
589 errExit("mount bind"); 612 errExit("mount bind");
613 EUID_USER();
590 close(fd); 614 close(fd);
591 615
592 // check /proc/self/mountinfo to confirm the mount is ok 616 // check /proc/self/mountinfo to confirm the mount is ok
@@ -595,11 +619,7 @@ void fs_private_home_list(void) {
595 errLogExit("invalid private-home mount"); 619 errLogExit("invalid private-home mount");
596 fs_logger2("tmpfs", homedir); 620 fs_logger2("tmpfs", homedir);
597 621
598 // mask RUN_HOME_DIR, it is writable and not noexec 622 EUID_ROOT();
599 if (mount("tmpfs", RUN_HOME_DIR, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
600 errExit("mounting tmpfs");
601 fs_logger2("tmpfs", RUN_HOME_DIR);
602
603 if (uid != 0) { 623 if (uid != 0) {
604 // mask /root 624 // mask /root
605 if (arg_debug) 625 if (arg_debug)
@@ -619,7 +639,12 @@ void fs_private_home_list(void) {
619 fs_logger("tmpfs /home"); 639 fs_logger("tmpfs /home");
620 } 640 }
621 641
622 skel(homedir, uid, gid); 642 // mask RUN_HOME_DIR, it is writable and not noexec
643 if (mount("tmpfs", RUN_HOME_DIR, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
644 errExit("mounting tmpfs");
645 EUID_USER();
646
647 skel(homedir);
623 if (xflag) 648 if (xflag)
624 copy_xauthority(); 649 copy_xauthority();
625 if (aflag) 650 if (aflag)
diff --git a/src/firejail/fs_mkdir.c b/src/firejail/fs_mkdir.c
index bbc2aa938..0195435f9 100644
--- a/src/firejail/fs_mkdir.c
+++ b/src/firejail/fs_mkdir.c
@@ -26,7 +26,7 @@
26#include <string.h> 26#include <string.h>
27 27
28#ifdef HAVE_GCOV 28#ifdef HAVE_GCOV
29#include <gcov.h> 29#include "../include/gcov_wrapper.h"
30#endif 30#endif
31 31
32static void check(const char *fname) { 32static void check(const char *fname) {
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 370035a4d..943f275de 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -374,9 +374,11 @@ static void tmpfs_topdirs(const TopDir *topdirs) {
374 } 374 }
375 375
376 // user home directory 376 // user home directory
377 if (tmpfs_home) 377 if (tmpfs_home) {
378 // checks owner if outside /home 378 EUID_USER();
379 fs_private(); 379 fs_private(); // checks owner if outside /home
380 EUID_ROOT();
381 }
380 382
381 // /run/user/$UID directory 383 // /run/user/$UID directory
382 if (tmpfs_runuser) { 384 if (tmpfs_runuser) {
diff --git a/src/firejail/ls.c b/src/firejail/ls.c
index 6ee557648..ae7e89741 100644
--- a/src/firejail/ls.c
+++ b/src/firejail/ls.c
@@ -32,7 +32,7 @@
32//#include <stdlib.h> 32//#include <stdlib.h>
33 33
34#ifdef HAVE_GCOV 34#ifdef HAVE_GCOV
35#include <gcov.h> 35#include "../include/gcov_wrapper.h"
36#endif 36#endif
37 37
38// uid/gid cache 38// uid/gid cache
diff --git a/src/firejail/main.c b/src/firejail/main.c
index b376095f1..7b32f6f07 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -45,7 +45,7 @@
45#endif 45#endif
46 46
47#ifdef HAVE_GCOV 47#ifdef HAVE_GCOV
48#include <gcov.h> 48#include "../include/gcov_wrapper.h"
49#endif 49#endif
50 50
51#ifdef __ia64__ 51#ifdef __ia64__
@@ -967,7 +967,7 @@ void filter_add_blacklist_override(int fd, int syscall, int arg, void *ptrarg, b
967static int check_postexec(const char *list) { 967static int check_postexec(const char *list) {
968 char *prelist, *postlist; 968 char *prelist, *postlist;
969 969
970 if (list) { 970 if (list && list[0]) {
971 syscalls_in_list(list, "@default-keep", -1, &prelist, &postlist, true); 971 syscalls_in_list(list, "@default-keep", -1, &prelist, &postlist, true);
972 if (postlist) 972 if (postlist)
973 return 1; 973 return 1;
@@ -2895,6 +2895,15 @@ int main(int argc, char **argv, char **envp) {
2895 // check network configuration options - it will exit if anything went wrong 2895 // check network configuration options - it will exit if anything went wrong
2896 net_check_cfg(); 2896 net_check_cfg();
2897 2897
2898 // customization of default seccomp filter
2899 if (config_seccomp_filter_add) {
2900 if (arg_seccomp && !cfg.seccomp_list_keep && !cfg.seccomp_list_drop)
2901 profile_list_augment(&cfg.seccomp_list, config_seccomp_filter_add);
2902
2903 if (arg_seccomp32 && !cfg.seccomp_list_keep32 && !cfg.seccomp_list_drop32)
2904 profile_list_augment(&cfg.seccomp_list32, config_seccomp_filter_add);
2905 }
2906
2898 if (arg_seccomp) 2907 if (arg_seccomp)
2899 arg_seccomp_postexec = check_postexec(cfg.seccomp_list) || check_postexec(cfg.seccomp_list_drop); 2908 arg_seccomp_postexec = check_postexec(cfg.seccomp_list) || check_postexec(cfg.seccomp_list_drop);
2900 2909
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 5b1478918..7b21eb387 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -24,7 +24,7 @@
24#include <sys/stat.h> 24#include <sys/stat.h>
25 25
26#ifdef HAVE_GCOV 26#ifdef HAVE_GCOV
27#include <gcov.h> 27#include "../include/gcov_wrapper.h"
28#endif 28#endif
29 29
30extern char *xephyr_screen; 30extern char *xephyr_screen;
diff --git a/src/firejail/rlimit.c b/src/firejail/rlimit.c
index dd6fec972..2666486fa 100644
--- a/src/firejail/rlimit.c
+++ b/src/firejail/rlimit.c
@@ -22,7 +22,7 @@
22#include <sys/resource.h> 22#include <sys/resource.h>
23 23
24#ifdef HAVE_GCOV 24#ifdef HAVE_GCOV
25#include <gcov.h> 25#include "../include/gcov_wrapper.h"
26#endif 26#endif
27 27
28void set_rlimits(void) { 28void set_rlimits(void) {
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index e06ba3617..99abce57f 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -50,7 +50,7 @@
50#endif 50#endif
51 51
52#ifdef HAVE_GCOV 52#ifdef HAVE_GCOV
53#include <gcov.h> 53#include "../include/gcov_wrapper.h"
54#endif 54#endif
55 55
56static int force_nonewprivs = 0; 56static int force_nonewprivs = 0;
@@ -840,6 +840,7 @@ int sandbox(void* sandbox_arg) {
840 // private mode 840 // private mode
841 //**************************** 841 //****************************
842 if (arg_private) { 842 if (arg_private) {
843 EUID_USER();
843 if (cfg.home_private) { // --private= 844 if (cfg.home_private) { // --private=
844 if (cfg.chrootdir) 845 if (cfg.chrootdir)
845 fwarning("private=directory feature is disabled in chroot\n"); 846 fwarning("private=directory feature is disabled in chroot\n");
@@ -858,6 +859,7 @@ int sandbox(void* sandbox_arg) {
858 } 859 }
859 else // --private 860 else // --private
860 fs_private(); 861 fs_private();
862 EUID_ROOT();
861 } 863 }
862 864
863 if (arg_private_dev) 865 if (arg_private_dev)
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c
index 9670fe816..3d9bf9082 100644
--- a/src/firejail/seccomp.c
+++ b/src/firejail/seccomp.c
@@ -208,7 +208,8 @@ int seccomp_filter_drop(bool native) {
208 // - seccomp 208 // - seccomp
209 if (cfg.seccomp_list_drop == NULL) { 209 if (cfg.seccomp_list_drop == NULL) {
210 // default seccomp if error action is not changed 210 // default seccomp if error action is not changed
211 if (cfg.seccomp_list == NULL && arg_seccomp_error_action == DEFAULT_SECCOMP_ERROR_ACTION) { 211 if ((cfg.seccomp_list == NULL || cfg.seccomp_list[0] == '\0')
212 && arg_seccomp_error_action == DEFAULT_SECCOMP_ERROR_ACTION) {
212 if (arg_seccomp_block_secondary) 213 if (arg_seccomp_block_secondary)
213 seccomp_filter_block_secondary(); 214 seccomp_filter_block_secondary();
214 else { 215 else {
@@ -261,7 +262,7 @@ int seccomp_filter_drop(bool native) {
261 } 262 }
262 263
263 // build the seccomp filter as a regular user 264 // build the seccomp filter as a regular user
264 if (list) 265 if (list && list[0])
265 if (arg_allow_debuggers) 266 if (arg_allow_debuggers)
266 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 7, 267 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 7,
267 PATH_FSECCOMP, command, "drop", filter, postexec_filter, list, "allow-debuggers"); 268 PATH_FSECCOMP, command, "drop", filter, postexec_filter, list, "allow-debuggers");
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 68b76b8e8..55998e6c3 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -45,7 +45,7 @@
45#endif 45#endif
46 46
47#ifdef HAVE_GCOV 47#ifdef HAVE_GCOV
48#include <gcov.h> 48#include "../include/gcov_wrapper.h"
49#endif 49#endif
50 50
51#define MAX_GROUPS 1024 51#define MAX_GROUPS 1024
@@ -370,7 +370,7 @@ int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, m
370} 370}
371 371
372// return -1 if error, 0 if no error 372// return -1 if error, 0 if no error
373void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode) { 373void copy_file_as_user(const char *srcname, const char *destname, mode_t mode) {
374 pid_t child = fork(); 374 pid_t child = fork();
375 if (child < 0) 375 if (child < 0)
376 errExit("fork"); 376 errExit("fork");
@@ -378,8 +378,8 @@ void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid
378 // drop privileges 378 // drop privileges
379 drop_privs(0); 379 drop_privs(0);
380 380
381 // copy, set permissions and ownership 381 // copy, set permissions
382 int rv = copy_file(srcname, destname, uid, gid, mode); // already a regular user 382 int rv = copy_file(srcname, destname, -1, -1, mode); // already a regular user
383 if (rv) 383 if (rv)
384 fwarning("cannot copy %s\n", srcname); 384 fwarning("cannot copy %s\n", srcname);
385#ifdef HAVE_GCOV 385#ifdef HAVE_GCOV
@@ -1231,6 +1231,7 @@ unsigned extract_timeout(const char *str) {
1231} 1231}
1232 1232
1233void disable_file_or_dir(const char *fname) { 1233void disable_file_or_dir(const char *fname) {
1234 assert(geteuid() == 0);
1234 assert(fname); 1235 assert(fname);
1235 1236
1236 EUID_USER(); 1237 EUID_USER();
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index 0619ff380..896aa2fd3 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -1290,9 +1290,11 @@ void x11_xorg(void) {
1290 if (envar) { 1290 if (envar) {
1291 char *rp = realpath(envar, NULL); 1291 char *rp = realpath(envar, NULL);
1292 if (rp) { 1292 if (rp) {
1293 if (strcmp(rp, dest) != 0) 1293 if (strcmp(rp, dest) != 0) {
1294 // disable_file_or_dir returns with EUID 0 1294 EUID_ROOT();
1295 disable_file_or_dir(rp); 1295 disable_file_or_dir(rp);
1296 EUID_USER();
1297 }
1296 free(rp); 1298 free(rp);
1297 } 1299 }
1298 } 1300 }
diff --git a/src/firemon/interface.c b/src/firemon/interface.c
index b93d4a5a2..372cdee41 100644
--- a/src/firemon/interface.c
+++ b/src/firemon/interface.c
@@ -34,7 +34,7 @@
34//#include <linux/if_bridge.h> 34//#include <linux/if_bridge.h>
35 35
36#ifdef HAVE_GCOV 36#ifdef HAVE_GCOV
37#include <gcov.h> 37#include "../include/gcov_wrapper.h"
38#endif 38#endif
39 39
40// print IP addresses for all interfaces 40// print IP addresses for all interfaces
diff --git a/src/firemon/netstats.c b/src/firemon/netstats.c
index 23d228e26..bc951aa26 100644
--- a/src/firemon/netstats.c
+++ b/src/firemon/netstats.c
@@ -25,7 +25,7 @@
25#include <unistd.h> 25#include <unistd.h>
26 26
27#ifdef HAVE_GCOV 27#ifdef HAVE_GCOV
28#include <gcov.h> 28#include "../include/gcov_wrapper.h"
29#endif 29#endif
30 30
31#define MAXBUF 4096 31#define MAXBUF 4096
diff --git a/src/firemon/procevent.c b/src/firemon/procevent.c
index 4e809681e..79f487582 100644
--- a/src/firemon/procevent.c
+++ b/src/firemon/procevent.c
@@ -31,7 +31,7 @@
31#include <sys/uio.h> 31#include <sys/uio.h>
32 32
33#ifdef HAVE_GCOV 33#ifdef HAVE_GCOV
34#include <gcov.h> 34#include "../include/gcov_wrapper.h"
35#endif 35#endif
36 36
37#define PIDS_BUFLEN 4096 37#define PIDS_BUFLEN 4096
diff --git a/src/firemon/top.c b/src/firemon/top.c
index 9d6f34991..d0f911e60 100644
--- a/src/firemon/top.c
+++ b/src/firemon/top.c
@@ -25,7 +25,7 @@
25#include <unistd.h> 25#include <unistd.h>
26 26
27#ifdef HAVE_GCOV 27#ifdef HAVE_GCOV
28#include <gcov.h> 28#include "../include/gcov_wrapper.h"
29#endif 29#endif
30 30
31static unsigned pgs_rss = 0; 31static unsigned pgs_rss = 0;
diff --git a/src/include/gcov_wrapper.h b/src/include/gcov_wrapper.h
new file mode 100644
index 000000000..2f409309d
--- /dev/null
+++ b/src/include/gcov_wrapper.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) 2021 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifndef GCOV_WRAPPER_H
22#define GCOV_WRAPPER_H
23
24#include <gcov.h>
25
26/*
27 * __gcov_flush was removed on gcc 11.1.0 (as it's no longer needed), but it
28 * appears to be the safe/"correct" way to do things on previous versions (as
29 * it ensured proper locking, which is now done elsewhere). Thus, keep using
30 * it in the code and ensure that it exists, in order to support gcc <11.1.0
31 * and gcc >=11.1.0, respectively.
32 */
33#if __GNUC__ > 11 || (__GNUC__ == 11 && __GNUC_MINOR__ >= 1)
34static void __gcov_flush(void) {
35 __gcov_dump();
36 __gcov_reset();
37}
38#endif
39
40#endif /* GCOV_WRAPPER_H */
diff --git a/src/lib/syscall.c b/src/lib/syscall.c
index b3131ac17..d0d9ff5aa 100644
--- a/src/lib/syscall.c
+++ b/src/lib/syscall.c
@@ -253,9 +253,6 @@ static const SyscallGroupList sysgroups[] = {
253#ifdef SYS_fanotify_init 253#ifdef SYS_fanotify_init
254 "fanotify_init," 254 "fanotify_init,"
255#endif 255#endif
256#ifdef SYS_kcmp
257 "kcmp,"
258#endif
259#ifdef SYS_add_key 256#ifdef SYS_add_key
260 "add_key," 257 "add_key,"
261#endif 258#endif
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index d18811316..0462705c0 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -2178,7 +2178,7 @@ $ firejail \-\-net=eth0 \-\-scan
2178.TP 2178.TP
2179\fB\-\-seccomp 2179\fB\-\-seccomp
2180Enable seccomp filter and blacklist the syscalls in the default list, 2180Enable seccomp filter and blacklist the syscalls in the default list,
2181which is @default-nodebuggers unless allow-debuggers is specified, 2181which is @default-nodebuggers unless \-\-allow-debuggers is specified,
2182then it is @default. 2182then it is @default.
2183 2183
2184.br 2184.br
@@ -2189,18 +2189,13 @@ system call groups are defined: @aio, @basic-io, @chown, @clock,
2189@network-io, @obsolete, @privileged, @process, @raw-io, @reboot, 2189@network-io, @obsolete, @privileged, @process, @raw-io, @reboot,
2190@resources, @setuid, @swap, @sync, @system-service and @timer. 2190@resources, @setuid, @swap, @sync, @system-service and @timer.
2191More information about groups can be found in /usr/share/doc/firejail/syscalls.txt 2191More information about groups can be found in /usr/share/doc/firejail/syscalls.txt
2192 2192.br
2193In addition, a system call can be specified by its number instead of
2194name with prefix $, so for example $165 would be equal to mount on i386.
2195Exceptions can be allowed with prefix !.
2196 2193
2197.br 2194.br
2198System architecture is strictly imposed only if flag 2195System architecture is strictly imposed only if flag
2199\-\-seccomp.block-secondary is used. The filter is applied at run time 2196\-\-seccomp.block-secondary is used. The filter is applied at run time
2200only if the correct architecture was detected. For the case of I386 2197only if the correct architecture was detected. For the case of I386
2201and AMD64 both 32-bit and 64-bit filters are installed. On a 64 bit 2198and AMD64 both 32-bit and 64-bit filters are installed.
2202architecture, an additional filter for 32 bit system calls can be
2203installed with \-\-seccomp.32.
2204.br 2199.br
2205 2200
2206.br 2201.br
@@ -2211,11 +2206,18 @@ Firejail will print seccomp violations to the audit log if the kernel was compil
2211Example: 2206Example:
2212.br 2207.br
2213$ firejail \-\-seccomp 2208$ firejail \-\-seccomp
2209.br
2210
2211.br
2212The default list can be customized, see \-\-seccomp= for a description. It can be customized
2213also globally in /etc/firejail/firejail.config file.
2214
2214.TP 2215.TP
2215\fB\-\-seccomp=syscall,@group,!syscall2 2216\fB\-\-seccomp=syscall,@group,!syscall2
2216Enable seccomp filter, whitelist "syscall2", but blacklist the default 2217Enable seccomp filter, blacklist the default list and the syscalls or syscall groups
2217list and the syscalls or syscall groups specified by the 2218specified by the command, but don't blacklist "syscall2". On a 64 bit
2218command. 2219architecture, an additional filter for 32 bit system calls can be
2220installed with \-\-seccomp.32.
2219.br 2221.br
2220 2222
2221.br 2223.br
@@ -2225,6 +2227,13 @@ $ firejail \-\-seccomp=utime,utimensat,utimes firefox
2225.br 2227.br
2226$ firejail \-\-seccomp=@clock,mkdir,unlinkat transmission-gtk 2228$ firejail \-\-seccomp=@clock,mkdir,unlinkat transmission-gtk
2227.br 2229.br
2230$ firejail '\-\-seccomp=@ipc,!pipe,!pipe2' audacious
2231.br
2232
2233.br
2234Syscalls can be specified by their number if prefix $ is added,
2235so for example $165 would be equal to mount on i386.
2236.br
2228 2237
2229.br 2238.br
2230Instead of dropping the syscall by returning EPERM, another error 2239Instead of dropping the syscall by returning EPERM, another error
@@ -2237,6 +2246,7 @@ by using \fBsyscall:kill\fR syntax, or the attempt may be logged with
2237 2246
2238.br 2247.br
2239Example: 2248Example:
2249.br
2240$ firejail \-\-seccomp=unlinkat:ENOENT,utimensat,utimes 2250$ firejail \-\-seccomp=unlinkat:ENOENT,utimensat,utimes
2241.br 2251.br
2242Parent pid 10662, child pid 10663 2252Parent pid 10662, child pid 10663
@@ -2245,9 +2255,13 @@ Child process initialized
2245.br 2255.br
2246$ touch testfile 2256$ touch testfile
2247.br 2257.br
2258$ ls testfile
2259.br
2260testfile
2261.br
2248$ rm testfile 2262$ rm testfile
2249.br 2263.br
2250rm: cannot remove `testfile': Operation not permitted 2264rm: cannot remove `testfile': No such file or directory
2251.br 2265.br
2252 2266
2253.br 2267.br
@@ -2260,7 +2274,7 @@ filters.
2260.br 2274.br
2261Example: 2275Example:
2262.br 2276.br
2263$ firejail \-\-noprofile \-\-shell=none \-\-seccomp=execve bash 2277$ firejail \-\-noprofile \-\-shell=none \-\-seccomp=execve sh
2264.br 2278.br
2265Parent pid 32751, child pid 32752 2279Parent pid 32751, child pid 32752
2266.br 2280.br
@@ -2272,8 +2286,7 @@ Child process initialized in 46.44 ms
2272.br 2286.br
2273$ ls 2287$ ls
2274.br 2288.br
2275Bad system call 2289Operation not permitted
2276.br
2277 2290
2278.TP 2291.TP
2279\fB\-\-seccomp.block-secondary 2292\fB\-\-seccomp.block-secondary
@@ -2317,15 +2330,15 @@ Child process initialized
2317.br 2330.br
2318$ touch testfile 2331$ touch testfile
2319.br 2332.br
2333$ ls testfile
2334.br
2335testfile
2336.br
2320$ rm testfile 2337$ rm testfile
2321.br 2338.br
2322rm: cannot remove `testfile': Operation not permitted 2339rm: cannot remove `testfile': No such file or directory
2323.br 2340.br
2324 2341
2325
2326
2327
2328
2329.TP 2342.TP
2330\fB\-\-seccomp.keep=syscall,@group,!syscall2 2343\fB\-\-seccomp.keep=syscall,@group,!syscall2
2331Enable seccomp filter, blacklist all syscall not listed and "syscall2". 2344Enable seccomp filter, blacklist all syscall not listed and "syscall2".