aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/inc/disable-proc.inc82
-rw-r--r--etc/profile-a-l/alienarena.profile1
-rw-r--r--etc/profile-a-l/blobwars.profile1
-rw-r--r--etc/profile-a-l/frozen-bubble.profile1
-rw-r--r--etc/profile-a-l/funnyboat.profile1
-rw-r--r--etc/profile-a-l/gl-117.profile1
-rw-r--r--etc/profile-a-l/glaxium.profile1
-rw-r--r--etc/profile-a-l/jumpnbump-menu.profile2
-rw-r--r--etc/profile-a-l/jumpnbump.profile1
-rw-r--r--etc/profile-m-z/mrrescue.profile1
-rw-r--r--etc/profile-m-z/open-invaders.profile1
-rw-r--r--etc/profile-m-z/openclonk.profile1
-rw-r--r--etc/profile-m-z/supertux2.profile1
-rw-r--r--etc/profile-m-z/teeworlds.profile1
-rw-r--r--etc/profile-m-z/torcs.profile1
-rw-r--r--etc/profile-m-z/tremulous.profile5
-rw-r--r--etc/profile-m-z/warsow.profile8
-rw-r--r--etc/profile-m-z/xonotic.profile1
-rw-r--r--etc/templates/profile.template1
-rw-r--r--src/fbuilder/build_fs.c3
-rw-r--r--src/firejail/firejail.h5
-rw-r--r--src/firejail/fs.c11
-rw-r--r--src/firejail/main.c4
-rw-r--r--src/firejail/mountinfo.c149
-rw-r--r--src/firejail/profile.c5
-rw-r--r--src/firejail/util.c79
-rw-r--r--src/libtrace/libtrace.c14
-rw-r--r--src/man/firejail.txt14
28 files changed, 238 insertions, 158 deletions
diff --git a/etc/inc/disable-proc.inc b/etc/inc/disable-proc.inc
new file mode 100644
index 000000000..81a8883f3
--- /dev/null
+++ b/etc/inc/disable-proc.inc
@@ -0,0 +1,82 @@
1# This file is overwritten during software install.
2# Persistent customizations should go in a .local file.
3include disable-proc.local
4
5blacklist /proc/acpi
6blacklist /proc/asound
7blacklist /proc/bootconfig
8blacklist /proc/buddyinfo
9blacklist /proc/cgroups
10blacklist /proc/cmdline
11blacklist /proc/config.gz
12blacklist /proc/consoles
13#blacklist /proc/cpuinfo
14blacklist /proc/crypto
15blacklist /proc/devices
16blacklist /proc/diskstats
17blacklist /proc/dma
18#blacklist /proc/driver
19blacklist /proc/dynamic_debug
20blacklist /proc/execdomains
21blacklist /proc/fb
22#blacklist /proc/filesystems
23blacklist /proc/fs
24blacklist /proc/i8k
25blacklist /proc/interrupts
26blacklist /proc/iomem
27blacklist /proc/ioports
28blacklist /proc/irq
29blacklist /proc/kallsyms
30blacklist /proc/kcore
31blacklist /proc/keys
32blacklist /proc/key-users
33blacklist /proc/kmsg
34blacklist /proc/kpagecgroup
35blacklist /proc/kpagecount
36blacklist /proc/kpageflags
37blacklist /proc/latency_stats
38#blacklist /proc/loadavg
39blacklist /proc/locks
40blacklist /proc/mdstat
41#blacklist /proc/meminfo
42blacklist /proc/misc
43#blacklist /proc/modules
44#blacklist /proc/mounts
45blacklist /proc/mtrr
46#blacklist /proc/net
47blacklist /proc/partitions
48blacklist /proc/pressure
49blacklist /proc/sched_debug
50blacklist /proc/schedstat
51blacklist /proc/scsi
52#blacklist /proc/self
53blacklist /proc/slabinfo
54blacklist /proc/softirqs
55blacklist /proc/spl
56#blacklist /proc/stat
57blacklist /proc/swaps
58#blacklist /proc/sys
59blacklist /proc/sysrq-trigger
60blacklist /proc/sysvipc
61#blacklist /proc/thread-self
62blacklist /proc/timer_list
63blacklist /proc/tty
64#blacklist /proc/uptime
65#blacklist /proc/version
66blacklist /proc/version_signature
67blacklist /proc/vmallocinfo
68#blacklist /proc/vmstat
69#blacklist /proc/zoneinfo
70
71blacklist /proc/sys/abi
72blacklist /proc/sys/crypto
73blacklist /proc/sys/debug
74blacklist /proc/sys/dev
75blacklist /proc/sys/fs
76blacklist /proc/sys/net
77blacklist /proc/sys/user
78blacklist /proc/sys/vm
79
80noblacklist /proc/sys/kernel/osrelease
81noblacklist /proc/sys/kernel/yama
82blacklist /proc/sys/*/*
diff --git a/etc/profile-a-l/alienarena.profile b/etc/profile-a-l/alienarena.profile
index 62857a3e2..68512e37b 100644
--- a/etc/profile-a-l/alienarena.profile
+++ b/etc/profile-a-l/alienarena.profile
@@ -29,7 +29,6 @@ caps.drop all
29netfilter 29netfilter
30nodvd 30nodvd
31nogroups 31nogroups
32noinput
33nonewprivs 32nonewprivs
34noroot 33noroot
35notv 34notv
diff --git a/etc/profile-a-l/blobwars.profile b/etc/profile-a-l/blobwars.profile
index 6b7b59be4..66f38b358 100644
--- a/etc/profile-a-l/blobwars.profile
+++ b/etc/profile-a-l/blobwars.profile
@@ -29,7 +29,6 @@ caps.drop all
29net none 29net none
30nodvd 30nodvd
31nogroups 31nogroups
32noinput
33nonewprivs 32nonewprivs
34noroot 33noroot
35notv 34notv
diff --git a/etc/profile-a-l/frozen-bubble.profile b/etc/profile-a-l/frozen-bubble.profile
index bb35c9447..88943760a 100644
--- a/etc/profile-a-l/frozen-bubble.profile
+++ b/etc/profile-a-l/frozen-bubble.profile
@@ -30,7 +30,6 @@ caps.drop all
30net none 30net none
31nodvd 31nodvd
32nogroups 32nogroups
33noinput
34nonewprivs 33nonewprivs
35noroot 34noroot
36notv 35notv
diff --git a/etc/profile-a-l/funnyboat.profile b/etc/profile-a-l/funnyboat.profile
index 1009f345b..4a08fca9b 100644
--- a/etc/profile-a-l/funnyboat.profile
+++ b/etc/profile-a-l/funnyboat.profile
@@ -35,7 +35,6 @@ ipc-namespace
35netfilter 35netfilter
36nodvd 36nodvd
37nogroups 37nogroups
38noinput
39nonewprivs 38nonewprivs
40noroot 39noroot
41notv 40notv
diff --git a/etc/profile-a-l/gl-117.profile b/etc/profile-a-l/gl-117.profile
index 35d969e6d..edb85048b 100644
--- a/etc/profile-a-l/gl-117.profile
+++ b/etc/profile-a-l/gl-117.profile
@@ -29,7 +29,6 @@ caps.drop all
29net none 29net none
30nodvd 30nodvd
31nogroups 31nogroups
32noinput
33nonewprivs 32nonewprivs
34noroot 33noroot
35notv 34notv
diff --git a/etc/profile-a-l/glaxium.profile b/etc/profile-a-l/glaxium.profile
index dec0daef2..b5f98b411 100644
--- a/etc/profile-a-l/glaxium.profile
+++ b/etc/profile-a-l/glaxium.profile
@@ -29,7 +29,6 @@ caps.drop all
29net none 29net none
30nodvd 30nodvd
31nogroups 31nogroups
32noinput
33nonewprivs 32nonewprivs
34noroot 33noroot
35notv 34notv
diff --git a/etc/profile-a-l/jumpnbump-menu.profile b/etc/profile-a-l/jumpnbump-menu.profile
index 8d391b90f..59d762f55 100644
--- a/etc/profile-a-l/jumpnbump-menu.profile
+++ b/etc/profile-a-l/jumpnbump-menu.profile
@@ -10,7 +10,7 @@ include jumpnbump-menu.local
10# Allow python (blacklisted by disable-interpreters.inc) 10# Allow python (blacklisted by disable-interpreters.inc)
11include allow-python3.inc 11include allow-python3.inc
12 12
13private-bin jumpnbump-menu,python3* 13private-bin env,jumpnbump-menu,python3*
14 14
15# Redirect 15# Redirect
16include jumpnbump.profile 16include jumpnbump.profile
diff --git a/etc/profile-a-l/jumpnbump.profile b/etc/profile-a-l/jumpnbump.profile
index b9bc8f219..9726ff6fe 100644
--- a/etc/profile-a-l/jumpnbump.profile
+++ b/etc/profile-a-l/jumpnbump.profile
@@ -27,7 +27,6 @@ caps.drop all
27net none 27net none
28nodvd 28nodvd
29nogroups 29nogroups
30noinput
31nonewprivs 30nonewprivs
32noroot 31noroot
33notv 32notv
diff --git a/etc/profile-m-z/mrrescue.profile b/etc/profile-m-z/mrrescue.profile
index 16dc97d0c..5b5902563 100644
--- a/etc/profile-m-z/mrrescue.profile
+++ b/etc/profile-m-z/mrrescue.profile
@@ -37,7 +37,6 @@ caps.drop all
37net none 37net none
38nodvd 38nodvd
39nogroups 39nogroups
40noinput
41nonewprivs 40nonewprivs
42noroot 41noroot
43notv 42notv
diff --git a/etc/profile-m-z/open-invaders.profile b/etc/profile-m-z/open-invaders.profile
index 12c7ea3d0..c2c22f42d 100644
--- a/etc/profile-m-z/open-invaders.profile
+++ b/etc/profile-m-z/open-invaders.profile
@@ -25,7 +25,6 @@ caps.drop all
25net none 25net none
26nodvd 26nodvd
27nogroups 27nogroups
28noinput
29nonewprivs 28nonewprivs
30noroot 29noroot
31notv 30notv
diff --git a/etc/profile-m-z/openclonk.profile b/etc/profile-m-z/openclonk.profile
index 253465991..68362cbc8 100644
--- a/etc/profile-m-z/openclonk.profile
+++ b/etc/profile-m-z/openclonk.profile
@@ -28,7 +28,6 @@ ipc-namespace
28netfilter 28netfilter
29nodvd 29nodvd
30nogroups 30nogroups
31noinput
32nonewprivs 31nonewprivs
33noroot 32noroot
34notv 33notv
diff --git a/etc/profile-m-z/supertux2.profile b/etc/profile-m-z/supertux2.profile
index 323849e35..d48065c4b 100644
--- a/etc/profile-m-z/supertux2.profile
+++ b/etc/profile-m-z/supertux2.profile
@@ -30,7 +30,6 @@ caps.drop all
30net none 30net none
31nodvd 31nodvd
32nogroups 32nogroups
33noinput
34nonewprivs 33nonewprivs
35noroot 34noroot
36notv 35notv
diff --git a/etc/profile-m-z/teeworlds.profile b/etc/profile-m-z/teeworlds.profile
index df54fb9ba..d0fb0d43e 100644
--- a/etc/profile-m-z/teeworlds.profile
+++ b/etc/profile-m-z/teeworlds.profile
@@ -26,7 +26,6 @@ ipc-namespace
26netfilter 26netfilter
27nodvd 27nodvd
28nogroups 28nogroups
29noinput
30nonewprivs 29nonewprivs
31noroot 30noroot
32notv 31notv
diff --git a/etc/profile-m-z/torcs.profile b/etc/profile-m-z/torcs.profile
index a7ebaf2af..19e586db4 100644
--- a/etc/profile-m-z/torcs.profile
+++ b/etc/profile-m-z/torcs.profile
@@ -28,7 +28,6 @@ ipc-namespace
28net none 28net none
29nodvd 29nodvd
30nogroups 30nogroups
31noinput
32nonewprivs 31nonewprivs
33noroot 32noroot
34notv 33notv
diff --git a/etc/profile-m-z/tremulous.profile b/etc/profile-m-z/tremulous.profile
index 4e16df553..96541ae25 100644
--- a/etc/profile-m-z/tremulous.profile
+++ b/etc/profile-m-z/tremulous.profile
@@ -8,6 +8,9 @@ include globals.local
8 8
9noblacklist ${HOME}/.tremulous 9noblacklist ${HOME}/.tremulous
10 10
11# Allow /bin/sh (blacklisted by disable-shell.inc)
12include allow-bin-sh.inc
13
11include disable-common.inc 14include disable-common.inc
12include disable-devel.inc 15include disable-devel.inc
13include disable-exec.inc 16include disable-exec.inc
@@ -41,7 +44,7 @@ shell none
41tracelog 44tracelog
42 45
43disable-mnt 46disable-mnt
44private-bin tremded,tremulous,tremulous-wrapper 47private-bin env,sh,tremded,tremulous,tremulous-wrapper
45private-cache 48private-cache
46private-dev 49private-dev
47private-tmp 50private-tmp
diff --git a/etc/profile-m-z/warsow.profile b/etc/profile-m-z/warsow.profile
index 5659ec69c..2f818b733 100644
--- a/etc/profile-m-z/warsow.profile
+++ b/etc/profile-m-z/warsow.profile
@@ -11,6 +11,9 @@ ignore noexec ${HOME}
11noblacklist ${HOME}/.cache/warsow-2.1 11noblacklist ${HOME}/.cache/warsow-2.1
12noblacklist ${HOME}/.local/share/warsow-2.1 12noblacklist ${HOME}/.local/share/warsow-2.1
13 13
14# Allow /bin/sh (blacklisted by disable-shell.inc)
15include allow-bin-sh.inc
16
14include disable-common.inc 17include disable-common.inc
15include disable-devel.inc 18include disable-devel.inc
16include disable-exec.inc 19include disable-exec.inc
@@ -34,19 +37,18 @@ ipc-namespace
34netfilter 37netfilter
35nodvd 38nodvd
36nogroups 39nogroups
37noinput
38nonewprivs 40nonewprivs
39noroot 41noroot
40notv 42notv
41nou2f 43nou2f
42novideo 44novideo
43protocol unix,inet,inet6 45protocol unix,inet,inet6,netlink
44seccomp 46seccomp
45shell none 47shell none
46tracelog 48tracelog
47 49
48disable-mnt 50disable-mnt
49private-bin warsow 51private-bin basename,bash,dirname,sed,sh,uname,warsow
50private-cache 52private-cache
51private-dev 53private-dev
52private-tmp 54private-tmp
diff --git a/etc/profile-m-z/xonotic.profile b/etc/profile-m-z/xonotic.profile
index 6ffe9ece9..7c2b38d1d 100644
--- a/etc/profile-m-z/xonotic.profile
+++ b/etc/profile-m-z/xonotic.profile
@@ -32,7 +32,6 @@ caps.drop all
32netfilter 32netfilter
33nodvd 33nodvd
34nogroups 34nogroups
35noinput
36nonewprivs 35nonewprivs
37noroot 36noroot
38notv 37notv
diff --git a/etc/templates/profile.template b/etc/templates/profile.template
index 7628313e0..44197b547 100644
--- a/etc/templates/profile.template
+++ b/etc/templates/profile.template
@@ -116,6 +116,7 @@ include globals.local
116#include disable-devel.inc 116#include disable-devel.inc
117#include disable-exec.inc 117#include disable-exec.inc
118#include disable-interpreters.inc 118#include disable-interpreters.inc
119#include disable-proc.inc
119#include disable-programs.inc 120#include disable-programs.inc
120#include disable-shell.inc 121#include disable-shell.inc
121#include disable-write-mnt.inc 122#include disable-write-mnt.inc
diff --git a/src/fbuilder/build_fs.c b/src/fbuilder/build_fs.c
index 8700e0ba1..a1847284c 100644
--- a/src/fbuilder/build_fs.c
+++ b/src/fbuilder/build_fs.c
@@ -236,9 +236,6 @@ void build_share(const char *fname, FILE *fp) {
236//******************************************* 236//*******************************************
237static FileDB *tmp_out = NULL; 237static FileDB *tmp_out = NULL;
238static void tmp_callback(char *ptr) { 238static void tmp_callback(char *ptr) {
239 // skip strace file
240 if (strncmp(ptr, "/tmp/firejail-strace", 20) == 0)
241 return;
242 if (strncmp(ptr, "/tmp/runtime-", 13) == 0) 239 if (strncmp(ptr, "/tmp/runtime-", 13) == 0)
243 return; 240 return;
244 if (strcmp(ptr, "/tmp") == 0) 241 if (strcmp(ptr, "/tmp") == 0)
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index d29c2a976..a6924b830 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -519,6 +519,7 @@ void touch_file_as_user(const char *fname, mode_t mode);
519int is_dir(const char *fname); 519int is_dir(const char *fname);
520int is_link(const char *fname); 520int is_link(const char *fname);
521char *realpath_as_user(const char *fname); 521char *realpath_as_user(const char *fname);
522ssize_t readlink_as_user(const char *fname, char *buf, size_t sz);
522int stat_as_user(const char *fname, struct stat *s); 523int stat_as_user(const char *fname, struct stat *s);
523int lstat_as_user(const char *fname, struct stat *s); 524int lstat_as_user(const char *fname, struct stat *s);
524void trim_trailing_slash_or_dot(char *path); 525void trim_trailing_slash_or_dot(char *path);
@@ -532,7 +533,7 @@ void update_map(char *mapping, char *map_file);
532void wait_for_other(int fd); 533void wait_for_other(int fd);
533void notify_other(int fd); 534void notify_other(int fd);
534uid_t pid_get_uid(pid_t pid); 535uid_t pid_get_uid(pid_t pid);
535uid_t get_group_id(const char *group); 536gid_t get_group_id(const char *groupname);
536void flush_stdin(void); 537void flush_stdin(void);
537int create_empty_dir_as_user(const char *dir, mode_t mode); 538int create_empty_dir_as_user(const char *dir, mode_t mode);
538void create_empty_dir_as_root(const char *dir, mode_t mode); 539void create_empty_dir_as_root(const char *dir, mode_t mode);
@@ -566,7 +567,7 @@ typedef struct {
566// mountinfo.c 567// mountinfo.c
567MountData *get_last_mount(void); 568MountData *get_last_mount(void);
568int get_mount_id(int fd); 569int get_mount_id(int fd);
569char **build_mount_array(const int mount_id, const char *path); 570char **build_mount_array(const int mountid, const char *path);
570 571
571// fs_var.c 572// fs_var.c
572void fs_var_log(void); // mounting /var/log 573void fs_var_log(void); // mounting /var/log
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 0b9a38035..9c1b889ed 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -654,12 +654,13 @@ static void fs_remount_rec(const char *path, OPERATION op) {
654 654
655 // build array with all mount points that need to get remounted 655 // build array with all mount points that need to get remounted
656 char **arr = build_mount_array(mountid, path); 656 char **arr = build_mount_array(mountid, path);
657 assert(arr); 657 if (!arr)
658 return;
658 // remount 659 // remount
659 char **tmp = arr; 660 int i;
660 while (*tmp) { 661 for (i = 0; arr[i]; i++) {
661 fs_remount_simple(*tmp, op); 662 fs_remount_simple(arr[i], op);
662 free(*tmp++); 663 free(arr[i]);
663 } 664 }
664 free(arr); 665 free(arr);
665} 666}
diff --git a/src/firejail/main.c b/src/firejail/main.c
index c5b3d5739..1ba70b0bd 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -2156,6 +2156,10 @@ int main(int argc, char **argv, char **envp) {
2156 arg_novideo = 1; 2156 arg_novideo = 1;
2157 else if (strcmp(argv[i], "--no3d") == 0) 2157 else if (strcmp(argv[i], "--no3d") == 0)
2158 arg_no3d = 1; 2158 arg_no3d = 1;
2159 else if (strcmp(argv[i], "--noprinters") == 0) {
2160 profile_add("blacklist /dev/lp*");
2161 profile_add("blacklist /run/cups/cups.sock");
2162 }
2159 else if (strcmp(argv[i], "--notv") == 0) 2163 else if (strcmp(argv[i], "--notv") == 0)
2160 arg_notv = 1; 2164 arg_notv = 1;
2161 else if (strcmp(argv[i], "--nodvd") == 0) 2165 else if (strcmp(argv[i], "--nodvd") == 0)
diff --git a/src/firejail/mountinfo.c b/src/firejail/mountinfo.c
index 304f80eee..ee437e10b 100644
--- a/src/firejail/mountinfo.c
+++ b/src/firejail/mountinfo.c
@@ -33,43 +33,38 @@ static MountData mdata;
33 33
34 34
35// Convert octal escape sequence to decimal value 35// Convert octal escape sequence to decimal value
36static int read_oct(const char *path) { 36static unsigned read_oct(char *s) {
37 int dec = 0; 37 assert(s[0] == '\\');
38 int digit, i; 38 s++;
39 // there are always exactly three octal digits 39
40 for (i = 1; i < 4; i++) { 40 int i;
41 digit = *(path + i); 41 for (i = 0; i < 3; i++)
42 if (digit < '0' || digit > '7') { 42 assert(s[i] >= '0' && s[i] <= '7');
43 fprintf(stderr, "Error: cannot read /proc/self/mountinfo\n"); 43
44 exit(1); 44 return ((s[0] - '0') << 6 |
45 } 45 (s[1] - '0') << 3 |
46 dec = (dec << 3) + (digit - '0'); 46 (s[2] - '0') << 0);
47 }
48 return dec;
49} 47}
50 48
51// Restore empty spaces in pathnames extracted from /proc/self/mountinfo 49// Restore empty spaces in pathnames extracted from /proc/self/mountinfo
52static void unmangle_path(char *path) { 50static void unmangle_path(char *path) {
53 char *p = strchr(path, '\\'); 51 char *r = strchr(path, '\\');
54 if (p && read_oct(p) == ' ') { 52 if (!r)
55 *p = ' '; 53 return;
56 int i = 3; 54
57 do { 55 char *w = r;
58 p++; 56 do {
59 if (*(p + i) == '\\' && read_oct(p + i) == ' ') { 57 while (*r == '\\') {
60 *p = ' '; 58 *w++ = read_oct(r);
61 i += 3; 59 r += 4;
62 } 60 }
63 else 61 *w++ = *r;
64 *p = *(p + i); 62 } while (*r++);
65 } while (*p);
66 }
67} 63}
68 64
69// Parse a line from /proc/self/mountinfo, 65// Parse a line from /proc/self/mountinfo,
70// the function does an exit(1) if anything goes wrong. 66// the function does an exit(1) if anything goes wrong.
71static void parse_line(char *line, MountData *output) { 67static void parse_line(char *line, MountData *output) {
72 assert(line && output);
73 memset(output, 0, sizeof(*output)); 68 memset(output, 0, sizeof(*output));
74 // extract mount id, filesystem name, directory and filesystem types 69 // extract mount id, filesystem name, directory and filesystem types
75 // examples: 70 // examples:
@@ -87,8 +82,6 @@ static void parse_line(char *line, MountData *output) {
87 char *ptr = strtok(line, " "); 82 char *ptr = strtok(line, " ");
88 if (!ptr) 83 if (!ptr)
89 goto errexit; 84 goto errexit;
90 if (ptr != line)
91 goto errexit;
92 output->mountid = atoi(ptr); 85 output->mountid = atoi(ptr);
93 int cnt = 1; 86 int cnt = 1;
94 87
@@ -109,10 +102,9 @@ static void parse_line(char *line, MountData *output) {
109 ptr = strtok(NULL, " "); 102 ptr = strtok(NULL, " ");
110 if (!ptr) 103 if (!ptr)
111 goto errexit; 104 goto errexit;
112 output->fstype = ptr++; 105 output->fstype = ptr;
113 106
114 107 if (output->mountid < 0 ||
115 if (output->mountid == 0 ||
116 output->fsname == NULL || 108 output->fsname == NULL ||
117 output->dir == NULL || 109 output->dir == NULL ||
118 output->fstype == NULL) 110 output->fstype == NULL)
@@ -195,9 +187,9 @@ static int get_mount_id_from_fdinfo(int fd) {
195 char buf[MAX_BUF]; 187 char buf[MAX_BUF];
196 while (fgets(buf, MAX_BUF, fp)) { 188 while (fgets(buf, MAX_BUF, fp)) {
197 if (strncmp(buf, "mnt_id:", 7) == 0) { 189 if (strncmp(buf, "mnt_id:", 7) == 0) {
198 if (sscanf(buf + 7, "%d", &rv) != 1) 190 if (sscanf(buf + 7, "%d", &rv) == 1)
199 goto errexit; 191 break;
200 break; 192 goto errexit;
201 } 193 }
202 } 194 }
203 195
@@ -219,62 +211,50 @@ int get_mount_id(int fd) {
219 211
220// Check /proc/self/mountinfo if path contains any mounts points. 212// Check /proc/self/mountinfo if path contains any mounts points.
221// Returns an array that can be iterated over for recursive remounting. 213// Returns an array that can be iterated over for recursive remounting.
222char **build_mount_array(const int mount_id, const char *path) { 214char **build_mount_array(const int mountid, const char *path) {
223 assert(path); 215 assert(path);
224 216
225 // open /proc/self/mountinfo
226 FILE *fp = fopen("/proc/self/mountinfo", "re"); 217 FILE *fp = fopen("/proc/self/mountinfo", "re");
227 if (!fp) { 218 if (!fp) {
228 fprintf(stderr, "Error: cannot read /proc/self/mountinfo\n"); 219 fprintf(stderr, "Error: cannot read /proc/self/mountinfo\n");
229 exit(1); 220 exit(1);
230 } 221 }
231 222
232 // array to be returned 223 // try to find line with mount id
233 size_t cnt = 0; 224 int found = 0;
225 MountData mntp;
226 char line[MAX_BUF];
227 while (fgets(line, MAX_BUF, fp)) {
228 parse_line(line, &mntp);
229 if (mntp.mountid == mountid) {
230 found = 1;
231 break;
232 }
233 }
234
235 if (!found) {
236 fclose(fp);
237 return NULL;
238 }
239
240 // allocate array
234 size_t size = 32; 241 size_t size = 32;
235 char **rv = malloc(size * sizeof(*rv)); 242 char **rv = malloc(size * sizeof(*rv));
236 if (!rv) 243 if (!rv)
237 errExit("malloc"); 244 errExit("malloc");
238 245
239 // read /proc/self/mountinfo 246 // add directory itself
240 size_t pathlen = strlen(path); 247 size_t cnt = 0;
241 char buf[MAX_BUF]; 248 rv[cnt] = strdup(path);
242 MountData mntp; 249 if (rv[cnt] == NULL)
243 int found = 0; 250 errExit("strdup");
244 251
245 if (fgets(buf, MAX_BUF, fp) == NULL) { 252 // and add all following mountpoints contained in this directory
246 fprintf(stderr, "Error: cannot read /proc/self/mountinfo\n"); 253 size_t pathlen = strlen(path);
247 exit(1); 254 while (fgets(line, MAX_BUF, fp)) {
248 } 255 parse_line(line, &mntp);
249 do { 256 if (strncmp(mntp.dir, path, pathlen) == 0 && mntp.dir[pathlen] == '/') {
250 parse_line(buf, &mntp); 257 if (++cnt == size) {
251 // find mount point with mount id
252 if (!found) {
253 if (mntp.mountid == mount_id) {
254 // give up if mount id has been reassigned,
255 // don't remount blacklisted path
256 if (strncmp(mntp.dir, path, strlen(mntp.dir)) ||
257 strstr(mntp.fsname, "firejail.ro.dir") ||
258 strstr(mntp.fsname, "firejail.ro.file"))
259 break;
260
261 rv[cnt] = strdup(path);
262 if (rv[cnt] == NULL)
263 errExit("strdup");
264 cnt++;
265 found = 1;
266 continue;
267 }
268 continue;
269 }
270 // from here on add all mount points below path,
271 // don't remount blacklisted paths
272 if (strncmp(mntp.dir, path, pathlen) == 0 &&
273 mntp.dir[pathlen] == '/' &&
274 strstr(mntp.fsname, "firejail.ro.dir") == NULL &&
275 strstr(mntp.fsname, "firejail.ro.file") == NULL) {
276
277 if (cnt == size) {
278 size *= 2; 258 size *= 2;
279 rv = realloc(rv, size * sizeof(*rv)); 259 rv = realloc(rv, size * sizeof(*rv));
280 if (!rv) 260 if (!rv)
@@ -283,18 +263,17 @@ char **build_mount_array(const int mount_id, const char *path) {
283 rv[cnt] = strdup(mntp.dir); 263 rv[cnt] = strdup(mntp.dir);
284 if (rv[cnt] == NULL) 264 if (rv[cnt] == NULL)
285 errExit("strdup"); 265 errExit("strdup");
286 cnt++;
287 } 266 }
288 } while (fgets(buf, MAX_BUF, fp)); 267 }
268 fclose(fp);
289 269
290 if (cnt == size) { 270 // end of array
291 size++; 271 if (++cnt == size) {
272 ++size;
292 rv = realloc(rv, size * sizeof(*rv)); 273 rv = realloc(rv, size * sizeof(*rv));
293 if (!rv) 274 if (!rv)
294 errExit("realloc"); 275 errExit("realloc");
295 } 276 }
296 rv[cnt] = NULL; // end of the array 277 rv[cnt] = NULL;
297
298 fclose(fp);
299 return rv; 278 return rv;
300} 279}
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 9d92b6199..babc3941e 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -449,6 +449,11 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
449 arg_no3d = 1; 449 arg_no3d = 1;
450 return 0; 450 return 0;
451 } 451 }
452 else if (strcmp(ptr, "noprinters") == 0) {
453 profile_add("blacklist /dev/lp*");
454 profile_add("blacklist /run/cups/cups.sock");
455 return 0;
456 }
452 else if (strcmp(ptr, "noinput") == 0) { 457 else if (strcmp(ptr, "noinput") == 0) {
453 arg_noinput = 1; 458 arg_noinput = 1;
454 return 0; 459 return 0;
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 8749f79cc..55dcdc246 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -484,13 +484,6 @@ int is_link(const char *fname) {
484 if (*fname == '\0') 484 if (*fname == '\0')
485 return 0; 485 return 0;
486 486
487 int called_as_root = 0;
488 if (geteuid() == 0)
489 called_as_root = 1;
490
491 if (called_as_root)
492 EUID_USER();
493
494 // remove trailing '/' if any 487 // remove trailing '/' if any
495 char *tmp = strdup(fname); 488 char *tmp = strdup(fname);
496 if (!tmp) 489 if (!tmp)
@@ -498,12 +491,9 @@ int is_link(const char *fname) {
498 trim_trailing_slash_or_dot(tmp); 491 trim_trailing_slash_or_dot(tmp);
499 492
500 char c; 493 char c;
501 ssize_t rv = readlink(tmp, &c, 1); 494 ssize_t rv = readlink_as_user(tmp, &c, 1);
502 free(tmp); 495 free(tmp);
503 496
504 if (called_as_root)
505 EUID_ROOT();
506
507 return (rv != -1); 497 return (rv != -1);
508} 498}
509 499
@@ -525,6 +515,24 @@ char *realpath_as_user(const char *fname) {
525 return rv; 515 return rv;
526} 516}
527 517
518ssize_t readlink_as_user(const char *fname, char *buf, size_t sz) {
519 assert(fname && buf && sz);
520
521 int called_as_root = 0;
522 if (geteuid() == 0)
523 called_as_root = 1;
524
525 if (called_as_root)
526 EUID_USER();
527
528 ssize_t rv = readlink(fname, buf, sz);
529
530 if (called_as_root)
531 EUID_ROOT();
532
533 return rv;
534}
535
528int stat_as_user(const char *fname, struct stat *s) { 536int stat_as_user(const char *fname, struct stat *s) {
529 assert(fname); 537 assert(fname);
530 538
@@ -959,10 +967,9 @@ uid_t pid_get_uid(pid_t pid) {
959} 967}
960 968
961 969
962uid_t get_group_id(const char *group) { 970gid_t get_group_id(const char *groupname) {
963 // find tty group id
964 gid_t gid = 0; 971 gid_t gid = 0;
965 struct group *g = getgrnam(group); 972 struct group *g = getgrnam(groupname);
966 if (g) 973 if (g)
967 gid = g->gr_gid; 974 gid = g->gr_gid;
968 975
@@ -998,31 +1005,33 @@ int create_empty_dir_as_user(const char *dir, mode_t mode) {
998 assert(dir); 1005 assert(dir);
999 mode &= 07777; 1006 mode &= 07777;
1000 1007
1001 if (access(dir, F_OK) != 0) { 1008 if (access(dir, F_OK) == 0)
1009 return 0;
1010
1011 pid_t child = fork();
1012 if (child < 0)
1013 errExit("fork");
1014 if (child == 0) {
1015 // drop privileges
1016 drop_privs(0);
1017
1002 if (arg_debug) 1018 if (arg_debug)
1003 printf("Creating empty %s directory\n", dir); 1019 printf("Creating empty %s directory\n", dir);
1004 pid_t child = fork(); 1020 if (mkdir(dir, mode) == 0) {
1005 if (child < 0) 1021 int err = chmod(dir, mode);
1006 errExit("fork"); 1022 (void) err;
1007 if (child == 0) { 1023 }
1008 // drop privileges 1024 else if (arg_debug)
1009 drop_privs(0); 1025 printf("Directory %s not created: %s\n", dir, strerror(errno));
1010
1011 if (mkdir(dir, mode) == 0) {
1012 int err = chmod(dir, mode);
1013 (void) err;
1014 }
1015 else if (arg_debug)
1016 printf("Directory %s not created: %s\n", dir, strerror(errno));
1017 1026
1018 __gcov_flush(); 1027 __gcov_flush();
1019 1028
1020 _exit(0); 1029 _exit(0);
1021 }
1022 waitpid(child, NULL, 0);
1023 if (access(dir, F_OK) == 0)
1024 return 1;
1025 } 1030 }
1031 waitpid(child, NULL, 0);
1032
1033 if (access(dir, F_OK) == 0)
1034 return 1;
1026 return 0; 1035 return 0;
1027} 1036}
1028 1037
@@ -1412,7 +1421,7 @@ static int has_link(const char *dir) {
1412void check_homedir(const char *dir) { 1421void check_homedir(const char *dir) {
1413 assert(dir); 1422 assert(dir);
1414 if (dir[0] != '/') { 1423 if (dir[0] != '/') {
1415 fprintf(stderr, "Error: invalid user directory \"%s\"\n", cfg.homedir); 1424 fprintf(stderr, "Error: invalid user directory \"%s\"\n", dir);
1416 exit(1); 1425 exit(1);
1417 } 1426 }
1418 // symlinks are rejected in many places 1427 // symlinks are rejected in many places
diff --git a/src/libtrace/libtrace.c b/src/libtrace/libtrace.c
index d88512b0a..319902ff7 100644
--- a/src/libtrace/libtrace.c
+++ b/src/libtrace/libtrace.c
@@ -18,12 +18,12 @@
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/ 19*/
20#define _GNU_SOURCE 20#define _GNU_SOURCE
21#include <errno.h>
21#include <stdio.h> 22#include <stdio.h>
22#include <stdlib.h> 23#include <stdlib.h>
23#include <string.h> 24#include <string.h>
24#include <dlfcn.h> 25#include <dlfcn.h>
25#include <sys/types.h> 26#include <sys/types.h>
26#include <limits.h>
27#include <unistd.h> 27#include <unistd.h>
28#include <sys/socket.h> 28#include <sys/socket.h>
29#include <netinet/in.h> 29#include <netinet/in.h>
@@ -706,10 +706,14 @@ __attribute__((constructor))
706static void log_exec(int argc, char** argv) { 706static void log_exec(int argc, char** argv) {
707 (void) argc; 707 (void) argc;
708 (void) argv; 708 (void) argv;
709 static char buf[PATH_MAX + 1]; 709 char *buf = realpath("/proc/self/exe", NULL);
710 int rv = readlink("/proc/self/exe", buf, PATH_MAX); 710 if (buf == NULL) {
711 if (rv != -1) { 711 if (errno == ENOMEM) {
712 buf[rv] = '\0'; // readlink does not add a '\0' at the end 712 tprintf(ftty, "realpath: %s\n", strerror(errno));
713 exit(1);
714 }
715 } else {
713 tprintf(ftty, "%u:%s:exec %s:0\n", mypid, myname, buf); 716 tprintf(ftty, "%u:%s:exec %s:0\n", mypid, myname, buf);
717 free(buf);
714 } 718 }
715} 719}
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 154def585..e724e4bb9 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -310,6 +310,11 @@ regular user, nonewprivs and a default capabilities filter are enabled.
310Example: 310Example:
311.br 311.br
312$ firejail \-\-chroot=/media/ubuntu warzone2100 312$ firejail \-\-chroot=/media/ubuntu warzone2100
313.br
314
315.br
316For automatic mounting of X11 and PulseAudio sockets set environment variables
317FIREJAIL_CHROOT_X11 and FIREJAIL_CHROOT_PULSE.
313#endif 318#endif
314.TP 319.TP
315\fB\-\-cpu=cpu-number,cpu-number,cpu-number 320\fB\-\-cpu=cpu-number,cpu-number,cpu-number
@@ -2192,6 +2197,11 @@ More information about groups can be found in /usr/share/doc/firejail/syscalls.t
2192.br 2197.br
2193 2198
2194.br 2199.br
2200The default list can be customized, see \-\-seccomp= for a description.
2201It can be customized also globally in /etc/firejail/firejail.config file.
2202.br
2203
2204.br
2195System architecture is strictly imposed only if flag 2205System architecture is strictly imposed only if flag
2196\-\-seccomp.block-secondary is used. The filter is applied at run time 2206\-\-seccomp.block-secondary is used. The filter is applied at run time
2197only if the correct architecture was detected. For the case of I386 2207only if the correct architecture was detected. For the case of I386
@@ -2206,11 +2216,7 @@ Firejail will print seccomp violations to the audit log if the kernel was compil
2206Example: 2216Example:
2207.br 2217.br
2208$ firejail \-\-seccomp 2218$ firejail \-\-seccomp
2209.br
2210 2219
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 2220
2215.TP 2221.TP
2216\fB\-\-seccomp=syscall,@group,!syscall2 2222\fB\-\-seccomp=syscall,@group,!syscall2