aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2020-08-19 01:46:35 +0200
committerLibravatar GitHub <noreply@github.com>2020-08-19 01:46:35 +0200
commitef9fdc4a1f367ec4a0495ca51e3ed44338df0408 (patch)
tree2e3e93b374815c085f9f76ccbc8532bf20fb9b74 /src
parentcat option (diff)
parentMerge pull request #3592 from onovy/signal-audio-video (diff)
downloadfirejail-ef9fdc4a1f367ec4a0495ca51e3ed44338df0408.tar.gz
firejail-ef9fdc4a1f367ec4a0495ca51e3ed44338df0408.tar.zst
firejail-ef9fdc4a1f367ec4a0495ca51e3ed44338df0408.zip
Merge branch 'master' into ls
Diffstat (limited to 'src')
-rw-r--r--src/firecfg/firecfg.config4
-rw-r--r--src/firejail/arp.c4
-rw-r--r--src/firejail/bandwidth.c24
-rw-r--r--src/firejail/checkcfg.c2
-rw-r--r--src/firejail/chroot.c3
-rw-r--r--src/firejail/firejail.h37
-rw-r--r--src/firejail/fs_dev.c3
-rw-r--r--src/firejail/join.c2
-rw-r--r--src/firejail/main.c5
-rw-r--r--src/firejail/output.c3
-rw-r--r--src/firejail/profile.c2
-rw-r--r--src/firejail/protocol.c2
-rw-r--r--src/firejail/sandbox.c3
-rw-r--r--src/firejail/sbox.c2
-rw-r--r--src/firejail/shutdown.c2
-rw-r--r--src/firejail/usage.c3
-rw-r--r--src/firejail/x11.c4
-rw-r--r--src/firemon/firemon.h6
-rw-r--r--src/firemon/procevent.c13
-rw-r--r--src/fseccomp/main.c4
-rw-r--r--src/include/seccomp.h2
-rw-r--r--src/include/syscall.h2
-rw-r--r--src/lib/errno.c2
-rw-r--r--src/man/firejail-profile.txt6
-rw-r--r--src/man/firejail.txt12
25 files changed, 84 insertions, 68 deletions
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config
index 05c5681d5..0574daae6 100644
--- a/src/firecfg/firecfg.config
+++ b/src/firecfg/firecfg.config
@@ -327,6 +327,9 @@ gradio
327gramps 327gramps
328gravity-beams-and-evaporating-stars 328gravity-beams-and-evaporating-stars
329gthumb 329gthumb
330gtk-youtube-viewer
331gtk2-youtube-viewer
332gtk3-youtube-viewer
330guayadeque 333guayadeque
331gucharmap 334gucharmap
332gummi 335gummi
@@ -816,6 +819,7 @@ xviewer
816yandex-browser 819yandex-browser
817yelp 820yelp
818youtube-dl 821youtube-dl
822youtube-viewer
819zaproxy 823zaproxy
820zart 824zart
821zathura 825zathura
diff --git a/src/firejail/arp.c b/src/firejail/arp.c
index 3714af9a3..f88d0a1dd 100644
--- a/src/firejail/arp.c
+++ b/src/firejail/arp.c
@@ -239,9 +239,7 @@ int arp_check(const char *dev, uint32_t destaddr) {
239 } 239 }
240 } 240 }
241 241
242 // it will never get here! 242 __builtin_unreachable();
243 close(sock);
244 return -1;
245} 243}
246 244
247// assign a random IP address and check it 245// assign a random IP address and check it
diff --git a/src/firejail/bandwidth.c b/src/firejail/bandwidth.c
index edef823fd..6fd0b53ef 100644
--- a/src/firejail/bandwidth.c
+++ b/src/firejail/bandwidth.c
@@ -327,6 +327,15 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in
327 devname = strdup(buf + len + 1); 327 devname = strdup(buf + len + 1);
328 if (!devname) 328 if (!devname)
329 errExit("strdup"); 329 errExit("strdup");
330 // double-check device name
331 size_t i;
332 for (i = 0; devname[i]; i++) {
333 if (isalnum((unsigned char) devname[i]) == 0 &&
334 devname[i] != '-') {
335 fprintf(stderr, "Error: name of network device is invalid\n");
336 exit(1);
337 }
338 }
330 // check device in namespace 339 // check device in namespace
331 if (if_nametoindex(devname) == 0) { 340 if (if_nametoindex(devname) == 0) {
332 fprintf(stderr, "Error: cannot find network device %s\n", devname); 341 fprintf(stderr, "Error: cannot find network device %s\n", devname);
@@ -354,6 +363,7 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in
354 } 363 }
355 bandwidth_remove(pid, devname); 364 bandwidth_remove(pid, devname);
356 } 365 }
366 else assert(strcmp(command, "status") == 0);
357 367
358 // build fshaper.sh command 368 // build fshaper.sh command
359 char *cmd = NULL; 369 char *cmd = NULL;
@@ -375,26 +385,16 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in
375 } 385 }
376 assert(cmd); 386 assert(cmd);
377 387
378 // wipe out environment variables
379 environ = NULL;
380
381 //************************ 388 //************************
382 // build command 389 // build command
383 //************************ 390 //************************
384 // elevate privileges
385 if (setreuid(0, 0))
386 errExit("setreuid");
387 if (setregid(0, 0))
388 errExit("setregid");
389
390 char *arg[4]; 391 char *arg[4];
391 arg[0] = "/bin/sh"; 392 arg[0] = "/bin/sh";
392 arg[1] = "-c"; 393 arg[1] = "-c";
393 arg[2] = cmd; 394 arg[2] = cmd;
394 arg[3] = NULL; 395 arg[3] = NULL;
395 clearenv(); 396 clearenv();
396 execvp(arg[0], arg); 397 sbox_exec_v(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, arg);
397 398
398 // it will never get here 399 // it will never get here!!
399 errExit("execvp");
400} 400}
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c
index 5d6b4af66..f6b3b3252 100644
--- a/src/firejail/checkcfg.c
+++ b/src/firejail/checkcfg.c
@@ -229,6 +229,8 @@ int checkcfg(int val) {
229#ifdef HAVE_SECCOMP 229#ifdef HAVE_SECCOMP
230 if (strcmp(ptr + 21, "kill") == 0) 230 if (strcmp(ptr + 21, "kill") == 0)
231 cfg_val[CFG_SECCOMP_ERROR_ACTION] = SECCOMP_RET_KILL; 231 cfg_val[CFG_SECCOMP_ERROR_ACTION] = SECCOMP_RET_KILL;
232 else if (strcmp(ptr + 21, "log") == 0)
233 cfg_val[CFG_SECCOMP_ERROR_ACTION] = SECCOMP_RET_LOG;
232 else { 234 else {
233 cfg_val[CFG_SECCOMP_ERROR_ACTION] = errno_find_name(ptr + 21); 235 cfg_val[CFG_SECCOMP_ERROR_ACTION] = errno_find_name(ptr + 21);
234 if (cfg_val[CFG_SECCOMP_ERROR_ACTION] == -1) 236 if (cfg_val[CFG_SECCOMP_ERROR_ACTION] == -1)
diff --git a/src/firejail/chroot.c b/src/firejail/chroot.c
index cae52e20b..5fc6c8298 100644
--- a/src/firejail/chroot.c
+++ b/src/firejail/chroot.c
@@ -165,7 +165,8 @@ void fs_chroot(const char *rootdir) {
165 close(fd); 165 close(fd);
166 166
167 // x11 167 // x11
168 if (getenv("FIREJAIL_X11")) { 168 // if users want this mount, they should set FIREJAIL_CHROOT_X11
169 if (getenv("FIREJAIL_X11") || getenv("FIREJAIL_CHROOT_X11")) {
169 if (arg_debug) 170 if (arg_debug)
170 printf("Mounting /tmp/.X11-unix on chroot /tmp/.X11-unix\n"); 171 printf("Mounting /tmp/.X11-unix on chroot /tmp/.X11-unix\n");
171 check_subdir(parentfd, "tmp/.X11-unix", 0); 172 check_subdir(parentfd, "tmp/.X11-unix", 0);
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 56bdd7ec3..49d19e33d 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -186,7 +186,7 @@ typedef struct config_t {
186 char *seccomp_list_drop, *seccomp_list_drop32; // seccomp drop list 186 char *seccomp_list_drop, *seccomp_list_drop32; // seccomp drop list
187 char *seccomp_list_keep, *seccomp_list_keep32; // seccomp keep list 187 char *seccomp_list_keep, *seccomp_list_keep32; // seccomp keep list
188 char *protocol; // protocol list 188 char *protocol; // protocol list
189 char *seccomp_error_action; // error action: kill or errno 189 char *seccomp_error_action; // error action: kill, log or errno
190 190
191 // rlimits 191 // rlimits
192 long long unsigned rlimit_cpu; 192 long long unsigned rlimit_cpu;
@@ -371,14 +371,14 @@ char *guess_shell(void);
371 371
372// sandbox.c 372// sandbox.c
373int sandbox(void* sandbox_arg); 373int sandbox(void* sandbox_arg);
374void start_application(int no_sandbox, FILE *fp); 374void start_application(int no_sandbox, FILE *fp) __attribute__((noreturn));
375void set_apparmor(void); 375void set_apparmor(void);
376 376
377// network_main.c 377// network_main.c
378void net_configure_sandbox_ip(Bridge *br); 378void net_configure_sandbox_ip(Bridge *br);
379void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child); 379void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child);
380void net_check_cfg(void); 380void net_check_cfg(void);
381void net_dns_print(pid_t pid); 381void net_dns_print(pid_t pid) __attribute__((noreturn));
382void network_main(pid_t child); 382void network_main(pid_t child);
383void net_print(pid_t pid); 383void net_print(pid_t pid);
384 384
@@ -453,13 +453,12 @@ void profile_add_ignore(const char *str);
453void list(void); 453void list(void);
454void tree(void); 454void tree(void);
455void top(void); 455void top(void);
456void netstats(void);
457 456
458// usage.c 457// usage.c
459void usage(void); 458void usage(void);
460 459
461// join.c 460// join.c
462void join(pid_t pid, int argc, char **argv, int index); 461void join(pid_t pid, int argc, char **argv, int index) __attribute__((noreturn));
463bool is_ready_for_join(const pid_t pid); 462bool is_ready_for_join(const pid_t pid);
464void check_join_permission(pid_t pid); 463void check_join_permission(pid_t pid);
465pid_t switch_to_child(pid_t pid); 464pid_t switch_to_child(pid_t pid);
@@ -486,7 +485,7 @@ int macro_id(const char *name);
486 485
487 486
488// util.c 487// util.c
489void errLogExit(char* fmt, ...); 488void errLogExit(char* fmt, ...) __attribute__((noreturn));
490void fwarning(char* fmt, ...); 489void fwarning(char* fmt, ...);
491void fmessage(char* fmt, ...); 490void fmessage(char* fmt, ...);
492void drop_privs(int nogroups); 491void drop_privs(int nogroups);
@@ -584,7 +583,7 @@ int seccomp_load(const char *fname);
584int seccomp_filter_drop(bool native); 583int seccomp_filter_drop(bool native);
585int seccomp_filter_keep(bool native); 584int seccomp_filter_keep(bool native);
586int seccomp_filter_mdwx(bool native); 585int seccomp_filter_mdwx(bool native);
587void seccomp_print_filter(pid_t pid); 586void seccomp_print_filter(pid_t pid) __attribute__((noreturn));
588 587
589// caps.c 588// caps.c
590void seccomp_load_file_list(void); 589void seccomp_load_file_list(void);
@@ -595,7 +594,7 @@ void caps_set(uint64_t caps);
595void caps_check_list(const char *clist, void (*callback)(int)); 594void caps_check_list(const char *clist, void (*callback)(int));
596void caps_drop_list(const char *clist); 595void caps_drop_list(const char *clist);
597void caps_keep_list(const char *clist); 596void caps_keep_list(const char *clist);
598void caps_print_filter(pid_t pid); 597void caps_print_filter(pid_t pid) __attribute__((noreturn));
599void caps_drop_dac_override(void); 598void caps_drop_dac_override(void);
600 599
601// fs_trace.c 600// fs_trace.c
@@ -618,7 +617,7 @@ void read_cpu_list(const char *str);
618void set_cpu_affinity(void); 617void set_cpu_affinity(void);
619void load_cpu(const char *fname); 618void load_cpu(const char *fname);
620void save_cpu(void); 619void save_cpu(void);
621void cpu_print_filter(pid_t pid); 620void cpu_print_filter(pid_t pid) __attribute__((noreturn));
622 621
623// cgroup.c 622// cgroup.c
624void save_cgroup(void); 623void save_cgroup(void);
@@ -640,7 +639,7 @@ void netns(const char *nsname);
640void netns_mounts(const char *nsname); 639void netns_mounts(const char *nsname);
641 640
642// bandwidth.c 641// bandwidth.c
643void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up); 642void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up) __attribute__((noreturn));
644void network_set_run_file(pid_t pid); 643void network_set_run_file(pid_t pid);
645 644
646// fs_etc.c 645// fs_etc.c
@@ -650,7 +649,7 @@ void fs_private_dir_list(const char *private_dir, const char *private_run_dir, c
650// no_sandbox.c 649// no_sandbox.c
651int check_namespace_virt(void); 650int check_namespace_virt(void);
652int check_kernel_procs(void); 651int check_kernel_procs(void);
653void run_no_sandbox(int argc, char **argv); 652void run_no_sandbox(int argc, char **argv) __attribute__((noreturn));
654 653
655#define MAX_ENVS 256 // some sane maximum number of environment variables 654#define MAX_ENVS 256 // some sane maximum number of environment variables
656#define MAX_ENV_LEN (PATH_MAX + 32) // FOOBAR=SOME_PATH 655#define MAX_ENV_LEN (PATH_MAX + 32) // FOOBAR=SOME_PATH
@@ -681,7 +680,7 @@ void fs_private_lib(void);
681// protocol.c 680// protocol.c
682void protocol_filter_save(void); 681void protocol_filter_save(void);
683void protocol_filter_load(const char *fname); 682void protocol_filter_load(const char *fname);
684void protocol_print_filter(pid_t pid); 683void protocol_print_filter(pid_t pid) __attribute__((noreturn));
685 684
686// restrict_users.c 685// restrict_users.c
687void restrict_users(void); 686void restrict_users(void);
@@ -693,7 +692,7 @@ void fs_logger2int(const char *msg1, int d);
693void fs_logger3(const char *msg1, const char *msg2, const char *msg3); 692void fs_logger3(const char *msg1, const char *msg2, const char *msg3);
694void fs_logger_print(void); 693void fs_logger_print(void);
695void fs_logger_change_owner(void); 694void fs_logger_change_owner(void);
696void fs_logger_print_log(pid_t pid); 695void fs_logger_print_log(pid_t pid) __attribute__((noreturn));
697 696
698// run_symlink.c 697// run_symlink.c
699void run_symlink(int argc, char **argv, int run_as_is); 698void run_symlink(int argc, char **argv, int run_as_is);
@@ -719,11 +718,11 @@ void fs_mkfile(const char *name);
719 718
720void fs_x11(void); 719void fs_x11(void);
721int x11_display(void); 720int x11_display(void);
722void x11_start(int argc, char **argv); 721void x11_start(int argc, char **argv) __attribute__((noreturn));
723void x11_start_xpra(int argc, char **argv); 722void x11_start_xpra(int argc, char **argv) __attribute__((noreturn));
724void x11_start_xephyr(int argc, char **argv); 723void x11_start_xephyr(int argc, char **argv) __attribute__((noreturn));
725void x11_block(void); 724void x11_block(void);
726void x11_start_xvfb(int argc, char **argv); 725void x11_start_xvfb(int argc, char **argv) __attribute__((noreturn));
727void x11_xorg(void); 726void x11_xorg(void);
728 727
729// ls.c 728// ls.c
@@ -736,7 +735,7 @@ enum {
736}; 735};
737void ls(const char *path); 736void ls(const char *path);
738void cat(const char *path); 737void cat(const char *path);
739void sandboxfs(int op, pid_t pid, const char *path1, const char *path2); 738void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) __attribute__((noreturn));
740 739
741// checkcfg.c 740// checkcfg.c
742#define DEFAULT_ARP_PROBES 2 741#define DEFAULT_ARP_PROBES 2
@@ -842,7 +841,7 @@ void build_appimage_cmdline(char **command_line, char **window_title, int argc,
842// run sbox 841// run sbox
843int sbox_run(unsigned filter, int num, ...); 842int sbox_run(unsigned filter, int num, ...);
844int sbox_run_v(unsigned filter, char * const arg[]); 843int sbox_run_v(unsigned filter, char * const arg[]);
845void sbox_exec_v(unsigned filter, char * const arg[]); 844void sbox_exec_v(unsigned filter, char * const arg[]) __attribute__((noreturn));
846 845
847// run_files.c 846// run_files.c
848void delete_run_files(pid_t pid); 847void delete_run_files(pid_t pid);
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c
index fbce72429..00edc5f88 100644
--- a/src/firejail/fs_dev.c
+++ b/src/firejail/fs_dev.c
@@ -25,6 +25,7 @@
25#include <dirent.h> 25#include <dirent.h>
26#include <fcntl.h> 26#include <fcntl.h>
27#include <pwd.h> 27#include <pwd.h>
28#include <errno.h>
28#ifndef _BSD_SOURCE 29#ifndef _BSD_SOURCE
29#define _BSD_SOURCE 30#define _BSD_SOURCE
30#endif 31#endif
@@ -148,7 +149,7 @@ static void create_char_dev(const char *path, mode_t mode, int major, int minor)
148 return; 149 return;
149 150
150errexit: 151errexit:
151 fprintf(stderr, "Error: cannot create %s device\n", path); 152 fprintf(stderr, "Error: cannot create %s device: %s\n", path, strerror(errno));
152 exit(1); 153 exit(1);
153} 154}
154 155
diff --git a/src/firejail/join.c b/src/firejail/join.c
index 4c8555f29..f202d1a9c 100644
--- a/src/firejail/join.c
+++ b/src/firejail/join.c
@@ -588,7 +588,7 @@ void join(pid_t pid, int argc, char **argv, int index) {
588 588
589 start_application(0, NULL); 589 start_application(0, NULL);
590 590
591 // it will never get here!!! 591 __builtin_unreachable();
592 } 592 }
593 EUID_USER(); 593 EUID_USER();
594 594
diff --git a/src/firejail/main.c b/src/firejail/main.c
index afd9af91d..412c6148a 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -1190,8 +1190,7 @@ int main(int argc, char **argv, char **envp) {
1190 1190
1191 // start the program directly without sandboxing 1191 // start the program directly without sandboxing
1192 run_no_sandbox(argc, argv); 1192 run_no_sandbox(argc, argv);
1193 // it will never get here! 1193 __builtin_unreachable();
1194 assert(0);
1195 } 1194 }
1196 } 1195 }
1197 EUID_ASSERT(); 1196 EUID_ASSERT();
@@ -1473,6 +1472,8 @@ int main(int argc, char **argv, char **envp) {
1473 if (config_seccomp_error_action == -1) { 1472 if (config_seccomp_error_action == -1) {
1474 if (strcmp(argv[i] + 23, "kill") == 0) 1473 if (strcmp(argv[i] + 23, "kill") == 0)
1475 arg_seccomp_error_action = SECCOMP_RET_KILL; 1474 arg_seccomp_error_action = SECCOMP_RET_KILL;
1475 else if (strcmp(argv[i] + 23, "log") == 0)
1476 arg_seccomp_error_action = SECCOMP_RET_LOG;
1476 else { 1477 else {
1477 arg_seccomp_error_action = errno_find_name(argv[i] + 23); 1478 arg_seccomp_error_action = errno_find_name(argv[i] + 23);
1478 if (arg_seccomp_error_action == -1) 1479 if (arg_seccomp_error_action == -1)
diff --git a/src/firejail/output.c b/src/firejail/output.c
index 0e961bb61..36cb905cb 100644
--- a/src/firejail/output.c
+++ b/src/firejail/output.c
@@ -122,7 +122,8 @@ void check_output(int argc, char **argv) {
122 } 122 }
123 bool found_separator = false; 123 bool found_separator = false;
124 /* copy argv into args, but drop --output(-stderr) arguments */ 124 /* copy argv into args, but drop --output(-stderr) arguments */
125 for (int i = 0, j = 0; i < argc; i++) { 125 int j;
126 for (i = 0, j = 0; i < argc; i++) {
126 if (!found_separator && i > 0) { 127 if (!found_separator && i > 0) {
127 if (strncmp(argv[i], "--output=", 9) == 0) { 128 if (strncmp(argv[i], "--output=", 9) == 0) {
128 continue; 129 continue;
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 70acd8a2a..970033899 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -991,6 +991,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
991 if (config_seccomp_error_action == -1) { 991 if (config_seccomp_error_action == -1) {
992 if (strcmp(ptr + 21, "kill") == 0) 992 if (strcmp(ptr + 21, "kill") == 0)
993 arg_seccomp_error_action = SECCOMP_RET_KILL; 993 arg_seccomp_error_action = SECCOMP_RET_KILL;
994 else if (strcmp(ptr + 21, "log") == 0)
995 arg_seccomp_error_action = SECCOMP_RET_LOG;
994 else { 996 else {
995 arg_seccomp_error_action = errno_find_name(ptr + 21); 997 arg_seccomp_error_action = errno_find_name(ptr + 21);
996 if (arg_seccomp_error_action == -1) 998 if (arg_seccomp_error_action == -1)
diff --git a/src/firejail/protocol.c b/src/firejail/protocol.c
index 6402afbc6..a1594d6b9 100644
--- a/src/firejail/protocol.c
+++ b/src/firejail/protocol.c
@@ -90,7 +90,7 @@ void protocol_print_filter(pid_t pid) {
90 exit(0); 90 exit(0);
91#else 91#else
92 fwarning("--protocol not supported on this platform\n"); 92 fwarning("--protocol not supported on this platform\n");
93 return; 93 exit(1);
94#endif 94#endif
95} 95}
96 96
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index df33319f6..81d535762 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -654,7 +654,8 @@ int sandbox(void* sandbox_arg) {
654 // ... and mount a tmpfs on top of /run/firejail/mnt directory 654 // ... and mount a tmpfs on top of /run/firejail/mnt directory
655 preproc_mount_mnt_dir(); 655 preproc_mount_mnt_dir();
656 // bind-mount firejail binaries and helper programs 656 // bind-mount firejail binaries and helper programs
657 if (mount(LIBDIR "/firejail", RUN_FIREJAIL_LIB_DIR, "none", MS_BIND, NULL) < 0) 657 if (mount(LIBDIR "/firejail", RUN_FIREJAIL_LIB_DIR, NULL, MS_BIND, NULL) < 0 ||
658 mount(NULL, RUN_FIREJAIL_LIB_DIR, NULL, MS_RDONLY|MS_NOSUID|MS_NODEV|MS_BIND|MS_REMOUNT, NULL) < 0)
658 errExit("mounting " RUN_FIREJAIL_LIB_DIR); 659 errExit("mounting " RUN_FIREJAIL_LIB_DIR);
659 660
660 //**************************** 661 //****************************
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c
index 99f11a246..57c21ce78 100644
--- a/src/firejail/sbox.c
+++ b/src/firejail/sbox.c
@@ -31,7 +31,7 @@
31#define O_PATH 010000000 31#define O_PATH 010000000
32#endif 32#endif
33 33
34static int sbox_do_exec_v(unsigned filtermask, char * const arg[]) { 34static int __attribute__((noreturn)) sbox_do_exec_v(unsigned filtermask, char * const arg[]) {
35 // build a new, clean environment 35 // build a new, clean environment
36 int env_index = 0; 36 int env_index = 0;
37 char *new_environment[256] = { NULL }; 37 char *new_environment[256] = { NULL };
diff --git a/src/firejail/shutdown.c b/src/firejail/shutdown.c
index a7d0b2fbe..7e9628007 100644
--- a/src/firejail/shutdown.c
+++ b/src/firejail/shutdown.c
@@ -63,7 +63,9 @@ void shut(pid_t pid) {
63 sleep(1); 63 sleep(1);
64 monsec--; 64 monsec--;
65 65
66 EUID_ROOT();
66 FILE *fp = fopen(monfile, "r"); 67 FILE *fp = fopen(monfile, "r");
68 EUID_USER();
67 if (!fp) { 69 if (!fp) {
68 killdone = 1; 70 killdone = 1;
69 break; 71 break;
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index be6715df4..2390706f2 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -227,7 +227,8 @@ static char *usage_str =
227 " --seccomp.print=name|pid - print the seccomp filter for the sandbox\n" 227 " --seccomp.print=name|pid - print the seccomp filter for the sandbox\n"
228 "\tidentified by name or PID.\n" 228 "\tidentified by name or PID.\n"
229 " --seccomp.32[.drop,.keep][=syscall] - like above but for 32 bit architecture.\n" 229 " --seccomp.32[.drop,.keep][=syscall] - like above but for 32 bit architecture.\n"
230 " --seccomp-error-action=errno|kill - change error code or kill process.\n" 230 " --seccomp-error-action=errno|kill|log - change error code, kill process\n"
231 "\tor log the attempt.\n"
231#endif 232#endif
232 " --shell=none - run the program directly without a user shell.\n" 233 " --shell=none - run the program directly without a user shell.\n"
233 " --shell=program - set default user shell.\n" 234 " --shell=program - set default user shell.\n"
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index 98ac184d9..ba54ca376 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -682,7 +682,7 @@ static char * get_title_arg_str() {
682} 682}
683 683
684 684
685void x11_start_xpra_old(int argc, char **argv, int display, char *display_str) { 685static void __attribute__((noreturn)) x11_start_xpra_old(int argc, char **argv, int display, char *display_str) {
686 EUID_ASSERT(); 686 EUID_ASSERT();
687 int i; 687 int i;
688 struct stat s; 688 struct stat s;
@@ -921,7 +921,7 @@ void x11_start_xpra_old(int argc, char **argv, int display, char *display_str) {
921} 921}
922 922
923 923
924void x11_start_xpra_new(int argc, char **argv, char *display_str) { 924static void __attribute__((noreturn)) x11_start_xpra_new(int argc, char **argv, char *display_str) {
925 EUID_ASSERT(); 925 EUID_ASSERT();
926 int i; 926 int i;
927 pid_t server = 0; 927 pid_t server = 0;
diff --git a/src/firemon/firemon.h b/src/firemon/firemon.h
index 7a55a64fb..3fba486eb 100644
--- a/src/firemon/firemon.h
+++ b/src/firemon/firemon.h
@@ -46,13 +46,13 @@ void firemon_sleep(int st);
46 46
47 47
48// procevent.c 48// procevent.c
49void procevent(pid_t pid); 49void procevent(pid_t pid) __attribute__((noreturn));
50 50
51// usage.c 51// usage.c
52void usage(void); 52void usage(void);
53 53
54// top.c 54// top.c
55void top(void); 55void top(void) __attribute__((noreturn));
56 56
57// list.c 57// list.c
58void list(void); 58void list(void);
@@ -82,7 +82,7 @@ void cgroup(pid_t pid, int print_procs);
82void tree(pid_t pid); 82void tree(pid_t pid);
83 83
84// netstats.c 84// netstats.c
85void netstats(void); 85void netstats(void) __attribute__((noreturn));
86 86
87// x11.c 87// x11.c
88void x11(pid_t pid, int print_procs); 88void x11(pid_t pid, int print_procs);
diff --git a/src/firemon/procevent.c b/src/firemon/procevent.c
index 7dd08444e..45964d3a2 100644
--- a/src/firemon/procevent.c
+++ b/src/firemon/procevent.c
@@ -220,7 +220,7 @@ errexit:
220} 220}
221 221
222 222
223static int procevent_monitor(const int sock, pid_t mypid) { 223static void __attribute__((noreturn)) procevent_monitor(const int sock, pid_t mypid) {
224 ssize_t len; 224 ssize_t len;
225 struct nlmsghdr *nlmsghdr; 225 struct nlmsghdr *nlmsghdr;
226 226
@@ -246,8 +246,7 @@ static int procevent_monitor(const int sock, pid_t mypid) {
246 246
247 int rv = select(max, &readfds, NULL, NULL, &tv); 247 int rv = select(max, &readfds, NULL, NULL, &tv);
248 if (rv == -1) { 248 if (rv == -1) {
249 fprintf(stderr, "recv: %s\n", strerror(errno)); 249 errExit("recv");
250 return -1;
251 } 250 }
252 251
253 // timeout 252 // timeout
@@ -259,7 +258,7 @@ static int procevent_monitor(const int sock, pid_t mypid) {
259 258
260 259
261 if ((len = recv(sock, buf, sizeof(buf), 0)) == 0) 260 if ((len = recv(sock, buf, sizeof(buf), 0)) == 0)
262 return 0; 261 exit(0);
263 if (len == -1) { 262 if (len == -1) {
264 if (errno == EINTR) 263 if (errno == EINTR)
265 continue; 264 continue;
@@ -271,7 +270,7 @@ static int procevent_monitor(const int sock, pid_t mypid) {
271 } 270 }
272 else { 271 else {
273 fprintf(stderr,"Error: rx socket recv call, errno %d, %s\n", errno, strerror(errno)); 272 fprintf(stderr,"Error: rx socket recv call, errno %d, %s\n", errno, strerror(errno));
274 return -1; 273 exit(1);
275 } 274 }
276 } 275 }
277 276
@@ -497,7 +496,7 @@ static int procevent_monitor(const int sock, pid_t mypid) {
497 exit(0); 496 exit(0);
498 } 497 }
499 } 498 }
500 return 0; 499 __builtin_unreachable();
501} 500}
502 501
503void procevent(pid_t pid) { 502void procevent(pid_t pid) {
@@ -515,6 +514,4 @@ void procevent(pid_t pid) {
515 } 514 }
516 515
517 procevent_monitor(sock, pid); // it will never return from here 516 procevent_monitor(sock, pid); // it will never return from here
518 assert(0);
519 close(sock); // quiet static analyzers
520} 517}
diff --git a/src/fseccomp/main.c b/src/fseccomp/main.c
index 892a88e25..3b3c92b46 100644
--- a/src/fseccomp/main.c
+++ b/src/fseccomp/main.c
@@ -20,7 +20,7 @@
20#include "fseccomp.h" 20#include "fseccomp.h"
21#include "../include/seccomp.h" 21#include "../include/seccomp.h"
22int arg_quiet = 0; 22int arg_quiet = 0;
23int arg_seccomp_error_action = EPERM; // error action: errno or kill 23int arg_seccomp_error_action = EPERM; // error action: errno, log or kill
24 24
25static void usage(void) { 25static void usage(void) {
26 printf("Usage:\n"); 26 printf("Usage:\n");
@@ -73,6 +73,8 @@ printf("\n");
73 if (error_action) { 73 if (error_action) {
74 if (strcmp(error_action, "kill") == 0) 74 if (strcmp(error_action, "kill") == 0)
75 arg_seccomp_error_action = SECCOMP_RET_KILL; 75 arg_seccomp_error_action = SECCOMP_RET_KILL;
76 else if (strcmp(error_action, "log") == 0)
77 arg_seccomp_error_action = SECCOMP_RET_LOG;
76 else { 78 else {
77 arg_seccomp_error_action = errno_find_name(error_action); 79 arg_seccomp_error_action = errno_find_name(error_action);
78 if (arg_seccomp_error_action == -1) 80 if (arg_seccomp_error_action == -1)
diff --git a/src/include/seccomp.h b/src/include/seccomp.h
index 50920ce3a..29b858c70 100644
--- a/src/include/seccomp.h
+++ b/src/include/seccomp.h
@@ -274,7 +274,7 @@ struct seccomp_data {
274#define RETURN_ERRNO(nr) \ 274#define RETURN_ERRNO(nr) \
275 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO | nr) 275 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO | nr)
276 276
277extern int arg_seccomp_error_action; // error action: errno or kill 277extern int arg_seccomp_error_action; // error action: errno, log or kill
278#define KILL_OR_RETURN_ERRNO \ 278#define KILL_OR_RETURN_ERRNO \
279 BPF_STMT(BPF_RET+BPF_K, arg_seccomp_error_action) 279 BPF_STMT(BPF_RET+BPF_K, arg_seccomp_error_action)
280 280
diff --git a/src/include/syscall.h b/src/include/syscall.h
index 89b54170e..489da0600 100644
--- a/src/include/syscall.h
+++ b/src/include/syscall.h
@@ -32,7 +32,7 @@ void filter_add_blacklist_override(int fd, int syscall, int arg, void *ptrarg, b
32// errno.c 32// errno.c
33void errno_print(void); 33void errno_print(void);
34int errno_find_name(const char *name); 34int errno_find_name(const char *name);
35char *errno_find_nr(int nr); 35const char *errno_find_nr(int nr);
36 36
37// syscall.c 37// syscall.c
38void syscall_print(void); 38void syscall_print(void);
diff --git a/src/lib/errno.c b/src/lib/errno.c
index d38c197ad..881c3b27e 100644
--- a/src/lib/errno.c
+++ b/src/lib/errno.c
@@ -183,7 +183,7 @@ int errno_find_name(const char *name) {
183 return -1; 183 return -1;
184} 184}
185 185
186char *errno_find_nr(int nr) { 186const char *errno_find_nr(int nr) {
187 int i; 187 int i;
188 int elems = sizeof(errnolist) / sizeof(errnolist[0]); 188 int elems = sizeof(errnolist) / sizeof(errnolist[0]);
189 for (i = 0; i < elems; i++) { 189 for (i = 0; i < elems; i++) {
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt
index 7b5653942..0784e7fd7 100644
--- a/src/man/firejail-profile.txt
+++ b/src/man/firejail-profile.txt
@@ -433,8 +433,10 @@ Enable seccomp filter and whitelist the system calls in the list.
433\fBseccomp.32.keep syscall,syscall,syscall 433\fBseccomp.32.keep syscall,syscall,syscall
434Enable seccomp filter and whitelist the system calls in the list for 32 bit system calls on a 64 bit architecture system. 434Enable seccomp filter and whitelist the system calls in the list for 32 bit system calls on a 64 bit architecture system.
435.TP 435.TP
436\fBseccomp-error-action kill | ERRNO 436\fBseccomp-error-action kill | log | ERRNO
437Return a different error instead of EPERM to the process or kill it when an attempt is made to call a blocked system call. 437Return a different error instead of EPERM to the process, kill it when
438an attempt is made to call a blocked system call, or allow but log the
439attempt.
438.TP 440.TP
439\fBx11 441\fBx11
440Enable X11 sandboxing. 442Enable X11 sandboxing.
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index f5f092bd9..abb73b5e2 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -1063,7 +1063,7 @@ that are both writable and executable, to change mappings to be
1063executable, or to create executable shared memory. The filter examines 1063executable, or to create executable shared memory. The filter examines
1064the arguments of mmap, mmap2, mprotect, pkey_mprotect, memfd_create 1064the arguments of mmap, mmap2, mprotect, pkey_mprotect, memfd_create
1065and shmat system calls and returns error EPERM to the process (or 1065and shmat system calls and returns error EPERM to the process (or
1066kills it, see \-\-seccomp-error-action below) if necessary. 1066kills it or log the attempt, see \-\-seccomp-error-action below) if necessary.
1067.br 1067.br
1068 1068
1069.br 1069.br
@@ -2126,8 +2126,8 @@ Instead of dropping the syscall by returning EPERM, another error
2126number can be returned using \fBsyscall:errno\fR syntax. This can be 2126number can be returned using \fBsyscall:errno\fR syntax. This can be
2127also changed globally with \-\-seccomp-error-action or 2127also changed globally with \-\-seccomp-error-action or
2128in /etc/firejail/firejail.config file. The process can also be killed 2128in /etc/firejail/firejail.config file. The process can also be killed
2129by using \fBsyscall:kill\fR syntax. 2129by using \fBsyscall:kill\fR syntax, or the attempt may be logged with
2130 2130\fBsyscall:log\fR.
2131.br 2131.br
2132 2132
2133.br 2133.br
@@ -2197,7 +2197,8 @@ Instead of dropping the syscall by returning EPERM, another error
2197number can be returned using \fBsyscall:errno\fR syntax. This can be 2197number can be returned using \fBsyscall:errno\fR syntax. This can be
2198also changed globally with \-\-seccomp-error-action or 2198also changed globally with \-\-seccomp-error-action or
2199in /etc/firejail/firejail.config file. The process can also be killed 2199in /etc/firejail/firejail.config file. The process can also be killed
2200by using \fBsyscall:kill\fR syntax. 2200by using \fBsyscall:kill\fR syntax, or the attempt may be logged with
2201\fBsyscall:log\fR.
2201.br 2202.br
2202 2203
2203.br 2204.br
@@ -2406,7 +2407,8 @@ By default, if a seccomp filter blocks a system call, the process gets
2406EPERM as the error. With \-\-seccomp-error-action=error, another error 2407EPERM as the error. With \-\-seccomp-error-action=error, another error
2407number can be returned, for example ENOSYS or EACCES. The process can 2408number can be returned, for example ENOSYS or EACCES. The process can
2408also be killed (like in versions <0.9.63 of Firejail) by using 2409also be killed (like in versions <0.9.63 of Firejail) by using
2409\-\-seccomp-error-action=kill syntax. Not killing the process weakens 2410\-\-seccomp-error-action=kill syntax, or the attempt may be logged
2411with \-\-seccomp-error-action=log. Not killing the process weakens
2410Firejail slightly when trying to contain intrusion, but it may also 2412Firejail slightly when trying to contain intrusion, but it may also
2411allow tighter filters if the only alternative is to allow a system 2413allow tighter filters if the only alternative is to allow a system
2412call. 2414call.