aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@protonmail.com>2021-10-09 13:16:31 +0000
committerLibravatar GitHub <noreply@github.com>2021-10-09 13:16:31 +0000
commit44c15b67d48f2e5d2deff3f88cbf1129979065f7 (patch)
tree093e526ad450867c3cdf0b19a48a35553a91d342
parentfirejail.h: add missing linux/limits.h include (diff)
parentMerge pull request #4579 from dm9pZCAq/master (diff)
downloadfirejail-44c15b67d48f2e5d2deff3f88cbf1129979065f7.tar.gz
firejail-44c15b67d48f2e5d2deff3f88cbf1129979065f7.tar.zst
firejail-44c15b67d48f2e5d2deff3f88cbf1129979065f7.zip
Merge branch 'master' into fix-include-limits-h
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md21
-rw-r--r--README.md3
-rw-r--r--RELNOTES5
-rw-r--r--contrib/vim/syntax/firejail.vim2
-rw-r--r--etc/firejail.config3
-rw-r--r--etc/inc/allow-common-devel.inc5
-rw-r--r--etc/inc/allow-ruby.inc1
-rw-r--r--etc/inc/disable-interpreters.inc1
-rw-r--r--etc/inc/disable-programs.inc5
-rw-r--r--etc/profile-a-l/amule.profile1
-rw-r--r--etc/profile-a-l/build-systems-common.profile66
-rw-r--r--etc/profile-a-l/bundle.profile23
-rw-r--r--etc/profile-a-l/cargo.profile56
-rw-r--r--etc/profile-a-l/cheese.profile12
-rw-r--r--etc/profile-a-l/cmake.profile13
-rw-r--r--etc/profile-a-l/codium.profile10
-rw-r--r--etc/profile-a-l/geekbench.profile12
-rw-r--r--etc/profile-a-l/inkscape.profile1
-rw-r--r--etc/profile-m-z/make.profile13
-rw-r--r--etc/profile-m-z/meson.profile14
-rw-r--r--etc/profile-m-z/musixmatch.profile2
-rw-r--r--etc/profile-m-z/nheko.profile9
-rw-r--r--etc/profile-m-z/pandoc.profile5
-rw-r--r--etc/profile-m-z/pip.profile18
-rw-r--r--etc/profile-m-z/vscodium.profile4
-rw-r--r--src/fbuilder/build_fs.c8
-rw-r--r--src/fbuilder/build_home.c4
-rw-r--r--src/fbuilder/build_profile.c2
-rw-r--r--src/fcopy/main.c3
-rw-r--r--src/firecfg/firecfg.config1
-rw-r--r--src/firejail/checkcfg.c2
-rw-r--r--src/firejail/env.c1
-rw-r--r--src/firejail/firejail.h6
-rw-r--r--src/firejail/fs.c50
-rw-r--r--src/firejail/fs_dev.c2
-rw-r--r--src/firejail/fs_home.c11
-rw-r--r--src/firejail/fs_trace.c31
-rw-r--r--src/firejail/fs_whitelist.c59
-rw-r--r--src/firejail/main.c2
-rw-r--r--src/firejail/mountinfo.c71
-rw-r--r--src/firejail/profile.c15
-rw-r--r--src/firejail/sandbox.c13
-rw-r--r--src/firejail/selinux.c21
-rw-r--r--src/firejail/util.c14
-rw-r--r--src/man/firejail-profile.txt2
-rwxr-xr-xtest/utils/build.exp2
46 files changed, 414 insertions, 211 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 0f13afc51..eb485b8a2 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -7,6 +7,13 @@ assignees: ''
7 7
8--- 8---
9 9
10<!--
11See the following links for help with formatting:
12
13https://guides.github.com/features/mastering-markdown/
14https://docs.github.com/en/github/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax
15-->
16
10### Description 17### Description
11 18
12_Describe the bug_ 19_Describe the bug_
@@ -15,7 +22,7 @@ _Describe the bug_
15 22
16_Steps to reproduce the behavior_ 23_Steps to reproduce the behavior_
17 24
181. Run in bash `LANG=C firejail PROGRAM` (`LANG=C` to get English messages that can be understood by everybody) 251. Run in bash `LC_ALL=C firejail PROGRAM` (`LC_ALL=C` to get a consistent output in English that can be understood by everybody)
192. Click on '....' 262. Click on '....'
203. Scroll down to '....' 273. Scroll down to '....'
214. See error `ERROR` 284. See error `ERROR`
@@ -30,7 +37,7 @@ _What actually happened_
30 37
31### Behavior without a profile 38### Behavior without a profile
32 39
33_What changed calling `firejail --noprofile /path/to/program` in a terminal?_ 40_What changed calling `LC_ALL=C firejail --noprofile /path/to/program` in a terminal?_
34 41
35### Additional context 42### Additional context
36 43
@@ -44,6 +51,12 @@ _Any other detail that may help to understand/debug the problem_
44 51
45### Checklist 52### Checklist
46 53
54<!--
55Note: Items are checked with an "x", like so:
56
57- [x] This is a checked item.
58-->
59
47- [ ] The issues is caused by firejail (i.e. running the program by path (e.g. `/usr/bin/vlc`) "fixes" it). 60- [ ] The issues is caused by firejail (i.e. running the program by path (e.g. `/usr/bin/vlc`) "fixes" it).
48- [ ] I can reproduce the issue without custom modifications (e.g. globals.local). 61- [ ] I can reproduce the issue without custom modifications (e.g. globals.local).
49- [ ] The program has a profile. (If not, request one in `https://github.com/netblue30/firejail/issues/1139`) 62- [ ] The program has a profile. (If not, request one in `https://github.com/netblue30/firejail/issues/1139`)
@@ -55,7 +68,7 @@ _Any other detail that may help to understand/debug the problem_
55### Log 68### Log
56 69
57<details> 70<details>
58<summary>Output of <code>firejail /path/to/program</code></summary> 71<summary>Output of <code>LC_ALL=C firejail /path/to/program</code></summary>
59<p> 72<p>
60 73
61``` 74```
@@ -66,7 +79,7 @@ output goes here
66</details> 79</details>
67 80
68<details> 81<details>
69<summary>Output of <code>firejail --debug /path/to/program</code></summary> 82<summary>Output of <code>LC_ALL=C firejail --debug /path/to/program</code></summary>
70<p> 83<p>
71 84
72``` 85```
diff --git a/README.md b/README.md
index 0623d9463..40c6e9d98 100644
--- a/README.md
+++ b/README.md
@@ -267,4 +267,5 @@ $ ./profstats *.profile
267 267
268### New profiles: 268### New profiles:
269 269
270clion-eap, lifeograph, io.github.lainsce.Notejot, rednotebook, zim, microsoft-edge-beta, ncdu2, gallery-dl, yt-dlp 270clion-eap, lifeograph, io.github.lainsce.Notejot, rednotebook, zim, microsoft-edge-beta, ncdu2, gallery-dl, yt-dlp, goldendict, bundle,
271cmake, make, meson, pip, codium
diff --git a/RELNOTES b/RELNOTES
index f52ce09f1..3f92c89c7 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -1,13 +1,16 @@
1firejail (0.9.67) baseline; urgency=low 1firejail (0.9.67) baseline; urgency=low
2 * work in progress 2 * work in progress
3 * exit code: distinguish fatal signals by adding 128
3 * deprecated --disable-whitelist at compile time 4 * deprecated --disable-whitelist at compile time
4 * deprecated whitelist=yes/no in /etc/firejail/firejail.config 5 * deprecated whitelist=yes/no in /etc/firejail/firejail.config
6 * new condition: ALLOW_TRAY
5 * remove (some) environment variables with auth-tokens 7 * remove (some) environment variables with auth-tokens
6 * new includes: whitelist-run-common.inc, disable-X11.inc 8 * new includes: whitelist-run-common.inc, disable-X11.inc
7 * removed includes: disable-passwordmgr.inc 9 * removed includes: disable-passwordmgr.inc
8 * new profiles: microsoft-edge-beta, clion-eap, lifeograph, zim 10 * new profiles: microsoft-edge-beta, clion-eap, lifeograph, zim
9 * new profiles: io.github.lainsce.Notejot, rednotebook, gallery-dl 11 * new profiles: io.github.lainsce.Notejot, rednotebook, gallery-dl
10 * new profiles: yt-dlp 12 * new profiles: yt-dlp, goldendict, goldendict, bundle, cmake
13 * new profiles: make, meson, pip, codium
11 -- netblue30 <netblue30@yahoo.com> Thu, 29 Jul 2021 09:00:00 -0500 14 -- netblue30 <netblue30@yahoo.com> Thu, 29 Jul 2021 09:00:00 -0500
12 15
13firejail (0.9.66) baseline; urgency=low 16firejail (0.9.66) baseline; urgency=low
diff --git a/contrib/vim/syntax/firejail.vim b/contrib/vim/syntax/firejail.vim
index d07690ee2..fa80a9c00 100644
--- a/contrib/vim/syntax/firejail.vim
+++ b/contrib/vim/syntax/firejail.vim
@@ -72,7 +72,7 @@ syn match fjCommandNoCond /quiet$/ contained
72 72
73" Conditionals grabbed from: src/firejail/profile.c 73" Conditionals grabbed from: src/firejail/profile.c
74" Generate list with: awk -- 'BEGIN {process=0;} /^Cond conditionals\[\] = \{$/ {process=1;} /\t*\{"[^"]+".*/ { if (process) {print gensub(/^\t*\{"([^"]+)".*$/, "\\1", 1);} } /^\t\{ NULL, NULL \}$/ {process=0;}' src/firejail/profile.c | sort -u | tr $'\n' '|' 74" Generate list with: awk -- 'BEGIN {process=0;} /^Cond conditionals\[\] = \{$/ {process=1;} /\t*\{"[^"]+".*/ { if (process) {print gensub(/^\t*\{"([^"]+)".*$/, "\\1", 1);} } /^\t\{ NULL, NULL \}$/ {process=0;}' src/firejail/profile.c | sort -u | tr $'\n' '|'
75syn match fjConditional /\v\?(BROWSER_ALLOW_DRM|BROWSER_DISABLE_U2F|HAS_APPIMAGE|HAS_NET|HAS_NODBUS|HAS_NOSOUND|HAS_X11) ?:/ nextgroup=fjCommand skipwhite contained 75syn match fjConditional /\v\?(ALLOW_TRAY|BROWSER_ALLOW_DRM|BROWSER_DISABLE_U2F|HAS_APPIMAGE|HAS_NET|HAS_NODBUS|HAS_NOSOUND|HAS_X11) ?:/ nextgroup=fjCommand skipwhite contained
76 76
77" A line is either a command, a conditional or a comment 77" A line is either a command, a conditional or a comment
78syn match fjStatement /^/ nextgroup=fjCommand,fjCommandNoCond,fjConditional,fjComment 78syn match fjStatement /^/ nextgroup=fjCommand,fjCommandNoCond,fjConditional,fjComment
diff --git a/etc/firejail.config b/etc/firejail.config
index aec152b85..7912b746c 100644
--- a/etc/firejail.config
+++ b/etc/firejail.config
@@ -2,6 +2,9 @@
2# keyword-argument pairs, one per line. Most features are enabled by default. 2# keyword-argument pairs, one per line. Most features are enabled by default.
3# Use 'yes' or 'no' as configuration values. 3# Use 'yes' or 'no' as configuration values.
4 4
5# Allow programs to display a tray icon
6# allow-tray no
7
5# Enable AppArmor functionality, default enabled. 8# Enable AppArmor functionality, default enabled.
6# apparmor yes 9# apparmor yes
7 10
diff --git a/etc/inc/allow-common-devel.inc b/etc/inc/allow-common-devel.inc
index 011bbe226..4e460fc10 100644
--- a/etc/inc/allow-common-devel.inc
+++ b/etc/inc/allow-common-devel.inc
@@ -27,5 +27,8 @@ noblacklist ${HOME}/.python-history
27noblacklist ${HOME}/.python_history 27noblacklist ${HOME}/.python_history
28noblacklist ${HOME}/.pythonhist 28noblacklist ${HOME}/.pythonhist
29 29
30# Ruby
31noblacklist ${HOME}/.bundle
32
30# Rust 33# Rust
31noblacklist ${HOME}/.cargo/* 34noblacklist ${HOME}/.cargo
diff --git a/etc/inc/allow-ruby.inc b/etc/inc/allow-ruby.inc
index a8c701219..00276cac7 100644
--- a/etc/inc/allow-ruby.inc
+++ b/etc/inc/allow-ruby.inc
@@ -4,3 +4,4 @@ include allow-ruby.local
4 4
5noblacklist ${PATH}/ruby 5noblacklist ${PATH}/ruby
6noblacklist /usr/lib/ruby 6noblacklist /usr/lib/ruby
7noblacklist /usr/lib64/ruby
diff --git a/etc/inc/disable-interpreters.inc b/etc/inc/disable-interpreters.inc
index 5d8a236fb..804869e2a 100644
--- a/etc/inc/disable-interpreters.inc
+++ b/etc/inc/disable-interpreters.inc
@@ -48,6 +48,7 @@ blacklist /usr/share/php*
48# Ruby 48# Ruby
49blacklist ${PATH}/ruby 49blacklist ${PATH}/ruby
50blacklist /usr/lib/ruby 50blacklist /usr/lib/ruby
51blacklist /usr/lib64/ruby
51 52
52# Programs using python: deluge, firefox addons, filezilla, cherrytree, xchat, hexchat, libreoffice, scribus 53# Programs using python: deluge, firefox addons, filezilla, cherrytree, xchat, hexchat, libreoffice, scribus
53# Python 2 54# Python 2
diff --git a/etc/inc/disable-programs.inc b/etc/inc/disable-programs.inc
index e77ceb41c..6734e220a 100644
--- a/etc/inc/disable-programs.inc
+++ b/etc/inc/disable-programs.inc
@@ -49,8 +49,9 @@ blacklist ${HOME}/.bibletime
49blacklist ${HOME}/.bitcoin 49blacklist ${HOME}/.bitcoin
50blacklist ${HOME}/.blobby 50blacklist ${HOME}/.blobby
51blacklist ${HOME}/.bogofilter 51blacklist ${HOME}/.bogofilter
52blacklist ${HOME}/.bundle
52blacklist ${HOME}/.bzf 53blacklist ${HOME}/.bzf
53blacklist ${HOME}/.cargo/* 54blacklist ${HOME}/.cargo
54blacklist ${HOME}/.claws-mail 55blacklist ${HOME}/.claws-mail
55blacklist ${HOME}/.cliqz 56blacklist ${HOME}/.cliqz
56blacklist ${HOME}/.clion* 57blacklist ${HOME}/.clion*
@@ -142,6 +143,7 @@ blacklist ${HOME}/.config/SubDownloader
142blacklist ${HOME}/.config/Thunar 143blacklist ${HOME}/.config/Thunar
143blacklist ${HOME}/.config/Twitch 144blacklist ${HOME}/.config/Twitch
144blacklist ${HOME}/.config/Unknown Organization 145blacklist ${HOME}/.config/Unknown Organization
146blacklist ${HOME}/.config/VSCodium
145blacklist ${HOME}/.config/VirtualBox 147blacklist ${HOME}/.config/VirtualBox
146blacklist ${HOME}/.config/Whalebird 148blacklist ${HOME}/.config/Whalebird
147blacklist ${HOME}/.config/Wire 149blacklist ${HOME}/.config/Wire
@@ -496,6 +498,7 @@ blacklist ${HOME}/.frogatto
496blacklist ${HOME}/.frozen-bubble 498blacklist ${HOME}/.frozen-bubble
497blacklist ${HOME}/.funnyboat 499blacklist ${HOME}/.funnyboat
498blacklist ${HOME}/.gallery-dl.conf 500blacklist ${HOME}/.gallery-dl.conf
501blacklist ${HOME}/.geekbench5
499blacklist ${HOME}/.gimp* 502blacklist ${HOME}/.gimp*
500blacklist ${HOME}/.gist 503blacklist ${HOME}/.gist
501blacklist ${HOME}/.gitconfig 504blacklist ${HOME}/.gitconfig
diff --git a/etc/profile-a-l/amule.profile b/etc/profile-a-l/amule.profile
index 3ce05c5bc..e82c145d1 100644
--- a/etc/profile-a-l/amule.profile
+++ b/etc/profile-a-l/amule.profile
@@ -32,6 +32,7 @@ nosound
32notv 32notv
33nou2f 33nou2f
34novideo 34novideo
35# Add netlink protocol to use UPnP
35protocol unix,inet,inet6 36protocol unix,inet,inet6
36seccomp 37seccomp
37shell none 38shell none
diff --git a/etc/profile-a-l/build-systems-common.profile b/etc/profile-a-l/build-systems-common.profile
new file mode 100644
index 000000000..1b199d612
--- /dev/null
+++ b/etc/profile-a-l/build-systems-common.profile
@@ -0,0 +1,66 @@
1# Firejail profile for build-systems-common
2# This file is overwritten after every install/update
3# Persistent local customizations
4include build-systems-common.local
5# Persistent global definitions
6# added by caller profile
7#include globals.local
8
9ignore noexec ${HOME}
10ignore noexec /tmp
11
12# Allow /bin/sh (blacklisted by disable-shell.inc)
13include allow-bin-sh.inc
14
15# Allows files commonly used by IDEs
16include allow-common-devel.inc
17
18# Allow ssh (blacklisted by disable-common.inc)
19#include allow-ssh.inc
20
21blacklist ${RUNUSER}
22
23include disable-common.inc
24include disable-exec.inc
25include disable-interpreters.inc
26include disable-programs.inc
27include disable-shell.inc
28include disable-X11.inc
29include disable-xdg.inc
30
31#whitelist ${HOME}/Projects
32#include whitelist-common.inc
33
34whitelist /usr/share/pkgconfig
35include whitelist-run-common.inc
36include whitelist-usr-share-common.inc
37include whitelist-var-common.inc
38
39caps.drop all
40ipc-namespace
41machine-id
42# net none
43netfilter
44no3d
45nodvd
46nogroups
47noinput
48nonewprivs
49noroot
50nosound
51notv
52nou2f
53novideo
54protocol unix,inet,inet6
55seccomp
56seccomp.block-secondary
57shell none
58tracelog
59
60disable-mnt
61private-cache
62private-dev
63private-tmp
64
65dbus-user none
66dbus-system none
diff --git a/etc/profile-a-l/bundle.profile b/etc/profile-a-l/bundle.profile
new file mode 100644
index 000000000..bb82022b1
--- /dev/null
+++ b/etc/profile-a-l/bundle.profile
@@ -0,0 +1,23 @@
1# Firejail profile for bundle
2# Description: Ruby Dependency Management
3# This file is overwritten after every install/update
4quiet
5# Persistent local customizations
6include bundle.local
7# Persistent global definitions
8include globals.local
9
10noblacklist ${HOME}/.bundle
11
12# Allow ruby (blacklisted by disable-interpreters.inc)
13include allow-ruby.inc
14
15#whitelist ${HOME}/.bundle
16#whitelist ${HOME}/.gem
17#whitelist ${HOME}/.local/share/gem
18whitelist /usr/share/gems
19whitelist /usr/share/ruby
20whitelist /usr/share/rubygems
21
22# Redirect
23include build-systems-common.profile
diff --git a/etc/profile-a-l/cargo.profile b/etc/profile-a-l/cargo.profile
index ff46cd429..4c8afd895 100644
--- a/etc/profile-a-l/cargo.profile
+++ b/etc/profile-a-l/cargo.profile
@@ -7,66 +7,18 @@ include cargo.local
7# Persistent global definitions 7# Persistent global definitions
8include globals.local 8include globals.local
9 9
10ignore noexec ${HOME} 10ignore read-only ${HOME}/.cargo/bin
11ignore noexec /tmp
12
13blacklist /tmp/.X11-unix
14blacklist ${RUNUSER}
15 11
16noblacklist ${HOME}/.cargo/credentials 12noblacklist ${HOME}/.cargo/credentials
17noblacklist ${HOME}/.cargo/credentials.toml 13noblacklist ${HOME}/.cargo/credentials.toml
18 14
19# Allows files commonly used by IDEs
20include allow-common-devel.inc
21
22# Allow ssh (blacklisted by disable-common.inc)
23#include allow-ssh.inc
24
25include disable-common.inc
26include disable-exec.inc
27include disable-interpreters.inc
28include disable-programs.inc
29include disable-xdg.inc
30
31#mkdir ${HOME}/.cargo
32#whitelist ${HOME}/YOUR_CARGO_PROJECTS
33#whitelist ${HOME}/.cargo 15#whitelist ${HOME}/.cargo
34#whitelist ${HOME}/.rustup 16#whitelist ${HOME}/.rustup
35#include whitelist-common.inc
36whitelist /usr/share/pkgconfig
37include whitelist-runuser-common.inc
38include whitelist-usr-share-common.inc
39include whitelist-var-common.inc
40 17
41caps.drop all
42ipc-namespace
43machine-id
44netfilter
45no3d
46nodvd
47nogroups
48noinput
49nonewprivs
50noroot
51nosound
52notv
53nou2f
54novideo
55protocol unix,inet,inet6
56seccomp
57seccomp.block-secondary
58shell none
59tracelog
60
61disable-mnt
62#private-bin cargo,rustc 18#private-bin cargo,rustc
63private-cache
64private-dev
65private-etc alternatives,ca-certificates,crypto-policies,group,host.conf,hostname,hosts,ld.so.cache,ld.so.conf,ld.so.conf.d,ld.so.preload,locale,locale.alias,locale.conf,localtime,magic,magic.mgc,nsswitch.conf,passwd,pki,protocols,resolv.conf,rpc,services,ssl 19private-etc alternatives,ca-certificates,crypto-policies,group,host.conf,hostname,hosts,ld.so.cache,ld.so.conf,ld.so.conf.d,ld.so.preload,locale,locale.alias,locale.conf,localtime,magic,magic.mgc,nsswitch.conf,passwd,pki,protocols,resolv.conf,rpc,services,ssl
66private-tmp
67
68dbus-user none
69dbus-system none
70 20
71memory-deny-write-execute 21memory-deny-write-execute
72read-write ${HOME}/.cargo/bin 22
23# Redirect
24include build-systems-common.profile
diff --git a/etc/profile-a-l/cheese.profile b/etc/profile-a-l/cheese.profile
index 53d221631..978d727f4 100644
--- a/etc/profile-a-l/cheese.profile
+++ b/etc/profile-a-l/cheese.profile
@@ -9,17 +9,24 @@ include globals.local
9noblacklist ${VIDEOS} 9noblacklist ${VIDEOS}
10noblacklist ${PICTURES} 10noblacklist ${PICTURES}
11 11
12include allow-python3.inc
13
12include disable-common.inc 14include disable-common.inc
13include disable-devel.inc 15include disable-devel.inc
14include disable-exec.inc 16include disable-exec.inc
15include disable-interpreters.inc 17include disable-interpreters.inc
16include disable-programs.inc 18include disable-programs.inc
19include disable-shell.inc
17include disable-xdg.inc 20include disable-xdg.inc
18 21
19whitelist ${VIDEOS} 22whitelist ${VIDEOS}
20whitelist ${PICTURES} 23whitelist ${PICTURES}
24whitelist /run/udev/data
25whitelist /usr/libexec/gstreamer-1.0/gst-plugin-scanner
21whitelist /usr/share/gnome-video-effects 26whitelist /usr/share/gnome-video-effects
27whitelist /usr/share/gstreamer-1.0
22include whitelist-common.inc 28include whitelist-common.inc
29include whitelist-run-common.inc
23include whitelist-runuser-common.inc 30include whitelist-runuser-common.inc
24include whitelist-usr-share-common.inc 31include whitelist-usr-share-common.inc
25include whitelist-var-common.inc 32include whitelist-var-common.inc
@@ -30,21 +37,26 @@ machine-id
30net none 37net none
31nodvd 38nodvd
32nogroups 39nogroups
40noinput
33nonewprivs 41nonewprivs
34noroot 42noroot
43nosound
35notv 44notv
36nou2f 45nou2f
37protocol unix 46protocol unix
38seccomp 47seccomp
48seccomp.block-secondary
39shell none 49shell none
40tracelog 50tracelog
41 51
42disable-mnt 52disable-mnt
43private-bin cheese 53private-bin cheese
44private-cache 54private-cache
55private-dev
45private-etc alternatives,clutter-1.0,dconf,drirc,fonts,gtk-3.0,ld.so.preload 56private-etc alternatives,clutter-1.0,dconf,drirc,fonts,gtk-3.0,ld.so.preload
46private-tmp 57private-tmp
47 58
48dbus-user filter 59dbus-user filter
60dbus-user.own org.gnome.Cheese
49dbus-user.talk ca.desrt.dconf 61dbus-user.talk ca.desrt.dconf
50dbus-system none 62dbus-system none
diff --git a/etc/profile-a-l/cmake.profile b/etc/profile-a-l/cmake.profile
new file mode 100644
index 000000000..26cc2a00a
--- /dev/null
+++ b/etc/profile-a-l/cmake.profile
@@ -0,0 +1,13 @@
1# Firejail profile for cargo
2# Description: The Rust package manager
3# This file is overwritten after every install/update
4quiet
5# Persistent local customizations
6include cargo.local
7# Persistent global definitions
8include globals.local
9
10memory-deny-write-execute
11
12# Redirect
13include build-systems-common.profile
diff --git a/etc/profile-a-l/codium.profile b/etc/profile-a-l/codium.profile
new file mode 100644
index 000000000..9ff87ed8a
--- /dev/null
+++ b/etc/profile-a-l/codium.profile
@@ -0,0 +1,10 @@
1# Firejail profile alias for VSCodium
2# This file is overwritten after every install/update
3# Persistent local customizations
4include codium.local
5# Persistent global definitions
6# added by included profile
7#include globals.local
8
9# Redirect
10include vscodium.profile
diff --git a/etc/profile-a-l/geekbench.profile b/etc/profile-a-l/geekbench.profile
index 60f2f338d..4812e1368 100644
--- a/etc/profile-a-l/geekbench.profile
+++ b/etc/profile-a-l/geekbench.profile
@@ -6,6 +6,10 @@ include geekbench.local
6# Persistent global definitions 6# Persistent global definitions
7include globals.local 7include globals.local
8 8
9noblacklist ${HOME}/.geekbench5
10noblacklist /sbin
11noblacklist /usr/sbin
12
9include disable-common.inc 13include disable-common.inc
10include disable-devel.inc 14include disable-devel.inc
11include disable-exec.inc 15include disable-exec.inc
@@ -13,6 +17,8 @@ include disable-interpreters.inc
13include disable-programs.inc 17include disable-programs.inc
14include disable-xdg.inc 18include disable-xdg.inc
15 19
20mkdir ${HOME}/.geekbench5
21whitelist ${HOME}/.geekbench5
16include whitelist-common.inc 22include whitelist-common.inc
17include whitelist-usr-share-common.inc 23include whitelist-usr-share-common.inc
18include whitelist-var-common.inc 24include whitelist-var-common.inc
@@ -39,16 +45,14 @@ shell none
39tracelog 45tracelog
40 46
41disable-mnt 47disable-mnt
42private-bin bash,geekbenc*,sh 48#private-bin bash,geekbench*,sh -- #4576
43private-cache 49private-cache
44private-dev 50private-dev
45private-etc alternatives,group,ld.so.preload,lsb-release,passwd 51private-etc alternatives,group,ld.so.preload,lsb-release,passwd
46private-lib gcc/*/*/libstdc++.so.*
47private-opt none
48private-tmp 52private-tmp
49 53
50dbus-user none 54dbus-user none
51dbus-system none 55dbus-system none
52 56
53#memory-deny-write-execute - breaks on Arch (see issue #1803)
54read-only ${HOME} 57read-only ${HOME}
58read-write ${HOME}/.geekbench5
diff --git a/etc/profile-a-l/inkscape.profile b/etc/profile-a-l/inkscape.profile
index 5e54b5441..e0015e69a 100644
--- a/etc/profile-a-l/inkscape.profile
+++ b/etc/profile-a-l/inkscape.profile
@@ -1,6 +1,7 @@
1# Firejail profile for inkscape 1# Firejail profile for inkscape
2# Description: Vector-based drawing program 2# Description: Vector-based drawing program
3# This file is overwritten after every install/update 3# This file is overwritten after every install/update
4quiet
4# Persistent local customizations 5# Persistent local customizations
5include inkscape.local 6include inkscape.local
6# Persistent global definitions 7# Persistent global definitions
diff --git a/etc/profile-m-z/make.profile b/etc/profile-m-z/make.profile
new file mode 100644
index 000000000..7e9638fe4
--- /dev/null
+++ b/etc/profile-m-z/make.profile
@@ -0,0 +1,13 @@
1# Firejail profile for make
2# Description: GNU make utility to maintain groups of programs
3# This file is overwritten after every install/update
4quiet
5# Persistent local customizations
6include make.local
7# Persistent global definitions
8include globals.local
9
10memory-deny-write-execute
11
12# Redirect
13include build-systems-common.profile
diff --git a/etc/profile-m-z/meson.profile b/etc/profile-m-z/meson.profile
new file mode 100644
index 000000000..b4909a9d8
--- /dev/null
+++ b/etc/profile-m-z/meson.profile
@@ -0,0 +1,14 @@
1# Firejail profile for meson
2# Description: A high productivity build system
3# This file is overwritten after every install/update
4quiet
5# Persistent local customizations
6include meson.local
7# Persistent global definitions
8include globals.local
9
10# Allow python3 (blacklisted by disable-interpreters.inc)
11include allow-python3.inc
12
13# Redirect
14include build-systems-common.profile
diff --git a/etc/profile-m-z/musixmatch.profile b/etc/profile-m-z/musixmatch.profile
index dac90cfa5..aab2ac19d 100644
--- a/etc/profile-m-z/musixmatch.profile
+++ b/etc/profile-m-z/musixmatch.profile
@@ -29,7 +29,7 @@ notv
29nou2f 29nou2f
30novideo 30novideo
31protocol unix,inet,inet6,netlink 31protocol unix,inet,inet6,netlink
32seccomp 32seccomp !chroot
33 33
34disable-mnt 34disable-mnt
35private-dev 35private-dev
diff --git a/etc/profile-m-z/nheko.profile b/etc/profile-m-z/nheko.profile
index 035ad086a..2f305dae9 100644
--- a/etc/profile-m-z/nheko.profile
+++ b/etc/profile-m-z/nheko.profile
@@ -51,11 +51,10 @@ private-dev
51private-etc alsa,alternatives,asound.conf,ca-certificates,crypto-policies,fonts,gtk-2.0,gtk-3.0,host.conf,hostname,hosts,ld.so.cache,ld.so.conf,ld.so.conf.d,ld.so.preload,locale,locale.alias,locale.conf,mime.types,nsswitch.conf,pki,pulse,resolv.conf,selinux,ssl,X11,xdg 51private-etc alsa,alternatives,asound.conf,ca-certificates,crypto-policies,fonts,gtk-2.0,gtk-3.0,host.conf,hostname,hosts,ld.so.cache,ld.so.conf,ld.so.conf.d,ld.so.preload,locale,locale.alias,locale.conf,mime.types,nsswitch.conf,pki,pulse,resolv.conf,selinux,ssl,X11,xdg
52private-tmp 52private-tmp
53 53
54 54dbus-user filter
55# Add the next lines to your nheko.local to enable notification support. 55dbus-user.talk org.freedesktop.secrets
56#ignore dbus-user none 56# Add the next line to your nheko.local to enable notification support.
57#dbus-user filter
58#dbus-user.talk org.freedesktop.Notifications 57#dbus-user.talk org.freedesktop.Notifications
58# Add the next line to your nheko.local to enable tray icon support.
59#dbus-user.talk org.kde.StatusNotifierWatcher 59#dbus-user.talk org.kde.StatusNotifierWatcher
60dbus-user none
61dbus-system none 60dbus-system none
diff --git a/etc/profile-m-z/pandoc.profile b/etc/profile-m-z/pandoc.profile
index b8e8a750f..460f60beb 100644
--- a/etc/profile-m-z/pandoc.profile
+++ b/etc/profile-m-z/pandoc.profile
@@ -11,6 +11,8 @@ blacklist ${RUNUSER}
11 11
12noblacklist ${DOCUMENTS} 12noblacklist ${DOCUMENTS}
13 13
14include allow-bin-sh.inc
15
14include disable-common.inc 16include disable-common.inc
15include disable-devel.inc 17include disable-devel.inc
16include disable-exec.inc 18include disable-exec.inc
@@ -19,6 +21,7 @@ include disable-programs.inc
19include disable-shell.inc 21include disable-shell.inc
20include disable-xdg.inc 22include disable-xdg.inc
21 23
24include whitelist-runuser-common.inc
22# breaks pdf output 25# breaks pdf output
23#include whitelist-var-common.inc 26#include whitelist-var-common.inc
24 27
@@ -39,12 +42,12 @@ nou2f
39novideo 42novideo
40protocol unix 43protocol unix
41seccomp 44seccomp
45seccomp.block-secondary
42shell none 46shell none
43tracelog 47tracelog
44x11 none 48x11 none
45 49
46disable-mnt 50disable-mnt
47private-bin context,latex,mktexfmt,pandoc,pdflatex,pdfroff,prince,weasyprint,wkhtmltopdf
48private-cache 51private-cache
49private-dev 52private-dev
50private-etc alternatives,ld.so.preload,texlive,texmf 53private-etc alternatives,ld.so.preload,texlive,texmf
diff --git a/etc/profile-m-z/pip.profile b/etc/profile-m-z/pip.profile
new file mode 100644
index 000000000..a0926371f
--- /dev/null
+++ b/etc/profile-m-z/pip.profile
@@ -0,0 +1,18 @@
1# Firejail profile for pip
2# Description: package manager for Python packages
3# This file is overwritten after every install/update
4quiet
5# Persistent local customizations
6include meson.local
7# Persistent global definitions
8include globals.local
9
10ignore read-only ${HOME}/.local/lib
11
12# Allow python3 (blacklisted by disable-interpreters.inc)
13include allow-python3.inc
14
15#whitelist ${HOME}/.local/lib/python*
16
17# Redirect
18include build-systems-common.profile
diff --git a/etc/profile-m-z/vscodium.profile b/etc/profile-m-z/vscodium.profile
index a4a4fb7d8..9c0a887b2 100644
--- a/etc/profile-m-z/vscodium.profile
+++ b/etc/profile-m-z/vscodium.profile
@@ -1,4 +1,4 @@
1# Firejail profile alias for Visual Studio Code 1# Firejail profile alias for VSCodium
2# This file is overwritten after every install/update 2# This file is overwritten after every install/update
3# Persistent local customizations 3# Persistent local customizations
4include vscodium.local 4include vscodium.local
@@ -7,6 +7,8 @@ include vscodium.local
7#include globals.local 7#include globals.local
8 8
9noblacklist ${HOME}/.VSCodium 9noblacklist ${HOME}/.VSCodium
10noblacklist ${HOME}/.config/VSCodium
11noblacklist ${HOME}/.vscode-oss
10 12
11# Redirect 13# Redirect
12include code.profile 14include code.profile
diff --git a/src/fbuilder/build_fs.c b/src/fbuilder/build_fs.c
index 019c3ac5a..8700e0ba1 100644
--- a/src/fbuilder/build_fs.c
+++ b/src/fbuilder/build_fs.c
@@ -182,12 +182,12 @@ static void var_callback(char *ptr) {
182void build_var(const char *fname, FILE *fp) { 182void build_var(const char *fname, FILE *fp) {
183 assert(fname); 183 assert(fname);
184 184
185 var_skip = filedb_load_whitelist(var_skip, "whitelist-var-common.inc", "allow /var/"); 185 var_skip = filedb_load_whitelist(var_skip, "whitelist-var-common.inc", "whitelist /var/");
186 process_files(fname, "/var", var_callback); 186 process_files(fname, "/var", var_callback);
187 187
188 // always whitelist /var 188 // always whitelist /var
189 if (var_out) 189 if (var_out)
190 filedb_print(var_out, "allow /var/", fp); 190 filedb_print(var_out, "whitelist /var/", fp);
191 fprintf(fp, "include whitelist-var-common.inc\n"); 191 fprintf(fp, "include whitelist-var-common.inc\n");
192} 192}
193 193
@@ -222,12 +222,12 @@ static void share_callback(char *ptr) {
222void build_share(const char *fname, FILE *fp) { 222void build_share(const char *fname, FILE *fp) {
223 assert(fname); 223 assert(fname);
224 224
225 share_skip = filedb_load_whitelist(share_skip, "whitelist-usr-share-common.inc", "allow /usr/share/"); 225 share_skip = filedb_load_whitelist(share_skip, "whitelist-usr-share-common.inc", "whitelist /usr/share/");
226 process_files(fname, "/usr/share", share_callback); 226 process_files(fname, "/usr/share", share_callback);
227 227
228 // always whitelist /usr/share 228 // always whitelist /usr/share
229 if (share_out) 229 if (share_out)
230 filedb_print(share_out, "allow /usr/share/", fp); 230 filedb_print(share_out, "whitelist /usr/share/", fp);
231 fprintf(fp, "include whitelist-usr-share-common.inc\n"); 231 fprintf(fp, "include whitelist-usr-share-common.inc\n");
232} 232}
233 233
diff --git a/src/fbuilder/build_home.c b/src/fbuilder/build_home.c
index c85474779..0fe0ffef6 100644
--- a/src/fbuilder/build_home.c
+++ b/src/fbuilder/build_home.c
@@ -140,7 +140,7 @@ void build_home(const char *fname, FILE *fp) {
140 assert(fname); 140 assert(fname);
141 141
142 // load whitelist common 142 // load whitelist common
143 db_skip = filedb_load_whitelist(db_skip, "whitelist-common.inc", "allow ${HOME}/"); 143 db_skip = filedb_load_whitelist(db_skip, "whitelist-common.inc", "whitelist ${HOME}/");
144 144
145 // find user home directory 145 // find user home directory
146 struct passwd *pw = getpwuid(getuid()); 146 struct passwd *pw = getpwuid(getuid());
@@ -168,7 +168,7 @@ void build_home(const char *fname, FILE *fp) {
168 168
169 // print the out list if any 169 // print the out list if any
170 if (db_out) { 170 if (db_out) {
171 filedb_print(db_out, "allow ${HOME}/", fp); 171 filedb_print(db_out, "whitelist ${HOME}/", fp);
172 fprintf(fp, "include whitelist-common.inc\n"); 172 fprintf(fp, "include whitelist-common.inc\n");
173 } 173 }
174 else 174 else
diff --git a/src/fbuilder/build_profile.c b/src/fbuilder/build_profile.c
index 0b9a99739..c945d7253 100644
--- a/src/fbuilder/build_profile.c
+++ b/src/fbuilder/build_profile.c
@@ -92,7 +92,7 @@ void build_profile(int argc, char **argv, int index, FILE *fp) {
92 92
93 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { 93 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
94 if (fp == stdout) 94 if (fp == stdout)
95 printf("--- Built profile beings after this line ---\n"); 95 printf("--- Built profile begins after this line ---\n");
96 fprintf(fp, "# Save this file as \"application.profile\" (change \"application\" with the\n"); 96 fprintf(fp, "# Save this file as \"application.profile\" (change \"application\" with the\n");
97 fprintf(fp, "# program name) in ~/.config/firejail directory. Firejail will find it\n"); 97 fprintf(fp, "# program name) in ~/.config/firejail directory. Firejail will find it\n");
98 fprintf(fp, "# automatically every time you sandbox your application.\n#\n"); 98 fprintf(fp, "# automatically every time you sandbox your application.\n#\n");
diff --git a/src/fcopy/main.c b/src/fcopy/main.c
index 31810de9a..f279af89f 100644
--- a/src/fcopy/main.c
+++ b/src/fcopy/main.c
@@ -88,7 +88,8 @@ static void selinux_relabel_path(const char *path, const char *inside_path) {
88 if (arg_debug) 88 if (arg_debug)
89 printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon); 89 printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon);
90 90
91 setfilecon_raw(procfs_path, fcon); 91 if (setfilecon_raw(procfs_path, fcon) != 0 && arg_debug)
92 printf("Cannot relabel %s: %s\n", path, strerror(errno));
92 } 93 }
93 freecon(fcon); 94 freecon(fcon);
94 close: 95 close:
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config
index a544e25f2..aad22ec7a 100644
--- a/src/firecfg/firecfg.config
+++ b/src/firecfg/firecfg.config
@@ -151,6 +151,7 @@ clocks
151cmus 151cmus
152code 152code
153code-oss 153code-oss
154codium
154cola 155cola
155colorful 156colorful
156com.github.bleakgrey.tootle 157com.github.bleakgrey.tootle
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c
index 06e6f0ccb..e5d837bbb 100644
--- a/src/firejail/checkcfg.c
+++ b/src/firejail/checkcfg.c
@@ -58,6 +58,7 @@ int checkcfg(int val) {
58 cfg_val[CFG_XPRA_ATTACH] = 0; 58 cfg_val[CFG_XPRA_ATTACH] = 0;
59 cfg_val[CFG_SECCOMP_ERROR_ACTION] = -1; 59 cfg_val[CFG_SECCOMP_ERROR_ACTION] = -1;
60 cfg_val[CFG_BROWSER_ALLOW_DRM] = 0; 60 cfg_val[CFG_BROWSER_ALLOW_DRM] = 0;
61 cfg_val[CFG_ALLOW_TRAY] = 0;
61 62
62 // open configuration file 63 // open configuration file
63 const char *fname = SYSCONFDIR "/firejail.config"; 64 const char *fname = SYSCONFDIR "/firejail.config";
@@ -122,6 +123,7 @@ int checkcfg(int val) {
122 PARSE_YESNO(CFG_XPRA_ATTACH, "xpra-attach") 123 PARSE_YESNO(CFG_XPRA_ATTACH, "xpra-attach")
123 PARSE_YESNO(CFG_BROWSER_DISABLE_U2F, "browser-disable-u2f") 124 PARSE_YESNO(CFG_BROWSER_DISABLE_U2F, "browser-disable-u2f")
124 PARSE_YESNO(CFG_BROWSER_ALLOW_DRM, "browser-allow-drm") 125 PARSE_YESNO(CFG_BROWSER_ALLOW_DRM, "browser-allow-drm")
126 PARSE_YESNO(CFG_ALLOW_TRAY, "allow-tray")
125#undef PARSE_YESNO 127#undef PARSE_YESNO
126 128
127 // netfilter 129 // netfilter
diff --git a/src/firejail/env.c b/src/firejail/env.c
index ad16de037..4c0d729a1 100644
--- a/src/firejail/env.c
+++ b/src/firejail/env.c
@@ -22,6 +22,7 @@
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <unistd.h> 23#include <unistd.h>
24#include <dirent.h> 24#include <dirent.h>
25#include <limits.h>
25 26
26typedef struct env_t { 27typedef struct env_t {
27 struct env_t *next; 28 struct env_t *next;
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index f554a3204..bf51a4c93 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -564,7 +564,7 @@ typedef struct {
564 564
565// mountinfo.c 565// mountinfo.c
566MountData *get_last_mount(void); 566MountData *get_last_mount(void);
567int get_mount_id(const char *path); 567int get_mount_id(int fd);
568char **build_mount_array(const int mount_id, const char *path); 568char **build_mount_array(const int mount_id, const char *path);
569 569
570// fs_var.c 570// fs_var.c
@@ -622,7 +622,8 @@ void caps_print_filter(pid_t pid) __attribute__((noreturn));
622void caps_drop_dac_override(void); 622void caps_drop_dac_override(void);
623 623
624// fs_trace.c 624// fs_trace.c
625void fs_trace_preload(void); 625void fs_trace_touch_preload(void);
626void fs_trace_touch_or_store_preload(void);
626void fs_tracefile(void); 627void fs_tracefile(void);
627void fs_trace(void); 628void fs_trace(void);
628 629
@@ -802,6 +803,7 @@ enum {
802 CFG_NAME_CHANGE, 803 CFG_NAME_CHANGE,
803 CFG_SECCOMP_ERROR_ACTION, 804 CFG_SECCOMP_ERROR_ACTION,
804 // CFG_FILE_COPY_LIMIT - file copy limit handled using setenv/getenv 805 // CFG_FILE_COPY_LIMIT - file copy limit handled using setenv/getenv
806 CFG_ALLOW_TRAY,
805 CFG_MAX // this should always be the last entry 807 CFG_MAX // this should always be the last entry
806}; 808};
807extern char *xephyr_screen; 809extern char *xephyr_screen;
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 7e0a6e347..1a9a8df0d 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -199,8 +199,6 @@ static void disable_file(OPERATION op, const char *filename) {
199 } 199 }
200 200
201 fs_tmpfs(fname, uid); 201 fs_tmpfs(fname, uid);
202 EUID_USER(); // fs_tmpfs returns with EUID 0
203
204 selinux_relabel_path(fname, fname); 202 selinux_relabel_path(fname, fname);
205 } 203 }
206 else 204 else
@@ -281,6 +279,8 @@ static void globbing(OPERATION op, const char *pattern, const char *noblacklist[
281 279
282// blacklist files or directories by mounting empty files on top of them 280// blacklist files or directories by mounting empty files on top of them
283void fs_blacklist(void) { 281void fs_blacklist(void) {
282 EUID_ASSERT();
283
284 ProfileEntry *entry = cfg.profile; 284 ProfileEntry *entry = cfg.profile;
285 if (!entry) 285 if (!entry)
286 return; 286 return;
@@ -292,7 +292,6 @@ void fs_blacklist(void) {
292 if (noblacklist == NULL) 292 if (noblacklist == NULL)
293 errExit("failed allocating memory for noblacklist entries"); 293 errExit("failed allocating memory for noblacklist entries");
294 294
295 EUID_USER();
296 while (entry) { 295 while (entry) {
297 OPERATION op = OPERATION_MAX; 296 OPERATION op = OPERATION_MAX;
298 char *ptr; 297 char *ptr;
@@ -468,8 +467,6 @@ void fs_blacklist(void) {
468 for (i = 0; i < noblacklist_c; i++) 467 for (i = 0; i < noblacklist_c; i++)
469 free(noblacklist[i]); 468 free(noblacklist[i]);
470 free(noblacklist); 469 free(noblacklist);
471
472 EUID_ROOT();
473} 470}
474 471
475//*********************************************** 472//***********************************************
@@ -478,7 +475,7 @@ void fs_blacklist(void) {
478 475
479// mount a writable tmpfs on directory; requires a resolved path 476// mount a writable tmpfs on directory; requires a resolved path
480void fs_tmpfs(const char *dir, unsigned check_owner) { 477void fs_tmpfs(const char *dir, unsigned check_owner) {
481 EUID_USER(); 478 EUID_ASSERT();
482 assert(dir); 479 assert(dir);
483 if (arg_debug) 480 if (arg_debug)
484 printf("Mounting tmpfs on %s, check owner: %s\n", dir, (check_owner)? "yes": "no"); 481 printf("Mounting tmpfs on %s, check owner: %s\n", dir, (check_owner)? "yes": "no");
@@ -503,12 +500,13 @@ void fs_tmpfs(const char *dir, unsigned check_owner) {
503 errExit("fstatvfs"); 500 errExit("fstatvfs");
504 unsigned long flags = buf.f_flag & ~(MS_RDONLY|MS_BIND|MS_REMOUNT); 501 unsigned long flags = buf.f_flag & ~(MS_RDONLY|MS_BIND|MS_REMOUNT);
505 // mount via the symbolic link in /proc/self/fd 502 // mount via the symbolic link in /proc/self/fd
506 EUID_ROOT();
507 char *proc; 503 char *proc;
508 if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) 504 if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1)
509 errExit("asprintf"); 505 errExit("asprintf");
506 EUID_ROOT();
510 if (mount("tmpfs", proc, "tmpfs", flags|MS_NOSUID|MS_NODEV, options) < 0) 507 if (mount("tmpfs", proc, "tmpfs", flags|MS_NOSUID|MS_NODEV, options) < 0)
511 errExit("mounting tmpfs"); 508 errExit("mounting tmpfs");
509 EUID_USER();
512 // check the last mount operation 510 // check the last mount operation
513 MountData *mdata = get_last_mount(); 511 MountData *mdata = get_last_mount();
514 if (strcmp(mdata->fstype, "tmpfs") != 0 || strcmp(mdata->dir, dir) != 0) 512 if (strcmp(mdata->fstype, "tmpfs") != 0 || strcmp(mdata->dir, dir) != 0)
@@ -634,34 +632,30 @@ out:
634} 632}
635 633
636// remount recursively; requires a resolved path 634// remount recursively; requires a resolved path
637static void fs_remount_rec(const char *dir, OPERATION op) { 635static void fs_remount_rec(const char *path, OPERATION op) {
638 EUID_ASSERT(); 636 EUID_ASSERT();
639 assert(dir); 637 assert(op < OPERATION_MAX);
638 assert(path);
640 639
641 struct stat s; 640 // no need to search /proc/self/mountinfo for submounts if not a directory
642 if (stat(dir, &s) != 0) 641 int fd = open(path, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
643 return; 642 if (fd < 0) {
644 if (!S_ISDIR(s.st_mode)) { 643 fs_remount_simple(path, op);
645 // no need to search in /proc/self/mountinfo for submounts if not a directory
646 fs_remount_simple(dir, op);
647 return; 644 return;
648 } 645 }
649 // get mount point of the directory 646
650 int mountid = get_mount_id(dir); 647 // get mount id of the directory
651 if (mountid == -1) 648 int mountid = get_mount_id(fd);
652 return; 649 close(fd);
653 if (mountid == -2) { 650 if (mountid < 0) {
654 // falling back to a simple remount on old kernels 651 // falling back to a simple remount
655 static int mount_warning = 0; 652 fwarning("%s %s not applied recursively\n", opstr[op], path);
656 if (!mount_warning) { 653 fs_remount_simple(path, op);
657 fwarning("read-only, read-write and noexec options are not applied recursively\n");
658 mount_warning = 1;
659 }
660 fs_remount_simple(dir, op);
661 return; 654 return;
662 } 655 }
656
663 // build array with all mount points that need to get remounted 657 // build array with all mount points that need to get remounted
664 char **arr = build_mount_array(mountid, dir); 658 char **arr = build_mount_array(mountid, path);
665 assert(arr); 659 assert(arr);
666 // remount 660 // remount
667 char **tmp = arr; 661 char **tmp = arr;
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c
index d8bb1aded..694d0a379 100644
--- a/src/firejail/fs_dev.c
+++ b/src/firejail/fs_dev.c
@@ -329,8 +329,10 @@ void fs_dev_disable_sound(void) {
329 } 329 }
330 330
331 // disable all jack sockets in /dev/shm 331 // disable all jack sockets in /dev/shm
332 EUID_USER();
332 glob_t globbuf; 333 glob_t globbuf;
333 int globerr = glob("/dev/shm/jack*", GLOB_NOSORT, NULL, &globbuf); 334 int globerr = glob("/dev/shm/jack*", GLOB_NOSORT, NULL, &globbuf);
335 EUID_ROOT();
334 if (globerr) 336 if (globerr)
335 return; 337 return;
336 338
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index 45889b27f..8d8530d81 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -394,14 +394,16 @@ void fs_private(void) {
394 } 394 }
395 if (chown(homedir, u, g) < 0) 395 if (chown(homedir, u, g) < 0)
396 errExit("chown"); 396 errExit("chown");
397
398 fs_logger2("mkdir", homedir); 397 fs_logger2("mkdir", homedir);
399 fs_logger2("tmpfs", homedir); 398 fs_logger2("tmpfs", homedir);
400 } 399 }
401 else 400 else {
402 // mask user home directory 401 // mask user home directory
403 // the directory should be owned by the current user 402 // the directory should be owned by the current user
403 EUID_USER();
404 fs_tmpfs(homedir, 1); 404 fs_tmpfs(homedir, 1);
405 EUID_ROOT();
406 }
405 407
406 selinux_relabel_path(homedir, homedir); 408 selinux_relabel_path(homedir, homedir);
407 } 409 }
@@ -563,12 +565,13 @@ void fs_private_home_list(void) {
563 int xflag = store_xauthority(); 565 int xflag = store_xauthority();
564 int aflag = store_asoundrc(); 566 int aflag = store_asoundrc();
565 567
566 // create /run/firejail/mnt/home directory
567 EUID_ROOT(); 568 EUID_ROOT();
569 // create /run/firejail/mnt/home directory
568 mkdir_attr(RUN_HOME_DIR, 0755, uid, gid); 570 mkdir_attr(RUN_HOME_DIR, 0755, uid, gid);
569 selinux_relabel_path(RUN_HOME_DIR, homedir); 571 selinux_relabel_path(RUN_HOME_DIR, homedir);
570 572
571 fs_logger_print(); // save the current log 573 // save the current log
574 fs_logger_print();
572 EUID_USER(); 575 EUID_USER();
573 576
574 // copy the list of files in the new home directory 577 // copy the list of files in the new home directory
diff --git a/src/firejail/fs_trace.c b/src/firejail/fs_trace.c
index 9463fbcd0..28852a689 100644
--- a/src/firejail/fs_trace.c
+++ b/src/firejail/fs_trace.c
@@ -25,19 +25,26 @@
25#include <fcntl.h> 25#include <fcntl.h>
26#include <pwd.h> 26#include <pwd.h>
27 27
28void fs_trace_preload(void) { 28// create an empty /etc/ld.so.preload
29void fs_trace_touch_preload(void) {
30 create_empty_file_as_root("/etc/ld.so.preload", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
31}
32
33void fs_trace_touch_or_store_preload(void) {
29 struct stat s; 34 struct stat s;
30 35
31 // create an empty /etc/ld.so.preload 36 if (stat("/etc/ld.so.preload", &s) != 0) {
32 if (stat("/etc/ld.so.preload", &s)) { 37 fs_trace_touch_preload();
33 if (arg_debug) 38 return;
34 printf("Creating an empty /etc/ld.so.preload file\n"); 39 }
35 FILE *fp = fopen("/etc/ld.so.preload", "wxe"); 40
36 if (!fp) 41 if (s.st_size == 0)
37 errExit("fopen"); 42 return;
38 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH); 43
39 fclose(fp); 44 // create a copy of /etc/ld.so.preload
40 fs_logger("touch /etc/ld.so.preload"); 45 if (copy_file("/etc/ld.so.preload", RUN_LDPRELOAD_FILE, 0, 0, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) {
46 fprintf(stderr, "Error: cannot copy /etc/ld.so.preload file\n");
47 exit(1);
41 } 48 }
42} 49}
43 50
@@ -82,7 +89,7 @@ void fs_trace(void) {
82 if (arg_debug) 89 if (arg_debug)
83 printf("Create the new ld.so.preload file\n"); 90 printf("Create the new ld.so.preload file\n");
84 91
85 FILE *fp = fopen(RUN_LDPRELOAD_FILE, "we"); 92 FILE *fp = fopen(RUN_LDPRELOAD_FILE, "ae");
86 if (!fp) 93 if (!fp)
87 errExit("fopen"); 94 errExit("fopen");
88 const char *prefix = RUN_FIREJAIL_LIB_DIR; 95 const char *prefix = RUN_FIREJAIL_LIB_DIR;
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 943f275de..7afebed1f 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -105,6 +105,7 @@ static int whitelist_mkpath(const char* path, mode_t mode) {
105} 105}
106 106
107static void whitelist_file(int dirfd, const char *relpath, const char *path) { 107static void whitelist_file(int dirfd, const char *relpath, const char *path) {
108 EUID_ASSERT();
108 assert(relpath && path); 109 assert(relpath && path);
109 110
110 // open mount source, using a file descriptor that refers to the 111 // open mount source, using a file descriptor that refers to the
@@ -130,12 +131,9 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) {
130 } 131 }
131 132
132 // create mount target as root, except if inside home or run/user/$UID directory 133 // create mount target as root, except if inside home or run/user/$UID directory
133 int userprivs = 0; 134 if ((strncmp(path, cfg.homedir, homedir_len) != 0 || path[homedir_len] != '/') &&
134 if ((strncmp(path, cfg.homedir, homedir_len) == 0 && path[homedir_len] == '/') || 135 (strncmp(path, runuser, runuser_len) != 0 || path[runuser_len] != '/'))
135 (strncmp(path, runuser, runuser_len) == 0 && path[runuser_len] == '/')) { 136 EUID_ROOT();
136 EUID_USER();
137 userprivs = 1;
138 }
139 137
140 // create path of the mount target 138 // create path of the mount target
141 int fd2 = whitelist_mkpath(path, 0755); 139 int fd2 = whitelist_mkpath(path, 0755);
@@ -146,8 +144,7 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) {
146 if (arg_debug || arg_debug_whitelists) 144 if (arg_debug || arg_debug_whitelists)
147 printf("Debug %d: skip whitelist %s\n", __LINE__, path); 145 printf("Debug %d: skip whitelist %s\n", __LINE__, path);
148 close(fd); 146 close(fd);
149 if (userprivs) 147 EUID_USER();
150 EUID_ROOT();
151 return; 148 return;
152 } 149 }
153 150
@@ -166,8 +163,7 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) {
166 } 163 }
167 close(fd); 164 close(fd);
168 close(fd2); 165 close(fd2);
169 if (userprivs) 166 EUID_USER();
170 EUID_ROOT();
171 return; 167 return;
172 } 168 }
173 fd3 = openat(fd2, file, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); 169 fd3 = openat(fd2, file, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
@@ -184,19 +180,17 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) {
184 } 180 }
185 close(fd); 181 close(fd);
186 close(fd2); 182 close(fd2);
187 if (userprivs) 183 EUID_USER();
188 EUID_ROOT();
189 return; 184 return;
190 } 185 }
191
192 close(fd2); 186 close(fd2);
193 if (userprivs)
194 EUID_ROOT();
195 187
196 if (arg_debug || arg_debug_whitelists) 188 if (arg_debug || arg_debug_whitelists)
197 printf("Whitelisting %s\n", path); 189 printf("Whitelisting %s\n", path);
190 EUID_ROOT();
198 if (bind_mount_by_fd(fd, fd3)) 191 if (bind_mount_by_fd(fd, fd3))
199 errExit("mount bind"); 192 errExit("mount bind");
193 EUID_USER();
200 // check the last mount operation 194 // check the last mount operation
201 MountData *mptr = get_last_mount(); // will do exit(1) if the mount cannot be found 195 MountData *mptr = get_last_mount(); // will do exit(1) if the mount cannot be found
202#ifdef TEST_MOUNTINFO 196#ifdef TEST_MOUNTINFO
@@ -219,22 +213,19 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) {
219} 213}
220 214
221static void whitelist_symlink(const char *link, const char *target) { 215static void whitelist_symlink(const char *link, const char *target) {
216 EUID_ASSERT();
222 assert(link && target); 217 assert(link && target);
223 218
224 // create files as root, except if inside home or run/user/$UID directory 219 // create files as root, except if inside home or run/user/$UID directory
225 int userprivs = 0; 220 if ((strncmp(link, cfg.homedir, homedir_len) != 0 || link[homedir_len] != '/') &&
226 if ((strncmp(link, cfg.homedir, homedir_len) == 0 && link[homedir_len] == '/') || 221 (strncmp(link, runuser, runuser_len) != 0 || link[runuser_len] != '/'))
227 (strncmp(link, runuser, runuser_len) == 0 && link[runuser_len] == '/')) { 222 EUID_ROOT();
228 EUID_USER();
229 userprivs = 1;
230 }
231 223
232 int fd = whitelist_mkpath(link, 0755); 224 int fd = whitelist_mkpath(link, 0755);
233 if (fd == -1) { 225 if (fd == -1) {
234 if (arg_debug || arg_debug_whitelists) 226 if (arg_debug || arg_debug_whitelists)
235 printf("Debug %d: cannot create symbolic link %s\n", __LINE__, link); 227 printf("Debug %d: cannot create symbolic link %s\n", __LINE__, link);
236 if (userprivs) 228 EUID_USER();
237 EUID_ROOT();
238 return; 229 return;
239 } 230 }
240 231
@@ -252,8 +243,7 @@ static void whitelist_symlink(const char *link, const char *target) {
252 printf("Created symbolic link %s -> %s\n", link, target); 243 printf("Created symbolic link %s -> %s\n", link, target);
253 244
254 close(fd); 245 close(fd);
255 if (userprivs) 246 EUID_USER();
256 EUID_ROOT();
257} 247}
258 248
259static void globbing(const char *pattern) { 249static void globbing(const char *pattern) {
@@ -330,10 +320,11 @@ static void tmpfs_topdirs(const TopDir *topdirs) {
330 // init tmpfs 320 // init tmpfs
331 if (strcmp(topdirs[i].path, "/run") == 0) { 321 if (strcmp(topdirs[i].path, "/run") == 0) {
332 // restore /run/firejail directory 322 // restore /run/firejail directory
333 if (mkdir(RUN_FIREJAIL_DIR, 0755) == -1) 323 EUID_ROOT();
334 errExit("mkdir"); 324 mkdir_attr(RUN_FIREJAIL_DIR, 0755, 0, 0);
335 if (bind_mount_fd_to_path(fd, RUN_FIREJAIL_DIR)) 325 if (bind_mount_fd_to_path(fd, RUN_FIREJAIL_DIR))
336 errExit("mount bind"); 326 errExit("mount bind");
327 EUID_USER();
337 close(fd); 328 close(fd);
338 fs_logger2("whitelist", RUN_FIREJAIL_DIR); 329 fs_logger2("whitelist", RUN_FIREJAIL_DIR);
339 330
@@ -351,12 +342,14 @@ static void tmpfs_topdirs(const TopDir *topdirs) {
351 errExit("asprintf"); 342 errExit("asprintf");
352 if (strcmp(env, pamtmpdir) == 0) { 343 if (strcmp(env, pamtmpdir) == 0) {
353 // create empty user-owned /tmp/user/$UID directory 344 // create empty user-owned /tmp/user/$UID directory
345 EUID_ROOT();
354 mkdir_attr("/tmp/user", 0711, 0, 0); 346 mkdir_attr("/tmp/user", 0711, 0, 0);
355 selinux_relabel_path("/tmp/user", "/tmp/user"); 347 selinux_relabel_path("/tmp/user", "/tmp/user");
356 fs_logger("mkdir /tmp/user"); 348 fs_logger("mkdir /tmp/user");
357 mkdir_attr(pamtmpdir, 0700, getuid(), 0); 349 mkdir_attr(pamtmpdir, 0700, getuid(), 0);
358 selinux_relabel_path(pamtmpdir, pamtmpdir); 350 selinux_relabel_path(pamtmpdir, pamtmpdir);
359 fs_logger2("mkdir", pamtmpdir); 351 fs_logger2("mkdir", pamtmpdir);
352 EUID_USER();
360 } 353 }
361 free(pamtmpdir); 354 free(pamtmpdir);
362 } 355 }
@@ -374,11 +367,8 @@ static void tmpfs_topdirs(const TopDir *topdirs) {
374 } 367 }
375 368
376 // user home directory 369 // user home directory
377 if (tmpfs_home) { 370 if (tmpfs_home)
378 EUID_USER();
379 fs_private(); // checks owner if outside /home 371 fs_private(); // checks owner if outside /home
380 EUID_ROOT();
381 }
382 372
383 // /run/user/$UID directory 373 // /run/user/$UID directory
384 if (tmpfs_runuser) { 374 if (tmpfs_runuser) {
@@ -402,6 +392,7 @@ static int reject_topdir(const char *dir) {
402// keep track of whitelist top level directories by adding them to an array 392// keep track of whitelist top level directories by adding them to an array
403// open each directory 393// open each directory
404static TopDir *add_topdir(const char *dir, TopDir *topdirs, const char *path) { 394static TopDir *add_topdir(const char *dir, TopDir *topdirs, const char *path) {
395 EUID_ASSERT();
405 assert(dir && path); 396 assert(dir && path);
406 397
407 // /proc and /sys are not allowed 398 // /proc and /sys are not allowed
@@ -516,6 +507,8 @@ static char *extract_topdir(const char *path) {
516} 507}
517 508
518void fs_whitelist(void) { 509void fs_whitelist(void) {
510 EUID_ASSERT();
511
519 ProfileEntry *entry = cfg.profile; 512 ProfileEntry *entry = cfg.profile;
520 if (!entry) 513 if (!entry)
521 return; 514 return;
@@ -536,7 +529,6 @@ void fs_whitelist(void) {
536 errExit("calloc"); 529 errExit("calloc");
537 530
538 // verify whitelist files, extract symbolic links, etc. 531 // verify whitelist files, extract symbolic links, etc.
539 EUID_USER();
540 while (entry) { 532 while (entry) {
541 int nowhitelist_flag = 0; 533 int nowhitelist_flag = 0;
542 534
@@ -630,7 +622,7 @@ void fs_whitelist(void) {
630 if (!fname) { 622 if (!fname) {
631 if (arg_debug || arg_debug_whitelists) { 623 if (arg_debug || arg_debug_whitelists) {
632 printf("Removed path: %s\n", entry->data); 624 printf("Removed path: %s\n", entry->data);
633 printf("\texpanded: %s\n", new_name); 625 printf("\tnew_name: %s\n", new_name);
634 printf("\trealpath: (null)\n"); 626 printf("\trealpath: (null)\n");
635 printf("\t%s\n", strerror(errno)); 627 printf("\t%s\n", strerror(errno));
636 } 628 }
@@ -712,7 +704,6 @@ void fs_whitelist(void) {
712 free(nowhitelist); 704 free(nowhitelist);
713 705
714 // mount tmpfs on all top level directories 706 // mount tmpfs on all top level directories
715 EUID_ROOT();
716 tmpfs_topdirs(topdirs); 707 tmpfs_topdirs(topdirs);
717 708
718 // go through profile rules again, and interpret whitelist commands 709 // go through profile rules again, and interpret whitelist commands
diff --git a/src/firejail/main.c b/src/firejail/main.c
index a99249be9..cc5186204 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -32,6 +32,8 @@
32#include <dirent.h> 32#include <dirent.h>
33#include <pwd.h> 33#include <pwd.h>
34#include <errno.h> 34#include <errno.h>
35
36#include <limits.h>
35#include <sys/file.h> 37#include <sys/file.h>
36#include <sys/prctl.h> 38#include <sys/prctl.h>
37#include <signal.h> 39#include <signal.h>
diff --git a/src/firejail/mountinfo.c b/src/firejail/mountinfo.c
index 64a94bd84..304f80eee 100644
--- a/src/firejail/mountinfo.c
+++ b/src/firejail/mountinfo.c
@@ -19,6 +19,7 @@
19*/ 19*/
20 20
21#include "firejail.h" 21#include "firejail.h"
22#include <errno.h>
22 23
23#include <fcntl.h> 24#include <fcntl.h>
24#ifndef O_PATH 25#ifndef O_PATH
@@ -151,53 +152,71 @@ MountData *get_last_mount(void) {
151 return &mdata; 152 return &mdata;
152} 153}
153 154
154// Extract the mount id from /proc/self/fdinfo and return it. 155// Returns mount id, or -1 if fd refers to a procfs or sysfs file
155int get_mount_id(const char *path) { 156static int get_mount_id_from_handle(int fd) {
156 EUID_ASSERT(); 157 EUID_ASSERT();
157 assert(path);
158 158
159 int fd = open(path, O_PATH|O_CLOEXEC); 159 char *proc;
160 if (fd == -1) 160 if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1)
161 return -1; 161 errExit("asprintf");
162 struct file_handle *fh = malloc(sizeof *fh);
163 if (!fh)
164 errExit("malloc");
165 fh->handle_bytes = 0;
166
167 int rv = -1;
168 int tmp;
169 if (name_to_handle_at(-1, proc, fh, &tmp, AT_SYMLINK_FOLLOW) != -1) {
170 fprintf(stderr, "Error: unexpected result from name_to_handle_at\n");
171 exit(1);
172 }
173 if (errno == EOVERFLOW && fh->handle_bytes)
174 rv = tmp;
175
176 free(proc);
177 free(fh);
178 return rv;
179}
180
181// Returns mount id, or -1 on kernels < 3.15
182static int get_mount_id_from_fdinfo(int fd) {
183 EUID_ASSERT();
184 int rv = -1;
162 185
163 char *fdinfo; 186 char *proc;
164 if (asprintf(&fdinfo, "/proc/self/fdinfo/%d", fd) == -1) 187 if (asprintf(&proc, "/proc/self/fdinfo/%d", fd) == -1)
165 errExit("asprintf"); 188 errExit("asprintf");
166 EUID_ROOT(); 189 EUID_ROOT();
167 FILE *fp = fopen(fdinfo, "re"); 190 FILE *fp = fopen(proc, "re");
168 EUID_USER(); 191 EUID_USER();
169 free(fdinfo);
170 if (!fp) 192 if (!fp)
171 goto errexit; 193 goto errexit;
172 194
173 // read the file
174 char buf[MAX_BUF]; 195 char buf[MAX_BUF];
175 if (fgets(buf, MAX_BUF, fp) == NULL) 196 while (fgets(buf, MAX_BUF, fp)) {
176 goto errexit;
177 do {
178 if (strncmp(buf, "mnt_id:", 7) == 0) { 197 if (strncmp(buf, "mnt_id:", 7) == 0) {
179 char *ptr = buf + 7; 198 if (sscanf(buf + 7, "%d", &rv) != 1)
180 while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\t')) {
181 ptr++;
182 }
183 if (*ptr == '\0')
184 goto errexit; 199 goto errexit;
185 fclose(fp); 200 break;
186 close(fd);
187 return atoi(ptr);
188 } 201 }
189 } while (fgets(buf, MAX_BUF, fp)); 202 }
190 203
191 // fallback, kernels older than 3.15 don't expose the mount id in this place 204 free(proc);
192 fclose(fp); 205 fclose(fp);
193 close(fd); 206 return rv;
194 return -2;
195 207
196errexit: 208errexit:
197 fprintf(stderr, "Error: cannot read proc file\n"); 209 fprintf(stderr, "Error: cannot read proc file\n");
198 exit(1); 210 exit(1);
199} 211}
200 212
213int get_mount_id(int fd) {
214 int rv = get_mount_id_from_fdinfo(fd);
215 if (rv < 0)
216 rv = get_mount_id_from_handle(fd);
217 return rv;
218}
219
201// Check /proc/self/mountinfo if path contains any mounts points. 220// Check /proc/self/mountinfo if path contains any mounts points.
202// Returns an array that can be iterated over for recursive remounting. 221// Returns an array that can be iterated over for recursive remounting.
203char **build_mount_array(const int mount_id, const char *path) { 222char **build_mount_array(const int mount_id, const char *path) {
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 059100fcb..5390249ea 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -175,6 +175,10 @@ static int check_allow_drm(void) {
175 return checkcfg(CFG_BROWSER_ALLOW_DRM) != 0; 175 return checkcfg(CFG_BROWSER_ALLOW_DRM) != 0;
176} 176}
177 177
178static int check_allow_tray(void) {
179 return checkcfg(CFG_ALLOW_TRAY) != 0;
180}
181
178Cond conditionals[] = { 182Cond conditionals[] = {
179 {"HAS_APPIMAGE", check_appimage}, 183 {"HAS_APPIMAGE", check_appimage},
180 {"HAS_NET", check_netoptions}, 184 {"HAS_NET", check_netoptions},
@@ -184,6 +188,7 @@ Cond conditionals[] = {
184 {"HAS_X11", check_x11}, 188 {"HAS_X11", check_x11},
185 {"BROWSER_DISABLE_U2F", check_disable_u2f}, 189 {"BROWSER_DISABLE_U2F", check_disable_u2f},
186 {"BROWSER_ALLOW_DRM", check_allow_drm}, 190 {"BROWSER_ALLOW_DRM", check_allow_drm},
191 {"ALLOW_TRAY", check_allow_tray},
187 { NULL, NULL } 192 { NULL, NULL }
188}; 193};
189 194
@@ -630,7 +635,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
630#endif 635#endif
631 return 0; 636 return 0;
632 } 637 }
633 else if (strncmp(ptr, "netns ", 6) == 0) { 638 else if (strncmp(ptr, "netns ", 6) == 0) {
634#ifdef HAVE_NETWORK 639#ifdef HAVE_NETWORK
635 if (checkcfg(CFG_NETWORK)) { 640 if (checkcfg(CFG_NETWORK)) {
636 arg_netns = ptr + 6; 641 arg_netns = ptr + 6;
@@ -981,10 +986,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
981 warning_feature_disabled("seccomp"); 986 warning_feature_disabled("seccomp");
982 return 0; 987 return 0;
983 } 988 }
984 if (strncmp(ptr, "seccomp.32.drop ", 13) == 0) { 989 if (strncmp(ptr, "seccomp.32.drop ", 16) == 0) {
985 if (checkcfg(CFG_SECCOMP)) { 990 if (checkcfg(CFG_SECCOMP)) {
986 arg_seccomp32 = 1; 991 arg_seccomp32 = 1;
987 cfg.seccomp_list_drop32 = seccomp_check_list(ptr + 13); 992 cfg.seccomp_list_drop32 = seccomp_check_list(ptr + 16);
988 } 993 }
989 else 994 else
990 warning_feature_disabled("seccomp"); 995 warning_feature_disabled("seccomp");
@@ -1001,10 +1006,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
1001 warning_feature_disabled("seccomp"); 1006 warning_feature_disabled("seccomp");
1002 return 0; 1007 return 0;
1003 } 1008 }
1004 if (strncmp(ptr, "seccomp.32.keep ", 13) == 0) { 1009 if (strncmp(ptr, "seccomp.32.keep ", 16) == 0) {
1005 if (checkcfg(CFG_SECCOMP)) { 1010 if (checkcfg(CFG_SECCOMP)) {
1006 arg_seccomp32 = 1; 1011 arg_seccomp32 = 1;
1007 cfg.seccomp_list_keep32 = seccomp_check_list(ptr + 13); 1012 cfg.seccomp_list_keep32 = seccomp_check_list(ptr + 16);
1008 } 1013 }
1009 else 1014 else
1010 warning_feature_disabled("seccomp"); 1015 warning_feature_disabled("seccomp");
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 995827fb7..b776a0cc5 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -798,7 +798,7 @@ int sandbox(void* sandbox_arg) {
798 798
799 // trace pre-install 799 // trace pre-install
800 if (need_preload) 800 if (need_preload)
801 fs_trace_preload(); 801 fs_trace_touch_or_store_preload();
802 802
803 // store hosts file 803 // store hosts file
804 if (cfg.hosts_file) 804 if (cfg.hosts_file)
@@ -814,8 +814,11 @@ int sandbox(void* sandbox_arg) {
814 //**************************** 814 //****************************
815 // trace pre-install, this time inside chroot 815 // trace pre-install, this time inside chroot
816 //**************************** 816 //****************************
817 if (need_preload) 817 if (need_preload) {
818 fs_trace_preload(); 818 int rv = unlink(RUN_LDPRELOAD_FILE);
819 (void) rv;
820 fs_trace_touch_or_store_preload();
821 }
819 } 822 }
820 else 823 else
821#endif 824#endif
@@ -992,7 +995,7 @@ int sandbox(void* sandbox_arg) {
992 995
993 // create /etc/ld.so.preload file again 996 // create /etc/ld.so.preload file again
994 if (need_preload) 997 if (need_preload)
995 fs_trace_preload(); 998 fs_trace_touch_preload();
996 999
997 // openSUSE configuration is split between /etc and /usr/etc 1000 // openSUSE configuration is split between /etc and /usr/etc
998 // process private-etc a second time 1001 // process private-etc a second time
@@ -1004,10 +1007,12 @@ int sandbox(void* sandbox_arg) {
1004 // apply the profile file 1007 // apply the profile file
1005 //**************************** 1008 //****************************
1006 // apply all whitelist commands ... 1009 // apply all whitelist commands ...
1010 EUID_USER();
1007 fs_whitelist(); 1011 fs_whitelist();
1008 1012
1009 // ... followed by blacklist commands 1013 // ... followed by blacklist commands
1010 fs_blacklist(); // mkdir and mkfile are processed all over again 1014 fs_blacklist(); // mkdir and mkfile are processed all over again
1015 EUID_ROOT();
1011 1016
1012 //**************************** 1017 //****************************
1013 // nosound/no3d/notv/novideo and fix for pulseaudio 7.0 1018 // nosound/no3d/notv/novideo and fix for pulseaudio 7.0
diff --git a/src/firejail/selinux.c b/src/firejail/selinux.c
index 6969e7a3d..fa59882ed 100644
--- a/src/firejail/selinux.c
+++ b/src/firejail/selinux.c
@@ -21,6 +21,7 @@
21#include "firejail.h" 21#include "firejail.h"
22#include <sys/types.h> 22#include <sys/types.h>
23#include <sys/stat.h> 23#include <sys/stat.h>
24#include <errno.h>
24 25
25#include <fcntl.h> 26#include <fcntl.h>
26#ifndef O_PATH 27#ifndef O_PATH
@@ -57,7 +58,17 @@ void selinux_relabel_path(const char *path, const char *inside_path)
57 58
58 /* Open the file as O_PATH, to pin it while we determine and adjust the label 59 /* Open the file as O_PATH, to pin it while we determine and adjust the label
59 * Defeat symlink races by not allowing symbolic links */ 60 * Defeat symlink races by not allowing symbolic links */
61 int called_as_root = 0;
62 if (geteuid() == 0)
63 called_as_root = 1;
64 if (called_as_root)
65 EUID_USER();
66
60 fd = safer_openat(-1, path, O_NOFOLLOW|O_CLOEXEC|O_PATH); 67 fd = safer_openat(-1, path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
68
69 if (called_as_root)
70 EUID_ROOT();
71
61 if (fd < 0) 72 if (fd < 0)
62 return; 73 return;
63 if (fstat(fd, &st) < 0) 74 if (fstat(fd, &st) < 0)
@@ -68,8 +79,16 @@ void selinux_relabel_path(const char *path, const char *inside_path)
68 if (arg_debug) 79 if (arg_debug)
69 printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon); 80 printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon);
70 81
71 setfilecon_raw(procfs_path, fcon); 82 if (!called_as_root)
83 EUID_ROOT();
84
85 if (setfilecon_raw(procfs_path, fcon) != 0 && arg_debug)
86 printf("Cannot relabel %s: %s\n", path, strerror(errno));
87
88 if (!called_as_root)
89 EUID_USER();
72 } 90 }
91
73 freecon(fcon); 92 freecon(fcon);
74 close: 93 close:
75 close(fd); 94 close(fd);
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 094a68c60..f0df45eb2 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -459,31 +459,21 @@ int is_dir(const char *fname) {
459 if (*fname == '\0') 459 if (*fname == '\0')
460 return 0; 460 return 0;
461 461
462 int called_as_root = 0;
463 if (geteuid() == 0)
464 called_as_root = 1;
465
466 if (called_as_root)
467 EUID_USER();
468
469 // if fname doesn't end in '/', add one 462 // if fname doesn't end in '/', add one
470 int rv; 463 int rv;
471 struct stat s; 464 struct stat s;
472 if (fname[strlen(fname) - 1] == '/') 465 if (fname[strlen(fname) - 1] == '/')
473 rv = stat(fname, &s); 466 rv = stat_as_user(fname, &s);
474 else { 467 else {
475 char *tmp; 468 char *tmp;
476 if (asprintf(&tmp, "%s/", fname) == -1) { 469 if (asprintf(&tmp, "%s/", fname) == -1) {
477 fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__); 470 fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__);
478 errExit("asprintf"); 471 errExit("asprintf");
479 } 472 }
480 rv = stat(tmp, &s); 473 rv = stat_as_user(tmp, &s);
481 free(tmp); 474 free(tmp);
482 } 475 }
483 476
484 if (called_as_root)
485 EUID_ROOT();
486
487 if (rv == -1) 477 if (rv == -1)
488 return 0; 478 return 0;
489 479
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt
index a76fd3765..a1eccaa5e 100644
--- a/src/man/firejail-profile.txt
+++ b/src/man/firejail-profile.txt
@@ -174,7 +174,7 @@ Example: "?HAS_APPIMAGE: whitelist ${HOME}/special/appimage/dir"
174 174
175This example will load the whitelist profile line only if the \-\-appimage option has been specified on the command line. 175This example will load the whitelist profile line only if the \-\-appimage option has been specified on the command line.
176 176
177Currently the only conditionals supported this way are HAS_APPIMAGE, HAS_NET, HAS_NODBUS, HAS_NOSOUND, HAS_PRIVATE and HAS_X11. The conditionals BROWSER_DISABLE_U2F and BROWSER_ALLOW_DRM 177Currently the only conditionals supported this way are HAS_APPIMAGE, HAS_NET, HAS_NODBUS, HAS_NOSOUND, HAS_PRIVATE and HAS_X11. The conditionals ALLOW_TRAY, BROWSER_DISABLE_U2F and BROWSER_ALLOW_DRM
178can be enabled or disabled globally in Firejail's configuration file. 178can be enabled or disabled globally in Firejail's configuration file.
179 179
180The profile line may be any profile line that you would normally use in a profile \fBexcept\fR for "quiet" and "include" lines. 180The profile line may be any profile line that you would normally use in a profile \fBexcept\fR for "quiet" and "include" lines.
diff --git a/test/utils/build.exp b/test/utils/build.exp
index 104ac037c..b9733c137 100755
--- a/test/utils/build.exp
+++ b/test/utils/build.exp
@@ -13,7 +13,7 @@ after 100
13send -- "firejail --build cat ~/_firejail-test-file\r" 13send -- "firejail --build cat ~/_firejail-test-file\r"
14expect { 14expect {
15 timeout {puts "TESTING ERROR 0\n";exit} 15 timeout {puts "TESTING ERROR 0\n";exit}
16 "allow $\{HOME\}/_firejail-test-file" 16 "whitelist $\{HOME\}/_firejail-test-file"
17} 17}
18expect { 18expect {
19 timeout {puts "TESTING ERROR 1\n";exit} 19 timeout {puts "TESTING ERROR 1\n";exit}