-Output of firejail --debug /path/to/program
+Output of LC_ALL=C firejail --debug /path/to/program
```
diff --git a/README.md b/README.md
index 0623d946305..40c6e9d98bf 100644
--- a/README.md
+++ b/README.md
@@ -267,4 +267,5 @@ $ ./profstats *.profile
### New profiles:
-clion-eap, lifeograph, io.github.lainsce.Notejot, rednotebook, zim, microsoft-edge-beta, ncdu2, gallery-dl, yt-dlp
+clion-eap, lifeograph, io.github.lainsce.Notejot, rednotebook, zim, microsoft-edge-beta, ncdu2, gallery-dl, yt-dlp, goldendict, bundle,
+cmake, make, meson, pip, codium
diff --git a/RELNOTES b/RELNOTES
index f52ce09f149..3f92c89c771 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -1,13 +1,16 @@
firejail (0.9.67) baseline; urgency=low
* work in progress
+ * exit code: distinguish fatal signals by adding 128
* deprecated --disable-whitelist at compile time
* deprecated whitelist=yes/no in /etc/firejail/firejail.config
+ * new condition: ALLOW_TRAY
* remove (some) environment variables with auth-tokens
* new includes: whitelist-run-common.inc, disable-X11.inc
* removed includes: disable-passwordmgr.inc
* new profiles: microsoft-edge-beta, clion-eap, lifeograph, zim
* new profiles: io.github.lainsce.Notejot, rednotebook, gallery-dl
- * new profiles: yt-dlp
+ * new profiles: yt-dlp, goldendict, goldendict, bundle, cmake
+ * new profiles: make, meson, pip, codium
-- netblue30 Thu, 29 Jul 2021 09:00:00 -0500
firejail (0.9.66) baseline; urgency=low
diff --git a/contrib/vim/syntax/firejail.vim b/contrib/vim/syntax/firejail.vim
index d07690ee23f..fa80a9c0062 100644
--- a/contrib/vim/syntax/firejail.vim
+++ b/contrib/vim/syntax/firejail.vim
@@ -72,7 +72,7 @@ syn match fjCommandNoCond /quiet$/ contained
" Conditionals grabbed from: src/firejail/profile.c
" 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' '|'
-syn match fjConditional /\v\?(BROWSER_ALLOW_DRM|BROWSER_DISABLE_U2F|HAS_APPIMAGE|HAS_NET|HAS_NODBUS|HAS_NOSOUND|HAS_X11) ?:/ nextgroup=fjCommand skipwhite contained
+syn 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
" A line is either a command, a conditional or a comment
syn match fjStatement /^/ nextgroup=fjCommand,fjCommandNoCond,fjConditional,fjComment
diff --git a/etc/firejail.config b/etc/firejail.config
index aec152b8587..7912b746c36 100644
--- a/etc/firejail.config
+++ b/etc/firejail.config
@@ -2,6 +2,9 @@
# keyword-argument pairs, one per line. Most features are enabled by default.
# Use 'yes' or 'no' as configuration values.
+# Allow programs to display a tray icon
+# allow-tray no
+
# Enable AppArmor functionality, default enabled.
# apparmor yes
diff --git a/etc/inc/allow-common-devel.inc b/etc/inc/allow-common-devel.inc
index 011bbe226b8..4e460fc102f 100644
--- a/etc/inc/allow-common-devel.inc
+++ b/etc/inc/allow-common-devel.inc
@@ -27,5 +27,8 @@ noblacklist ${HOME}/.python-history
noblacklist ${HOME}/.python_history
noblacklist ${HOME}/.pythonhist
+# Ruby
+noblacklist ${HOME}/.bundle
+
# Rust
-noblacklist ${HOME}/.cargo/*
+noblacklist ${HOME}/.cargo
diff --git a/etc/inc/allow-ruby.inc b/etc/inc/allow-ruby.inc
index a8c70121902..00276cac7e2 100644
--- a/etc/inc/allow-ruby.inc
+++ b/etc/inc/allow-ruby.inc
@@ -4,3 +4,4 @@ include allow-ruby.local
noblacklist ${PATH}/ruby
noblacklist /usr/lib/ruby
+noblacklist /usr/lib64/ruby
diff --git a/etc/inc/disable-interpreters.inc b/etc/inc/disable-interpreters.inc
index 5d8a236fbf8..804869e2aba 100644
--- a/etc/inc/disable-interpreters.inc
+++ b/etc/inc/disable-interpreters.inc
@@ -48,6 +48,7 @@ blacklist /usr/share/php*
# Ruby
blacklist ${PATH}/ruby
blacklist /usr/lib/ruby
+blacklist /usr/lib64/ruby
# Programs using python: deluge, firefox addons, filezilla, cherrytree, xchat, hexchat, libreoffice, scribus
# Python 2
diff --git a/etc/inc/disable-programs.inc b/etc/inc/disable-programs.inc
index e77ceb41c86..6734e220a6a 100644
--- a/etc/inc/disable-programs.inc
+++ b/etc/inc/disable-programs.inc
@@ -49,8 +49,9 @@ blacklist ${HOME}/.bibletime
blacklist ${HOME}/.bitcoin
blacklist ${HOME}/.blobby
blacklist ${HOME}/.bogofilter
+blacklist ${HOME}/.bundle
blacklist ${HOME}/.bzf
-blacklist ${HOME}/.cargo/*
+blacklist ${HOME}/.cargo
blacklist ${HOME}/.claws-mail
blacklist ${HOME}/.cliqz
blacklist ${HOME}/.clion*
@@ -142,6 +143,7 @@ blacklist ${HOME}/.config/SubDownloader
blacklist ${HOME}/.config/Thunar
blacklist ${HOME}/.config/Twitch
blacklist ${HOME}/.config/Unknown Organization
+blacklist ${HOME}/.config/VSCodium
blacklist ${HOME}/.config/VirtualBox
blacklist ${HOME}/.config/Whalebird
blacklist ${HOME}/.config/Wire
@@ -496,6 +498,7 @@ blacklist ${HOME}/.frogatto
blacklist ${HOME}/.frozen-bubble
blacklist ${HOME}/.funnyboat
blacklist ${HOME}/.gallery-dl.conf
+blacklist ${HOME}/.geekbench5
blacklist ${HOME}/.gimp*
blacklist ${HOME}/.gist
blacklist ${HOME}/.gitconfig
diff --git a/etc/profile-a-l/amule.profile b/etc/profile-a-l/amule.profile
index 3ce05c5bcc3..e82c145d108 100644
--- a/etc/profile-a-l/amule.profile
+++ b/etc/profile-a-l/amule.profile
@@ -32,6 +32,7 @@ nosound
notv
nou2f
novideo
+# Add netlink protocol to use UPnP
protocol unix,inet,inet6
seccomp
shell 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 00000000000..1b199d612b7
--- /dev/null
+++ b/etc/profile-a-l/build-systems-common.profile
@@ -0,0 +1,66 @@
+# Firejail profile for build-systems-common
+# This file is overwritten after every install/update
+# Persistent local customizations
+include build-systems-common.local
+# Persistent global definitions
+# added by caller profile
+#include globals.local
+
+ignore noexec ${HOME}
+ignore noexec /tmp
+
+# Allow /bin/sh (blacklisted by disable-shell.inc)
+include allow-bin-sh.inc
+
+# Allows files commonly used by IDEs
+include allow-common-devel.inc
+
+# Allow ssh (blacklisted by disable-common.inc)
+#include allow-ssh.inc
+
+blacklist ${RUNUSER}
+
+include disable-common.inc
+include disable-exec.inc
+include disable-interpreters.inc
+include disable-programs.inc
+include disable-shell.inc
+include disable-X11.inc
+include disable-xdg.inc
+
+#whitelist ${HOME}/Projects
+#include whitelist-common.inc
+
+whitelist /usr/share/pkgconfig
+include whitelist-run-common.inc
+include whitelist-usr-share-common.inc
+include whitelist-var-common.inc
+
+caps.drop all
+ipc-namespace
+machine-id
+# net none
+netfilter
+no3d
+nodvd
+nogroups
+noinput
+nonewprivs
+noroot
+nosound
+notv
+nou2f
+novideo
+protocol unix,inet,inet6
+seccomp
+seccomp.block-secondary
+shell none
+tracelog
+
+disable-mnt
+private-cache
+private-dev
+private-tmp
+
+dbus-user none
+dbus-system none
diff --git a/etc/profile-a-l/bundle.profile b/etc/profile-a-l/bundle.profile
new file mode 100644
index 00000000000..bb82022b155
--- /dev/null
+++ b/etc/profile-a-l/bundle.profile
@@ -0,0 +1,23 @@
+# Firejail profile for bundle
+# Description: Ruby Dependency Management
+# This file is overwritten after every install/update
+quiet
+# Persistent local customizations
+include bundle.local
+# Persistent global definitions
+include globals.local
+
+noblacklist ${HOME}/.bundle
+
+# Allow ruby (blacklisted by disable-interpreters.inc)
+include allow-ruby.inc
+
+#whitelist ${HOME}/.bundle
+#whitelist ${HOME}/.gem
+#whitelist ${HOME}/.local/share/gem
+whitelist /usr/share/gems
+whitelist /usr/share/ruby
+whitelist /usr/share/rubygems
+
+# Redirect
+include build-systems-common.profile
diff --git a/etc/profile-a-l/cargo.profile b/etc/profile-a-l/cargo.profile
index ff46cd42915..4c8afd8950e 100644
--- a/etc/profile-a-l/cargo.profile
+++ b/etc/profile-a-l/cargo.profile
@@ -7,66 +7,18 @@ include cargo.local
# Persistent global definitions
include globals.local
-ignore noexec ${HOME}
-ignore noexec /tmp
-
-blacklist /tmp/.X11-unix
-blacklist ${RUNUSER}
+ignore read-only ${HOME}/.cargo/bin
noblacklist ${HOME}/.cargo/credentials
noblacklist ${HOME}/.cargo/credentials.toml
-# Allows files commonly used by IDEs
-include allow-common-devel.inc
-
-# Allow ssh (blacklisted by disable-common.inc)
-#include allow-ssh.inc
-
-include disable-common.inc
-include disable-exec.inc
-include disable-interpreters.inc
-include disable-programs.inc
-include disable-xdg.inc
-
-#mkdir ${HOME}/.cargo
-#whitelist ${HOME}/YOUR_CARGO_PROJECTS
#whitelist ${HOME}/.cargo
#whitelist ${HOME}/.rustup
-#include whitelist-common.inc
-whitelist /usr/share/pkgconfig
-include whitelist-runuser-common.inc
-include whitelist-usr-share-common.inc
-include whitelist-var-common.inc
-caps.drop all
-ipc-namespace
-machine-id
-netfilter
-no3d
-nodvd
-nogroups
-noinput
-nonewprivs
-noroot
-nosound
-notv
-nou2f
-novideo
-protocol unix,inet,inet6
-seccomp
-seccomp.block-secondary
-shell none
-tracelog
-
-disable-mnt
#private-bin cargo,rustc
-private-cache
-private-dev
private-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
-private-tmp
-
-dbus-user none
-dbus-system none
memory-deny-write-execute
-read-write ${HOME}/.cargo/bin
+
+# Redirect
+include build-systems-common.profile
diff --git a/etc/profile-a-l/cheese.profile b/etc/profile-a-l/cheese.profile
index 53d22163171..978d727f4c1 100644
--- a/etc/profile-a-l/cheese.profile
+++ b/etc/profile-a-l/cheese.profile
@@ -9,17 +9,24 @@ include globals.local
noblacklist ${VIDEOS}
noblacklist ${PICTURES}
+include allow-python3.inc
+
include disable-common.inc
include disable-devel.inc
include disable-exec.inc
include disable-interpreters.inc
include disable-programs.inc
+include disable-shell.inc
include disable-xdg.inc
whitelist ${VIDEOS}
whitelist ${PICTURES}
+whitelist /run/udev/data
+whitelist /usr/libexec/gstreamer-1.0/gst-plugin-scanner
whitelist /usr/share/gnome-video-effects
+whitelist /usr/share/gstreamer-1.0
include whitelist-common.inc
+include whitelist-run-common.inc
include whitelist-runuser-common.inc
include whitelist-usr-share-common.inc
include whitelist-var-common.inc
@@ -30,21 +37,26 @@ machine-id
net none
nodvd
nogroups
+noinput
nonewprivs
noroot
+nosound
notv
nou2f
protocol unix
seccomp
+seccomp.block-secondary
shell none
tracelog
disable-mnt
private-bin cheese
private-cache
+private-dev
private-etc alternatives,clutter-1.0,dconf,drirc,fonts,gtk-3.0,ld.so.preload
private-tmp
dbus-user filter
+dbus-user.own org.gnome.Cheese
dbus-user.talk ca.desrt.dconf
dbus-system none
diff --git a/etc/profile-a-l/cmake.profile b/etc/profile-a-l/cmake.profile
new file mode 100644
index 00000000000..26cc2a00a4c
--- /dev/null
+++ b/etc/profile-a-l/cmake.profile
@@ -0,0 +1,13 @@
+# Firejail profile for cargo
+# Description: The Rust package manager
+# This file is overwritten after every install/update
+quiet
+# Persistent local customizations
+include cargo.local
+# Persistent global definitions
+include globals.local
+
+memory-deny-write-execute
+
+# Redirect
+include 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 00000000000..9ff87ed8af7
--- /dev/null
+++ b/etc/profile-a-l/codium.profile
@@ -0,0 +1,10 @@
+# Firejail profile alias for VSCodium
+# This file is overwritten after every install/update
+# Persistent local customizations
+include codium.local
+# Persistent global definitions
+# added by included profile
+#include globals.local
+
+# Redirect
+include vscodium.profile
diff --git a/etc/profile-a-l/geekbench.profile b/etc/profile-a-l/geekbench.profile
index 60f2f338db9..4812e13683d 100644
--- a/etc/profile-a-l/geekbench.profile
+++ b/etc/profile-a-l/geekbench.profile
@@ -6,6 +6,10 @@ include geekbench.local
# Persistent global definitions
include globals.local
+noblacklist ${HOME}/.geekbench5
+noblacklist /sbin
+noblacklist /usr/sbin
+
include disable-common.inc
include disable-devel.inc
include disable-exec.inc
@@ -13,6 +17,8 @@ include disable-interpreters.inc
include disable-programs.inc
include disable-xdg.inc
+mkdir ${HOME}/.geekbench5
+whitelist ${HOME}/.geekbench5
include whitelist-common.inc
include whitelist-usr-share-common.inc
include whitelist-var-common.inc
@@ -39,16 +45,14 @@ shell none
tracelog
disable-mnt
-private-bin bash,geekbenc*,sh
+#private-bin bash,geekbench*,sh -- #4576
private-cache
private-dev
private-etc alternatives,group,ld.so.preload,lsb-release,passwd
-private-lib gcc/*/*/libstdc++.so.*
-private-opt none
private-tmp
dbus-user none
dbus-system none
-#memory-deny-write-execute - breaks on Arch (see issue #1803)
read-only ${HOME}
+read-write ${HOME}/.geekbench5
diff --git a/etc/profile-a-l/inkscape.profile b/etc/profile-a-l/inkscape.profile
index 5e54b544166..e0015e69a38 100644
--- a/etc/profile-a-l/inkscape.profile
+++ b/etc/profile-a-l/inkscape.profile
@@ -1,6 +1,7 @@
# Firejail profile for inkscape
# Description: Vector-based drawing program
# This file is overwritten after every install/update
+quiet
# Persistent local customizations
include inkscape.local
# Persistent global definitions
diff --git a/etc/profile-m-z/make.profile b/etc/profile-m-z/make.profile
new file mode 100644
index 00000000000..7e9638fe409
--- /dev/null
+++ b/etc/profile-m-z/make.profile
@@ -0,0 +1,13 @@
+# Firejail profile for make
+# Description: GNU make utility to maintain groups of programs
+# This file is overwritten after every install/update
+quiet
+# Persistent local customizations
+include make.local
+# Persistent global definitions
+include globals.local
+
+memory-deny-write-execute
+
+# Redirect
+include 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 00000000000..b4909a9d872
--- /dev/null
+++ b/etc/profile-m-z/meson.profile
@@ -0,0 +1,14 @@
+# Firejail profile for meson
+# Description: A high productivity build system
+# This file is overwritten after every install/update
+quiet
+# Persistent local customizations
+include meson.local
+# Persistent global definitions
+include globals.local
+
+# Allow python3 (blacklisted by disable-interpreters.inc)
+include allow-python3.inc
+
+# Redirect
+include build-systems-common.profile
diff --git a/etc/profile-m-z/musixmatch.profile b/etc/profile-m-z/musixmatch.profile
index dac90cfa5f9..aab2ac19d78 100644
--- a/etc/profile-m-z/musixmatch.profile
+++ b/etc/profile-m-z/musixmatch.profile
@@ -29,7 +29,7 @@ notv
nou2f
novideo
protocol unix,inet,inet6,netlink
-seccomp
+seccomp !chroot
disable-mnt
private-dev
diff --git a/etc/profile-m-z/nheko.profile b/etc/profile-m-z/nheko.profile
index 035ad086a9a..2f305dae965 100644
--- a/etc/profile-m-z/nheko.profile
+++ b/etc/profile-m-z/nheko.profile
@@ -51,11 +51,10 @@ private-dev
private-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
private-tmp
-
-# Add the next lines to your nheko.local to enable notification support.
-#ignore dbus-user none
-#dbus-user filter
+dbus-user filter
+dbus-user.talk org.freedesktop.secrets
+# Add the next line to your nheko.local to enable notification support.
#dbus-user.talk org.freedesktop.Notifications
+# Add the next line to your nheko.local to enable tray icon support.
#dbus-user.talk org.kde.StatusNotifierWatcher
-dbus-user none
dbus-system none
diff --git a/etc/profile-m-z/pandoc.profile b/etc/profile-m-z/pandoc.profile
index b8e8a750f57..460f60beb3a 100644
--- a/etc/profile-m-z/pandoc.profile
+++ b/etc/profile-m-z/pandoc.profile
@@ -11,6 +11,8 @@ blacklist ${RUNUSER}
noblacklist ${DOCUMENTS}
+include allow-bin-sh.inc
+
include disable-common.inc
include disable-devel.inc
include disable-exec.inc
@@ -19,6 +21,7 @@ include disable-programs.inc
include disable-shell.inc
include disable-xdg.inc
+include whitelist-runuser-common.inc
# breaks pdf output
#include whitelist-var-common.inc
@@ -39,12 +42,12 @@ nou2f
novideo
protocol unix
seccomp
+seccomp.block-secondary
shell none
tracelog
x11 none
disable-mnt
-private-bin context,latex,mktexfmt,pandoc,pdflatex,pdfroff,prince,weasyprint,wkhtmltopdf
private-cache
private-dev
private-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 00000000000..a0926371fac
--- /dev/null
+++ b/etc/profile-m-z/pip.profile
@@ -0,0 +1,18 @@
+# Firejail profile for pip
+# Description: package manager for Python packages
+# This file is overwritten after every install/update
+quiet
+# Persistent local customizations
+include meson.local
+# Persistent global definitions
+include globals.local
+
+ignore read-only ${HOME}/.local/lib
+
+# Allow python3 (blacklisted by disable-interpreters.inc)
+include allow-python3.inc
+
+#whitelist ${HOME}/.local/lib/python*
+
+# Redirect
+include build-systems-common.profile
diff --git a/etc/profile-m-z/vscodium.profile b/etc/profile-m-z/vscodium.profile
index a4a4fb7d83b..9c0a887b2fc 100644
--- a/etc/profile-m-z/vscodium.profile
+++ b/etc/profile-m-z/vscodium.profile
@@ -1,4 +1,4 @@
-# Firejail profile alias for Visual Studio Code
+# Firejail profile alias for VSCodium
# This file is overwritten after every install/update
# Persistent local customizations
include vscodium.local
@@ -7,6 +7,8 @@ include vscodium.local
#include globals.local
noblacklist ${HOME}/.VSCodium
+noblacklist ${HOME}/.config/VSCodium
+noblacklist ${HOME}/.vscode-oss
# Redirect
include code.profile
diff --git a/src/fbuilder/build_fs.c b/src/fbuilder/build_fs.c
index 019c3ac5abb..8700e0ba16c 100644
--- a/src/fbuilder/build_fs.c
+++ b/src/fbuilder/build_fs.c
@@ -182,12 +182,12 @@ static void var_callback(char *ptr) {
void build_var(const char *fname, FILE *fp) {
assert(fname);
- var_skip = filedb_load_whitelist(var_skip, "whitelist-var-common.inc", "allow /var/");
+ var_skip = filedb_load_whitelist(var_skip, "whitelist-var-common.inc", "whitelist /var/");
process_files(fname, "/var", var_callback);
// always whitelist /var
if (var_out)
- filedb_print(var_out, "allow /var/", fp);
+ filedb_print(var_out, "whitelist /var/", fp);
fprintf(fp, "include whitelist-var-common.inc\n");
}
@@ -222,12 +222,12 @@ static void share_callback(char *ptr) {
void build_share(const char *fname, FILE *fp) {
assert(fname);
- share_skip = filedb_load_whitelist(share_skip, "whitelist-usr-share-common.inc", "allow /usr/share/");
+ share_skip = filedb_load_whitelist(share_skip, "whitelist-usr-share-common.inc", "whitelist /usr/share/");
process_files(fname, "/usr/share", share_callback);
// always whitelist /usr/share
if (share_out)
- filedb_print(share_out, "allow /usr/share/", fp);
+ filedb_print(share_out, "whitelist /usr/share/", fp);
fprintf(fp, "include whitelist-usr-share-common.inc\n");
}
diff --git a/src/fbuilder/build_home.c b/src/fbuilder/build_home.c
index c85474779c2..0fe0ffef60d 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) {
assert(fname);
// load whitelist common
- db_skip = filedb_load_whitelist(db_skip, "whitelist-common.inc", "allow ${HOME}/");
+ db_skip = filedb_load_whitelist(db_skip, "whitelist-common.inc", "whitelist ${HOME}/");
// find user home directory
struct passwd *pw = getpwuid(getuid());
@@ -168,7 +168,7 @@ void build_home(const char *fname, FILE *fp) {
// print the out list if any
if (db_out) {
- filedb_print(db_out, "allow ${HOME}/", fp);
+ filedb_print(db_out, "whitelist ${HOME}/", fp);
fprintf(fp, "include whitelist-common.inc\n");
}
else
diff --git a/src/fbuilder/build_profile.c b/src/fbuilder/build_profile.c
index 0b9a997398d..c945d725339 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) {
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
if (fp == stdout)
- printf("--- Built profile beings after this line ---\n");
+ printf("--- Built profile begins after this line ---\n");
fprintf(fp, "# Save this file as \"application.profile\" (change \"application\" with the\n");
fprintf(fp, "# program name) in ~/.config/firejail directory. Firejail will find it\n");
fprintf(fp, "# automatically every time you sandbox your application.\n#\n");
diff --git a/src/fcopy/main.c b/src/fcopy/main.c
index 31810de9ac5..f279af89fc9 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) {
if (arg_debug)
printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon);
- setfilecon_raw(procfs_path, fcon);
+ if (setfilecon_raw(procfs_path, fcon) != 0 && arg_debug)
+ printf("Cannot relabel %s: %s\n", path, strerror(errno));
}
freecon(fcon);
close:
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config
index a544e25f22a..aad22ec7a5e 100644
--- a/src/firecfg/firecfg.config
+++ b/src/firecfg/firecfg.config
@@ -151,6 +151,7 @@ clocks
cmus
code
code-oss
+codium
cola
colorful
com.github.bleakgrey.tootle
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c
index 06e6f0ccb9a..e5d837bbbf5 100644
--- a/src/firejail/checkcfg.c
+++ b/src/firejail/checkcfg.c
@@ -58,6 +58,7 @@ int checkcfg(int val) {
cfg_val[CFG_XPRA_ATTACH] = 0;
cfg_val[CFG_SECCOMP_ERROR_ACTION] = -1;
cfg_val[CFG_BROWSER_ALLOW_DRM] = 0;
+ cfg_val[CFG_ALLOW_TRAY] = 0;
// open configuration file
const char *fname = SYSCONFDIR "/firejail.config";
@@ -122,6 +123,7 @@ int checkcfg(int val) {
PARSE_YESNO(CFG_XPRA_ATTACH, "xpra-attach")
PARSE_YESNO(CFG_BROWSER_DISABLE_U2F, "browser-disable-u2f")
PARSE_YESNO(CFG_BROWSER_ALLOW_DRM, "browser-allow-drm")
+ PARSE_YESNO(CFG_ALLOW_TRAY, "allow-tray")
#undef PARSE_YESNO
// netfilter
diff --git a/src/firejail/env.c b/src/firejail/env.c
index ad16de03730..4c0d729a1f8 100644
--- a/src/firejail/env.c
+++ b/src/firejail/env.c
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
typedef struct env_t {
struct env_t *next;
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index f554a32044f..bf51a4c9315 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -564,7 +564,7 @@ typedef struct {
// mountinfo.c
MountData *get_last_mount(void);
-int get_mount_id(const char *path);
+int get_mount_id(int fd);
char **build_mount_array(const int mount_id, const char *path);
// fs_var.c
@@ -622,7 +622,8 @@ void caps_print_filter(pid_t pid) __attribute__((noreturn));
void caps_drop_dac_override(void);
// fs_trace.c
-void fs_trace_preload(void);
+void fs_trace_touch_preload(void);
+void fs_trace_touch_or_store_preload(void);
void fs_tracefile(void);
void fs_trace(void);
@@ -802,6 +803,7 @@ enum {
CFG_NAME_CHANGE,
CFG_SECCOMP_ERROR_ACTION,
// CFG_FILE_COPY_LIMIT - file copy limit handled using setenv/getenv
+ CFG_ALLOW_TRAY,
CFG_MAX // this should always be the last entry
};
extern char *xephyr_screen;
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 7e0a6e347a1..1a9a8df0deb 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -199,8 +199,6 @@ static void disable_file(OPERATION op, const char *filename) {
}
fs_tmpfs(fname, uid);
- EUID_USER(); // fs_tmpfs returns with EUID 0
-
selinux_relabel_path(fname, fname);
}
else
@@ -281,6 +279,8 @@ static void globbing(OPERATION op, const char *pattern, const char *noblacklist[
// blacklist files or directories by mounting empty files on top of them
void fs_blacklist(void) {
+ EUID_ASSERT();
+
ProfileEntry *entry = cfg.profile;
if (!entry)
return;
@@ -292,7 +292,6 @@ void fs_blacklist(void) {
if (noblacklist == NULL)
errExit("failed allocating memory for noblacklist entries");
- EUID_USER();
while (entry) {
OPERATION op = OPERATION_MAX;
char *ptr;
@@ -468,8 +467,6 @@ void fs_blacklist(void) {
for (i = 0; i < noblacklist_c; i++)
free(noblacklist[i]);
free(noblacklist);
-
- EUID_ROOT();
}
//***********************************************
@@ -478,7 +475,7 @@ void fs_blacklist(void) {
// mount a writable tmpfs on directory; requires a resolved path
void fs_tmpfs(const char *dir, unsigned check_owner) {
- EUID_USER();
+ EUID_ASSERT();
assert(dir);
if (arg_debug)
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) {
errExit("fstatvfs");
unsigned long flags = buf.f_flag & ~(MS_RDONLY|MS_BIND|MS_REMOUNT);
// mount via the symbolic link in /proc/self/fd
- EUID_ROOT();
char *proc;
if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1)
errExit("asprintf");
+ EUID_ROOT();
if (mount("tmpfs", proc, "tmpfs", flags|MS_NOSUID|MS_NODEV, options) < 0)
errExit("mounting tmpfs");
+ EUID_USER();
// check the last mount operation
MountData *mdata = get_last_mount();
if (strcmp(mdata->fstype, "tmpfs") != 0 || strcmp(mdata->dir, dir) != 0)
@@ -634,34 +632,30 @@ static void fs_remount_simple(const char *path, OPERATION op) {
}
// remount recursively; requires a resolved path
-static void fs_remount_rec(const char *dir, OPERATION op) {
+static void fs_remount_rec(const char *path, OPERATION op) {
EUID_ASSERT();
- assert(dir);
+ assert(op < OPERATION_MAX);
+ assert(path);
- struct stat s;
- if (stat(dir, &s) != 0)
- return;
- if (!S_ISDIR(s.st_mode)) {
- // no need to search in /proc/self/mountinfo for submounts if not a directory
- fs_remount_simple(dir, op);
+ // no need to search /proc/self/mountinfo for submounts if not a directory
+ int fd = open(path, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
+ if (fd < 0) {
+ fs_remount_simple(path, op);
return;
}
- // get mount point of the directory
- int mountid = get_mount_id(dir);
- if (mountid == -1)
- return;
- if (mountid == -2) {
- // falling back to a simple remount on old kernels
- static int mount_warning = 0;
- if (!mount_warning) {
- fwarning("read-only, read-write and noexec options are not applied recursively\n");
- mount_warning = 1;
- }
- fs_remount_simple(dir, op);
+
+ // get mount id of the directory
+ int mountid = get_mount_id(fd);
+ close(fd);
+ if (mountid < 0) {
+ // falling back to a simple remount
+ fwarning("%s %s not applied recursively\n", opstr[op], path);
+ fs_remount_simple(path, op);
return;
}
+
// build array with all mount points that need to get remounted
- char **arr = build_mount_array(mountid, dir);
+ char **arr = build_mount_array(mountid, path);
assert(arr);
// remount
char **tmp = arr;
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c
index d8bb1aded15..694d0a3793e 100644
--- a/src/firejail/fs_dev.c
+++ b/src/firejail/fs_dev.c
@@ -329,8 +329,10 @@ void fs_dev_disable_sound(void) {
}
// disable all jack sockets in /dev/shm
+ EUID_USER();
glob_t globbuf;
int globerr = glob("/dev/shm/jack*", GLOB_NOSORT, NULL, &globbuf);
+ EUID_ROOT();
if (globerr)
return;
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index 45889b27f95..8d8530d813b 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -394,14 +394,16 @@ void fs_private(void) {
}
if (chown(homedir, u, g) < 0)
errExit("chown");
-
fs_logger2("mkdir", homedir);
fs_logger2("tmpfs", homedir);
}
- else
+ else {
// mask user home directory
// the directory should be owned by the current user
+ EUID_USER();
fs_tmpfs(homedir, 1);
+ EUID_ROOT();
+ }
selinux_relabel_path(homedir, homedir);
}
@@ -563,12 +565,13 @@ void fs_private_home_list(void) {
int xflag = store_xauthority();
int aflag = store_asoundrc();
- // create /run/firejail/mnt/home directory
EUID_ROOT();
+ // create /run/firejail/mnt/home directory
mkdir_attr(RUN_HOME_DIR, 0755, uid, gid);
selinux_relabel_path(RUN_HOME_DIR, homedir);
- fs_logger_print(); // save the current log
+ // save the current log
+ fs_logger_print();
EUID_USER();
// 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 9463fbcd0c4..28852a68966 100644
--- a/src/firejail/fs_trace.c
+++ b/src/firejail/fs_trace.c
@@ -25,19 +25,26 @@
#include
#include
-void fs_trace_preload(void) {
+// create an empty /etc/ld.so.preload
+void fs_trace_touch_preload(void) {
+ create_empty_file_as_root("/etc/ld.so.preload", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+}
+
+void fs_trace_touch_or_store_preload(void) {
struct stat s;
- // create an empty /etc/ld.so.preload
- if (stat("/etc/ld.so.preload", &s)) {
- if (arg_debug)
- printf("Creating an empty /etc/ld.so.preload file\n");
- FILE *fp = fopen("/etc/ld.so.preload", "wxe");
- if (!fp)
- errExit("fopen");
- SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
- fclose(fp);
- fs_logger("touch /etc/ld.so.preload");
+ if (stat("/etc/ld.so.preload", &s) != 0) {
+ fs_trace_touch_preload();
+ return;
+ }
+
+ if (s.st_size == 0)
+ return;
+
+ // create a copy of /etc/ld.so.preload
+ if (copy_file("/etc/ld.so.preload", RUN_LDPRELOAD_FILE, 0, 0, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) {
+ fprintf(stderr, "Error: cannot copy /etc/ld.so.preload file\n");
+ exit(1);
}
}
@@ -82,7 +89,7 @@ void fs_trace(void) {
if (arg_debug)
printf("Create the new ld.so.preload file\n");
- FILE *fp = fopen(RUN_LDPRELOAD_FILE, "we");
+ FILE *fp = fopen(RUN_LDPRELOAD_FILE, "ae");
if (!fp)
errExit("fopen");
const char *prefix = RUN_FIREJAIL_LIB_DIR;
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 943f275de58..7afebed1fce 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) {
}
static void whitelist_file(int dirfd, const char *relpath, const char *path) {
+ EUID_ASSERT();
assert(relpath && path);
// 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) {
}
// create mount target as root, except if inside home or run/user/$UID directory
- int userprivs = 0;
- if ((strncmp(path, cfg.homedir, homedir_len) == 0 && path[homedir_len] == '/') ||
- (strncmp(path, runuser, runuser_len) == 0 && path[runuser_len] == '/')) {
- EUID_USER();
- userprivs = 1;
- }
+ if ((strncmp(path, cfg.homedir, homedir_len) != 0 || path[homedir_len] != '/') &&
+ (strncmp(path, runuser, runuser_len) != 0 || path[runuser_len] != '/'))
+ EUID_ROOT();
// create path of the mount target
int fd2 = whitelist_mkpath(path, 0755);
@@ -146,8 +144,7 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) {
if (arg_debug || arg_debug_whitelists)
printf("Debug %d: skip whitelist %s\n", __LINE__, path);
close(fd);
- if (userprivs)
- EUID_ROOT();
+ EUID_USER();
return;
}
@@ -166,8 +163,7 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) {
}
close(fd);
close(fd2);
- if (userprivs)
- EUID_ROOT();
+ EUID_USER();
return;
}
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) {
}
close(fd);
close(fd2);
- if (userprivs)
- EUID_ROOT();
+ EUID_USER();
return;
}
-
close(fd2);
- if (userprivs)
- EUID_ROOT();
if (arg_debug || arg_debug_whitelists)
printf("Whitelisting %s\n", path);
+ EUID_ROOT();
if (bind_mount_by_fd(fd, fd3))
errExit("mount bind");
+ EUID_USER();
// check the last mount operation
MountData *mptr = get_last_mount(); // will do exit(1) if the mount cannot be found
#ifdef TEST_MOUNTINFO
@@ -219,22 +213,19 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) {
}
static void whitelist_symlink(const char *link, const char *target) {
+ EUID_ASSERT();
assert(link && target);
// create files as root, except if inside home or run/user/$UID directory
- int userprivs = 0;
- if ((strncmp(link, cfg.homedir, homedir_len) == 0 && link[homedir_len] == '/') ||
- (strncmp(link, runuser, runuser_len) == 0 && link[runuser_len] == '/')) {
- EUID_USER();
- userprivs = 1;
- }
+ if ((strncmp(link, cfg.homedir, homedir_len) != 0 || link[homedir_len] != '/') &&
+ (strncmp(link, runuser, runuser_len) != 0 || link[runuser_len] != '/'))
+ EUID_ROOT();
int fd = whitelist_mkpath(link, 0755);
if (fd == -1) {
if (arg_debug || arg_debug_whitelists)
printf("Debug %d: cannot create symbolic link %s\n", __LINE__, link);
- if (userprivs)
- EUID_ROOT();
+ EUID_USER();
return;
}
@@ -252,8 +243,7 @@ static void whitelist_symlink(const char *link, const char *target) {
printf("Created symbolic link %s -> %s\n", link, target);
close(fd);
- if (userprivs)
- EUID_ROOT();
+ EUID_USER();
}
static void globbing(const char *pattern) {
@@ -330,10 +320,11 @@ static void tmpfs_topdirs(const TopDir *topdirs) {
// init tmpfs
if (strcmp(topdirs[i].path, "/run") == 0) {
// restore /run/firejail directory
- if (mkdir(RUN_FIREJAIL_DIR, 0755) == -1)
- errExit("mkdir");
+ EUID_ROOT();
+ mkdir_attr(RUN_FIREJAIL_DIR, 0755, 0, 0);
if (bind_mount_fd_to_path(fd, RUN_FIREJAIL_DIR))
errExit("mount bind");
+ EUID_USER();
close(fd);
fs_logger2("whitelist", RUN_FIREJAIL_DIR);
@@ -351,12 +342,14 @@ static void tmpfs_topdirs(const TopDir *topdirs) {
errExit("asprintf");
if (strcmp(env, pamtmpdir) == 0) {
// create empty user-owned /tmp/user/$UID directory
+ EUID_ROOT();
mkdir_attr("/tmp/user", 0711, 0, 0);
selinux_relabel_path("/tmp/user", "/tmp/user");
fs_logger("mkdir /tmp/user");
mkdir_attr(pamtmpdir, 0700, getuid(), 0);
selinux_relabel_path(pamtmpdir, pamtmpdir);
fs_logger2("mkdir", pamtmpdir);
+ EUID_USER();
}
free(pamtmpdir);
}
@@ -374,11 +367,8 @@ static void tmpfs_topdirs(const TopDir *topdirs) {
}
// user home directory
- if (tmpfs_home) {
- EUID_USER();
+ if (tmpfs_home)
fs_private(); // checks owner if outside /home
- EUID_ROOT();
- }
// /run/user/$UID directory
if (tmpfs_runuser) {
@@ -402,6 +392,7 @@ static int reject_topdir(const char *dir) {
// keep track of whitelist top level directories by adding them to an array
// open each directory
static TopDir *add_topdir(const char *dir, TopDir *topdirs, const char *path) {
+ EUID_ASSERT();
assert(dir && path);
// /proc and /sys are not allowed
@@ -516,6 +507,8 @@ static char *extract_topdir(const char *path) {
}
void fs_whitelist(void) {
+ EUID_ASSERT();
+
ProfileEntry *entry = cfg.profile;
if (!entry)
return;
@@ -536,7 +529,6 @@ void fs_whitelist(void) {
errExit("calloc");
// verify whitelist files, extract symbolic links, etc.
- EUID_USER();
while (entry) {
int nowhitelist_flag = 0;
@@ -630,7 +622,7 @@ void fs_whitelist(void) {
if (!fname) {
if (arg_debug || arg_debug_whitelists) {
printf("Removed path: %s\n", entry->data);
- printf("\texpanded: %s\n", new_name);
+ printf("\tnew_name: %s\n", new_name);
printf("\trealpath: (null)\n");
printf("\t%s\n", strerror(errno));
}
@@ -712,7 +704,6 @@ void fs_whitelist(void) {
free(nowhitelist);
// mount tmpfs on all top level directories
- EUID_ROOT();
tmpfs_topdirs(topdirs);
// go through profile rules again, and interpret whitelist commands
diff --git a/src/firejail/main.c b/src/firejail/main.c
index a99249be9c3..cc5186204b8 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -32,6 +32,8 @@
#include
#include
#include
+
+#include
#include
#include
#include
diff --git a/src/firejail/mountinfo.c b/src/firejail/mountinfo.c
index 64a94bd849a..304f80eee46 100644
--- a/src/firejail/mountinfo.c
+++ b/src/firejail/mountinfo.c
@@ -19,6 +19,7 @@
*/
#include "firejail.h"
+#include
#include
#ifndef O_PATH
@@ -151,53 +152,71 @@ MountData *get_last_mount(void) {
return &mdata;
}
-// Extract the mount id from /proc/self/fdinfo and return it.
-int get_mount_id(const char *path) {
+// Returns mount id, or -1 if fd refers to a procfs or sysfs file
+static int get_mount_id_from_handle(int fd) {
EUID_ASSERT();
- assert(path);
- int fd = open(path, O_PATH|O_CLOEXEC);
- if (fd == -1)
- return -1;
+ char *proc;
+ if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1)
+ errExit("asprintf");
+ struct file_handle *fh = malloc(sizeof *fh);
+ if (!fh)
+ errExit("malloc");
+ fh->handle_bytes = 0;
+
+ int rv = -1;
+ int tmp;
+ if (name_to_handle_at(-1, proc, fh, &tmp, AT_SYMLINK_FOLLOW) != -1) {
+ fprintf(stderr, "Error: unexpected result from name_to_handle_at\n");
+ exit(1);
+ }
+ if (errno == EOVERFLOW && fh->handle_bytes)
+ rv = tmp;
+
+ free(proc);
+ free(fh);
+ return rv;
+}
+
+// Returns mount id, or -1 on kernels < 3.15
+static int get_mount_id_from_fdinfo(int fd) {
+ EUID_ASSERT();
+ int rv = -1;
- char *fdinfo;
- if (asprintf(&fdinfo, "/proc/self/fdinfo/%d", fd) == -1)
+ char *proc;
+ if (asprintf(&proc, "/proc/self/fdinfo/%d", fd) == -1)
errExit("asprintf");
EUID_ROOT();
- FILE *fp = fopen(fdinfo, "re");
+ FILE *fp = fopen(proc, "re");
EUID_USER();
- free(fdinfo);
if (!fp)
goto errexit;
- // read the file
char buf[MAX_BUF];
- if (fgets(buf, MAX_BUF, fp) == NULL)
- goto errexit;
- do {
+ while (fgets(buf, MAX_BUF, fp)) {
if (strncmp(buf, "mnt_id:", 7) == 0) {
- char *ptr = buf + 7;
- while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\t')) {
- ptr++;
- }
- if (*ptr == '\0')
+ if (sscanf(buf + 7, "%d", &rv) != 1)
goto errexit;
- fclose(fp);
- close(fd);
- return atoi(ptr);
+ break;
}
- } while (fgets(buf, MAX_BUF, fp));
+ }
- // fallback, kernels older than 3.15 don't expose the mount id in this place
+ free(proc);
fclose(fp);
- close(fd);
- return -2;
+ return rv;
errexit:
fprintf(stderr, "Error: cannot read proc file\n");
exit(1);
}
+int get_mount_id(int fd) {
+ int rv = get_mount_id_from_fdinfo(fd);
+ if (rv < 0)
+ rv = get_mount_id_from_handle(fd);
+ return rv;
+}
+
// Check /proc/self/mountinfo if path contains any mounts points.
// Returns an array that can be iterated over for recursive remounting.
char **build_mount_array(const int mount_id, const char *path) {
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 059100fcb99..5390249eada 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -175,6 +175,10 @@ static int check_allow_drm(void) {
return checkcfg(CFG_BROWSER_ALLOW_DRM) != 0;
}
+static int check_allow_tray(void) {
+ return checkcfg(CFG_ALLOW_TRAY) != 0;
+}
+
Cond conditionals[] = {
{"HAS_APPIMAGE", check_appimage},
{"HAS_NET", check_netoptions},
@@ -184,6 +188,7 @@ Cond conditionals[] = {
{"HAS_X11", check_x11},
{"BROWSER_DISABLE_U2F", check_disable_u2f},
{"BROWSER_ALLOW_DRM", check_allow_drm},
+ {"ALLOW_TRAY", check_allow_tray},
{ NULL, NULL }
};
@@ -630,7 +635,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
#endif
return 0;
}
- else if (strncmp(ptr, "netns ", 6) == 0) {
+ else if (strncmp(ptr, "netns ", 6) == 0) {
#ifdef HAVE_NETWORK
if (checkcfg(CFG_NETWORK)) {
arg_netns = ptr + 6;
@@ -981,10 +986,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
warning_feature_disabled("seccomp");
return 0;
}
- if (strncmp(ptr, "seccomp.32.drop ", 13) == 0) {
+ if (strncmp(ptr, "seccomp.32.drop ", 16) == 0) {
if (checkcfg(CFG_SECCOMP)) {
arg_seccomp32 = 1;
- cfg.seccomp_list_drop32 = seccomp_check_list(ptr + 13);
+ cfg.seccomp_list_drop32 = seccomp_check_list(ptr + 16);
}
else
warning_feature_disabled("seccomp");
@@ -1001,10 +1006,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
warning_feature_disabled("seccomp");
return 0;
}
- if (strncmp(ptr, "seccomp.32.keep ", 13) == 0) {
+ if (strncmp(ptr, "seccomp.32.keep ", 16) == 0) {
if (checkcfg(CFG_SECCOMP)) {
arg_seccomp32 = 1;
- cfg.seccomp_list_keep32 = seccomp_check_list(ptr + 13);
+ cfg.seccomp_list_keep32 = seccomp_check_list(ptr + 16);
}
else
warning_feature_disabled("seccomp");
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 995827fb78b..b776a0cc538 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -798,7 +798,7 @@ int sandbox(void* sandbox_arg) {
// trace pre-install
if (need_preload)
- fs_trace_preload();
+ fs_trace_touch_or_store_preload();
// store hosts file
if (cfg.hosts_file)
@@ -814,8 +814,11 @@ int sandbox(void* sandbox_arg) {
//****************************
// trace pre-install, this time inside chroot
//****************************
- if (need_preload)
- fs_trace_preload();
+ if (need_preload) {
+ int rv = unlink(RUN_LDPRELOAD_FILE);
+ (void) rv;
+ fs_trace_touch_or_store_preload();
+ }
}
else
#endif
@@ -992,7 +995,7 @@ int sandbox(void* sandbox_arg) {
// create /etc/ld.so.preload file again
if (need_preload)
- fs_trace_preload();
+ fs_trace_touch_preload();
// openSUSE configuration is split between /etc and /usr/etc
// process private-etc a second time
@@ -1004,10 +1007,12 @@ int sandbox(void* sandbox_arg) {
// apply the profile file
//****************************
// apply all whitelist commands ...
+ EUID_USER();
fs_whitelist();
// ... followed by blacklist commands
fs_blacklist(); // mkdir and mkfile are processed all over again
+ EUID_ROOT();
//****************************
// nosound/no3d/notv/novideo and fix for pulseaudio 7.0
diff --git a/src/firejail/selinux.c b/src/firejail/selinux.c
index 6969e7a3dbc..fa59882ed74 100644
--- a/src/firejail/selinux.c
+++ b/src/firejail/selinux.c
@@ -21,6 +21,7 @@
#include "firejail.h"
#include
#include
+#include
#include
#ifndef O_PATH
@@ -57,7 +58,17 @@ void selinux_relabel_path(const char *path, const char *inside_path)
/* Open the file as O_PATH, to pin it while we determine and adjust the label
* Defeat symlink races by not allowing symbolic links */
+ int called_as_root = 0;
+ if (geteuid() == 0)
+ called_as_root = 1;
+ if (called_as_root)
+ EUID_USER();
+
fd = safer_openat(-1, path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
+
+ if (called_as_root)
+ EUID_ROOT();
+
if (fd < 0)
return;
if (fstat(fd, &st) < 0)
@@ -68,8 +79,16 @@ void selinux_relabel_path(const char *path, const char *inside_path)
if (arg_debug)
printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon);
- setfilecon_raw(procfs_path, fcon);
+ if (!called_as_root)
+ EUID_ROOT();
+
+ if (setfilecon_raw(procfs_path, fcon) != 0 && arg_debug)
+ printf("Cannot relabel %s: %s\n", path, strerror(errno));
+
+ if (!called_as_root)
+ EUID_USER();
}
+
freecon(fcon);
close:
close(fd);
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 094a68c6083..f0df45eb2a3 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -459,31 +459,21 @@ int is_dir(const char *fname) {
if (*fname == '\0')
return 0;
- int called_as_root = 0;
- if (geteuid() == 0)
- called_as_root = 1;
-
- if (called_as_root)
- EUID_USER();
-
// if fname doesn't end in '/', add one
int rv;
struct stat s;
if (fname[strlen(fname) - 1] == '/')
- rv = stat(fname, &s);
+ rv = stat_as_user(fname, &s);
else {
char *tmp;
if (asprintf(&tmp, "%s/", fname) == -1) {
fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__);
errExit("asprintf");
}
- rv = stat(tmp, &s);
+ rv = stat_as_user(tmp, &s);
free(tmp);
}
- if (called_as_root)
- EUID_ROOT();
-
if (rv == -1)
return 0;
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt
index a76fd376562..a1eccaa5eab 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"
This example will load the whitelist profile line only if the \-\-appimage option has been specified on the command line.
-Currently 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
+Currently 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
can be enabled or disabled globally in Firejail's configuration file.
The 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 104ac037c56..b9733c137c9 100755
--- a/test/utils/build.exp
+++ b/test/utils/build.exp
@@ -13,7 +13,7 @@ after 100
send -- "firejail --build cat ~/_firejail-test-file\r"
expect {
timeout {puts "TESTING ERROR 0\n";exit}
- "allow $\{HOME\}/_firejail-test-file"
+ "whitelist $\{HOME\}/_firejail-test-file"
}
expect {
timeout {puts "TESTING ERROR 1\n";exit}