aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/codeql-analysis.yml6
-rw-r--r--.gitlab-ci.yml4
-rw-r--r--Makefile.in2
-rw-r--r--README12
-rw-r--r--README.md24
-rw-r--r--RELNOTES12
-rwxr-xr-xconfigure26
-rw-r--r--configure.ac2
-rw-r--r--contrib/vim/syntax/firejail.vim2
-rw-r--r--etc/inc/allow-perl.inc3
-rw-r--r--etc/inc/disable-common.inc3
-rw-r--r--etc/inc/disable-programs.inc12
-rw-r--r--etc/profile-a-l/1password.profile20
-rw-r--r--etc/profile-a-l/akonadi_control.profile1
-rw-r--r--etc/profile-a-l/chromium-common.profile1
-rw-r--r--etc/profile-a-l/cointop.profile63
-rw-r--r--etc/profile-a-l/firefox-common.profile1
-rw-r--r--etc/profile-a-l/kmail.profile1
-rw-r--r--etc/profile-a-l/lutris.profile3
-rw-r--r--etc/profile-m-z/mediathekview.profile4
-rw-r--r--etc/profile-m-z/raincat.profile49
-rw-r--r--etc/profile-m-z/seafile-applet.profile62
-rw-r--r--etc/profile-m-z/signal-desktop.profile8
-rw-r--r--etc/profile-m-z/ssh.profile1
-rw-r--r--etc/profile-m-z/steam.profile4
-rw-r--r--etc/profile-m-z/supertuxkart.profile2
-rw-r--r--etc/profile-m-z/uzbl-browser.profile1
-rw-r--r--etc/profile-m-z/warzone2100.profile7
-rw-r--r--etc/profile-m-z/wget2.profile19
-rw-r--r--etc/profile-m-z/wine.profile1
-rw-r--r--etc/profile-m-z/youtube-viewers-common.profile2
-rw-r--r--src/fbuilder/build_profile.c48
-rw-r--r--src/fbuilder/fbuilder.h1
-rw-r--r--src/fbuilder/main.c3
-rw-r--r--src/fcopy/main.c3
-rw-r--r--src/firecfg/firecfg.config5
-rw-r--r--src/firejail/cgroup.c4
-rw-r--r--src/firejail/dbus.c11
-rw-r--r--src/firejail/firejail.h5
-rw-r--r--src/firejail/fs_etc.c2
-rw-r--r--src/firejail/fs_whitelist.c29
-rw-r--r--src/firejail/join.c5
-rw-r--r--src/firejail/macros.c4
-rw-r--r--src/firejail/main.c50
-rw-r--r--src/firejail/netfilter.c5
-rw-r--r--src/firejail/profile.c9
-rw-r--r--src/firejail/pulseaudio.c54
-rw-r--r--src/firejail/sandbox.c46
-rw-r--r--src/firejail/sbox.c16
-rw-r--r--src/firejail/usage.c1
-rw-r--r--src/firejail/util.c48
-rw-r--r--src/fnettrace/fnettrace.h11
-rw-r--r--src/fnettrace/hostnames.c20
-rw-r--r--src/fnettrace/main.c224
-rw-r--r--src/fnettrace/radix.c175
-rw-r--r--src/fnettrace/radix.h16
-rw-r--r--src/fnettrace/static-ip-map (renamed from src/fnettrace/hostnames)17
-rw-r--r--src/include/common.h1
-rw-r--r--src/lib/common.c50
-rw-r--r--src/lib/syscall.c10
-rw-r--r--src/man/firejail-profile.txt10
-rw-r--r--src/man/firejail.txt85
-rw-r--r--src/zsh_completion/_firejail.in1
-rwxr-xr-xtest/environment/deterministic-shutdown.exp5
-rwxr-xr-xtest/environment/environment.sh6
-rwxr-xr-xtest/environment/keep-fd-bad.exp40
-rwxr-xr-xtest/environment/keep-fd.exp223
-rwxr-xr-xtest/fcopy/dircopy.exp14
-rwxr-xr-xtest/fcopy/fcopy.sh7
-rwxr-xr-xtest/fcopy/linkcopy.exp14
-rwxr-xr-xtest/fcopy/src/dircopy.exp139
71 files changed, 1279 insertions, 496 deletions
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index b69bb728e..0ecde565c 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -47,7 +47,7 @@ jobs:
47 47
48 # Initializes the CodeQL tools for scanning. 48 # Initializes the CodeQL tools for scanning.
49 - name: Initialize CodeQL 49 - name: Initialize CodeQL
50 uses: github/codeql-action/init@5f532563584d71fdef14ee64d17bafb34f751ce5 50 uses: github/codeql-action/init@384cfc42b2131df01c009d3d2eed7b78d8e8556e
51 with: 51 with:
52 languages: ${{ matrix.language }} 52 languages: ${{ matrix.language }}
53 # If you wish to specify custom queries, you can do so here or in a config file. 53 # If you wish to specify custom queries, you can do so here or in a config file.
@@ -58,7 +58,7 @@ jobs:
58 # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 58 # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
59 # If this step fails, then you should remove it and run the build manually (see below) 59 # If this step fails, then you should remove it and run the build manually (see below)
60 - name: Autobuild 60 - name: Autobuild
61 uses: github/codeql-action/autobuild@5f532563584d71fdef14ee64d17bafb34f751ce5 61 uses: github/codeql-action/autobuild@384cfc42b2131df01c009d3d2eed7b78d8e8556e
62 62
63 # ℹī¸ Command-line programs to run using the OS shell. 63 # ℹī¸ Command-line programs to run using the OS shell.
64 # 📚 https://git.io/JvXDl 64 # 📚 https://git.io/JvXDl
@@ -72,4 +72,4 @@ jobs:
72 # make release 72 # make release
73 73
74 - name: Perform CodeQL Analysis 74 - name: Perform CodeQL Analysis
75 uses: github/codeql-action/analyze@5f532563584d71fdef14ee64d17bafb34f751ce5 75 uses: github/codeql-action/analyze@384cfc42b2131df01c009d3d2eed7b78d8e8556e
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 03e18d269..d9fe768ff 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -67,8 +67,8 @@ debian_ci:
67 - cd $CI_PROJECT_DIR/.. && (apt-get source --download-only -t experimental firejail || apt-get source --download-only firejail) 67 - cd $CI_PROJECT_DIR/.. && (apt-get source --download-only -t experimental firejail || apt-get source --download-only firejail)
68 - cd $CI_PROJECT_DIR && tar xf ../firejail_*.debian.tar.* 68 - cd $CI_PROJECT_DIR && tar xf ../firejail_*.debian.tar.*
69 - rm -rf debian/patches/ 69 - rm -rf debian/patches/
70 # next line is a temporary fix for dh_missing failure; remove it after next release 70 # /etc/firejail/hostnames is no longer installed
71 - echo "etc/firejail/*.config" >> debian/firejail.install 71 - sed '/etc\/firejail\/hostnames/d' -i debian/firejail.install
72 - VERSION=$(grep ^PACKAGE_VERSION= configure | cut -d"'" -f2) && dch -v ${VERSION}-0.1~ci "Non-maintainer upload." && git archive -o ../firejail_${VERSION}.orig.tar.gz HEAD && pristine-tar commit ../firejail_${VERSION}.orig.tar.gz ci_build && git branch -m pristine-tar origin/pristine-tar 72 - VERSION=$(grep ^PACKAGE_VERSION= configure | cut -d"'" -f2) && dch -v ${VERSION}-0.1~ci "Non-maintainer upload." && git archive -o ../firejail_${VERSION}.orig.tar.gz HEAD && pristine-tar commit ../firejail_${VERSION}.orig.tar.gz ci_build && git branch -m pristine-tar origin/pristine-tar
73 - git add debian && git commit -m "add debian/" 73 - git add debian && git commit -m "add debian/"
74 - export CI_COMMIT_SHA=$(git rev-parse HEAD) 74 - export CI_COMMIT_SHA=$(git rev-parse HEAD)
diff --git a/Makefile.in b/Makefile.in
index ccd59170d..29bd53d21 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -123,6 +123,7 @@ endif
123 # plugins w/o read permission (non-dumpable) 123 # plugins w/o read permission (non-dumpable)
124 install -m 0711 -t $(DESTDIR)$(libdir)/firejail $(SBOX_APPS_NON_DUMPABLE) 124 install -m 0711 -t $(DESTDIR)$(libdir)/firejail $(SBOX_APPS_NON_DUMPABLE)
125 install -m 0711 -t $(DESTDIR)$(libdir)/firejail src/fshaper/fshaper.sh 125 install -m 0711 -t $(DESTDIR)$(libdir)/firejail src/fshaper/fshaper.sh
126 install -m 0644 -t $(DESTDIR)$(libdir)/firejail src/fnettrace/static-ip-map
126ifeq ($(HAVE_CONTRIB_INSTALL),yes) 127ifeq ($(HAVE_CONTRIB_INSTALL),yes)
127 # contrib scripts 128 # contrib scripts
128 install -m 0755 -t $(DESTDIR)$(libdir)/firejail contrib/*.py contrib/*.sh 129 install -m 0755 -t $(DESTDIR)$(libdir)/firejail contrib/*.py contrib/*.sh
@@ -138,7 +139,6 @@ endif
138 # profiles and settings 139 # profiles and settings
139 install -m 0755 -d $(DESTDIR)$(sysconfdir)/firejail 140 install -m 0755 -d $(DESTDIR)$(sysconfdir)/firejail
140 install -m 0644 -t $(DESTDIR)$(sysconfdir)/firejail src/firecfg/firecfg.config 141 install -m 0644 -t $(DESTDIR)$(sysconfdir)/firejail src/firecfg/firecfg.config
141 install -m 0644 -t $(DESTDIR)$(sysconfdir)/firejail src/fnettrace/hostnames
142 install -m 0644 -t $(DESTDIR)$(sysconfdir)/firejail etc/profile-a-l/*.profile etc/profile-m-z/*.profile etc/inc/*.inc etc/net/*.net etc/firejail.config etc/ids.config 142 install -m 0644 -t $(DESTDIR)$(sysconfdir)/firejail etc/profile-a-l/*.profile etc/profile-m-z/*.profile etc/inc/*.inc etc/net/*.net etc/firejail.config etc/ids.config
143 sh -c "if [ ! -f $(DESTDIR)/$(sysconfdir)/firejail/login.users ]; then install -c -m 0644 etc/login.users $(DESTDIR)/$(sysconfdir)/firejail/.; fi;" 143 sh -c "if [ ! -f $(DESTDIR)/$(sysconfdir)/firejail/login.users ]; then install -c -m 0644 etc/login.users $(DESTDIR)/$(sysconfdir)/firejail/.; fi;"
144ifeq ($(BUSYBOX_WORKAROUND),yes) 144ifeq ($(BUSYBOX_WORKAROUND),yes)
diff --git a/README b/README
index 92703d677..34f62b538 100644
--- a/README
+++ b/README
@@ -134,6 +134,8 @@ announ (https://github.com/announ)
134 - evince profile fix 134 - evince profile fix
135Anton Shestakov (https://github.com/antonv6) 135Anton Shestakov (https://github.com/antonv6)
136 - add whitelist items for uim 136 - add whitelist items for uim
137 - allow /etc/vulkan in steam profile
138 - allow ~/.cache/wine in lutris and wine profile
137Antonio Russo (https://github.com/aerusso) 139Antonio Russo (https://github.com/aerusso)
138 - enumerate root directories in apparmor profile 140 - enumerate root directories in apparmor profile
139 - fix join-or-start 141 - fix join-or-start
@@ -226,6 +228,8 @@ Carlo Abelli (https://github.com/carloabelli)
226 - fixed udiskie profile 228 - fixed udiskie profile
227 - Allow mbind syscall for GIMP 229 - Allow mbind syscall for GIMP
228 - fixed simple-scan 230 - fixed simple-scan
231Case_Of (https://github.com/CaseOf)
232 - added Seafile profile
229Cat (https://github.com/ecat3) 233Cat (https://github.com/ecat3)
230 - prevent tmux connecting to an existing session 234 - prevent tmux connecting to an existing session
231cayday (https://github.com/caydey) 235cayday (https://github.com/caydey)
@@ -838,6 +842,11 @@ RaphaÃĢl Droz (https://github.com/drzraf)
838 - zoom profile fixes 842 - zoom profile fixes
839realaltffour (https://github.com/realaltffour) 843realaltffour (https://github.com/realaltffour)
840 - add lynx support to newsboat profile 844 - add lynx support to newsboat profile
845Reed Riley (https://github.com/reedriley)
846 - cointop profile
847 - 1password profile
848 - blacklist rclone, 1Password, Ledger Live and cointop
849 - allow Signal to open links in Firefox
841Reiner Herrmann (https://github.com/reinerh) 850Reiner Herrmann (https://github.com/reinerh)
842 - a number of build patches 851 - a number of build patches
843 - man page fixes 852 - man page fixes
@@ -960,6 +969,8 @@ SkewedZeppelin (https://github.com/SkewedZeppelin)
960 - hardern /var 969 - hardern /var
961 - profile standard layout 970 - profile standard layout
962 - Spotify and itch.io profile fixes 971 - Spotify and itch.io profile fixes
972Spacewalker2 (https://github.com/Spacewalker2)
973 - fix MediathekView profile
963sshirokov (https://sourceforge.net/u/yshirokov/profile/) 974sshirokov (https://sourceforge.net/u/yshirokov/profile/)
964 - Patch to output "Reading profile" to stderr instead of stdout 975 - Patch to output "Reading profile" to stderr instead of stdout
965SYN-cook (https://github.com/SYN-cook) 976SYN-cook (https://github.com/SYN-cook)
@@ -1093,6 +1104,7 @@ Vincent Blillault (https://github.com/Feandil)
1093 - fix mumble profile 1104 - fix mumble profile
1094Vincent Lefèvre (https://github.com/vinc17fr) 1105Vincent Lefèvre (https://github.com/vinc17fr)
1095 - blacklist rxvt after the blacklist of Perl 1106 - blacklist rxvt after the blacklist of Perl
1107 - Noblacklist rxvt in allow-perl.inc
1096vismir2 (https://github.com/vismir2) 1108vismir2 (https://github.com/vismir2)
1097 - feh, ranger, 7z, keepass, keepassx and zathura profiles 1109 - feh, ranger, 7z, keepass, keepassx and zathura profiles
1098 - claws-mail, mutt, git, emacs, vim profiles 1110 - claws-mail, mutt, git, emacs, vim profiles
diff --git a/README.md b/README.md
index ab5719522..72e8cac31 100644
--- a/README.md
+++ b/README.md
@@ -283,6 +283,25 @@ INTRUSION DETECTION SYSTEM (IDS)
283 283
284````` 284`````
285 285
286### File descriptors
287`````
288 --keep-fd=all
289 Inherit all open file descriptors to the sandbox. By default
290 only file descriptors 0, 1 and 2 are inherited to the sandbox,
291 and all other file descriptors are closed.
292
293 Example:
294 $ firejail --keep-fd=all
295
296 --keep-fd=file_descriptor
297 Don't close specified open file descriptors. By default only
298 file descriptors 0, 1 and 2 are inherited to the sandbox, and
299 all other file descriptors are closed.
300
301 Example:
302 $ firejail --keep-fd=3,4,5
303`````
304
286### Deteministic Shutdown 305### Deteministic Shutdown
287````` 306`````
288 --deterministic-exit-code 307 --deterministic-exit-code
@@ -298,7 +317,7 @@ INTRUSION DETECTION SYSTEM (IDS)
298 317
299### Network Monitor 318### Network Monitor
300````` 319`````
301 --nettrace=name|pid 320 --nettrace=name|pid
302 Monitor TCP and UDP traffic coming into the sandbox specified by 321 Monitor TCP and UDP traffic coming into the sandbox specified by
303 name or pid. Only networked sandboxes created with --net are 322 name or pid. Only networked sandboxes created with --net are
304 supported. 323 supported.
@@ -357,4 +376,5 @@ Stats:
357### New profiles: 376### New profiles:
358 377
359clion-eap, lifeograph, io.github.lainsce.Notejot, rednotebook, zim, microsoft-edge-beta, ncdu2, gallery-dl, yt-dlp, goldendict, bundle, 378clion-eap, lifeograph, io.github.lainsce.Notejot, rednotebook, zim, microsoft-edge-beta, ncdu2, gallery-dl, yt-dlp, goldendict, bundle,
360cmake, make, meson, pip, codium, telnet, ftp, OpenStego, imv, retroarch, torbrowser, CachyBrowser, notable, RPCS3 379cmake, make, meson, pip, codium, telnet, ftp, OpenStego, imv, retroarch, torbrowser, CachyBrowser, notable, RPCS3, wget2, raincat,
380cointop, 1password, Seafile
diff --git a/RELNOTES b/RELNOTES
index 9624b7ef6..043107d6c 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -1,12 +1,15 @@
1firejail (0.9.67) baseline; urgency=low 1firejail (0.9.68rc2) baseline; urgency=low
2 * work in progress 2 * work in progress
3 * exit code: distinguish fatal signals by adding 128 (#4533) 3 * exit code: distinguish fatal signals by adding 128 (#4533)
4 * close file descriptors greater than 2 (--keep-fd) (#4845)
4 * intrusion detection system (--ids-init, --ids-check) 5 * intrusion detection system (--ids-init, --ids-check)
5 * deterministic shutdown (--deterministic-exit-code, 6 * deterministic shutdown (--deterministic-exit-code,
6 --deterministic-shutdown) (#4635) 7 --deterministic-shutdown) (#4635)
7 * noprinters command (#4607) 8 * noprinters command (#4607 #4827)
8 * network monitor (--nettrace) 9 * network monitor (--nettrace)
10 * network locker (--netlock)
9 * whitelist-ro profile command 11 * whitelist-ro profile command
12 * AppImage support in --build command
10 * build: firecfg.config is now installed to /etc/firejail/ (#4669) 13 * build: firecfg.config is now installed to /etc/firejail/ (#4669)
11 * removed --disable-whitelist at compile time 14 * removed --disable-whitelist at compile time
12 * removed whitelist=yes/no in /etc/firejail/firejail.config 15 * removed whitelist=yes/no in /etc/firejail/firejail.config
@@ -19,8 +22,9 @@ firejail (0.9.67) baseline; urgency=low
19 * new profiles: yt-dlp, goldendict, goldendict, bundle, cmake 22 * new profiles: yt-dlp, goldendict, goldendict, bundle, cmake
20 * new profiles: make, meson, pip, codium, telnet, ftp, OpenStego 23 * new profiles: make, meson, pip, codium, telnet, ftp, OpenStego
21 * new profiles: imv, retroarch, torbrowser, CachyBrowser, 24 * new profiles: imv, retroarch, torbrowser, CachyBrowser,
22 * new profiles: notable, RPCS3 25 * new profiles: notable, RPCS3, wget2, raincat, conitop, 1passwd,
23 -- netblue30 <netblue30@yahoo.com> Thu, 29 Jul 2021 09:00:00 -0500 26 * new profiles: Seafile
27 -- netblue30 <netblue30@yahoo.com> Tue, 18 Jan 2022 09:00:00 -0500
24 28
25firejail (0.9.66) baseline; urgency=low 29firejail (0.9.66) baseline; urgency=low
26 * deprecated --audit options, relpaced by jailcheck utility 30 * deprecated --audit options, relpaced by jailcheck utility
diff --git a/configure b/configure
index a8c9a1d96..a52a70c9f 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
1#! /bin/sh 1#! /bin/sh
2# Guess values for system-dependent variables and create Makefiles. 2# Guess values for system-dependent variables and create Makefiles.
3# Generated by GNU Autoconf 2.69 for firejail 0.9.67. 3# Generated by GNU Autoconf 2.69 for firejail 0.9.68rc2.
4# 4#
5# Report bugs to <netblue30@protonmail.com>. 5# Report bugs to <netblue30@protonmail.com>.
6# 6#
@@ -580,8 +580,8 @@ MAKEFLAGS=
580# Identity of this package. 580# Identity of this package.
581PACKAGE_NAME='firejail' 581PACKAGE_NAME='firejail'
582PACKAGE_TARNAME='firejail' 582PACKAGE_TARNAME='firejail'
583PACKAGE_VERSION='0.9.67' 583PACKAGE_VERSION='0.9.68rc2'
584PACKAGE_STRING='firejail 0.9.67' 584PACKAGE_STRING='firejail 0.9.68rc2'
585PACKAGE_BUGREPORT='netblue30@protonmail.com' 585PACKAGE_BUGREPORT='netblue30@protonmail.com'
586PACKAGE_URL='https://firejail.wordpress.com' 586PACKAGE_URL='https://firejail.wordpress.com'
587 587
@@ -1298,7 +1298,7 @@ if test "$ac_init_help" = "long"; then
1298 # Omit some internal or obsolete options to make the list less imposing. 1298 # Omit some internal or obsolete options to make the list less imposing.
1299 # This message is too long to be a string in the A/UX 3.1 sh. 1299 # This message is too long to be a string in the A/UX 3.1 sh.
1300 cat <<_ACEOF 1300 cat <<_ACEOF
1301\`configure' configures firejail 0.9.67 to adapt to many kinds of systems. 1301\`configure' configures firejail 0.9.68rc2 to adapt to many kinds of systems.
1302 1302
1303Usage: $0 [OPTION]... [VAR=VALUE]... 1303Usage: $0 [OPTION]... [VAR=VALUE]...
1304 1304
@@ -1360,7 +1360,7 @@ fi
1360 1360
1361if test -n "$ac_init_help"; then 1361if test -n "$ac_init_help"; then
1362 case $ac_init_help in 1362 case $ac_init_help in
1363 short | recursive ) echo "Configuration of firejail 0.9.67:";; 1363 short | recursive ) echo "Configuration of firejail 0.9.68rc2:";;
1364 esac 1364 esac
1365 cat <<\_ACEOF 1365 cat <<\_ACEOF
1366 1366
@@ -1481,7 +1481,7 @@ fi
1481test -n "$ac_init_help" && exit $ac_status 1481test -n "$ac_init_help" && exit $ac_status
1482if $ac_init_version; then 1482if $ac_init_version; then
1483 cat <<\_ACEOF 1483 cat <<\_ACEOF
1484firejail configure 0.9.67 1484firejail configure 0.9.68rc2
1485generated by GNU Autoconf 2.69 1485generated by GNU Autoconf 2.69
1486 1486
1487Copyright (C) 2012 Free Software Foundation, Inc. 1487Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1737,7 +1737,7 @@ cat >config.log <<_ACEOF
1737This file contains any messages produced by compilers while 1737This file contains any messages produced by compilers while
1738running configure, to aid debugging if configure makes a mistake. 1738running configure, to aid debugging if configure makes a mistake.
1739 1739
1740It was created by firejail $as_me 0.9.67, which was 1740It was created by firejail $as_me 0.9.68rc2, which was
1741generated by GNU Autoconf 2.69. Invocation command line was 1741generated by GNU Autoconf 2.69. Invocation command line was
1742 1742
1743 $ $0 $@ 1743 $ $0 $@
@@ -3434,8 +3434,8 @@ if test "x$enable_apparmor" = "xyes"; then :
3434 HAVE_APPARMOR="-DHAVE_APPARMOR" 3434 HAVE_APPARMOR="-DHAVE_APPARMOR"
3435 3435
3436pkg_failed=no 3436pkg_failed=no
3437{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AA" >&5 3437{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libapparmor" >&5
3438$as_echo_n "checking for AA... " >&6; } 3438$as_echo_n "checking for libapparmor... " >&6; }
3439 3439
3440if test -n "$AA_CFLAGS"; then 3440if test -n "$AA_CFLAGS"; then
3441 pkg_cv_AA_CFLAGS="$AA_CFLAGS" 3441 pkg_cv_AA_CFLAGS="$AA_CFLAGS"
@@ -3475,7 +3475,7 @@ fi
3475 3475
3476 3476
3477if test $pkg_failed = yes; then 3477if test $pkg_failed = yes; then
3478 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 3478 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3479$as_echo "no" >&6; } 3479$as_echo "no" >&6; }
3480 3480
3481if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then 3481if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
@@ -3502,7 +3502,7 @@ Alternatively, you may set the environment variables AA_CFLAGS
3502and AA_LIBS to avoid the need to call pkg-config. 3502and AA_LIBS to avoid the need to call pkg-config.
3503See the pkg-config man page for more details." "$LINENO" 5 3503See the pkg-config man page for more details." "$LINENO" 5
3504elif test $pkg_failed = untried; then 3504elif test $pkg_failed = untried; then
3505 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 3505 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3506$as_echo "no" >&6; } 3506$as_echo "no" >&6; }
3507 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 3507 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
3508$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} 3508$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
@@ -4815,7 +4815,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
4815# report actual input values of CONFIG_FILES etc. instead of their 4815# report actual input values of CONFIG_FILES etc. instead of their
4816# values after options handling. 4816# values after options handling.
4817ac_log=" 4817ac_log="
4818This file was extended by firejail $as_me 0.9.67, which was 4818This file was extended by firejail $as_me 0.9.68rc2, which was
4819generated by GNU Autoconf 2.69. Invocation command line was 4819generated by GNU Autoconf 2.69. Invocation command line was
4820 4820
4821 CONFIG_FILES = $CONFIG_FILES 4821 CONFIG_FILES = $CONFIG_FILES
@@ -4869,7 +4869,7 @@ _ACEOF
4869cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 4869cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
4870ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" 4870ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
4871ac_cs_version="\\ 4871ac_cs_version="\\
4872firejail config.status 0.9.67 4872firejail config.status 0.9.68rc2
4873configured by $0, generated by GNU Autoconf 2.69, 4873configured by $0, generated by GNU Autoconf 2.69,
4874 with options \\"\$ac_cs_config\\" 4874 with options \\"\$ac_cs_config\\"
4875 4875
diff --git a/configure.ac b/configure.ac
index 232d49e1e..8c541d886 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,7 +12,7 @@
12# 12#
13 13
14AC_PREREQ([2.68]) 14AC_PREREQ([2.68])
15AC_INIT([firejail], [0.9.67], [netblue30@protonmail.com], [], 15AC_INIT([firejail], [0.9.68rc2], [netblue30@protonmail.com], [],
16 [https://firejail.wordpress.com]) 16 [https://firejail.wordpress.com])
17 17
18AC_CONFIG_SRCDIR([src/firejail/main.c]) 18AC_CONFIG_SRCDIR([src/firejail/main.c])
diff --git a/contrib/vim/syntax/firejail.vim b/contrib/vim/syntax/firejail.vim
index 57c7b371d..714ed8e6e 100644
--- a/contrib/vim/syntax/firejail.vim
+++ b/contrib/vim/syntax/firejail.vim
@@ -51,7 +51,7 @@ syn match fjVar /\v\$\{(CFG|DESKTOP|DOCUMENTS|DOWNLOADS|HOME|MUSIC|PATH|PICTURES
51" Generate list with: { rg -o 'strn?cmp\(ptr, "([^"]+) "' -r '$1' src/firejail/profile.c; echo private-lib; } | grep -vEx '(include|ignore|caps\.drop|caps\.keep|protocol|seccomp|seccomp\.drop|seccomp\.keep|env|rmenv|net|ip)' | sort -u | tr $'\n' '|' # private-lib is special-cased in the code and doesn't match the regex; grep-ed patterns are handled later with 'syn match nextgroup=' directives (except for include which is special-cased as a fjCommandNoCond keyword) 51" Generate list with: { rg -o 'strn?cmp\(ptr, "([^"]+) "' -r '$1' src/firejail/profile.c; echo private-lib; } | grep -vEx '(include|ignore|caps\.drop|caps\.keep|protocol|seccomp|seccomp\.drop|seccomp\.keep|env|rmenv|net|ip)' | sort -u | tr $'\n' '|' # private-lib is special-cased in the code and doesn't match the regex; grep-ed patterns are handled later with 'syn match nextgroup=' directives (except for include which is special-cased as a fjCommandNoCond keyword)
52syn match fjCommand /\v(bind|blacklist|blacklist-nolog|cgroup|cpu|defaultgw|dns|hostname|hosts-file|ip6|iprange|join-or-start|mac|mkdir|mkfile|mtu|name|netfilter|netfilter6|netmask|nice|noblacklist|noexec|nowhitelist|overlay-named|private|private-bin|private-cwd|private-etc|private-home|private-lib|private-opt|private-srv|read-only|read-write|rlimit-as|rlimit-cpu|rlimit-fsize|rlimit-nofile|rlimit-nproc|rlimit-sigpending|timeout|tmpfs|veth-name|whitelist|xephyr-screen) / skipwhite contained 52syn match fjCommand /\v(bind|blacklist|blacklist-nolog|cgroup|cpu|defaultgw|dns|hostname|hosts-file|ip6|iprange|join-or-start|mac|mkdir|mkfile|mtu|name|netfilter|netfilter6|netmask|nice|noblacklist|noexec|nowhitelist|overlay-named|private|private-bin|private-cwd|private-etc|private-home|private-lib|private-opt|private-srv|read-only|read-write|rlimit-as|rlimit-cpu|rlimit-fsize|rlimit-nofile|rlimit-nproc|rlimit-sigpending|timeout|tmpfs|veth-name|whitelist|xephyr-screen) / skipwhite contained
53" Generate list with: rg -o 'strn?cmp\(ptr, "([^ "]*[^ ])"' -r '$1' src/firejail/profile.c | grep -vEx '(include|rlimit|quiet)' | sed -e 's/\./\\./' | sort -u | tr $'\n' '|' # include/rlimit are false positives, quiet is special-cased below 53" Generate list with: rg -o 'strn?cmp\(ptr, "([^ "]*[^ ])"' -r '$1' src/firejail/profile.c | grep -vEx '(include|rlimit|quiet)' | sed -e 's/\./\\./' | sort -u | tr $'\n' '|' # include/rlimit are false positives, quiet is special-cased below
54syn match fjCommand /\v(allow-debuggers|allusers|apparmor|caps|deterministic-exit-code|deterministic-shutdown|disable-mnt|ipc-namespace|keep-config-pulse|keep-dev-shm|keep-var-tmp|machine-id|memory-deny-write-execute|netfilter|no3d|noautopulse|nodbus|nodvd|nogroups|noinput|nonewprivs|noprinters|noroot|nosound|notv|nou2f|novideo|overlay|overlay-tmpfs|private|private-cache|private-cwd|private-dev|private-lib|private-tmp|seccomp|seccomp\.32|seccomp\.block-secondary|tracelog|writable-etc|writable-run-user|writable-var|writable-var-log|x11)$/ contained 54syn match fjCommand /\v(allow-debuggers|allusers|apparmor|caps|deterministic-exit-code|deterministic-shutdown|disable-mnt|ipc-namespace|keep-config-pulse|keep-dev-shm|keep-fd|keep-var-tmp|machine-id|memory-deny-write-execute|netfilter|no3d|noautopulse|nodbus|nodvd|nogroups|noinput|nonewprivs|noprinters|noroot|nosound|notv|nou2f|novideo|overlay|overlay-tmpfs|private|private-cache|private-cwd|private-dev|private-lib|private-tmp|seccomp|seccomp\.32|seccomp\.block-secondary|tracelog|writable-etc|writable-run-user|writable-var|writable-var-log|x11)$/ contained
55syn match fjCommand /ignore / nextgroup=fjCommand,fjCommandNoCond skipwhite contained 55syn match fjCommand /ignore / nextgroup=fjCommand,fjCommandNoCond skipwhite contained
56syn match fjCommand /caps\.drop / nextgroup=fjCapability,fjAll skipwhite contained 56syn match fjCommand /caps\.drop / nextgroup=fjCapability,fjAll skipwhite contained
57syn match fjCommand /caps\.keep / nextgroup=fjCapability skipwhite contained 57syn match fjCommand /caps\.keep / nextgroup=fjCapability skipwhite contained
diff --git a/etc/inc/allow-perl.inc b/etc/inc/allow-perl.inc
index 5a1952c94..a473900da 100644
--- a/etc/inc/allow-perl.inc
+++ b/etc/inc/allow-perl.inc
@@ -10,3 +10,6 @@ noblacklist ${PATH}/vendor_perl
10noblacklist /usr/lib/perl* 10noblacklist /usr/lib/perl*
11noblacklist /usr/lib64/perl* 11noblacklist /usr/lib64/perl*
12noblacklist /usr/share/perl* 12noblacklist /usr/share/perl*
13
14# rxvt is also blacklisted in disable-interpreters.inc
15noblacklist ${PATH}/rxvt
diff --git a/etc/inc/disable-common.inc b/etc/inc/disable-common.inc
index 625364cf6..43332b4d0 100644
--- a/etc/inc/disable-common.inc
+++ b/etc/inc/disable-common.inc
@@ -635,3 +635,6 @@ blacklist ${RUNUSER}/update-notifier.pid
635 635
636# tor-browser 636# tor-browser
637blacklist ${HOME}/.local/opt/tor-browser 637blacklist ${HOME}/.local/opt/tor-browser
638
639# pass utility (pass package in Debian etc.)
640blacklist ${HOME}/.password-store
diff --git a/etc/inc/disable-programs.inc b/etc/inc/disable-programs.inc
index ded5e4b46..5a189559a 100644
--- a/etc/inc/disable-programs.inc
+++ b/etc/inc/disable-programs.inc
@@ -191,6 +191,7 @@ blacklist ${HOME}/.cache/qBittorrent
191blacklist ${HOME}/.cache/quodlibet 191blacklist ${HOME}/.cache/quodlibet
192blacklist ${HOME}/.cache/qupzilla 192blacklist ${HOME}/.cache/qupzilla
193blacklist ${HOME}/.cache/qutebrowser 193blacklist ${HOME}/.cache/qutebrowser
194blacklist ${HOME}/.cache/rclone
194blacklist ${HOME}/.cache/rednotebook 195blacklist ${HOME}/.cache/rednotebook
195blacklist ${HOME}/.cache/rhythmbox 196blacklist ${HOME}/.cache/rhythmbox
196blacklist ${HOME}/.cache/rpcs3 197blacklist ${HOME}/.cache/rpcs3
@@ -216,6 +217,7 @@ blacklist ${HOME}/.cache/vmware
216blacklist ${HOME}/.cache/warsow-2.1 217blacklist ${HOME}/.cache/warsow-2.1
217blacklist ${HOME}/.cache/waterfox 218blacklist ${HOME}/.cache/waterfox
218blacklist ${HOME}/.cache/wesnoth 219blacklist ${HOME}/.cache/wesnoth
220blacklist ${HOME}/.cache/wine
219blacklist ${HOME}/.cache/winetricks 221blacklist ${HOME}/.cache/winetricks
220blacklist ${HOME}/.cache/xmms2 222blacklist ${HOME}/.cache/xmms2
221blacklist ${HOME}/.cache/xournalpp 223blacklist ${HOME}/.cache/xournalpp
@@ -233,6 +235,7 @@ blacklist ${HOME}/.clion*
233blacklist ${HOME}/.cliqz 235blacklist ${HOME}/.cliqz
234blacklist ${HOME}/.clonk 236blacklist ${HOME}/.clonk
235blacklist ${HOME}/.config/0ad 237blacklist ${HOME}/.config/0ad
238blacklist ${HOME}/.config/1Password
236blacklist ${HOME}/.config/2048-qt 239blacklist ${HOME}/.config/2048-qt
237blacklist ${HOME}/.config/Atom 240blacklist ${HOME}/.config/Atom
238blacklist ${HOME}/.config/Audaciousrc 241blacklist ${HOME}/.config/Audaciousrc
@@ -278,6 +281,7 @@ blacklist ${HOME}/.config/KeePass
278blacklist ${HOME}/.config/KeePassXCrc 281blacklist ${HOME}/.config/KeePassXCrc
279blacklist ${HOME}/.config/Kid3 282blacklist ${HOME}/.config/Kid3
280blacklist ${HOME}/.config/Kingsoft 283blacklist ${HOME}/.config/Kingsoft
284blacklist ${HOME}/.config/Ledger Live
281blacklist ${HOME}/.config/LibreCAD 285blacklist ${HOME}/.config/LibreCAD
282blacklist ${HOME}/.config/Loop_Hero 286blacklist ${HOME}/.config/Loop_Hero
283blacklist ${HOME}/.config/Luminance 287blacklist ${HOME}/.config/Luminance
@@ -314,6 +318,7 @@ blacklist ${HOME}/.config/Riot
314blacklist ${HOME}/.config/Rocket.Chat 318blacklist ${HOME}/.config/Rocket.Chat
315blacklist ${HOME}/.config/RogueLegacy 319blacklist ${HOME}/.config/RogueLegacy
316blacklist ${HOME}/.config/RogueLegacyStorageContainer 320blacklist ${HOME}/.config/RogueLegacyStorageContainer
321blacklist ${HOME}/.config/Seafile
317blacklist ${HOME}/.config/Signal 322blacklist ${HOME}/.config/Signal
318blacklist ${HOME}/.config/Sinew Software Systems 323blacklist ${HOME}/.config/Sinew Software Systems
319blacklist ${HOME}/.config/Slack 324blacklist ${HOME}/.config/Slack
@@ -378,6 +383,7 @@ blacklist ${HOME}/.config/chromium-flags.conf
378blacklist ${HOME}/.config/clipit 383blacklist ${HOME}/.config/clipit
379blacklist ${HOME}/.config/cliqz 384blacklist ${HOME}/.config/cliqz
380blacklist ${HOME}/.config/cmus 385blacklist ${HOME}/.config/cmus
386blacklist ${HOME}/.config/cointop
381blacklist ${HOME}/.config/com.github.bleakgrey.tootle 387blacklist ${HOME}/.config/com.github.bleakgrey.tootle
382blacklist ${HOME}/.config/corebird 388blacklist ${HOME}/.config/corebird
383blacklist ${HOME}/.config/cower 389blacklist ${HOME}/.config/cower
@@ -572,6 +578,7 @@ blacklist ${HOME}/.config/quodlibet
572blacklist ${HOME}/.config/qupzilla 578blacklist ${HOME}/.config/qupzilla
573blacklist ${HOME}/.config/qutebrowser 579blacklist ${HOME}/.config/qutebrowser
574blacklist ${HOME}/.config/ranger 580blacklist ${HOME}/.config/ranger
581blacklist ${HOME}/.config/rclone
575blacklist ${HOME}/.config/redshift 582blacklist ${HOME}/.config/redshift
576blacklist ${HOME}/.config/redshift.conf 583blacklist ${HOME}/.config/redshift.conf
577blacklist ${HOME}/.config/remmina 584blacklist ${HOME}/.config/remmina
@@ -618,6 +625,7 @@ blacklist ${HOME}/.config/vivaldi
618blacklist ${HOME}/.config/vivaldi-snapshot 625blacklist ${HOME}/.config/vivaldi-snapshot
619blacklist ${HOME}/.config/vlc 626blacklist ${HOME}/.config/vlc
620blacklist ${HOME}/.config/wesnoth 627blacklist ${HOME}/.config/wesnoth
628blacklist ${HOME}/.config/wget
621blacklist ${HOME}/.config/wireshark 629blacklist ${HOME}/.config/wireshark
622blacklist ${HOME}/.config/wormux 630blacklist ${HOME}/.config/wormux
623blacklist ${HOME}/.config/xchat 631blacklist ${HOME}/.config/xchat
@@ -979,6 +987,7 @@ blacklist ${HOME}/.local/share/vlc
979blacklist ${HOME}/.local/share/vpltd 987blacklist ${HOME}/.local/share/vpltd
980blacklist ${HOME}/.local/share/vulkan 988blacklist ${HOME}/.local/share/vulkan
981blacklist ${HOME}/.local/share/warsow-2.1 989blacklist ${HOME}/.local/share/warsow-2.1
990blacklist ${HOME}/.local/share/warzone2100-3.*
982blacklist ${HOME}/.local/share/wesnoth 991blacklist ${HOME}/.local/share/wesnoth
983blacklist ${HOME}/.local/share/wormux 992blacklist ${HOME}/.local/share/wormux
984blacklist ${HOME}/.local/share/xplayer 993blacklist ${HOME}/.local/share/xplayer
@@ -1032,7 +1041,6 @@ blacklist ${HOME}/.opera-beta
1032blacklist ${HOME}/.ostrichriders 1041blacklist ${HOME}/.ostrichriders
1033blacklist ${HOME}/.paradoxinteractive 1042blacklist ${HOME}/.paradoxinteractive
1034blacklist ${HOME}/.parallelrealities/blobwars 1043blacklist ${HOME}/.parallelrealities/blobwars
1035blacklist ${HOME}/.password-store
1036blacklist ${HOME}/.pcsxr 1044blacklist ${HOME}/.pcsxr
1037blacklist ${HOME}/.penguin-command 1045blacklist ${HOME}/.penguin-command
1038blacklist ${HOME}/.pine-crash 1046blacklist ${HOME}/.pine-crash
@@ -1127,6 +1135,7 @@ blacklist ${HOME}/Arduino
1127blacklist ${HOME}/Monero/wallets 1135blacklist ${HOME}/Monero/wallets
1128blacklist ${HOME}/Nextcloud 1136blacklist ${HOME}/Nextcloud
1129blacklist ${HOME}/Nextcloud/Notes 1137blacklist ${HOME}/Nextcloud/Notes
1138blacklist ${HOME}/Seafile/.seafile-data
1130blacklist ${HOME}/SoftMaker 1139blacklist ${HOME}/SoftMaker
1131blacklist ${HOME}/Standard Notes Backups 1140blacklist ${HOME}/Standard Notes Backups
1132blacklist ${HOME}/TeamSpeak3-Client-linux_amd64 1141blacklist ${HOME}/TeamSpeak3-Client-linux_amd64
@@ -1139,6 +1148,7 @@ blacklist ${HOME}/wallet.dat
1139blacklist ${HOME}/yt-dlp.conf 1148blacklist ${HOME}/yt-dlp.conf
1140blacklist ${HOME}/yt-dlp.conf.txt 1149blacklist ${HOME}/yt-dlp.conf.txt
1141blacklist ${RUNUSER}/*firefox* 1150blacklist ${RUNUSER}/*firefox*
1151blacklist ${RUNUSER}/akonadi
1142blacklist /tmp/.wine-* 1152blacklist /tmp/.wine-*
1143blacklist /tmp/akonadi-* 1153blacklist /tmp/akonadi-*
1144blacklist /var/games/nethack 1154blacklist /var/games/nethack
diff --git a/etc/profile-a-l/1password.profile b/etc/profile-a-l/1password.profile
new file mode 100644
index 000000000..bc8bfae0d
--- /dev/null
+++ b/etc/profile-a-l/1password.profile
@@ -0,0 +1,20 @@
1# Firejail profile for 1password
2# Description: 1Password is a password manager developed by AgileBits Inc.
3# This file is overwritten after every install/update
4# Persistent local customizations
5include 1password.local
6# Persistent global definitions
7include globals.local
8
9noblacklist ${HOME}/.config/1Password
10
11mkdir ${HOME}/.config/1Password
12whitelist ${HOME}/.config/1Password
13
14private-etc alternatives,ca-certificates,crypto-policies,fonts,ld.so.cache,ld.so.conf,ld.so.conf.d,ld.so.preload,localtime,machine-id,nsswitch.conf,pki,resolv.conf,ssl
15
16# Needed for keychain things, talking to Firefox, possibly other things? Not sure how to narrow down
17ignore dbus-user none
18
19# Redirect
20include electron.profile
diff --git a/etc/profile-a-l/akonadi_control.profile b/etc/profile-a-l/akonadi_control.profile
index f3fb678d1..2f58d9146 100644
--- a/etc/profile-a-l/akonadi_control.profile
+++ b/etc/profile-a-l/akonadi_control.profile
@@ -17,6 +17,7 @@ noblacklist ${HOME}/.local/share/apps/korganizer
17noblacklist ${HOME}/.local/share/contacts 17noblacklist ${HOME}/.local/share/contacts
18noblacklist ${HOME}/.local/share/local-mail 18noblacklist ${HOME}/.local/share/local-mail
19noblacklist ${HOME}/.local/share/notes 19noblacklist ${HOME}/.local/share/notes
20noblacklist ${RUNUSER}/akonadi
20noblacklist /sbin 21noblacklist /sbin
21noblacklist /tmp/akonadi-* 22noblacklist /tmp/akonadi-*
22noblacklist /usr/sbin 23noblacklist /usr/sbin
diff --git a/etc/profile-a-l/chromium-common.profile b/etc/profile-a-l/chromium-common.profile
index 075cac967..998ffd9da 100644
--- a/etc/profile-a-l/chromium-common.profile
+++ b/etc/profile-a-l/chromium-common.profile
@@ -57,6 +57,7 @@ private-cache
57 57
58blacklist ${PATH}/curl 58blacklist ${PATH}/curl
59blacklist ${PATH}/wget 59blacklist ${PATH}/wget
60blacklist ${PATH}/wget2
60 61
61#dbus-user none - prevents access to passwords saved in GNOME Keyring and KWallet, also breaks Gnome connector. 62#dbus-user none - prevents access to passwords saved in GNOME Keyring and KWallet, also breaks Gnome connector.
62dbus-system none 63dbus-system none
diff --git a/etc/profile-a-l/cointop.profile b/etc/profile-a-l/cointop.profile
new file mode 100644
index 000000000..4349f58fc
--- /dev/null
+++ b/etc/profile-a-l/cointop.profile
@@ -0,0 +1,63 @@
1# Firejail profile for cointop
2# Description: TUI for tracking cryptocurrency stats
3# This file is overwritten after every install/update
4# Persistent local customizations
5include cointop.local
6# Persistent global definitions
7include globals.local
8
9noblacklist ${HOME}/.config/cointop
10
11blacklist ${RUNUSER}
12
13include disable-common.inc
14include disable-devel.inc
15include disable-exec.inc
16include disable-interpreters.inc
17include disable-proc.inc
18include disable-programs.inc
19include disable-shell.inc
20include disable-X11.inc
21include disable-xdg.inc
22
23mkdir ${HOME}/.config/cointop
24whitelist ${HOME}/.config/cointop
25include whitelist-common.inc
26include whitelist-runuser-common.inc
27include whitelist-usr-share-common.inc
28include whitelist-var-common.inc
29
30apparmor
31caps.drop all
32ipc-namespace
33machine-id
34netfilter
35no3d
36nodvd
37nogroups
38noinput
39nonewprivs
40noprinters
41noroot
42nosound
43notv
44nou2f
45novideo
46protocol inet,inet6
47seccomp
48seccomp.block-secondary
49shell none
50tracelog
51
52disable-mnt
53private-bin cointop
54private-cache
55private-dev
56private-etc alternatives,ca-certificates,crypto-policies,host.conf,hostname,hosts,ld.so.cache,ld.so.preload,nsswitch.conf,pki,protocols,resolv.conf,rpc,services,ssl
57private-lib
58private-tmp
59
60dbus-user none
61dbus-system none
62
63memory-deny-write-execute
diff --git a/etc/profile-a-l/firefox-common.profile b/etc/profile-a-l/firefox-common.profile
index 2fe12843e..373f41ffe 100644
--- a/etc/profile-a-l/firefox-common.profile
+++ b/etc/profile-a-l/firefox-common.profile
@@ -61,6 +61,7 @@ private-tmp
61 61
62blacklist ${PATH}/curl 62blacklist ${PATH}/curl
63blacklist ${PATH}/wget 63blacklist ${PATH}/wget
64blacklist ${PATH}/wget2
64 65
65# 'dbus-user none' breaks various desktop integration features like global menus, native notifications, 66# 'dbus-user none' breaks various desktop integration features like global menus, native notifications,
66# Gnome connector, KDE connect and power management on KDE Plasma. 67# Gnome connector, KDE connect and power management on KDE Plasma.
diff --git a/etc/profile-a-l/kmail.profile b/etc/profile-a-l/kmail.profile
index 0796e6876..1bbc141e8 100644
--- a/etc/profile-a-l/kmail.profile
+++ b/etc/profile-a-l/kmail.profile
@@ -29,6 +29,7 @@ noblacklist ${HOME}/.local/share/kxmlgui5/kmail
29noblacklist ${HOME}/.local/share/kxmlgui5/kmail2 29noblacklist ${HOME}/.local/share/kxmlgui5/kmail2
30noblacklist ${HOME}/.local/share/local-mail 30noblacklist ${HOME}/.local/share/local-mail
31noblacklist ${HOME}/.local/share/notes 31noblacklist ${HOME}/.local/share/notes
32noblacklist ${RUNUSER}/akonadi
32noblacklist /tmp/akonadi-* 33noblacklist /tmp/akonadi-*
33 34
34include disable-common.inc 35include disable-common.inc
diff --git a/etc/profile-a-l/lutris.profile b/etc/profile-a-l/lutris.profile
index bf8ab9e64..71309b48f 100644
--- a/etc/profile-a-l/lutris.profile
+++ b/etc/profile-a-l/lutris.profile
@@ -9,6 +9,7 @@ include globals.local
9noblacklist ${PATH}/llvm* 9noblacklist ${PATH}/llvm*
10noblacklist ${HOME}/Games 10noblacklist ${HOME}/Games
11noblacklist ${HOME}/.cache/lutris 11noblacklist ${HOME}/.cache/lutris
12noblacklist ${HOME}/.cache/wine
12noblacklist ${HOME}/.cache/winetricks 13noblacklist ${HOME}/.cache/winetricks
13noblacklist ${HOME}/.config/lutris 14noblacklist ${HOME}/.config/lutris
14noblacklist ${HOME}/.local/share/lutris 15noblacklist ${HOME}/.local/share/lutris
@@ -34,6 +35,7 @@ include disable-xdg.inc
34 35
35mkdir ${HOME}/Games 36mkdir ${HOME}/Games
36mkdir ${HOME}/.cache/lutris 37mkdir ${HOME}/.cache/lutris
38mkdir ${HOME}/.cache/wine
37mkdir ${HOME}/.cache/winetricks 39mkdir ${HOME}/.cache/winetricks
38mkdir ${HOME}/.config/lutris 40mkdir ${HOME}/.config/lutris
39mkdir ${HOME}/.local/share/lutris 41mkdir ${HOME}/.local/share/lutris
@@ -41,6 +43,7 @@ mkdir ${HOME}/.local/share/lutris
41whitelist ${DOWNLOADS} 43whitelist ${DOWNLOADS}
42whitelist ${HOME}/Games 44whitelist ${HOME}/Games
43whitelist ${HOME}/.cache/lutris 45whitelist ${HOME}/.cache/lutris
46whitelist ${HOME}/.cache/wine
44whitelist ${HOME}/.cache/winetricks 47whitelist ${HOME}/.cache/winetricks
45whitelist ${HOME}/.config/lutris 48whitelist ${HOME}/.config/lutris
46whitelist ${HOME}/.local/share/lutris 49whitelist ${HOME}/.local/share/lutris
diff --git a/etc/profile-m-z/mediathekview.profile b/etc/profile-m-z/mediathekview.profile
index f73ef0935..f0ef7d010 100644
--- a/etc/profile-m-z/mediathekview.profile
+++ b/etc/profile-m-z/mediathekview.profile
@@ -17,6 +17,8 @@ noblacklist ${HOME}/.mediathek3
17noblacklist ${HOME}/.mplayer 17noblacklist ${HOME}/.mplayer
18noblacklist ${VIDEOS} 18noblacklist ${VIDEOS}
19 19
20ignore noexec /tmp
21
20# Allow java (blacklisted by disable-devel.inc) 22# Allow java (blacklisted by disable-devel.inc)
21include allow-java.inc 23include allow-java.inc
22 24
@@ -27,6 +29,8 @@ include disable-interpreters.inc
27include disable-programs.inc 29include disable-programs.inc
28include disable-xdg.inc 30include disable-xdg.inc
29 31
32mkdir ${HOME}/.mediathek3
33whitelist ${HOME}/.mediathek3
30include whitelist-var-common.inc 34include whitelist-var-common.inc
31 35
32caps.drop all 36caps.drop all
diff --git a/etc/profile-m-z/raincat.profile b/etc/profile-m-z/raincat.profile
new file mode 100644
index 000000000..104577bdb
--- /dev/null
+++ b/etc/profile-m-z/raincat.profile
@@ -0,0 +1,49 @@
1# Firejail profile for raincat
2# This file is overwritten after every install/update
3# Persistent local customizations
4include raincat.local
5# Persistent global definitions
6include globals.local
7
8include disable-devel.inc
9include disable-exec.inc
10include disable-interpreters.inc
11include disable-programs.inc
12include disable-shell.inc
13include disable-xdg.inc
14
15whitelist /usr/share/games
16whitelist /usr/share/timidity
17include whitelist-usr-share-common.inc
18include whitelist-var-common.inc
19
20apparmor
21caps.drop all
22ipc-namespace
23netfilter
24nodvd
25nogroups
26noinput
27nonewprivs
28noroot
29notv
30nou2f
31novideo
32protocol unix
33net none
34seccomp
35shell none
36tracelog
37
38disable-mnt
39private
40private-bin raincat
41private-cache
42private-dev
43private-etc alternatives,drirc,ld.so.cache,ld.so.preload,machine-id,passwd,pulse,timidity,timidity.cfg
44#private-lib
45private-tmp
46
47dbus-user none
48dbus-system none
49
diff --git a/etc/profile-m-z/seafile-applet.profile b/etc/profile-m-z/seafile-applet.profile
new file mode 100644
index 000000000..79e072475
--- /dev/null
+++ b/etc/profile-m-z/seafile-applet.profile
@@ -0,0 +1,62 @@
1# Firejail profile for Seafile
2# Description: Seafile desktop client.
3# This file is overwritten after every install/update
4# Persistent local customizations
5include seafile-applet.local
6# Persistent global definitions
7include globals.local
8
9noblacklist ${HOME}/.config/Seafile
10noblacklist ${HOME}/Seafile/.seafile-data
11
12blacklist /usr/libexec
13
14include disable-common.inc
15include disable-devel.inc
16include disable-exec.inc
17include disable-interpreters.inc
18include disable-programs.inc
19include disable-xdg.inc
20
21mkdir ${HOME}/.ccnet
22mkdir ${HOME}/.config/Seafile
23mkdir ${HOME}/Seafile
24whitelist ${HOME}/.ccnet
25whitelist ${HOME}/.config/Seafile
26whitelist ${HOME}/Seafile
27
28include whitelist-common.inc
29include whitelist-run-common.inc
30include whitelist-runuser-common.inc
31include whitelist-usr-share-common.inc
32include whitelist-var-common.inc
33
34apparmor
35caps.drop all
36netfilter
37nodvd
38nogroups
39noinput
40nonewprivs
41noprinters
42noroot
43nosound
44notv
45nou2f
46novideo
47protocol unix,inet,inet6
48seccomp
49seccomp.block-secondary
50shell none
51tracelog
52
53disable-mnt
54private-bin seaf-cli,seaf-daemon,seafile-applet
55private-cache
56private-dev
57private-etc alternatives,ca-certificates,crypto-policies,host.conf,hostname,hosts,ld.so.cache,ld.so.preload,nsswitch.conf,pki,protocols,resolv.conf,rpc,services,ssl
58#private-opt none
59private-tmp
60
61dbus-user none
62dbus-system none
diff --git a/etc/profile-m-z/signal-desktop.profile b/etc/profile-m-z/signal-desktop.profile
index 77a7f5b38..1166f378b 100644
--- a/etc/profile-m-z/signal-desktop.profile
+++ b/etc/profile-m-z/signal-desktop.profile
@@ -21,9 +21,15 @@ whitelist ${HOME}/.config/Signal
21 21
22private-etc alternatives,ca-certificates,crypto-policies,fonts,ld.so.cache,ld.so.conf,ld.so.conf.d,ld.so.preload,localtime,machine-id,nsswitch.conf,pki,resolv.conf,ssl 22private-etc alternatives,ca-certificates,crypto-policies,fonts,ld.so.cache,ld.so.conf,ld.so.conf.d,ld.so.preload,localtime,machine-id,nsswitch.conf,pki,resolv.conf,ssl
23 23
24# allow D-Bus notifications
25dbus-user filter 24dbus-user filter
25
26# allow D-Bus notifications
26dbus-user.talk org.freedesktop.Notifications 27dbus-user.talk org.freedesktop.Notifications
28
29# allow D-Bus communication with firefox for opening links
30dbus-user.talk org.mozilla.Firefox.*
31dbus-user.talk org.mozilla.firefox.*
32
27ignore dbus-user none 33ignore dbus-user none
28 34
29# Redirect 35# Redirect
diff --git a/etc/profile-m-z/ssh.profile b/etc/profile-m-z/ssh.profile
index 9295013e7..4da0db517 100644
--- a/etc/profile-m-z/ssh.profile
+++ b/etc/profile-m-z/ssh.profile
@@ -50,4 +50,5 @@ writable-run-user
50dbus-user none 50dbus-user none
51dbus-system none 51dbus-system none
52 52
53deterministic-shutdown
53memory-deny-write-execute 54memory-deny-write-execute
diff --git a/etc/profile-m-z/steam.profile b/etc/profile-m-z/steam.profile
index bcf94de51..b31818274 100644
--- a/etc/profile-m-z/steam.profile
+++ b/etc/profile-m-z/steam.profile
@@ -147,7 +147,7 @@ shell none
147 147
148# private-bin is disabled while in testing, but is known to work with multiple games. 148# private-bin is disabled while in testing, but is known to work with multiple games.
149# Add the next line to your steam.local to enable private-bin. 149# Add the next line to your steam.local to enable private-bin.
150#private-bin awk,basename,bash,bsdtar,bzip2,cat,chmod,cksum,cmp,comm,compress,cp,curl,cut,date,dbus-launch,dbus-send,desktop-file-edit,desktop-file-install,desktop-file-validate,dirname,echo,env,expr,file,find,getopt,grep,gtar,gzip,head,hostname,id,lbzip2,ldconfig,ldd,ln,ls,lsb_release,lsof,lspci,lz4,lzip,lzma,lzop,md5sum,mkdir,mktemp,mv,netstat,ps,pulseaudio,python*,readlink,realpath,rm,sed,sh,sha1sum,sha256sum,sha512sum,sleep,sort,steam,steamdeps,steam-native,steam-runtime,sum,tail,tar,tclsh,test,touch,tr,umask,uname,update-desktop-database,wc,wget,which,whoami,xterm,xz,zenity 150#private-bin awk,basename,bash,bsdtar,bzip2,cat,chmod,cksum,cmp,comm,compress,cp,curl,cut,date,dbus-launch,dbus-send,desktop-file-edit,desktop-file-install,desktop-file-validate,dirname,echo,env,expr,file,find,getopt,grep,gtar,gzip,head,hostname,id,lbzip2,ldconfig,ldd,ln,ls,lsb_release,lsof,lspci,lz4,lzip,lzma,lzop,md5sum,mkdir,mktemp,mv,netstat,ps,pulseaudio,python*,readlink,realpath,rm,sed,sh,sha1sum,sha256sum,sha512sum,sleep,sort,steam,steamdeps,steam-native,steam-runtime,sum,tail,tar,tclsh,test,touch,tr,umask,uname,update-desktop-database,wc,wget,wget2,which,whoami,xterm,xz,zenity
151# Extra programs are available which might be needed for select games. 151# Extra programs are available which might be needed for select games.
152# Add the next line to your steam.local to enable support for these programs. 152# Add the next line to your steam.local to enable support for these programs.
153#private-bin java,java-config,mono 153#private-bin java,java-config,mono
@@ -157,7 +157,7 @@ shell none
157private-dev 157private-dev
158# private-etc breaks a small selection of games on some systems. Add 'ignore private-etc' 158# private-etc breaks a small selection of games on some systems. Add 'ignore private-etc'
159# to your steam.local to support those. 159# to your steam.local to support those.
160private-etc alsa,alternatives,asound.conf,bumblebee,ca-certificates,crypto-policies,dbus-1,drirc,fonts,group,gtk-2.0,gtk-3.0,host.conf,hostname,hosts,ld.so.cache,ld.so.conf,ld.so.conf.d,ld.so.preload,localtime,lsb-release,machine-id,mime.types,nvidia,os-release,passwd,pki,pulse,resolv.conf,services,ssl 160private-etc alsa,alternatives,asound.conf,bumblebee,ca-certificates,crypto-policies,dbus-1,drirc,fonts,group,gtk-2.0,gtk-3.0,host.conf,hostname,hosts,ld.so.cache,ld.so.conf,ld.so.conf.d,ld.so.preload,localtime,lsb-release,machine-id,mime.types,nvidia,os-release,passwd,pki,pulse,resolv.conf,services,ssl,vulkan
161private-tmp 161private-tmp
162 162
163# dbus-user none 163# dbus-user none
diff --git a/etc/profile-m-z/supertuxkart.profile b/etc/profile-m-z/supertuxkart.profile
index 473472251..23c8a6c58 100644
--- a/etc/profile-m-z/supertuxkart.profile
+++ b/etc/profile-m-z/supertuxkart.profile
@@ -43,7 +43,7 @@ noroot
43notv 43notv
44nou2f 44nou2f
45novideo 45novideo
46protocol unix,inet,inet6,bluetooth 46protocol unix,inet,inet6,netlink,bluetooth
47seccomp 47seccomp
48seccomp.block-secondary 48seccomp.block-secondary
49shell none 49shell none
diff --git a/etc/profile-m-z/uzbl-browser.profile b/etc/profile-m-z/uzbl-browser.profile
index 41487a8f2..dcdae279f 100644
--- a/etc/profile-m-z/uzbl-browser.profile
+++ b/etc/profile-m-z/uzbl-browser.profile
@@ -8,6 +8,7 @@ include globals.local
8noblacklist ${HOME}/.config/uzbl 8noblacklist ${HOME}/.config/uzbl
9noblacklist ${HOME}/.gnupg 9noblacklist ${HOME}/.gnupg
10noblacklist ${HOME}/.local/share/uzbl 10noblacklist ${HOME}/.local/share/uzbl
11noblacklist ${HOME}/.password-store
11 12
12# Allow python (blacklisted by disable-interpreters.inc) 13# Allow python (blacklisted by disable-interpreters.inc)
13include allow-python2.inc 14include allow-python2.inc
diff --git a/etc/profile-m-z/warzone2100.profile b/etc/profile-m-z/warzone2100.profile
index 46dca0547..5519c3c1e 100644
--- a/etc/profile-m-z/warzone2100.profile
+++ b/etc/profile-m-z/warzone2100.profile
@@ -7,19 +7,22 @@ include warzone2100.local
7include globals.local 7include globals.local
8 8
9noblacklist ${HOME}/.warzone2100-3.* 9noblacklist ${HOME}/.warzone2100-3.*
10noblacklist ${HOME}/.local/share/warzone2100-3.*
10 11
11include disable-common.inc 12include disable-common.inc
12include disable-devel.inc 13include disable-devel.inc
13include disable-exec.inc 14include disable-exec.inc
14include disable-interpreters.inc 15include disable-interpreters.inc
15include disable-programs.inc 16include disable-programs.inc
16include disable-shell.inc 17#include disable-shell.inc - problems on Debian 11
17 18
18mkdir ${HOME}/.warzone2100-3.1 19mkdir ${HOME}/.warzone2100-3.1
19mkdir ${HOME}/.warzone2100-3.2 20mkdir ${HOME}/.warzone2100-3.2
21whitelist ${HOME}/.local/share/warzone2100-3.3.0 # config dir moved under .local/share
20whitelist ${HOME}/.warzone2100-3.1 22whitelist ${HOME}/.warzone2100-3.1
21whitelist ${HOME}/.warzone2100-3.2 23whitelist ${HOME}/.warzone2100-3.2
22whitelist /usr/share/games 24whitelist /usr/share/games
25whitelist /usr/share/gdm
23include whitelist-common.inc 26include whitelist-common.inc
24include whitelist-runuser-common.inc 27include whitelist-runuser-common.inc
25include whitelist-usr-share-common.inc 28include whitelist-usr-share-common.inc
@@ -42,6 +45,6 @@ shell none
42tracelog 45tracelog
43 46
44disable-mnt 47disable-mnt
45private-bin warzone2100 48private-bin bash,dash,sh,warzone2100,which
46private-dev 49private-dev
47private-tmp 50private-tmp
diff --git a/etc/profile-m-z/wget2.profile b/etc/profile-m-z/wget2.profile
new file mode 100644
index 000000000..18918c6af
--- /dev/null
+++ b/etc/profile-m-z/wget2.profile
@@ -0,0 +1,19 @@
1# Firejail profile for wget2
2# Description: Updated version of the popular wget URL retrieval tool
3# This file is overwritten after every install/update
4quiet
5# Persistent local customizations
6include wget2.local
7# Persistent global definitions
8# added by included profile
9#include globals.local
10
11noblacklist ${HOME}/.config/wget
12ignore noblacklist ${HOME}/.wgetrc
13
14private-bin wget2
15# Depending on workflow you can add the next line to your wget2.local.
16#private-etc wget2rc
17
18# Redirect
19include wget.profile
diff --git a/etc/profile-m-z/wine.profile b/etc/profile-m-z/wine.profile
index 1e9b9341b..f30fc971f 100644
--- a/etc/profile-m-z/wine.profile
+++ b/etc/profile-m-z/wine.profile
@@ -6,6 +6,7 @@ include wine.local
6# Persistent global definitions 6# Persistent global definitions
7include globals.local 7include globals.local
8 8
9noblacklist ${HOME}/.cache/wine
9noblacklist ${HOME}/.cache/winetricks 10noblacklist ${HOME}/.cache/winetricks
10noblacklist ${HOME}/.Steam 11noblacklist ${HOME}/.Steam
11noblacklist ${HOME}/.local/share/Steam 12noblacklist ${HOME}/.local/share/Steam
diff --git a/etc/profile-m-z/youtube-viewers-common.profile b/etc/profile-m-z/youtube-viewers-common.profile
index 80d551038..f212a6721 100644
--- a/etc/profile-m-z/youtube-viewers-common.profile
+++ b/etc/profile-m-z/youtube-viewers-common.profile
@@ -50,7 +50,7 @@ shell none
50tracelog 50tracelog
51 51
52disable-mnt 52disable-mnt
53private-bin bash,ffmpeg,ffprobe,firefox,mpv,perl,python*,sh,smplayer,stty,wget,which,xterm,youtube-dl,yt-dlp 53private-bin bash,ffmpeg,ffprobe,firefox,mpv,perl,python*,sh,smplayer,stty,wget,wget2,which,xterm,youtube-dl,yt-dlp
54private-cache 54private-cache
55private-dev 55private-dev
56private-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.preload,machine-id,mime.types,nsswitch.conf,passwd,pki,pulse,resolv.conf,ssl,X11,xdg 56private-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.preload,machine-id,mime.types,nsswitch.conf,passwd,pki,pulse,resolv.conf,ssl,X11,xdg
diff --git a/src/fbuilder/build_profile.c b/src/fbuilder/build_profile.c
index 2e6b46e77..3a7a12fb3 100644
--- a/src/fbuilder/build_profile.c
+++ b/src/fbuilder/build_profile.c
@@ -22,7 +22,6 @@
22#include <sys/wait.h> 22#include <sys/wait.h>
23 23
24#define TRACE_OUTPUT "/tmp/firejail-trace.XXXXXX" 24#define TRACE_OUTPUT "/tmp/firejail-trace.XXXXXX"
25#define STRACE_OUTPUT "/tmp/firejail-strace.XXXXXX"
26 25
27void build_profile(int argc, char **argv, int index, FILE *fp) { 26void build_profile(int argc, char **argv, int index, FILE *fp) {
28 // next index is the application name 27 // next index is the application name
@@ -41,36 +40,33 @@ void build_profile(int argc, char **argv, int index, FILE *fp) {
41 if(asprintf(&output,"--trace=%s",trace_output) == -1) 40 if(asprintf(&output,"--trace=%s",trace_output) == -1)
42 errExit("asprintf"); 41 errExit("asprintf");
43 42
44 char *cmdlist[] = {
45 BINDIR "/firejail",
46 "--quiet",
47 "--noprofile",
48 "--caps.drop=all",
49 "--seccomp",
50 output,
51 "--shell=none",
52 };
53
54 // calculate command length 43 // calculate command length
55 unsigned len = (int) sizeof(cmdlist) / sizeof(char*) + argc - index + 1; 44 unsigned len = 64; // plenty of space for firejail command line
56 if (arg_debug) 45 len += argc - index; // program command line
57 printf("command len %d + %d + 1\n", (int) (sizeof(cmdlist) / sizeof(char*)), argc - index); 46 len += 1; // NULL
58 char *cmd[len];
59 cmd[0] = cmdlist[0]; // explicit assignment to clean scan-build error
60 47
61 // build command 48 // build command
62 unsigned i = 0; 49 char *cmd[len];
63 for (i = 0; i < (int) sizeof(cmdlist) / sizeof(char*); i++) 50 unsigned curr_len = 0;
64 cmd[i] = cmdlist[i]; 51 cmd[curr_len++] = BINDIR "/firejail";
65 52 cmd[curr_len++] = "--quiet";
66 int i2 = index; 53 cmd[curr_len++] = "--noprofile";
67 for (; i < (len - 1); i++, i2++) 54 cmd[curr_len++] = "--caps.drop=all";
68 cmd[i] = argv[i2]; 55 cmd[curr_len++] = "--seccomp";
69 assert(i < len); 56 cmd[curr_len++] = "--shell=none";
70 cmd[i] = NULL; 57 cmd[curr_len++] = output;
58 if (arg_appimage)
59 cmd[curr_len++] = "--appimage";
60
61 int i;
62 for (i = index; i < argc; i++)
63 cmd[curr_len++] = argv[i];
64
65 assert(curr_len < len);
66 cmd[curr_len] = NULL;
71 67
72 if (arg_debug) { 68 if (arg_debug) {
73 for (i = 0; i < len; i++) 69 for (i = 0; cmd[i]; i++)
74 printf("%s%s\n", (i)?"\t":"", cmd[i]); 70 printf("%s%s\n", (i)?"\t":"", cmd[i]);
75 } 71 }
76 72
diff --git a/src/fbuilder/fbuilder.h b/src/fbuilder/fbuilder.h
index 12dfdb8be..3e23d7854 100644
--- a/src/fbuilder/fbuilder.h
+++ b/src/fbuilder/fbuilder.h
@@ -31,6 +31,7 @@
31#define MAX_BUF 4096 31#define MAX_BUF 4096
32// main.c 32// main.c
33extern int arg_debug; 33extern int arg_debug;
34extern int arg_appimage;
34 35
35// build_profile.c 36// build_profile.c
36void build_profile(int argc, char **argv, int index, FILE *fp); 37void build_profile(int argc, char **argv, int index, FILE *fp);
diff --git a/src/fbuilder/main.c b/src/fbuilder/main.c
index 9e30ec539..aa49b2489 100644
--- a/src/fbuilder/main.c
+++ b/src/fbuilder/main.c
@@ -19,6 +19,7 @@
19*/ 19*/
20#include "fbuilder.h" 20#include "fbuilder.h"
21int arg_debug = 0; 21int arg_debug = 0;
22int arg_appimage = 0;
22 23
23static void usage(void) { 24static void usage(void) {
24 printf("Firejail profile builder\n"); 25 printf("Firejail profile builder\n");
@@ -49,6 +50,8 @@ printf("\n");
49 } 50 }
50 else if (strcmp(argv[i], "--debug") == 0) 51 else if (strcmp(argv[i], "--debug") == 0)
51 arg_debug = 1; 52 arg_debug = 1;
53 else if (strcmp(argv[i], "--appimage") == 0)
54 arg_appimage = 1;
52 else if (strcmp(argv[i], "--build") == 0) 55 else if (strcmp(argv[i], "--build") == 0)
53 ; // do nothing, this is passed down from firejail 56 ; // do nothing, this is passed down from firejail
54 else if (strncmp(argv[i], "--build=", 8) == 0) { 57 else if (strncmp(argv[i], "--build=", 8) == 0) {
diff --git a/src/fcopy/main.c b/src/fcopy/main.c
index a9443a764..c64d20127 100644
--- a/src/fcopy/main.c
+++ b/src/fcopy/main.c
@@ -200,7 +200,8 @@ static char *proc_pid_to_self(const char *target) {
200 200
201 // check where /proc/self points to 201 // check where /proc/self points to
202 static const char proc_self[] = "/proc/self"; 202 static const char proc_self[] = "/proc/self";
203 if (!(proc_pid = realpath(proc_self, NULL))) 203 proc_pid = realpath(proc_self, NULL);
204 if (proc_pid == NULL)
204 goto done; 205 goto done;
205 206
206 // redirect /proc/PID/xxx -> /proc/self/XXX 207 // redirect /proc/PID/xxx -> /proc/self/XXX
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config
index e68c04b4c..77f233bce 100644
--- a/src/firecfg/firecfg.config
+++ b/src/firecfg/firecfg.config
@@ -2,6 +2,7 @@
2# This is the list of programs in alphabetical order handled by firecfg utility 2# This is the list of programs in alphabetical order handled by firecfg utility
3# 3#
40ad 40ad
51password
52048-qt 62048-qt
6Books 7Books
7Builder 8Builder
@@ -152,6 +153,7 @@ cmus
152code 153code
153code-oss 154code-oss
154codium 155codium
156cointop
155cola 157cola
156colorful 158colorful
157com.github.bleakgrey.tootle 159com.github.bleakgrey.tootle
@@ -687,6 +689,7 @@ quaternion
687quiterss 689quiterss
688qupzilla 690qupzilla
689qutebrowser 691qutebrowser
692raincat
690rambox 693rambox
691redeclipse 694redeclipse
692rednotebook 695rednotebook
@@ -711,6 +714,7 @@ scorched3d
711scorchwentbonkers 714scorchwentbonkers
712scribus 715scribus
713sdat2img 716sdat2img
717seafile-applet
714seahorse 718seahorse
715seahorse-adventures 719seahorse-adventures
716seahorse-daemon 720seahorse-daemon
@@ -874,6 +878,7 @@ weechat
874weechat-curses 878weechat-curses
875wesnoth 879wesnoth
876wget 880wget
881wget2
877whalebird 882whalebird
878whois 883whois
879widelands 884widelands
diff --git a/src/firejail/cgroup.c b/src/firejail/cgroup.c
index bd4e8d2df..f1e16187f 100644
--- a/src/firejail/cgroup.c
+++ b/src/firejail/cgroup.c
@@ -18,6 +18,7 @@
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/ 19*/
20#include "firejail.h" 20#include "firejail.h"
21#include "../include/gcov_wrapper.h"
21#include <sys/wait.h> 22#include <sys/wait.h>
22#include <errno.h> 23#include <errno.h>
23 24
@@ -122,6 +123,9 @@ void set_cgroup(const char *fname, pid_t pid) {
122 drop_privs(0); 123 drop_privs(0);
123 124
124 do_set_cgroup(fname, pid); 125 do_set_cgroup(fname, pid);
126
127 __gcov_flush();
128
125 _exit(0); 129 _exit(0);
126 } 130 }
127 waitpid(child, NULL, 0); 131 waitpid(child, NULL, 0);
diff --git a/src/firejail/dbus.c b/src/firejail/dbus.c
index e1475870c..66738bd4b 100644
--- a/src/firejail/dbus.c
+++ b/src/firejail/dbus.c
@@ -297,11 +297,12 @@ void dbus_proxy_start(void) {
297 if (dbus_proxy_pid == -1) 297 if (dbus_proxy_pid == -1)
298 errExit("fork"); 298 errExit("fork");
299 if (dbus_proxy_pid == 0) { 299 if (dbus_proxy_pid == 0) {
300 int i; 300 // close open files
301 for (i = STDERR_FILENO + 1; i < FIREJAIL_MAX_FD; i++) { 301 int keep[2];
302 if (i != status_pipe[1] && i != args_pipe[0]) 302 keep[0] = status_pipe[1];
303 close(i); // close open files 303 keep[1] = args_pipe[0];
304 } 304 close_all(keep, ARRAY_SIZE(keep));
305
305 if (arg_dbus_log_file != NULL) { 306 if (arg_dbus_log_file != NULL) {
306 int output_fd = creat(arg_dbus_log_file, 0666); 307 int output_fd = creat(arg_dbus_log_file, 0666);
307 if (output_fd < 0) 308 if (output_fd < 0)
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 7529256d0..f1fa66707 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -161,6 +161,7 @@ typedef struct config_t {
161 161
162#define MAX_PROFILE_IGNORE 32 162#define MAX_PROFILE_IGNORE 32
163 char *profile_ignore[MAX_PROFILE_IGNORE]; 163 char *profile_ignore[MAX_PROFILE_IGNORE];
164 char *keep_fd; // inherit file descriptors to sandbox
164 char *chrootdir; // chroot directory 165 char *chrootdir; // chroot directory
165 char *home_private; // private home directory 166 char *home_private; // private home directory
166 char *home_private_keep; // keep list for private home directory 167 char *home_private_keep; // keep list for private home directory
@@ -352,6 +353,7 @@ extern int arg_nou2f; // --nou2f
352extern int arg_noinput; // --noinput 353extern int arg_noinput; // --noinput
353extern int arg_deterministic_exit_code; // always exit with first child's exit status 354extern int arg_deterministic_exit_code; // always exit with first child's exit status
354extern int arg_deterministic_shutdown; // shut down the sandbox if first child dies 355extern int arg_deterministic_shutdown; // shut down the sandbox if first child dies
356extern int arg_keep_fd_all; // inherit all file descriptors to sandbox
355 357
356typedef enum { 358typedef enum {
357 DBUS_POLICY_ALLOW, // Allow unrestricted access to the bus 359 DBUS_POLICY_ALLOW, // Allow unrestricted access to the bus
@@ -551,6 +553,7 @@ int remount_by_fd(int dst, unsigned long mountflags);
551int bind_mount_by_fd(int src, int dst); 553int bind_mount_by_fd(int src, int dst);
552int bind_mount_path_to_fd(const char *srcname, int dst); 554int bind_mount_path_to_fd(const char *srcname, int dst);
553int bind_mount_fd_to_path(int src, const char *destname); 555int bind_mount_fd_to_path(int src, const char *destname);
556void close_all(int *keep_list, size_t sz);
554int has_handler(pid_t pid, int signal); 557int has_handler(pid_t pid, int signal);
555void enter_network_namespace(pid_t pid); 558void enter_network_namespace(pid_t pid);
556int read_pid(const char *name, pid_t *pid); 559int read_pid(const char *name, pid_t *pid);
@@ -707,6 +710,7 @@ void env_ibus_load(void);
707void fs_whitelist(void); 710void fs_whitelist(void);
708 711
709// pulseaudio.c 712// pulseaudio.c
713void pipewire_disable(void);
710void pulseaudio_init(void); 714void pulseaudio_init(void);
711void pulseaudio_disable(void); 715void pulseaudio_disable(void);
712 716
@@ -881,7 +885,6 @@ void build_appimage_cmdline(char **command_line, char **window_title, int argc,
881#define SBOX_CAPS_HIDEPID (1 << 7) // hidepid caps filter for running firemon 885#define SBOX_CAPS_HIDEPID (1 << 7) // hidepid caps filter for running firemon
882#define SBOX_CAPS_NET_SERVICE (1 << 8) // caps filter for programs running network services 886#define SBOX_CAPS_NET_SERVICE (1 << 8) // caps filter for programs running network services
883#define SBOX_KEEP_FDS (1 << 9) // keep file descriptors open 887#define SBOX_KEEP_FDS (1 << 9) // keep file descriptors open
884#define FIREJAIL_MAX_FD 20 // getdtablesize() is overkill for a firejail process
885 888
886// run sbox 889// run sbox
887int sbox_run(unsigned filter, int num, ...); 890int sbox_run(unsigned filter, int num, ...);
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c
index baa707741..786e0d360 100644
--- a/src/firejail/fs_etc.c
+++ b/src/firejail/fs_etc.c
@@ -142,7 +142,7 @@ errexit:
142static void duplicate(const char *fname, const char *private_dir, const char *private_run_dir) { 142static void duplicate(const char *fname, const char *private_dir, const char *private_run_dir) {
143 assert(fname); 143 assert(fname);
144 144
145 if (*fname == '~' || *fname == '/' || strncmp(fname, "..", 2) == 0) { 145 if (*fname == '~' || *fname == '/' || strstr(fname, "..")) {
146 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname); 146 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname);
147 exit(1); 147 exit(1);
148 } 148 }
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index bdc0e277d..c515b59f5 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -337,21 +337,34 @@ static void tmpfs_topdirs(const TopDir *topdirs) {
337 // fix pam-tmpdir (#2685) 337 // fix pam-tmpdir (#2685)
338 const char *env = env_get("TMP"); 338 const char *env = env_get("TMP");
339 if (env) { 339 if (env) {
340 char *pamtmpdir; 340 // we allow TMP env set as /tmp/user/$UID and /tmp/$UID - see #4151
341 if (asprintf(&pamtmpdir, "/tmp/user/%u", getuid()) == -1) 341 char *pamtmpdir1;
342 if (asprintf(&pamtmpdir1, "/tmp/user/%u", getuid()) == -1)
342 errExit("asprintf"); 343 errExit("asprintf");
343 if (strcmp(env, pamtmpdir) == 0) { 344 char *pamtmpdir2;
345 if (asprintf(&pamtmpdir2, "/tmp/%u", getuid()) == -1)
346 errExit("asprintf");
347 if (strcmp(env, pamtmpdir1) == 0) {
344 // create empty user-owned /tmp/user/$UID directory 348 // create empty user-owned /tmp/user/$UID directory
345 EUID_ROOT(); 349 EUID_ROOT();
346 mkdir_attr("/tmp/user", 0711, 0, 0); 350 mkdir_attr("/tmp/user", 0755, 0, 0);
347 selinux_relabel_path("/tmp/user", "/tmp/user"); 351 selinux_relabel_path("/tmp/user", "/tmp/user");
348 fs_logger("mkdir /tmp/user"); 352 fs_logger("mkdir /tmp/user");
349 mkdir_attr(pamtmpdir, 0700, getuid(), 0); 353 mkdir_attr(pamtmpdir1, 0700, getuid(), 0);
350 selinux_relabel_path(pamtmpdir, pamtmpdir); 354 selinux_relabel_path(pamtmpdir1, pamtmpdir1);
351 fs_logger2("mkdir", pamtmpdir); 355 fs_logger2("mkdir", pamtmpdir1);
356 EUID_USER();
357 }
358 else if (strcmp(env, pamtmpdir2) == 0) {
359 // create empty user-owned /tmp/$UID directory
360 EUID_ROOT();
361 mkdir_attr(pamtmpdir2, 0700, getuid(), 0);
362 selinux_relabel_path(pamtmpdir2, pamtmpdir2);
363 fs_logger2("mkdir", pamtmpdir2);
352 EUID_USER(); 364 EUID_USER();
353 } 365 }
354 free(pamtmpdir); 366 free(pamtmpdir1);
367 free(pamtmpdir2);
355 } 368 }
356 } 369 }
357 370
diff --git a/src/firejail/join.c b/src/firejail/join.c
index 9fc80d85b..b62a1ca9d 100644
--- a/src/firejail/join.c
+++ b/src/firejail/join.c
@@ -569,11 +569,6 @@ void join(pid_t pid, int argc, char **argv, int index) {
569 dbus_set_system_bus_env(); 569 dbus_set_system_bus_env();
570#endif 570#endif
571 571
572 // set nice and rlimits
573 if (arg_nice)
574 set_nice(cfg.nice);
575 set_rlimits();
576
577 start_application(0, shfd, NULL); 572 start_application(0, shfd, NULL);
578 573
579 __builtin_unreachable(); 574 __builtin_unreachable();
diff --git a/src/firejail/macros.c b/src/firejail/macros.c
index 6d67fecbd..11385143a 100644
--- a/src/firejail/macros.c
+++ b/src/firejail/macros.c
@@ -314,9 +314,9 @@ void invalid_filename(const char *fname, int globbing) {
314 314
315 char *reject; 315 char *reject;
316 if (globbing) 316 if (globbing)
317 reject = "\\&!\"'<>%^{};,"; // file globbing ('*?[]') is allowed 317 reject = "\\&!\"<>%^{};,"; // file globbing ('*?[]') is allowed
318 else 318 else
319 reject = "\\&!?\"'<>%^{};,*[]"; 319 reject = "\\&!?\"<>%^{};,*[]";
320 char *c = strpbrk(ptr, reject); 320 char *c = strpbrk(ptr, reject);
321 if (c) { 321 if (c) {
322 fprintf(stderr, "Error: \"%s\" is an invalid filename: rejected character: \"%c\"\n", fname, *c); 322 fprintf(stderr, "Error: \"%s\" is an invalid filename: rejected character: \"%c\"\n", fname, *c);
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 09e1a1071..d614ae1ac 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -149,6 +149,7 @@ int arg_nou2f = 0; // --nou2f
149int arg_noinput = 0; // --noinput 149int arg_noinput = 0; // --noinput
150int arg_deterministic_exit_code = 0; // always exit with first child's exit status 150int arg_deterministic_exit_code = 0; // always exit with first child's exit status
151int arg_deterministic_shutdown = 0; // shut down the sandbox if first child dies 151int arg_deterministic_shutdown = 0; // shut down the sandbox if first child dies
152int arg_keep_fd_all = 0; // inherit all file descriptors to sandbox
152DbusPolicy arg_dbus_user = DBUS_POLICY_ALLOW; // --dbus-user 153DbusPolicy arg_dbus_user = DBUS_POLICY_ALLOW; // --dbus-user
153DbusPolicy arg_dbus_system = DBUS_POLICY_ALLOW; // --dbus-system 154DbusPolicy arg_dbus_system = DBUS_POLICY_ALLOW; // --dbus-system
154const char *arg_dbus_log_file = NULL; 155const char *arg_dbus_log_file = NULL;
@@ -408,9 +409,22 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
408 } 409 }
409#endif 410#endif
410#ifdef HAVE_NETWORK 411#ifdef HAVE_NETWORK
412 else if (strcmp(argv[i], "--nettrace") == 0) {
413 if (checkcfg(CFG_NETWORK)) {
414 netfilter_trace(0);
415 }
416 else
417 exit_err_feature("networking");
418 exit(0);
419 }
411 else if (strncmp(argv[i], "--nettrace=", 11) == 0) { 420 else if (strncmp(argv[i], "--nettrace=", 11) == 0) {
412 pid_t pid = require_pid(argv[i] + 11); 421 if (checkcfg(CFG_NETWORK)) {
413 netfilter_trace(pid); 422 pid_t pid = require_pid(argv[i] + 11);
423 netfilter_trace(pid);
424 }
425 else
426 exit_err_feature("networking");
427 exit(0);
414 } 428 }
415 else if (strncmp(argv[i], "--bandwidth=", 12) == 0) { 429 else if (strncmp(argv[i], "--bandwidth=", 12) == 0) {
416 if (checkcfg(CFG_NETWORK)) { 430 if (checkcfg(CFG_NETWORK)) {
@@ -1862,6 +1876,14 @@ int main(int argc, char **argv, char **envp) {
1862 } 1876 }
1863 profile_add_ignore(argv[i] + 9); 1877 profile_add_ignore(argv[i] + 9);
1864 } 1878 }
1879 else if (strncmp(argv[i], "--keep-fd=", 10) == 0) {
1880 if (strcmp(argv[i] + 10, "all") == 0)
1881 arg_keep_fd_all = 1;
1882 else {
1883 const char *add = argv[i] + 10;
1884 profile_list_augment(&cfg.keep_fd, add);
1885 }
1886 }
1865#ifdef HAVE_CHROOT 1887#ifdef HAVE_CHROOT
1866 else if (strncmp(argv[i], "--chroot=", 9) == 0) { 1888 else if (strncmp(argv[i], "--chroot=", 9) == 0) {
1867 if (checkcfg(CFG_CHROOT)) { 1889 if (checkcfg(CFG_CHROOT)) {
@@ -2307,11 +2329,20 @@ int main(int argc, char **argv, char **envp) {
2307 continue; 2329 continue;
2308 } 2330 }
2309#ifdef HAVE_NETWORK 2331#ifdef HAVE_NETWORK
2310 else if (strcmp(argv[i], "--netlock") == 0) 2332 else if (strcmp(argv[i], "--netlock") == 0) {
2311 arg_netlock = 1; 2333 if (checkcfg(CFG_NETWORK))
2334 arg_netlock = 1;
2335 else
2336 exit_err_feature("networking");
2337 }
2312 else if (strncmp(argv[i], "--netlock=", 10) == 0) { 2338 else if (strncmp(argv[i], "--netlock=", 10) == 0) {
2313 pid_t pid = require_pid(argv[i] + 10); 2339 if (checkcfg(CFG_NETWORK)) {
2314 netfilter_netlock(pid); 2340 pid_t pid = require_pid(argv[i] + 10);
2341 netfilter_netlock(pid);
2342 }
2343 else
2344 exit_err_feature("networking");
2345 exit(0);
2315 } 2346 }
2316 else if (strncmp(argv[i], "--interface=", 12) == 0) { 2347 else if (strncmp(argv[i], "--interface=", 12) == 0) {
2317 if (checkcfg(CFG_NETWORK)) { 2348 if (checkcfg(CFG_NETWORK)) {
@@ -3150,13 +3181,18 @@ int main(int argc, char **argv, char **envp) {
3150 } 3181 }
3151 } 3182 }
3152 3183
3153 // add render group 3184 // add render/vglusers group
3154 if (!arg_no3d) { 3185 if (!arg_no3d) {
3155 g = get_group_id("render"); 3186 g = get_group_id("render");
3156 if (g) { 3187 if (g) {
3157 sprintf(ptr, "%d %d 1\n", g, g); 3188 sprintf(ptr, "%d %d 1\n", g, g);
3158 ptr += strlen(ptr); 3189 ptr += strlen(ptr);
3159 } 3190 }
3191 g = get_group_id("vglusers");
3192 if (g) {
3193 sprintf(ptr, "%d %d 1\n", g, g);
3194 ptr += strlen(ptr);
3195 }
3160 } 3196 }
3161 3197
3162 // add lp group 3198 // add lp group
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c
index 61164d740..939ab29fa 100644
--- a/src/firejail/netfilter.c
+++ b/src/firejail/netfilter.c
@@ -93,7 +93,10 @@ void netfilter_netlock(pid_t pid) {
93void netfilter_trace(pid_t pid) { 93void netfilter_trace(pid_t pid) {
94 EUID_ASSERT(); 94 EUID_ASSERT();
95 95
96 enter_network_namespace(pid); 96 // a pid of 0 means the main system network namespace
97 if (pid)
98 enter_network_namespace(pid);
99
97 char *cmd; 100 char *cmd;
98 if (asprintf(&cmd, "%s/firejail/fnettrace", LIBDIR) == -1) 101 if (asprintf(&cmd, "%s/firejail/fnettrace", LIBDIR) == -1)
99 errExit("asprintf"); 102 errExit("asprintf");
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 5725100e4..794668dc6 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -290,6 +290,15 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
290 return 0; 290 return 0;
291 } 291 }
292 292
293 if (strncmp(ptr, "keep-fd ", 8) == 0) {
294 if (strcmp(ptr + 8, "all") == 0)
295 arg_keep_fd_all = 1;
296 else {
297 const char *add = ptr + 8;
298 profile_list_augment(&cfg.keep_fd, add);
299 }
300 return 0;
301 }
293 if (strncmp(ptr, "xephyr-screen ", 14) == 0) { 302 if (strncmp(ptr, "xephyr-screen ", 14) == 0) {
294#ifdef HAVE_X11 303#ifdef HAVE_X11
295 if (checkcfg(CFG_X11)) { 304 if (checkcfg(CFG_X11)) {
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c
index 2af00e37b..320668bf9 100644
--- a/src/firejail/pulseaudio.c
+++ b/src/firejail/pulseaudio.c
@@ -25,6 +25,7 @@
25#include <dirent.h> 25#include <dirent.h>
26#include <errno.h> 26#include <errno.h>
27#include <sys/wait.h> 27#include <sys/wait.h>
28#include <glob.h>
28 29
29#include <fcntl.h> 30#include <fcntl.h>
30#ifndef O_PATH 31#ifndef O_PATH
@@ -33,6 +34,59 @@
33 34
34#define PULSE_CLIENT_SYSCONF "/etc/pulse/client.conf" 35#define PULSE_CLIENT_SYSCONF "/etc/pulse/client.conf"
35 36
37
38
39static void disable_rundir_pipewire(const char *path) {
40 assert(path);
41
42 // globbing for path/pipewire-*
43 char *pattern;
44 if (asprintf(&pattern, "%s/pipewire-*", path) == -1)
45 errExit("asprintf");
46
47 glob_t globbuf;
48 int globerr = glob(pattern, GLOB_NOCHECK | GLOB_NOSORT, NULL, &globbuf);
49 if (globerr) {
50 fprintf(stderr, "Error: failed to glob pattern %s\n", pattern);
51 exit(1);
52 }
53
54 size_t i;
55 for (i = 0; i < globbuf.gl_pathc; i++) {
56 char *dir = globbuf.gl_pathv[i];
57 assert(dir);
58
59 // don't disable symlinks - disable_file_or_dir will bind-mount an empty directory on top of it!
60 if (is_link(dir))
61 continue;
62 disable_file_or_dir(dir);
63 }
64 globfree(&globbuf);
65 free(pattern);
66}
67
68
69
70// disable pipewire socket
71void pipewire_disable(void) {
72 if (arg_debug)
73 printf("disable pipewire\n");
74 // blacklist user config directory
75 disable_file_path(cfg.homedir, ".config/pipewire");
76
77 // blacklist pipewire in XDG_RUNTIME_DIR
78 const char *name = env_get("XDG_RUNTIME_DIR");
79 if (name)
80 disable_rundir_pipewire(name);
81
82 // try the default location anyway
83 char *path;
84 if (asprintf(&path, "/run/user/%d", getuid()) == -1)
85 errExit("asprintf");
86 disable_rundir_pipewire(path);
87 free(path);
88}
89
36// disable pulseaudio socket 90// disable pulseaudio socket
37void pulseaudio_disable(void) { 91void pulseaudio_disable(void) {
38 if (arg_debug) 92 if (arg_debug)
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 61d6578a0..96407d081 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -404,7 +404,6 @@ static void print_time(void) {
404 fmessage("Child process initialized in %.02f ms\n", delta); 404 fmessage("Child process initialized in %.02f ms\n", delta);
405} 405}
406 406
407
408// check execute permissions for the program 407// check execute permissions for the program
409// this is done typically by the shell 408// this is done typically by the shell
410// we are here because of --shell=none 409// we are here because of --shell=none
@@ -461,10 +460,42 @@ static int ok_to_run(const char *program) {
461 return 0; 460 return 0;
462} 461}
463 462
463static void close_file_descriptors(void) {
464 if (arg_keep_fd_all)
465 return;
466
467 if (arg_debug)
468 printf("Closing non-standard file descriptors\n");
469
470 if (!cfg.keep_fd) {
471 close_all(NULL, 0);
472 return;
473 }
474
475 size_t sz = 0;
476 int *keep = str_to_int_array(cfg.keep_fd, &sz);
477 if (!keep) {
478 fprintf(stderr, "Error: invalid keep-fd option\n");
479 exit(1);
480 }
481 close_all(keep, sz);
482 free(keep);
483}
484
485
464void start_application(int no_sandbox, int fd, char *set_sandbox_status) { 486void start_application(int no_sandbox, int fd, char *set_sandbox_status) {
465 // set environment 487 if (no_sandbox == 0) {
466 if (no_sandbox == 0) 488 close_file_descriptors();
489
490 // set nice and rlimits
491 if (arg_nice)
492 set_nice(cfg.nice);
493 set_rlimits();
494
467 env_defaults(); 495 env_defaults();
496 }
497
498 // set environment
468 env_apply_all(); 499 env_apply_all();
469 500
470 // restore original umask 501 // restore original umask
@@ -1018,6 +1049,9 @@ int sandbox(void* sandbox_arg) {
1018 // disable pulseaudio 1049 // disable pulseaudio
1019 pulseaudio_disable(); 1050 pulseaudio_disable();
1020 1051
1052 // disable pipewire
1053 pipewire_disable();
1054
1021 // disable /dev/snd 1055 // disable /dev/snd
1022 fs_dev_disable_sound(); 1056 fs_dev_disable_sound();
1023 } 1057 }
@@ -1252,12 +1286,6 @@ int sandbox(void* sandbox_arg) {
1252#ifdef HAVE_APPARMOR 1286#ifdef HAVE_APPARMOR
1253 set_apparmor(); 1287 set_apparmor();
1254#endif 1288#endif
1255
1256 // set nice and rlimits
1257 if (arg_nice)
1258 set_nice(cfg.nice);
1259 set_rlimits();
1260
1261 start_application(0, -1, set_sandbox_status); 1289 start_application(0, -1, set_sandbox_status);
1262 } 1290 }
1263 1291
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c
index e5e67c09d..a37943940 100644
--- a/src/firejail/sbox.c
+++ b/src/firejail/sbox.c
@@ -23,6 +23,7 @@
23#include <unistd.h> 23#include <unistd.h>
24#include <net/if.h> 24#include <net/if.h>
25#include <stdarg.h> 25#include <stdarg.h>
26#include <sys/resource.h>
26#include <sys/wait.h> 27#include <sys/wait.h>
27#include "../include/seccomp.h" 28#include "../include/seccomp.h"
28 29
@@ -72,11 +73,8 @@ static int __attribute__((noreturn)) sbox_do_exec_v(unsigned filtermask, char *
72 } 73 }
73 74
74 // close all other file descriptors 75 // close all other file descriptors
75 if ((filtermask & SBOX_KEEP_FDS) == 0) { 76 if ((filtermask & SBOX_KEEP_FDS) == 0)
76 int i; 77 close_all(NULL, 0);
77 for (i = 3; i < FIREJAIL_MAX_FD; i++)
78 close(i); // close open files
79 }
80 78
81 umask(027); 79 umask(027);
82 80
@@ -206,6 +204,11 @@ static int __attribute__((noreturn)) sbox_do_exec_v(unsigned filtermask, char *
206 if (filtermask & SBOX_USER) 204 if (filtermask & SBOX_USER)
207 drop_privs(1); 205 drop_privs(1);
208 else if (filtermask & SBOX_ROOT) { 206 else if (filtermask & SBOX_ROOT) {
207 // https://seclists.org/oss-sec/2021/q4/43
208 struct rlimit tozero = { .rlim_cur = 0, .rlim_max = 0 };
209 if (setrlimit(RLIMIT_CORE, &tozero))
210 errExit("setrlimit");
211
209 // elevate privileges in order to get grsecurity working 212 // elevate privileges in order to get grsecurity working
210 if (setreuid(0, 0)) 213 if (setreuid(0, 0))
211 errExit("setreuid"); 214 errExit("setreuid");
@@ -292,7 +295,8 @@ int sbox_run_v(unsigned filtermask, char * const arg[]) {
292 if (waitpid(child, &status, 0) == -1 ) { 295 if (waitpid(child, &status, 0) == -1 ) {
293 errExit("waitpid"); 296 errExit("waitpid");
294 } 297 }
295 if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { 298 if (WIFSIGNALED(status) ||
299 (WIFEXITED(status) && WEXITSTATUS(status) != 0)) {
296 fprintf(stderr, "Error: failed to run %s, exiting...\n", arg[0]); 300 fprintf(stderr, "Error: failed to run %s, exiting...\n", arg[0]);
297 exit(1); 301 exit(1);
298 } 302 }
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index 24c8e3194..c903841c5 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -119,6 +119,7 @@ static char *usage_str =
119 " --join-or-start=name|pid - join the sandbox or start a new one.\n" 119 " --join-or-start=name|pid - join the sandbox or start a new one.\n"
120 " --keep-config-pulse - disable automatic ~/.config/pulse init.\n" 120 " --keep-config-pulse - disable automatic ~/.config/pulse init.\n"
121 " --keep-dev-shm - /dev/shm directory is untouched (even with --private-dev).\n" 121 " --keep-dev-shm - /dev/shm directory is untouched (even with --private-dev).\n"
122 " --keep-fd - inherit open file descriptors to sandbox.\n"
122 " --keep-var-tmp - /var/tmp directory is untouched.\n" 123 " --keep-var-tmp - /var/tmp directory is untouched.\n"
123 " --list - list all sandboxes.\n" 124 " --list - list all sandboxes.\n"
124#ifdef HAVE_FILE_TRANSFER 125#ifdef HAVE_FILE_TRANSFER
diff --git a/src/firejail/util.c b/src/firejail/util.c
index dbbc1ea28..79ebfa1dd 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -209,6 +209,8 @@ static void clean_supplementary_groups(gid_t gid) {
209 if (!arg_no3d) { 209 if (!arg_no3d) {
210 copy_group_ifcont("render", groups, ngroups, 210 copy_group_ifcont("render", groups, ngroups,
211 new_groups, &new_ngroups, MAX_GROUPS); 211 new_groups, &new_ngroups, MAX_GROUPS);
212 copy_group_ifcont("vglusers", groups, ngroups,
213 new_groups, &new_ngroups, MAX_GROUPS);
212 } 214 }
213 215
214 if (!arg_noprinters) { 216 if (!arg_noprinters) {
@@ -1398,6 +1400,52 @@ int bind_mount_path_to_fd(const char *srcname, int dst) {
1398 return rv; 1400 return rv;
1399} 1401}
1400 1402
1403void close_all(int *keep_list, size_t sz) {
1404 DIR *dir;
1405 if (!(dir = opendir("/proc/self/fd"))) {
1406 // sleep 2 seconds and try again
1407 sleep(2);
1408 if (!(dir = opendir("/proc/self/fd"))) {
1409 fprintf(stderr, "Error: cannot open /proc/self/fd directory\n");
1410 exit(1);
1411 }
1412 }
1413 struct dirent *entry;
1414 while ((entry = readdir(dir)) != NULL) {
1415 if (strcmp(entry->d_name, ".") == 0 ||
1416 strcmp(entry->d_name, "..") == 0)
1417 continue;
1418
1419 int fd = atoi(entry->d_name);
1420
1421 // don't close standard streams
1422 if (fd == STDIN_FILENO ||
1423 fd == STDOUT_FILENO ||
1424 fd == STDERR_FILENO)
1425 continue;
1426
1427 if (fd == dirfd(dir))
1428 continue; // just postponed
1429
1430 // dont't close file descriptors in keep list
1431 int keep = 0;
1432 if (keep_list) {
1433 size_t i;
1434 for (i = 0; i < sz; i++) {
1435 if (keep_list[i] == fd) {
1436 keep = 1;
1437 break;
1438 }
1439 }
1440 }
1441 if (keep)
1442 continue;
1443
1444 close(fd);
1445 }
1446 closedir(dir);
1447}
1448
1401int has_handler(pid_t pid, int signal) { 1449int has_handler(pid_t pid, int signal) {
1402 if (signal > 0 && signal <= SIGRTMAX) { 1450 if (signal > 0 && signal <= SIGRTMAX) {
1403 char *fname; 1451 char *fname;
diff --git a/src/fnettrace/fnettrace.h b/src/fnettrace/fnettrace.h
index c2f76f3a6..66b7378da 100644
--- a/src/fnettrace/fnettrace.h
+++ b/src/fnettrace/fnettrace.h
@@ -29,11 +29,10 @@
29#include <stdarg.h> 29#include <stdarg.h>
30//#define DEBUG 1 30//#define DEBUG 1
31 31
32//#define NETLOCK_INTERVAL 15 32#define NETLOCK_INTERVAL 60 // seconds
33#define NETLOCK_INTERVAL 60 33#define DISPLAY_INTERVAL 2 // seconds
34#define DISPLAY_INTERVAL 2 34#define DISPLAY_TTL 4 // display intervals (4 * 2 seconds)
35#define DISPLAY_TTL 4 35#define DISPLAY_BW_UNITS 20 // length of the bandwidth bar
36#define DISPLAY_BW_UNITS 20
37 36
38 37
39static inline void ansi_topleft(void) { 38static inline void ansi_topleft(void) {
@@ -59,8 +58,8 @@ static inline uint8_t hash(uint32_t ip) {
59void logprintf(char* fmt, ...); 58void logprintf(char* fmt, ...);
60 59
61// hostnames.c 60// hostnames.c
61extern int geoip_calls;
62void load_hostnames(const char *fname); 62void load_hostnames(const char *fname);
63char* retrieve_hostname(uint32_t ip); 63char* retrieve_hostname(uint32_t ip);
64void build_list(const char *fname);
65 64
66#endif \ No newline at end of file 65#endif \ No newline at end of file
diff --git a/src/fnettrace/hostnames.c b/src/fnettrace/hostnames.c
index e1ad45f81..dd92070bf 100644
--- a/src/fnettrace/hostnames.c
+++ b/src/fnettrace/hostnames.c
@@ -21,8 +21,15 @@
21#include "radix.h" 21#include "radix.h"
22#define MAXBUF 1024 22#define MAXBUF 1024
23 23
24int geoip_calls = 0;
25static int geoip_not_found = 0;
26static char buf[MAXBUF];
24 27
25char *retrieve_hostname(uint32_t ip) { 28char *retrieve_hostname(uint32_t ip) {
29 if (geoip_not_found)
30 return NULL;
31 geoip_calls++;
32
26 char *rv = NULL; 33 char *rv = NULL;
27 char *cmd; 34 char *cmd;
28 if (asprintf(&cmd, "/usr/bin/geoiplookup %d.%d.%d.%d", PRINT_IP(ip)) == -1) 35 if (asprintf(&cmd, "/usr/bin/geoiplookup %d.%d.%d.%d", PRINT_IP(ip)) == -1)
@@ -31,7 +38,6 @@ char *retrieve_hostname(uint32_t ip) {
31 FILE *fp = popen(cmd, "r"); 38 FILE *fp = popen(cmd, "r");
32 if (fp) { 39 if (fp) {
33 char *ptr; 40 char *ptr;
34 char buf[MAXBUF];
35 if (fgets(buf, MAXBUF, fp)) { 41 if (fgets(buf, MAXBUF, fp)) {
36 ptr = strchr(buf, '\n'); 42 ptr = strchr(buf, '\n');
37 if (ptr) 43 if (ptr)
@@ -40,13 +46,17 @@ char *retrieve_hostname(uint32_t ip) {
40 ptr = buf + 22; 46 ptr = buf + 22;
41 if (*ptr == ' ' && *(ptr + 3) == ',' && *(ptr + 4) == ' ') { 47 if (*ptr == ' ' && *(ptr + 3) == ',' && *(ptr + 4) == ' ') {
42 rv = ptr + 5; 48 rv = ptr + 5;
43 radix_add(ip, 0xffffffff, ptr + 5); 49 rv = radix_add(ip, 0xffffffff, rv);
44 } 50 }
45 } 51 }
46 } 52 }
47 fclose(fp); 53 fclose(fp);
48 return rv; 54 return rv;
49 } 55 }
56 else
57 geoip_not_found = 1;
58
59 free(cmd);
50 60
51 return NULL; 61 return NULL;
52} 62}
@@ -112,9 +122,3 @@ errexit:
112 exit(1); 122 exit(1);
113} 123}
114 124
115void build_list(const char *fname) {
116 assert(fname);
117 load_hostnames(fname);
118 radix_build_list();
119}
120
diff --git a/src/fnettrace/main.c b/src/fnettrace/main.c
index 804a9cd80..e58cc79b3 100644
--- a/src/fnettrace/main.c
+++ b/src/fnettrace/main.c
@@ -26,10 +26,9 @@ static int arg_netfilter = 0;
26static char *arg_log = NULL; 26static char *arg_log = NULL;
27 27
28typedef struct hnode_t { 28typedef struct hnode_t {
29 struct hnode_t *hnext; // used for hash table 29 struct hnode_t *hnext; // used for hash table and unused linked list
30 struct hnode_t *dnext; // used to display stremas on the screen 30 struct hnode_t *dnext; // used to display stremas on the screen
31 uint32_t ip_src; 31 uint32_t ip_src;
32 uint32_t ip_dst;
33 uint32_t bytes; // number of bytes received in the last display interval 32 uint32_t bytes; // number of bytes received in the last display interval
34 uint16_t port_src; 33 uint16_t port_src;
35 uint8_t protocol; 34 uint8_t protocol;
@@ -46,9 +45,36 @@ HNode *htable[HMAX] = {NULL};
46// display linked list 45// display linked list
47HNode *dlist = NULL; 46HNode *dlist = NULL;
48 47
49static unsigned bwmax = 0; // max bytes received in a display interval
50 48
51static void hnode_add(uint32_t ip_src, uint32_t ip_dst, uint8_t protocol, uint16_t port_src, uint32_t bytes) { 49// speed up malloc/free
50#define HNODE_MAX_MALLOC 16
51static HNode *hnode_unused = NULL;
52HNode *hmalloc(void) {
53 if (hnode_unused == NULL) {
54 hnode_unused = malloc(sizeof(HNode) * HNODE_MAX_MALLOC);
55 if (!hnode_unused)
56 errExit("malloc");
57 memset(hnode_unused, 0, sizeof(HNode) * HNODE_MAX_MALLOC);
58 HNode *ptr = hnode_unused;
59 int i;
60 for ( i = 1; i < HNODE_MAX_MALLOC; i++, ptr++)
61 ptr->hnext = hnode_unused + i;
62 }
63
64 HNode *rv = hnode_unused;
65 hnode_unused = hnode_unused->hnext;
66 return rv;
67}
68
69void hfree(HNode *ptr) {
70 assert(ptr);
71 memset(ptr, 0, sizeof(HNode));
72 ptr->hnext = hnode_unused;
73 hnode_unused = ptr;
74}
75
76
77static void hnode_add(uint32_t ip_src, uint8_t protocol, uint16_t port_src, uint32_t bytes) {
52 uint8_t h = hash(ip_src); 78 uint8_t h = hash(ip_src);
53 79
54 // find 80 // find
@@ -57,7 +83,7 @@ static void hnode_add(uint32_t ip_src, uint32_t ip_dst, uint8_t protocol, uint16
57 while (ptr) { 83 while (ptr) {
58 if (ptr->ip_src == ip_src) { 84 if (ptr->ip_src == ip_src) {
59 ip_instance++; 85 ip_instance++;
60 if (ptr->ip_dst == ip_dst && ptr->port_src == port_src && ptr->protocol == protocol) { 86 if (ptr->port_src == port_src && ptr->protocol == protocol) {
61 ptr->bytes += bytes; 87 ptr->bytes += bytes;
62 return; 88 return;
63 } 89 }
@@ -68,12 +94,10 @@ static void hnode_add(uint32_t ip_src, uint32_t ip_dst, uint8_t protocol, uint16
68#ifdef DEBUG 94#ifdef DEBUG
69 printf("malloc %d.%d.%d.%d\n", PRINT_IP(ip_src)); 95 printf("malloc %d.%d.%d.%d\n", PRINT_IP(ip_src));
70#endif 96#endif
71 HNode *hnew = malloc(sizeof(HNode)); 97 HNode *hnew = hmalloc();
72 if (!hnew) 98 assert(hnew);
73 errExit("malloc");
74 hnew->hostname = NULL; 99 hnew->hostname = NULL;
75 hnew->ip_src = ip_src; 100 hnew->ip_src = ip_src;
76 hnew->ip_dst = ip_dst;
77 hnew->port_src = port_src; 101 hnew->port_src = port_src;
78 hnew->protocol = protocol; 102 hnew->protocol = protocol;
79 hnew->hnext = NULL; 103 hnew->hnext = NULL;
@@ -121,7 +145,7 @@ static void hnode_free(HNode *elem) {
121 htable[h] = elem->hnext; 145 htable[h] = elem->hnext;
122 else 146 else
123 prev->hnext = elem->hnext; 147 prev->hnext = elem->hnext;
124 free(elem); 148 hfree(elem);
125} 149}
126 150
127#ifdef DEBUG 151#ifdef DEBUG
@@ -151,7 +175,7 @@ static char *print_bw(unsigned units) {
151 units = DISPLAY_BW_UNITS ; 175 units = DISPLAY_BW_UNITS ;
152 176
153 if (bw_line[units] == NULL) { 177 if (bw_line[units] == NULL) {
154 char *ptr = malloc(DISPLAY_BW_UNITS + 1); 178 char *ptr = malloc(DISPLAY_BW_UNITS + 2);
155 if (!ptr) 179 if (!ptr)
156 errExit("malloc"); 180 errExit("malloc");
157 bw_line[units] = ptr; 181 bw_line[units] = ptr;
@@ -159,34 +183,77 @@ static char *print_bw(unsigned units) {
159 unsigned i; 183 unsigned i;
160 for (i = 0; i < DISPLAY_BW_UNITS; i++, ptr++) 184 for (i = 0; i < DISPLAY_BW_UNITS; i++, ptr++)
161 sprintf(ptr, "%s", (i < units)? "*": " "); 185 sprintf(ptr, "%s", (i < units)? "*": " ");
186 sprintf(ptr, "%s", " ");
162 } 187 }
163 188
164 return bw_line[units]; 189 return bw_line[units];
165} 190}
166 191
167static void hnode_print(void) { 192#define LINE_MAX 200
168 assert(!arg_netfilter); 193static inline void adjust_line(char *str, int len, int cols) {
169 ansi_clrscr(); 194 if (len > LINE_MAX) // functions such as snprintf truncate the string, and return the length of the untruncated string
195 len = LINE_MAX;
196 if (cols > 4 && len > cols) {
197 str[cols] = '\0';
198 str[cols- 1] = '\n';
199 }
200}
170 201
202#define BWMAX_CNT 8
203static unsigned adjust_bandwidth(unsigned bw) {
204 static unsigned array[BWMAX_CNT] = {0};
205 static int instance = 0;
206
207 array[instance] = bw;
208 int i;
209 unsigned sum = 0;
210 unsigned max = 0;
211 for ( i = 0; i < BWMAX_CNT; i++) {
212 sum += array[i];
213 max = (max > array[i])? max: array[i];
214 }
215 sum /= BWMAX_CNT;
216
217 if (++instance >= BWMAX_CNT)
218 instance = 0;
219
220 return (max < (sum / 2))? sum: max;
221}
222
223static void hnode_print(unsigned bw) {
224 assert(!arg_netfilter);
225 bw = (bw < 1024 * DISPLAY_INTERVAL)? 1024 * DISPLAY_INTERVAL: bw;
171#ifdef DEBUG 226#ifdef DEBUG
172 printf("*********************\n"); 227 printf("*********************\n");
173 debug_dlist(); 228 debug_dlist();
174 printf("-----------------------------\n"); 229 printf("-----------------------------\n");
175 debug_hnode(); 230 debug_hnode();
176 printf("*********************\n"); 231 printf("*********************\n");
232#else
233 ansi_clrscr();
177#endif 234#endif
178 235
179 // get terminal size 236 // get terminal size
180 struct winsize sz; 237 struct winsize sz;
181 int col = 80; 238 int cols = 80;
182 if (isatty(STDIN_FILENO)) { 239 if (isatty(STDIN_FILENO)) {
183 if (!ioctl(0, TIOCGWINSZ, &sz)) 240 if (!ioctl(0, TIOCGWINSZ, &sz))
184 col = sz.ws_col; 241 cols = sz.ws_col;
185 } 242 }
186#define LINE_MAX 200 243 if (cols > LINE_MAX)
244 cols = LINE_MAX;
187 char line[LINE_MAX + 1]; 245 char line[LINE_MAX + 1];
188 if (col > LINE_MAX) 246
189 col = LINE_MAX; 247 // print stats line
248 bw = adjust_bandwidth(bw);
249 char stats[31];
250 if (bw > (1024 * 1024 * DISPLAY_INTERVAL))
251 sprintf(stats, "%u MB/s ", bw / (1024 * 1024 * DISPLAY_INTERVAL));
252 else
253 sprintf(stats, "%u KB/s ", bw / (1024 * DISPLAY_INTERVAL));
254 int len = snprintf(line, LINE_MAX, "%32s geoip %d, IP database %d\n", stats, geoip_calls, radix_nodes);
255 adjust_line(line, len, cols);
256 printf("%s", line);
190 257
191 HNode *ptr = dlist; 258 HNode *ptr = dlist;
192 HNode *prev = NULL; 259 HNode *prev = NULL;
@@ -195,39 +262,45 @@ static void hnode_print(void) {
195 if (--ptr->ttl > 0) { 262 if (--ptr->ttl > 0) {
196 char bytes[11]; 263 char bytes[11];
197 if (ptr->bytes > (DISPLAY_INTERVAL * 1024 * 1024 * 2)) // > 2 MB/second 264 if (ptr->bytes > (DISPLAY_INTERVAL * 1024 * 1024 * 2)) // > 2 MB/second
198 sprintf(bytes, "%u MB/s", 265 snprintf(bytes, 11, "%u MB/s",
199 (unsigned) (ptr->bytes / (DISPLAY_INTERVAL * 1024* 1024))); 266 (unsigned) (ptr->bytes / (DISPLAY_INTERVAL * 1024* 1024)));
200 else if (ptr->bytes > (DISPLAY_INTERVAL * 1024 * 2)) // > 2 KB/second 267 else if (ptr->bytes > (DISPLAY_INTERVAL * 1024 * 2)) // > 2 KB/second
201 sprintf(bytes, "%u KB/s", 268 snprintf(bytes, 11, "%u KB/s",
202 (unsigned) (ptr->bytes / (DISPLAY_INTERVAL * 1024))); 269 (unsigned) (ptr->bytes / (DISPLAY_INTERVAL * 1024)));
203 else 270 else
204 sprintf(bytes, "%u B/s", (unsigned) (ptr->bytes / DISPLAY_INTERVAL)); 271 snprintf(bytes, 11, "%u B/s ", (unsigned) (ptr->bytes / DISPLAY_INTERVAL));
205 272
206 char *hostname = ptr->hostname; 273 if (!ptr->hostname)
207 if (!hostname) 274 ptr->hostname = radix_longest_prefix_match(ptr->ip_src);
208 hostname = radix_find_last(ptr->ip_src); 275 if (!ptr->hostname)
209 276 ptr->hostname = retrieve_hostname(ptr->ip_src);
210 if (!hostname) 277 if (!ptr->hostname)
211 hostname = retrieve_hostname(ptr->ip_src); 278 ptr->hostname = " ";
212 279
213 if (!hostname) 280 unsigned bwunit = bw / DISPLAY_BW_UNITS;
214 hostname = " "; 281 char *bwline;
215 else { 282 if (bwunit == 0)
216 ptr->hostname = strdup(hostname); 283 bwline = print_bw(0);
217 if (!ptr->hostname) 284 else
218 errExit("strdup"); 285 bwline = print_bw(ptr->bytes / bwunit);
219 } 286
220 287 char *protocol = "";
221 unsigned bwunit = bwmax / DISPLAY_BW_UNITS; 288 if (ptr->port_src == 80)
222 unsigned units = ptr->bytes / bwunit; 289 protocol = "(HTTP)";
223 char *bwline = print_bw(units); 290 else if (ptr->port_src == 853)
291 protocol = "(DoT)";
292 else if (ptr->protocol == 0x11)
293 protocol = "(UDP)";
294/*
295 else (ptr->port_src == 443)
296 protocol = "TLS";
297 else if (ptr->port_src == 53)
298 protocol = "DNS";
299*/
224 300
225 sprintf(line, "%10s %s %d.%d.%d.%d:%u %s\n", bytes, bwline, PRINT_IP(ptr->ip_src), ptr->port_src, hostname); 301 len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d:%u%s %s\n",
226 int len = strlen(line); 302 bytes, bwline, PRINT_IP(ptr->ip_src), ptr->port_src, protocol, ptr->hostname);
227 if (col > 4 && len > col) { 303 adjust_line(line, len, cols);
228 line[col] = '\0';
229 line[col - 1] = '\n';
230 }
231 printf("%s", line); 304 printf("%s", line);
232 305
233 if (ptr->bytes) 306 if (ptr->bytes)
@@ -246,6 +319,18 @@ static void hnode_print(void) {
246 319
247 ptr = next; 320 ptr = next;
248 } 321 }
322
323#ifdef DEBUG
324 {
325 int cnt = 0;
326 HNode *ptr = hnode_unused;
327 while (ptr) {
328 cnt++;
329 ptr = ptr->hnext;
330 }
331 printf("hnode unused %d\n", cnt);
332 }
333#endif
249} 334}
250 335
251static void run_trace(void) { 336static void run_trace(void) {
@@ -262,18 +347,16 @@ static void run_trace(void) {
262 unsigned last_print_traces = 0; 347 unsigned last_print_traces = 0;
263 unsigned last_print_remaining = 0; 348 unsigned last_print_remaining = 0;
264 unsigned char buf[MAX_BUF_SIZE]; 349 unsigned char buf[MAX_BUF_SIZE];
265 unsigned bwcurrent = 0; 350 unsigned bw = 0; // bandwidth calculations
266 while (1) { 351 while (1) {
267 unsigned end = time(NULL); 352 unsigned end = time(NULL);
268 if (arg_netfilter && end - start >= NETLOCK_INTERVAL) 353 if (arg_netfilter && end - start >= NETLOCK_INTERVAL)
269 break; 354 break;
270 if (end % DISPLAY_INTERVAL == 1 && last_print_traces != end) { // first print after 1 second 355 if (end % DISPLAY_INTERVAL == 1 && last_print_traces != end) { // first print after 1 second
271 if (bwcurrent > bwmax)
272 bwmax = bwcurrent;
273 if (!arg_netfilter) 356 if (!arg_netfilter)
274 hnode_print(); 357 hnode_print(bw);
275 last_print_traces = end; 358 last_print_traces = end;
276 bwcurrent = 0; 359 bw = 0;
277 } 360 }
278 if (arg_netfilter && last_print_remaining != end) { 361 if (arg_netfilter && last_print_remaining != end) {
279 logprintf("."); 362 logprintf(".");
@@ -300,9 +383,8 @@ static void run_trace(void) {
300 383
301 unsigned bytes = recvfrom(sock, buf, MAX_BUF_SIZE, 0, NULL, NULL); 384 unsigned bytes = recvfrom(sock, buf, MAX_BUF_SIZE, 0, NULL, NULL);
302 if (bytes >= 20) { // size of IP header 385 if (bytes >= 20) { // size of IP header
303 bwcurrent += bytes + 14; // assume a 14 byte Ethernet layer 386#ifdef DEBUG
304 // filter out loopback traffic 387 {
305 if (buf[12] != 127) {
306 uint32_t ip_src; 388 uint32_t ip_src;
307 memcpy(&ip_src, buf + 12, 4); 389 memcpy(&ip_src, buf + 12, 4);
308 ip_src = ntohl(ip_src); 390 ip_src = ntohl(ip_src);
@@ -310,13 +392,23 @@ static void run_trace(void) {
310 uint32_t ip_dst; 392 uint32_t ip_dst;
311 memcpy(&ip_dst, buf + 16, 4); 393 memcpy(&ip_dst, buf + 16, 4);
312 ip_dst = ntohl(ip_dst); 394 ip_dst = ntohl(ip_dst);
395 printf("%d.%d.%d.%d -> %d.%d.%d.%d, %u bytes\n", PRINT_IP(ip_src), PRINT_IP(ip_dst), bytes);
396 }
397#endif
398 // filter out loopback traffic
399 if (buf[12] != 127 && buf[16] != 127) {
400 bw += bytes + 14; // assume a 14 byte Ethernet layer
401
402 uint32_t ip_src;
403 memcpy(&ip_src, buf + 12, 4);
404 ip_src = ntohl(ip_src);
313 405
314 uint8_t hlen = (buf[0] & 0x0f) * 4; 406 uint8_t hlen = (buf[0] & 0x0f) * 4;
315 uint16_t port_src; 407 uint16_t port_src;
316 memcpy(&port_src, buf + hlen, 2); 408 memcpy(&port_src, buf + hlen, 2);
317 port_src = ntohs(port_src); 409 port_src = ntohs(port_src);
318 410
319 hnode_add(ip_src, ip_dst, buf[9], port_src, bytes + 14); 411 hnode_add(ip_src, buf[9], port_src, bytes + 14);
320 } 412 }
321 } 413 }
322 } 414 }
@@ -484,10 +576,9 @@ void logprintf(char* fmt, ...) {
484static void usage(void) { 576static void usage(void) {
485 printf("Usage: fnetlock [OPTIONS]\n"); 577 printf("Usage: fnetlock [OPTIONS]\n");
486 printf("Options:\n"); 578 printf("Options:\n");
487 printf(" --build=filename - compact list of addresses\n");
488 printf(" --help, -? - this help screen\n"); 579 printf(" --help, -? - this help screen\n");
580 printf(" --log=filename - netlocker logfile\n");
489 printf(" --netfilter - build the firewall rules and commit them.\n"); 581 printf(" --netfilter - build the firewall rules and commit them.\n");
490 printf(" --log=filename - logfile\n");
491 printf("\n"); 582 printf("\n");
492} 583}
493 584
@@ -499,21 +590,15 @@ int main(int argc, char **argv) {
499 radix_add(0x09000000, 0xff000000, "IBM"); 590 radix_add(0x09000000, 0xff000000, "IBM");
500 radix_add(0x09090909, 0xffffffff, "Quad9 DNS"); 591 radix_add(0x09090909, 0xffffffff, "Quad9 DNS");
501 radix_add(0x09000000, 0xff000000, "IBM"); 592 radix_add(0x09000000, 0xff000000, "IBM");
502 radix_print();
503 printf("This test should print \"IBM, Quad9 DNS, IBM\"\n"); 593 printf("This test should print \"IBM, Quad9 DNS, IBM\"\n");
504 char *name = radix_find_first(0x09090909); 594 char *name = radix_longest_prefix_match(0x09040404);
505 printf("%s, ", name); 595 printf("%s, ", name);
506 name = radix_find_last(0x09090909); 596 name = radix_longest_prefix_match(0x09090909);
507 printf("%s, ", name); 597 printf("%s, ", name);
508 name = radix_find_last(0x09322209); 598 name = radix_longest_prefix_match(0x09322209);
509 printf("%s\n", name); 599 printf("%s\n", name);
510#endif 600#endif
511 601
512 if (argc == 2 && strncmp(argv[1], "--build=", 8) == 0) {
513 build_list(argv[1] + 8);
514 return 0;
515 }
516
517 if (getuid() != 0) { 602 if (getuid() != 0) {
518 fprintf(stderr, "Error: you need to be root to run this program\n"); 603 fprintf(stderr, "Error: you need to be root to run this program\n");
519 return 1; 604 return 1;
@@ -538,11 +623,8 @@ int main(int argc, char **argv) {
538 if (arg_netfilter) 623 if (arg_netfilter)
539 logprintf("starting network lockdown\n"); 624 logprintf("starting network lockdown\n");
540 else { 625 else {
541 char *fname; 626 char *fname = LIBDIR "/firejail/static-ip-map";
542 if (asprintf(&fname, "%s/hostnames", SYSCONFDIR) == -1)
543 errExit("asprintf");
544 load_hostnames(fname); 627 load_hostnames(fname);
545 free(fname);
546 } 628 }
547 629
548 run_trace(); 630 run_trace();
diff --git a/src/fnettrace/radix.c b/src/fnettrace/radix.c
index a1f44dd31..c9493717d 100644
--- a/src/fnettrace/radix.c
+++ b/src/fnettrace/radix.c
@@ -25,57 +25,79 @@
25#include "radix.h" 25#include "radix.h"
26#include "fnettrace.h" 26#include "fnettrace.h"
27 27
28typedef struct rnode_t {
29 struct rnode_t *zero;
30 struct rnode_t *one;
31 char *name;
32} RNode;
33
28RNode *head = 0; 34RNode *head = 0;
35int radix_nodes = 0;
36
37// get rid of the malloc overhead
38#define RNODE_MAX_MALLOC 128
39static RNode *rnode_unused = NULL;
40static int rnode_malloc_cnt = 0;
41static RNode *rmalloc(void) {
42 if (rnode_unused == NULL || rnode_malloc_cnt >= RNODE_MAX_MALLOC) {
43 rnode_unused = malloc(sizeof(RNode) * RNODE_MAX_MALLOC);
44 if (!rnode_unused)
45 errExit("malloc");
46 memset(rnode_unused, 0, sizeof(RNode) * RNODE_MAX_MALLOC);
47 rnode_malloc_cnt = 0;
48 }
49
50 rnode_malloc_cnt++;
51 return rnode_unused + rnode_malloc_cnt - 1;
52}
53
54
55static inline char *duplicate_name(const char *name) {
56 assert(name);
29 57
30static inline RNode *addOne(RNode *ptr, uint32_t ip, uint32_t mask, char *name) { 58 if (strcmp(name, "United States") == 0)
59 return "United States";
60 else if (strcmp(name, "Amazon") == 0)
61 return "Amazon";
62 return strdup(name);
63}
64
65static inline RNode *addOne(RNode *ptr, char *name) {
31 assert(ptr); 66 assert(ptr);
32 if (ptr->one) 67 if (ptr->one)
33 return ptr->one; 68 return ptr->one;
34 RNode *node = malloc(sizeof(RNode)); 69 RNode *node = rmalloc();
35 if (!node) 70 assert(node);
36 errExit("malloc");
37 memset(node, 0, sizeof(RNode));
38 node->ip = ip;
39 node->mask = mask;
40 if (name) { 71 if (name) {
41 node->name = strdup(name); 72 node->name = duplicate_name(name);
42 if (!node->name) 73 if (!node->name)
43 errExit("strdup"); 74 errExit("duplicate name");
44 } 75 }
45 76
46 ptr->one = node; 77 ptr->one = node;
47 return node; 78 return node;
48} 79}
49 80
50static inline RNode *addZero(RNode *ptr, uint32_t ip, uint32_t mask, char *name) { 81static inline RNode *addZero(RNode *ptr, char *name) {
51 assert(ptr); 82 assert(ptr);
52 if (ptr->zero) 83 if (ptr->zero)
53 return ptr->zero; 84 return ptr->zero;
54 RNode *node = malloc(sizeof(RNode)); 85 RNode *node = rmalloc();
55 if (!node) 86 assert(node);
56 errExit("malloc");
57 memset(node, 0, sizeof(RNode));
58 node->ip = ip;
59 node->mask = mask;
60 if (name) { 87 if (name) {
61 node->name = strdup(name); 88 node->name = duplicate_name(name);
62 if (!node->name) 89 if (!node->name)
63 errExit("strdup"); 90 errExit("duplicate name");
64 } 91 }
65 92
66 ptr->zero = node; 93 ptr->zero = node;
67 return node; 94 return node;
68} 95}
69 96
70 97
71// add to radix tree 98// add to radix tree
72void radix_add(uint32_t ip, uint32_t mask, char *name) { 99char *radix_add(uint32_t ip, uint32_t mask, char *name) {
73 assert(name); 100 assert(name);
74 char *tmp = strdup(name);
75 if (!tmp)
76 errExit("strdup");
77 name = tmp;
78
79 uint32_t m = 0x80000000; 101 uint32_t m = 0x80000000;
80 uint32_t lastm = 0; 102 uint32_t lastm = 0;
81 if (head == 0) { 103 if (head == 0) {
@@ -83,6 +105,7 @@ void radix_add(uint32_t ip, uint32_t mask, char *name) {
83 memset(head, 0, sizeof(RNode)); 105 memset(head, 0, sizeof(RNode));
84 } 106 }
85 RNode *ptr = head; 107 RNode *ptr = head;
108 radix_nodes++;
86 109
87 int i; 110 int i;
88 for (i = 0; i < 32; i++, m >>= 1) { 111 for (i = 0; i < 32; i++, m >>= 1) {
@@ -92,42 +115,22 @@ void radix_add(uint32_t ip, uint32_t mask, char *name) {
92 lastm |= m; 115 lastm |= m;
93 int valid = (lastm == mask)? 1: 0; 116 int valid = (lastm == mask)? 1: 0;
94 if (m & ip) 117 if (m & ip)
95 ptr = addOne(ptr, ip & lastm, mask & lastm, (valid)? name: NULL); 118 ptr = addOne(ptr, (valid)? name: NULL);
96 else 119 else
97 ptr = addZero(ptr, ip & lastm, mask & lastm, (valid)? name: NULL); 120 ptr = addZero(ptr, (valid)? name: NULL);
98 } 121 }
99 assert(ptr); 122 assert(ptr);
100 if (!ptr->name) { 123 if (!ptr->name) {
101 ptr->name = strdup(name); 124 ptr->name = duplicate_name(name);
102 if (!ptr->name) 125 if (!ptr->name)
103 errExit("strdup"); 126 errExit("duplicate_name");
104 } 127 }
105}
106 128
107// find first match 129 return ptr->name;
108char *radix_find_first(uint32_t ip) {
109 if (!head)
110 return NULL;
111
112 uint32_t m = 0x80000000;
113 RNode *ptr = head;
114
115 int i;
116 for (i = 0; i < 32; i++, m >>= 1) {
117 if (m & ip)
118 ptr = ptr->one;
119 else
120 ptr = ptr->zero;
121 if (!ptr)
122 return NULL;
123 if (ptr->name)
124 return ptr->name;
125 }
126 return NULL;
127} 130}
128 131
129// find last match 132// find last match
130char *radix_find_last(uint32_t ip) { 133char *radix_longest_prefix_match(uint32_t ip) {
131 if (!head) 134 if (!head)
132 return NULL; 135 return NULL;
133 136
@@ -146,73 +149,7 @@ char *radix_find_last(uint32_t ip) {
146 if (ptr->name) 149 if (ptr->name)
147 rv = ptr; 150 rv = ptr;
148 } 151 }
149
150 return (rv)? rv->name: NULL;
151}
152
153static void radix_print_node(RNode *ptr, int level) {
154 assert(ptr);
155
156 int i;
157 for (i = 0; i < level; i++)
158 printf(" ");
159 printf("%08x %08x", ptr->ip, ptr->mask);
160 if (ptr->name)
161 printf(" (%s)\n", ptr->name);
162 else
163 printf(" (NULL)\n");
164
165 if (ptr->zero)
166 radix_print_node(ptr->zero, level + 1);
167 if (ptr->one)
168 radix_print_node(ptr->one, level + 1);
169}
170
171void radix_print(void) {
172 if (!head) {
173 printf("radix tree is empty\n");
174 return;
175 }
176
177 printf("radix IPv4 tree\n");
178 radix_print_node(head, 0);
179}
180
181 152
182static inline int mask2cidr(uint32_t mask) { 153 return (rv)? rv->name: NULL;
183 uint32_t m = 0x80000000;
184 int i;
185 int cnt = 0;
186 for (i = 0; i < 32; i++, m = m >> 1) {
187 if (mask & m)
188 cnt++;
189 }
190
191 return cnt;
192}
193
194static void radix_build_list_node(RNode *ptr) {
195 assert(ptr);
196
197
198 if (ptr->name) {
199 printf("%d.%d.%d.%d/%d %s\n", PRINT_IP(ptr->ip), mask2cidr(ptr->mask), ptr->name);
200 return;
201 }
202 else {
203 if (ptr->zero)
204 radix_build_list_node(ptr->zero);
205 if (ptr->one)
206 radix_build_list_node(ptr->one);
207 }
208}
209
210void radix_build_list(void) {
211 if (!head) {
212 printf("radix tree is empty\n");
213 return;
214 }
215
216 radix_build_list_node(head);
217} 154}
218 155
diff --git a/src/fnettrace/radix.h b/src/fnettrace/radix.h
index b77c24216..c22c5c547 100644
--- a/src/fnettrace/radix.h
+++ b/src/fnettrace/radix.h
@@ -20,18 +20,8 @@
20#ifndef RADIX_H 20#ifndef RADIX_H
21#define RADIX_H 21#define RADIX_H
22 22
23typedef struct rnode_t { 23extern int radix_nodes;
24 struct rnode_t *zero; 24char *radix_longest_prefix_match(uint32_t ip);
25 struct rnode_t *one; 25char *radix_add(uint32_t ip, uint32_t mask, char *name);
26 uint32_t ip;
27 uint32_t mask;
28 char *name;
29} RNode;
30
31char *radix_find_first(uint32_t ip);
32char *radix_find_last(uint32_t ip);
33void radix_add(uint32_t ip, uint32_t mask, char *name);
34void radix_print(void);
35void radix_build_list(void);
36 26
37#endif \ No newline at end of file 27#endif \ No newline at end of file
diff --git a/src/fnettrace/hostnames b/src/fnettrace/static-ip-map
index b10d9a13d..e24ecf218 100644
--- a/src/fnettrace/hostnames
+++ b/src/fnettrace/static-ip-map
@@ -20,7 +20,7 @@
20# 20#
21# Static Internet Map 21# Static Internet Map
22# 22#
23# Unfortunately, we cannot do a hostname lookup. This will leak a lot of 23# Unfortunately we cannot do a hostname lookup. This will leak a lot of
24# information about what network resources we access. 24# information about what network resources we access.
25# A static map, helped out by geoip package available on all Linux distros, 25# A static map, helped out by geoip package available on all Linux distros,
26# will have to do it for now! 26# will have to do it for now!
@@ -160,6 +160,21 @@
160108.46.0.0/16 MCI 160108.46.0.0/16 MCI
161192.229.128.0/17 MCI 161192.229.128.0/17 MCI
162 162
163# Microsoft
16440.76.0.0/14 Microsoft
16540.96.0.0/12 Microsoft
16640.112.0.0/13 Microsoft
16740.124.0.0/16 Microsoft
16840.74.0.0/15 Microsoft
16940.80.0.0/12 Microsoft
17040.120.0.0/14 Microsoft
17140.125.0.0/17 Microsoft
17252.145.0.0/16 Microsoft
17352.148.0.0/14 Microsoft
17452.152.0.0/13 Microsoft
17552.146.0.0/15 Microsoft
17652.160.0.0/11 Microsoft
177
163# Yahoo 178# Yahoo
16463.250.192.0/19 Yahoo 17963.250.192.0/19 Yahoo
16566.196.64.0/18 Yahoo 18066.196.64.0/18 Yahoo
diff --git a/src/include/common.h b/src/include/common.h
index 24feab02a..f72ec9738 100644
--- a/src/include/common.h
+++ b/src/include/common.h
@@ -142,4 +142,5 @@ int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid);
142int pid_hidepid(void); 142int pid_hidepid(void);
143void warn_dumpable(void); 143void warn_dumpable(void);
144const char *gnu_basename(const char *path); 144const char *gnu_basename(const char *path);
145int *str_to_int_array(const char *str, size_t *sz);
145#endif 146#endif
diff --git a/src/lib/common.c b/src/lib/common.c
index f46e7db1c..91d5125b1 100644
--- a/src/lib/common.c
+++ b/src/lib/common.c
@@ -31,6 +31,7 @@
31#include <dirent.h> 31#include <dirent.h>
32#include <string.h> 32#include <string.h>
33#include <time.h> 33#include <time.h>
34#include <limits.h>
34#include "../include/common.h" 35#include "../include/common.h"
35#define BUFLEN 4096 36#define BUFLEN 4096
36 37
@@ -320,6 +321,55 @@ const char *gnu_basename(const char *path) {
320 return last_slash+1; 321 return last_slash+1;
321} 322}
322 323
324// takes string with comma separated int values, returns int array
325int *str_to_int_array(const char *str, size_t *sz) {
326 assert(str && sz);
327
328 size_t curr_sz = 0;
329 size_t arr_sz = 16;
330 int *rv = malloc(arr_sz * sizeof(int));
331 if (!rv)
332 errExit("malloc");
333
334 char *dup = strdup(str);
335 if (!dup)
336 errExit("strdup");
337 char *tok = strtok(dup, ",");
338 if (!tok) {
339 free(dup);
340 free(rv);
341 goto errout;
342 }
343
344 while (tok) {
345 char *end;
346 long val = strtol(tok, &end, 10);
347 if (end == tok || *end != '\0' || val < INT_MIN || val > INT_MAX) {
348 free(dup);
349 free(rv);
350 goto errout;
351 }
352
353 if (curr_sz == arr_sz) {
354 arr_sz *= 2;
355 rv = realloc(rv, arr_sz * sizeof(int));
356 if (!rv)
357 errExit("realloc");
358 }
359 rv[curr_sz++] = val;
360
361 tok = strtok(NULL, ",");
362 }
363 free(dup);
364
365 *sz = curr_sz;
366 return rv;
367
368errout:
369 *sz = 0;
370 return NULL;
371}
372
323//************************** 373//**************************
324// time trace based on getticks function 374// time trace based on getticks function
325//************************** 375//**************************
diff --git a/src/lib/syscall.c b/src/lib/syscall.c
index 668f7fcc7..a17f6423a 100644
--- a/src/lib/syscall.c
+++ b/src/lib/syscall.c
@@ -1678,14 +1678,14 @@ void syscalls_in_list(const char *list, const char *slist, int fd, char **prelis
1678 sl.postlist = NULL; 1678 sl.postlist = NULL;
1679 syscall_check_list(list, syscall_in_list, 0, 0, &sl, native); 1679 syscall_check_list(list, syscall_in_list, 0, 0, &sl, native);
1680 if (!arg_quiet) { 1680 if (!arg_quiet) {
1681 printf("Seccomp list in: %s,", list); 1681 fprintf(stderr, "Seccomp list in: %s,", list);
1682 if (sl.slist) 1682 if (sl.slist)
1683 printf(" check list: %s,", sl.slist); 1683 fprintf(stderr, " check list: %s,", sl.slist);
1684 if (sl.prelist) 1684 if (sl.prelist)
1685 printf(" prelist: %s,", sl.prelist); 1685 fprintf(stderr, " prelist: %s,", sl.prelist);
1686 if (sl.postlist) 1686 if (sl.postlist)
1687 printf(" postlist: %s", sl.postlist); 1687 fprintf(stderr, " postlist: %s", sl.postlist);
1688 printf("\n"); 1688 fprintf(stderr, "\n");
1689 } 1689 }
1690 *prelist = sl.prelist; 1690 *prelist = sl.prelist;
1691 *postlist = sl.postlist; 1691 *postlist = sl.postlist;
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt
index 71dab18ba..e962e18da 100644
--- a/src/man/firejail-profile.txt
+++ b/src/man/firejail-profile.txt
@@ -349,6 +349,7 @@ Build a new /bin in a temporary filesystem, and copy the programs in the list.
349The files in the list must be expressed as relative to the /bin, 349The files in the list must be expressed as relative to the /bin,
350/sbin, /usr/bin, /usr/sbin, or /usr/local/bin directories. 350/sbin, /usr/bin, /usr/sbin, or /usr/local/bin directories.
351The same directory is also bind-mounted over /sbin, /usr/bin and /usr/sbin. 351The same directory is also bind-mounted over /sbin, /usr/bin and /usr/sbin.
352Multiple private-bin commands are allowed and they accumulate.
352.TP 353.TP
353\fBprivate-cache 354\fBprivate-cache
354Mount an empty temporary filesystem on top of the .cache directory in user home. All 355Mount an empty temporary filesystem on top of the .cache directory in user home. All
@@ -374,6 +375,7 @@ the /etc directory, and must not contain the / character
374(e.g., /etc/foo must be expressed as foo, but /etc/foo/bar -- 375(e.g., /etc/foo must be expressed as foo, but /etc/foo/bar --
375expressed as foo/bar -- is disallowed). 376expressed as foo/bar -- is disallowed).
376All modifications are discarded when the sandbox is closed. 377All modifications are discarded when the sandbox is closed.
378Multiple private-etc commands are allowed and they accumulate.
377#ifdef HAVE_PRIVATE_HOME 379#ifdef HAVE_PRIVATE_HOME
378.TP 380.TP
379\fBprivate-home file,directory 381\fBprivate-home file,directory
@@ -502,7 +504,8 @@ There is no root account (uid 0) defined in the namespace.
502\fBprotocol protocol1,protocol2,protocol3 504\fBprotocol protocol1,protocol2,protocol3
503Enable protocol filter. The filter is based on seccomp and checks the 505Enable protocol filter. The filter is based on seccomp and checks the
504first argument to socket system call. Recognized values: \fBunix\fR, 506first argument to socket system call. Recognized values: \fBunix\fR,
505\fBinet\fR, \fBinet6\fR, \fBnetlink\fR, \fBpacket\fR and \fBbluetooth\fR. 507\fBinet\fR, \fBinet6\fR, \fBnetlink\fR, \fBpacket\fR, and \fBbluetooth\fR.
508Multiple protocol commands are allowed.
506.TP 509.TP
507\fBseccomp 510\fBseccomp
508Enable seccomp filter and blacklist the syscalls in the default list. See man 1 firejail for more details. 511Enable seccomp filter and blacklist the syscalls in the default list. See man 1 firejail for more details.
@@ -724,6 +727,11 @@ env CFLAGS="-W -Wall -Werror"
724.TP 727.TP
725\fBipc-namespace 728\fBipc-namespace
726Enable IPC namespace. 729Enable IPC namespace.
730
731.TP
732\fBkeep-fd
733Inherit open file descriptors to sandbox.
734
727.TP 735.TP
728\fBname sandboxname 736\fBname sandboxname
729Set sandbox name. Example: 737Set sandbox name. Example:
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 80487a49d..59dc5d310 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -185,10 +185,7 @@ $ firejail "\-\-blacklist=/home/username/My Virtual Machines"
185$ firejail \-\-blacklist=/home/username/My\\ Virtual\\ Machines 185$ firejail \-\-blacklist=/home/username/My\\ Virtual\\ Machines
186.TP 186.TP
187\fB\-\-build 187\fB\-\-build
188The command builds a whitelisted profile. The profile is printed on the screen. If /usr/bin/strace is installed on the system, it also 188The command builds a whitelisted profile. The profile is printed on the screen. The program is run in a very relaxed sandbox, with only --caps.drop=all and --nonewprivs. Programs that raise user privileges are not supported. Chromium and Chromium-based browsers will not work.
189builds a whitelisted seccomp profile. The program is run in a very relaxed sandbox,
190with only --caps.drop=all and --nonewprivs. Programs that raise user privileges are not supported
191in order to allow strace to run. Chromium and Chromium-based browsers will not work.
192.br 189.br
193 190
194.br 191.br
@@ -197,10 +194,8 @@ Example:
197$ firejail --build vlc ~/Videos/test.mp4 194$ firejail --build vlc ~/Videos/test.mp4
198.TP 195.TP
199\fB\-\-build=profile-file 196\fB\-\-build=profile-file
200The command builds a whitelisted profile, and saves it in profile-file. If /usr/bin/strace is installed on the system, it also 197The command builds a whitelisted profile, and saves it in profile-file. The program is run in a very relaxed sandbox,
201builds a whitelisted seccomp profile. The program is run in a very relaxed sandbox, 198with only --caps.drop=all and --nonewprivs. Programs that raise user privileges are not supported. Chromium and Chromium-based browsers will not work.
202with only --caps.drop=all and --nonewprivs. Programs that raise user privileges are not supported
203in order to allow strace to run. Chromium and Chromium-based browsers will not work.
204.br 199.br
205 200
206.br 201.br
@@ -1104,6 +1099,26 @@ Example:
1104$ firejail --keep-dev-shm --private-dev 1099$ firejail --keep-dev-shm --private-dev
1105 1100
1106.TP 1101.TP
1102\fB\-\-keep-fd=all
1103Inherit all open file descriptors to the sandbox. By default only file descriptors 0, 1 and 2 are inherited to the sandbox, and all other file descriptors are closed.
1104.br
1105
1106.br
1107Example:
1108.br
1109$ firejail --keep-fd=all
1110
1111.TP
1112\fB\-\-keep-fd=file_descriptor
1113Don't close specified open file descriptors. By default only file descriptors 0, 1 and 2 are inherited to the sandbox, and all other file descriptors are closed.
1114.br
1115
1116.br
1117Example:
1118.br
1119$ firejail --keep-fd=3,4,5
1120
1121.TP
1107\fB\-\-keep-var-tmp 1122\fB\-\-keep-var-tmp
1108/var/tmp directory is untouched. 1123/var/tmp directory is untouched.
1109.br 1124.br
@@ -1443,6 +1458,28 @@ $ firejail --name=browser --net=eth0 --netfilter firefox &
1443$ firejail --netfilter6.print=browser 1458$ firejail --netfilter6.print=browser
1444 1459
1445.TP 1460.TP
1461\fB\-\-netlock=name/pid
1462Several type of programs (email clients, multiplayer games etc.) talk to a very small
1463number of IP addresses. But the best example is tor browser. It only talks to a guard node,
1464and there are two or three more on standby in case the main one fails.
1465During startup, the browser contacts all of them, after that it keeps talking to the main
1466one... for weeks!
1467
1468Use the network locking feature to build and deploy a network firewall in your sandbox.
1469The firewall allows only the network traffic to the IP addresses detected during the program
1470startup. Traffic to any other address is quietly dropped. By default the startup monitoring
1471time is one minute. Example:
1472.br
1473
1474.br
1475$ firejail --net=eth0 --netlock \\
1476.br
1477--private=~/tor-browser_en-US ./start-tor-browser.desktop
1478.br
1479
1480.br
1481
1482.TP
1446\fB\-\-netmask=address 1483\fB\-\-netmask=address
1447Use this option when you want to assign an IP address in a new namespace and 1484Use this option when you want to assign an IP address in a new namespace and
1448the parent interface specified by --net is not configured. An IP address and 1485the parent interface specified by --net is not configured. An IP address and
@@ -1480,25 +1517,35 @@ PID User RX(KB/s) TX(KB/s) Command
1480.br 1517.br
14817383 netblue 9.045 0.112 firejail \-\-net=eth0 transmission 15187383 netblue 9.045 0.112 firejail \-\-net=eth0 transmission
1482.TP 1519.TP
1483\fB\-\-nettrace=name|pid 1520\fB\-\-nettrace[=name|pid]
1484Monitor TCP and UDP traffic coming into the sandbox specified by name or pid. Only networked sandboxes 1521Monitor TCP and UDP traffic coming into the sandbox specified by name or pid. Only networked sandboxes
1485created with \-\-net are supported. 1522created with \-\-net are supported.
1486.br 1523.br
1487 1524
1488.br 1525.br
1489$ firejail --nettrace=browser 1526Without a name/pid, Firejail will monitor the main system network namespace.
1527.br
1528
1529.br
1530 $ firejail --nettrace=browser
1531.br
1532
1533.br
1534 95 KB/s geoip 457, IP database 4436
1535.br
1536 52 KB/s *********** 64.222.84.207:443 United States
1490.br 1537.br
1491 86 KB/s ********* 64.222.84.207:443 United States 1538 33 KB/s ******* 89.147.74.105:63930 Hungary
1492.br 1539.br
1493 76 KB/s ******** 192.229.210.163:443 MCI 1540 0 B/s 45.90.28.0:443 NextDNS
1494.br 1541.br
1495 111 B/s 9.9.9.9:53 Quad9 DNS 1542 0 B/s 94.70.122.176:52309(UDP) Greece
1496.br 1543.br
1497 32 KB/s *** 142.250.179.182:443 Google 1544 339 B/s 104.26.7.35:443 Cloudflare
1498.br 1545.br
1499 1546
1500.br 1547.br
1501If /usr/bin/geoiplookup is installed (geoip-bin packet in Debian), 1548If /usr/bin/geoiplookup is installed (geoip-bin package in Debian),
1502the country the IP address originates from is added to the trace. 1549the country the IP address originates from is added to the trace.
1503We also use the static IP map in /etc/firejail/hostnames 1550We also use the static IP map in /etc/firejail/hostnames
1504to print the domain names for some of the more common websites and cloud platforms. 1551to print the domain names for some of the more common websites and cloud platforms.
@@ -1860,8 +1907,9 @@ The files in the list must be expressed as relative to the /bin,
1860/sbin, /usr/bin, /usr/sbin, or /usr/local/bin directories. 1907/sbin, /usr/bin, /usr/sbin, or /usr/local/bin directories.
1861If no listed files are found, /bin directory will be empty. 1908If no listed files are found, /bin directory will be empty.
1862The same directory is also bind-mounted over /sbin, /usr/bin, /usr/sbin and /usr/local/bin. 1909The same directory is also bind-mounted over /sbin, /usr/bin, /usr/sbin and /usr/local/bin.
1863All modifications are discarded when the sandbox is closed. File globbing is supported, 1910All modifications are discarded when the sandbox is closed.
1864see \fBFILE GLOBBING\fR section for more details. 1911Multiple private-bin commands are allowed and they accumulate.
1912File globbing is supported, see \fBFILE GLOBBING\fR section for more details.
1865.br 1913.br
1866 1914
1867.br 1915.br
@@ -1957,6 +2005,7 @@ The files and directories in the list must be expressed as relative to
1957the /etc directory (e.g., /etc/foo must be expressed as foo). 2005the /etc directory (e.g., /etc/foo must be expressed as foo).
1958If no listed file is found, /etc directory will be empty. 2006If no listed file is found, /etc directory will be empty.
1959All modifications are discarded when the sandbox is closed. 2007All modifications are discarded when the sandbox is closed.
2008Multiple private-etc commands are allowed and they accumulate.
1960.br 2009.br
1961 2010
1962.br 2011.br
@@ -2115,7 +2164,7 @@ $ firejail \-\-profile.print=browser
2115.TP 2164.TP
2116\fB\-\-protocol=protocol,protocol,protocol 2165\fB\-\-protocol=protocol,protocol,protocol
2117Enable protocol filter. The filter is based on seccomp and checks the first argument to socket system call. 2166Enable protocol filter. The filter is based on seccomp and checks the first argument to socket system call.
2118Recognized values: unix, inet, inet6, netlink, packet and bluetooth. This option is not supported for i386 architecture. 2167Recognized values: unix, inet, inet6, netlink, packet, and bluetooth. This option is not supported for i386 architecture.
2119.br 2168.br
2120 2169
2121.br 2170.br
diff --git a/src/zsh_completion/_firejail.in b/src/zsh_completion/_firejail.in
index 334812dd6..f7cd3cdff 100644
--- a/src/zsh_completion/_firejail.in
+++ b/src/zsh_completion/_firejail.in
@@ -104,6 +104,7 @@ _firejail_args=(
104 '--join-or-start=-[join the sandbox or start a new one name|pid]: :_all_firejails' 104 '--join-or-start=-[join the sandbox or start a new one name|pid]: :_all_firejails'
105 '--keep-config-pulse[disable automatic ~/.config/pulse init]' 105 '--keep-config-pulse[disable automatic ~/.config/pulse init]'
106 '--keep-dev-shm[/dev/shm directory is untouched (even with --private-dev)]' 106 '--keep-dev-shm[/dev/shm directory is untouched (even with --private-dev)]'
107 '--keep-fd[inherit open file descriptors to sandbox]'
107 '--keep-var-tmp[/var/tmp directory is untouched]' 108 '--keep-var-tmp[/var/tmp directory is untouched]'
108 '--machine-id[spoof /etc/machine-id with a random id]' 109 '--machine-id[spoof /etc/machine-id with a random id]'
109 '--memory-deny-write-execute[seccomp filter to block attempts to create memory mappings that are both writable and executable]' 110 '--memory-deny-write-execute[seccomp filter to block attempts to create memory mappings that are both writable and executable]'
diff --git a/test/environment/deterministic-shutdown.exp b/test/environment/deterministic-shutdown.exp
index dbbe226bb..be4e9c42e 100755
--- a/test/environment/deterministic-shutdown.exp
+++ b/test/environment/deterministic-shutdown.exp
@@ -3,14 +3,15 @@
3# Copyright (C) 2014-2022 Firejail Authors 3# Copyright (C) 2014-2022 Firejail Authors
4# License GPL v2 4# License GPL v2
5 5
6set timeout 5 6set timeout 10
7spawn $env(SHELL) 7spawn $env(SHELL)
8match_max 100000 8match_max 100000
9 9
10send -- "firejail --deterministic-shutdown bash -c \"sleep 10 & exec sleep 1\"\r" 10send -- "firejail --deterministic-shutdown bash -c \"sleep 100 & exec sleep 1\"\r"
11expect { 11expect {
12 timeout {puts "TESTING ERROR 0\n";exit} 12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Parent is shutting down, bye..." 13 "Parent is shutting down, bye..."
14} 14}
15after 100
15 16
16puts "\nall done\n" 17puts "\nall done\n"
diff --git a/test/environment/environment.sh b/test/environment/environment.sh
index ce0bb306c..2b77973ac 100755
--- a/test/environment/environment.sh
+++ b/test/environment/environment.sh
@@ -127,5 +127,11 @@ echo "TESTING: deterministic exit code (test/environment/deterministic-exit-code
127echo "TESTING: deterministic shutdown (test/environment/deterministic-shutdown.exp)" 127echo "TESTING: deterministic shutdown (test/environment/deterministic-shutdown.exp)"
128./deterministic-shutdown.exp 128./deterministic-shutdown.exp
129 129
130echo "TESTING: keep fd (test/environment/keep-fd.exp)"
131./keep-fd.exp
132
133echo "TESTING: keep fd errors (test/environment/keep-fd-bad.exp)"
134./keep-fd-bad.exp
135
130echo "TESTING: retain umask (test/environment/umask.exp)" 136echo "TESTING: retain umask (test/environment/umask.exp)"
131(umask 123 && ./umask.exp) 137(umask 123 && ./umask.exp)
diff --git a/test/environment/keep-fd-bad.exp b/test/environment/keep-fd-bad.exp
new file mode 100755
index 000000000..e8b411ea0
--- /dev/null
+++ b/test/environment/keep-fd-bad.exp
@@ -0,0 +1,40 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2022 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10
11send -- "firejail --noprofile --keep-fd=\r"
12expect {
13 timeout {puts "TESTING ERROR 0\n";exit}
14 "Error: invalid keep-fd option"
15}
16after 100
17
18send -- "firejail --noprofile --keep-fd=,,,\r"
19expect {
20 timeout {puts "TESTING ERROR 1\n";exit}
21 "Error: invalid keep-fd option"
22}
23after 100
24
25send -- "firejail --noprofile --keep-fd=dall\r"
26expect {
27 timeout {puts "TESTING ERROR 2\n";exit}
28 "Error: invalid keep-fd option"
29}
30after 100
31
32send -- "firejail --noprofile --keep-fd=6,7,8,10b,11\r"
33expect {
34 timeout {puts "TESTING ERROR 3\n";exit}
35 "Error: invalid keep-fd option"
36}
37after 100
38
39
40puts "\nall done\n"
diff --git a/test/environment/keep-fd.exp b/test/environment/keep-fd.exp
new file mode 100755
index 000000000..222234ceb
--- /dev/null
+++ b/test/environment/keep-fd.exp
@@ -0,0 +1,223 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2022 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10
11#
12# obtain some open file descriptors
13#
14send -- "exec {WRITE_FD}> blabla\r"
15after 100
16
17send -- "readlink -v /proc/self/fd/\$WRITE_FD\r"
18expect {
19 timeout {puts "TESTING ERROR 0\n";exit}
20 "/blabla"
21}
22after 100
23
24send -- "exec {READ_FD}< blabla\r"
25after 100
26
27send -- "readlink -v /proc/self/fd/\$READ_FD\r"
28expect {
29 timeout {puts "TESTING ERROR 1\n";exit}
30 "/blabla"
31}
32after 100
33
34
35#
36# inherit environment variables
37#
38send -- "export READ_FD\r"
39send -- "export WRITE_FD\r"
40after 100
41
42
43#
44# close all file descriptors
45# 0, 1, 2 stay open
46#
47send -- "firejail --noprofile\r"
48expect {
49 timeout {puts "TESTING ERROR 2\n";exit}
50 "Child process initialized"
51}
52after 100
53
54# off by one because of ls
55send -- "ls /proc/self/fd | wc -w\r"
56expect {
57 timeout {puts "TESTING ERROR 3\n";exit}
58 "4"
59}
60after 100
61
62send -- "readlink -v /proc/self/fd/\$READ_FD\r"
63expect {
64 timeout {puts "TESTING ERROR 4\n";exit}
65 "No such file or directory"
66}
67after 100
68
69send -- "readlink -v /proc/self/fd/\$WRITE_FD\r"
70expect {
71 timeout {puts "TESTING ERROR 5\n";exit}
72 "No such file or directory"
73}
74after 100
75
76send -- "exit\r"
77after 500
78
79
80#
81# keep one file descriptor
82#
83send -- "firejail --noprofile --keep-fd=\$READ_FD\r"
84expect {
85 timeout {puts "TESTING ERROR 6\n";exit}
86 "Child process initialized"
87}
88after 100
89
90# off by one because of ls
91send -- "ls /proc/self/fd | wc -w\r"
92expect {
93 timeout {puts "TESTING ERROR 7\n";exit}
94 "5"
95}
96after 100
97
98send -- "readlink -v /proc/self/fd/\$READ_FD\r"
99expect {
100 timeout {puts "TESTING ERROR 8\n";exit}
101 "/blabla"
102}
103after 100
104
105send -- "readlink -v /proc/self/fd/\$WRITE_FD\r"
106expect {
107 timeout {puts "TESTING ERROR 9\n";exit}
108 "No such file or directory"
109}
110after 100
111
112send -- "exit\r"
113after 500
114
115
116#
117# keep other file descriptor
118#
119send -- "firejail --noprofile --keep-fd=\$WRITE_FD\r"
120expect {
121 timeout {puts "TESTING ERROR 10\n";exit}
122 "Child process initialized"
123}
124after 100
125
126# off by one because of ls
127send -- "ls /proc/self/fd | wc -w\r"
128expect {
129 timeout {puts "TESTING ERROR 11\n";exit}
130 "5"
131}
132after 100
133
134send -- "readlink -v /proc/self/fd/\$READ_FD\r"
135expect {
136 timeout {puts "TESTING ERROR 12\n";exit}
137 "No such file or directory"
138}
139after 100
140
141send -- "readlink -v /proc/self/fd/\$WRITE_FD\r"
142expect {
143 timeout {puts "TESTING ERROR 13\n";exit}
144 "/blabla"
145}
146after 100
147
148send -- "exit\r"
149after 500
150
151
152#
153# keep both file descriptors
154#
155send -- "firejail --noprofile --keep-fd=\$READ_FD,\$WRITE_FD\r"
156expect {
157 timeout {puts "TESTING ERROR 14\n";exit}
158 "Child process initialized"
159}
160after 100
161
162# off by one because of ls
163send -- "ls /proc/self/fd | wc -w\r"
164expect {
165 timeout {puts "TESTING ERROR 15\n";exit}
166 "6"
167}
168after 100
169
170send -- "readlink -v /proc/self/fd/\$READ_FD\r"
171expect {
172 timeout {puts "TESTING ERROR 16\n";exit}
173 "/blabla"
174}
175after 100
176
177send -- "readlink -v /proc/self/fd/\$WRITE_FD\r"
178expect {
179 timeout {puts "TESTING ERROR 17\n";exit}
180 "/blabla"
181}
182after 100
183
184send -- "exit\r"
185after 500
186
187
188#
189# keep all file descriptors
190#
191send -- "firejail --noprofile --keep-fd=all\r"
192expect {
193 timeout {puts "TESTING ERROR 18\n";exit}
194 "Child process initialized"
195}
196after 100
197
198send -- "readlink -v /proc/self/fd/\$READ_FD\r"
199expect {
200 timeout {puts "TESTING ERROR 19\n";exit}
201 "/blabla"
202}
203after 100
204
205send -- "readlink -v /proc/self/fd/\$WRITE_FD\r"
206expect {
207 timeout {puts "TESTING ERROR 20\n";exit}
208 "/blabla"
209}
210after 100
211
212send -- "exit\r"
213after 500
214
215
216#
217# cleanup
218#
219send -- "rm -f blabla\r"
220after 100
221
222
223puts "\nall done\n"
diff --git a/test/fcopy/dircopy.exp b/test/fcopy/dircopy.exp
index 0882561e5..a779f80cd 100755
--- a/test/fcopy/dircopy.exp
+++ b/test/fcopy/dircopy.exp
@@ -12,9 +12,21 @@ match_max 100000
12 12
13send -- "rm -fr dest/*\r" 13send -- "rm -fr dest/*\r"
14after 100 14after 100
15send -- "cd src\r"
16after 100
17send -- "ln -s ../dircopy.exp dircopy.exp\r"
18after 100
19send -- "cd ..\r"
20after 100
15 21
16send -- "fcopy src dest\r" 22send -- "fcopy src dest\r"
17after 100 23after 100
24send -- "cd src\r"
25after 100
26send -- "ln -s ../dircopy.exp dircopy.exp\r"
27after 100
28send -- "cd ..\r"
29after 100
18 30
19send -- "find dest\r" 31send -- "find dest\r"
20expect { 32expect {
@@ -135,5 +147,7 @@ expect {
135 147
136send -- "rm -fr dest/*\r" 148send -- "rm -fr dest/*\r"
137after 100 149after 100
150send -- "rm -f src/dircopy.exp\r"
151after 100
138 152
139puts "\nall done\n" 153puts "\nall done\n"
diff --git a/test/fcopy/fcopy.sh b/test/fcopy/fcopy.sh
index cdfc424a3..fca599889 100755
--- a/test/fcopy/fcopy.sh
+++ b/test/fcopy/fcopy.sh
@@ -19,13 +19,14 @@ mkdir dest
19echo "TESTING: fcopy cmdline (test/fcopy/cmdline.exp)" 19echo "TESTING: fcopy cmdline (test/fcopy/cmdline.exp)"
20./cmdline.exp 20./cmdline.exp
21 21
22echo "TESTING: fcopy directory (test/fcopy/dircopy.exp)"
23./dircopy.exp
24
25echo "TESTING: fcopy file (test/fcopy/filecopy.exp)" 22echo "TESTING: fcopy file (test/fcopy/filecopy.exp)"
26./filecopy.exp 23./filecopy.exp
27 24
28echo "TESTING: fcopy link (test/fcopy/linkcopy.exp)" 25echo "TESTING: fcopy link (test/fcopy/linkcopy.exp)"
29./linkcopy.exp 26./linkcopy.exp
30 27
28echo "TESTING: fcopy directory (test/fcopy/dircopy.exp)"
29./dircopy.exp
30
31rm -fr dest/* 31rm -fr dest/*
32rm -f src/dircopy.exp \ No newline at end of file
diff --git a/test/fcopy/linkcopy.exp b/test/fcopy/linkcopy.exp
index dd91ac26f..7c085e552 100755
--- a/test/fcopy/linkcopy.exp
+++ b/test/fcopy/linkcopy.exp
@@ -12,6 +12,12 @@ match_max 100000
12 12
13send -- "rm -fr dest/*\r" 13send -- "rm -fr dest/*\r"
14after 100 14after 100
15send -- "cd src\r"
16after 100
17send -- "ln -s ../dircopy.exp dircopy.exp\r"
18after 100
19send -- "cd ..\r"
20after 100
15 21
16send -- "fcopy src/dircopy.exp dest\r" 22send -- "fcopy src/dircopy.exp dest\r"
17after 100 23after 100
@@ -19,7 +25,7 @@ after 100
19send -- "find dest\r" 25send -- "find dest\r"
20expect { 26expect {
21 timeout {puts "TESTING ERROR 0\n";exit} 27 timeout {puts "TESTING ERROR 0\n";exit}
22 "dest/" 28 "dest"
23} 29}
24expect { 30expect {
25 timeout {puts "TESTING ERROR 1\n";exit} 31 timeout {puts "TESTING ERROR 1\n";exit}
@@ -27,11 +33,11 @@ expect {
27} 33}
28after 100 34after 100
29 35
30
31send -- "ls -al dest\r" 36send -- "ls -al dest\r"
32expect { 37expect {
33 timeout {puts "TESTING ERROR 2\n";exit} 38 timeout {puts "TESTING ERROR 2\n";exit}
34 "lrwxrwxrwx" 39 "rwxr-xr-x" { puts "umask 0022\n" }
40 "rwxrwxr-x" { puts "umask 0002\n" }
35} 41}
36after 100 42after 100
37send -- "stty -echo\r" 43send -- "stty -echo\r"
@@ -52,5 +58,7 @@ expect {
52 58
53send -- "rm -fr dest/*\r" 59send -- "rm -fr dest/*\r"
54after 100 60after 100
61send -- "rm -f src/dircopy.exp\r"
62after 100
55 63
56puts "\nall done\n" 64puts "\nall done\n"
diff --git a/test/fcopy/src/dircopy.exp b/test/fcopy/src/dircopy.exp
deleted file mode 100755
index 0882561e5..000000000
--- a/test/fcopy/src/dircopy.exp
+++ /dev/null
@@ -1,139 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2022 Firejail Authors
4# License GPL v2
5
6#
7# copy directory src to dest
8#
9set timeout 10
10spawn $env(SHELL)
11match_max 100000
12
13send -- "rm -fr dest/*\r"
14after 100
15
16send -- "fcopy src dest\r"
17after 100
18
19send -- "find dest\r"
20expect {
21 timeout {puts "TESTING ERROR 0\n";exit}
22 "dest/"
23}
24after 100
25
26send -- "find dest\r"
27expect {
28 timeout {puts "TESTING ERROR 0\n";exit}
29 "dest/"
30}
31after 100
32
33send -- "find dest\r"
34expect {
35 timeout {puts "TESTING ERROR 1\n";exit}
36 "dest/a"
37}
38after 100
39
40send -- "find dest\r"
41expect {
42 timeout {puts "TESTING ERROR 2\n";exit}
43 "dest/a/b"
44}
45after 100
46
47send -- "find dest\r"
48expect {
49 timeout {puts "TESTING ERROR 3\n";exit}
50 "dest/a/b/file4"
51}
52after 100
53
54send -- "find dest\r"
55expect {
56 timeout {puts "TESTING ERROR 4\n";exit}
57 "dest/a/file3"
58}
59after 100
60
61send -- "find dest\r"
62expect {
63 timeout {puts "TESTING ERROR 5\n";exit}
64 "dest/dircopy.exp"
65}
66after 100
67
68send -- "find dest\r"
69expect {
70 timeout {puts "TESTING ERROR 6\n";exit}
71 "dest/file2"
72}
73after 100
74
75send -- "find dest\r"
76expect {
77 timeout {puts "TESTING ERROR 7\n";exit}
78 "dest/file1"
79}
80after 100
81
82
83send -- "ls -al dest\r"
84expect {
85 timeout {puts "TESTING ERROR 8\n";exit}
86 "drwxr-xr-x" { puts "umask 0022\n" }
87 "drwxrwxr-x" { puts "umask 0002\n" }
88}
89expect {
90 timeout {puts "TESTING ERROR 9\n";exit}
91 "a"
92}
93expect {
94 timeout {puts "TESTING ERROR 10\n";exit}
95 "lrwxrwxrwx"
96}
97expect {
98 timeout {puts "TESTING ERROR 11\n";exit}
99 "dircopy.exp"
100}
101expect {
102 timeout {puts "TESTING ERROR 12\n";exit}
103 "rwxr-xr-x" { puts "umask 0022\n" }
104 "rwxrwxr-x" { puts "umask 0002\n" }
105}
106expect {
107 timeout {puts "TESTING ERROR 13\n";exit}
108 "file1"
109}
110expect {
111 timeout {puts "TESTING ERROR 14\n";exit}
112 "rw-r--r--" { puts "umask 0022\n" }
113 "rw-rw-r--" { puts "umask 0002\n" }
114}
115expect {
116 timeout {puts "TESTING ERROR 15\n";exit}
117 "file2"
118}
119after 100
120
121send -- "stty -echo\r"
122after 100
123send -- "diff -q src/a/b/file4 dest/a/b/file4; echo done\r"
124expect {
125 timeout {puts "TESTING ERROR 16\n";exit}
126 "differ" {puts "TESTING ERROR 17\n";exit}
127 "done"
128}
129
130send -- "file dest/dircopy.exp\r"
131expect {
132 timeout {puts "TESTING ERROR 18\n";exit}
133 "symbolic link"
134}
135
136send -- "rm -fr dest/*\r"
137after 100
138
139puts "\nall done\n"