diff options
50 files changed, 461 insertions, 197 deletions
diff --git a/Makefile.in b/Makefile.in index f3d1b3ad0..890ba1b0a 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -134,7 +134,7 @@ ifeq ($(HAVE_APPARMOR),-DHAVE_APPARMOR) | |||
134 | install -m 0644 etc/apparmor/firejail-default $(DESTDIR)$(sysconfdir)/apparmor.d | 134 | install -m 0644 etc/apparmor/firejail-default $(DESTDIR)$(sysconfdir)/apparmor.d |
135 | sh -c "if [ ! -d $(DESTDIR)/$(sysconfdir)/apparmor.d/local ]; then install -d -m 755 $(DESTDIR)/$(sysconfdir)/apparmor.d/local; fi;" | 135 | sh -c "if [ ! -d $(DESTDIR)/$(sysconfdir)/apparmor.d/local ]; then install -d -m 755 $(DESTDIR)/$(sysconfdir)/apparmor.d/local; fi;" |
136 | # install apparmor profile customization file | 136 | # install apparmor profile customization file |
137 | sh -c "if [ ! -f $(DESTDIR)/$(sysconfdir)/apparmor.d/local/firejail-local ]; then install -c -m 0644 etc/apparmor/firejail-local $(DESTDIR)/$(sysconfdir)/apparmor.d/local/.; fi;" | 137 | sh -c "if [ ! -f $(DESTDIR)/$(sysconfdir)/apparmor.d/local/firejail-default ]; then install -c -m 0644 etc/apparmor/firejail-local $(DESTDIR)/$(sysconfdir)/apparmor.d/local/firejail-default; fi;" |
138 | endif | 138 | endif |
139 | # man pages | 139 | # man pages |
140 | install -m 0755 -d $(DESTDIR)$(mandir)/man1 $(DESTDIR)$(mandir)/man5 | 140 | install -m 0755 -d $(DESTDIR)$(mandir)/man1 $(DESTDIR)$(mandir)/man5 |
@@ -63,6 +63,8 @@ Firejail Authors (alphabetical order) | |||
63 | - fix flameshot raw screenshots | 63 | - fix flameshot raw screenshots |
64 | 1dnrr (https://github.com/1dnrr) | 64 | 1dnrr (https://github.com/1dnrr) |
65 | - add pybitmessage profile | 65 | - add pybitmessage profile |
66 | Ádler Jonas Gross (https://github.com/adgross) | ||
67 | - AppArmor fix | ||
66 | Adrian L. Shaw (https://github.com/adrianlshaw) | 68 | Adrian L. Shaw (https://github.com/adrianlshaw) |
67 | - add profanity profile | 69 | - add profanity profile |
68 | - add barrirer profile | 70 | - add barrirer profile |
@@ -1,5 +1,6 @@ | |||
1 | firejail (0.9.63) baseline; urgency=low | 1 | firejail (0.9.63) baseline; urgency=low |
2 | * work in progress | 2 | * work in progress |
3 | * security: fixes for CVE-2020-17367 & CVE-2020-17368, reported by Tim Starling | ||
3 | * The blocking action of seccomp filters has been changed from | 4 | * The blocking action of seccomp filters has been changed from |
4 | killing the process to returning EPERM to the caller. To get the | 5 | killing the process to returning EPERM to the caller. To get the |
5 | previous behaviour, use --seccomp-error-action=kill or | 6 | previous behaviour, use --seccomp-error-action=kill or |
diff --git a/etc/apparmor/firejail-default b/etc/apparmor/firejail-default index 04a38f0ce..68e20d9b9 100644 --- a/etc/apparmor/firejail-default +++ b/etc/apparmor/firejail-default | |||
@@ -157,5 +157,5 @@ capability setfcap, | |||
157 | #capability mac_admin, | 157 | #capability mac_admin, |
158 | 158 | ||
159 | # Site-specific additions and overrides. See local/README for details. | 159 | # Site-specific additions and overrides. See local/README for details. |
160 | #include <local/firejail-local> | 160 | #include <local/firejail-default> |
161 | } | 161 | } |
diff --git a/etc/firejail.config b/etc/firejail.config index b2a96612f..731e744dd 100644 --- a/etc/firejail.config +++ b/etc/firejail.config | |||
@@ -107,7 +107,7 @@ | |||
107 | # Enable or disable seccomp support, default enabled. | 107 | # Enable or disable seccomp support, default enabled. |
108 | # seccomp yes | 108 | # seccomp yes |
109 | 109 | ||
110 | # Seccomp error action, kill or errno (EPERM, ENOSYS etc) | 110 | # Seccomp error action, kill, log or errno (EPERM, ENOSYS etc) |
111 | # seccomp-error-action EPERM | 111 | # seccomp-error-action EPERM |
112 | 112 | ||
113 | # Enable or disable user namespace support, default enabled. | 113 | # Enable or disable user namespace support, default enabled. |
diff --git a/etc/inc/disable-programs.inc b/etc/inc/disable-programs.inc index e911be93a..e5dd9cb59 100644 --- a/etc/inc/disable-programs.inc +++ b/etc/inc/disable-programs.inc | |||
@@ -396,6 +396,7 @@ blacklist ${HOME}/.config/yandex-browser | |||
396 | blacklist ${HOME}/.config/yandex-browser-beta | 396 | blacklist ${HOME}/.config/yandex-browser-beta |
397 | blacklist ${HOME}/.config/yelp | 397 | blacklist ${HOME}/.config/yelp |
398 | blacklist ${HOME}/.config/youtube-dl | 398 | blacklist ${HOME}/.config/youtube-dl |
399 | blacklist ${HOME}/.config/youtube-viewer | ||
399 | blacklist ${HOME}/.config/zathura | 400 | blacklist ${HOME}/.config/zathura |
400 | blacklist ${HOME}/.config/zoomus.conf | 401 | blacklist ${HOME}/.config/zoomus.conf |
401 | blacklist ${HOME}/.config/Zulip | 402 | blacklist ${HOME}/.config/Zulip |
diff --git a/etc/inc/whitelist-usr-share-common.inc b/etc/inc/whitelist-usr-share-common.inc index c9c8bdedf..ceeb14dcc 100644 --- a/etc/inc/whitelist-usr-share-common.inc +++ b/etc/inc/whitelist-usr-share-common.inc | |||
@@ -41,6 +41,8 @@ whitelist /usr/share/misc | |||
41 | whitelist /usr/share/Modules | 41 | whitelist /usr/share/Modules |
42 | whitelist /usr/share/myspell | 42 | whitelist /usr/share/myspell |
43 | whitelist /usr/share/p11-kit | 43 | whitelist /usr/share/p11-kit |
44 | whitelist /usr/share/perl | ||
45 | whitelist /usr/share/perl5 | ||
44 | whitelist /usr/share/pixmaps | 46 | whitelist /usr/share/pixmaps |
45 | whitelist /usr/share/pki | 47 | whitelist /usr/share/pki |
46 | whitelist /usr/share/plasma | 48 | whitelist /usr/share/plasma |
diff --git a/etc/profile-a-l/celluloid.profile b/etc/profile-a-l/celluloid.profile index 567bd912a..54d3f742f 100644 --- a/etc/profile-a-l/celluloid.profile +++ b/etc/profile-a-l/celluloid.profile | |||
@@ -9,8 +9,6 @@ include globals.local | |||
9 | noblacklist ${HOME}/.config/celluloid | 9 | noblacklist ${HOME}/.config/celluloid |
10 | noblacklist ${HOME}/.config/gnome-mpv | 10 | noblacklist ${HOME}/.config/gnome-mpv |
11 | noblacklist ${HOME}/.config/youtube-dl | 11 | noblacklist ${HOME}/.config/youtube-dl |
12 | noblacklist ${MUSIC} | ||
13 | noblacklist ${VIDEOS} | ||
14 | 12 | ||
15 | # Allow python (blacklisted by disable-interpreters.inc) | 13 | # Allow python (blacklisted by disable-interpreters.inc) |
16 | include allow-python2.inc | 14 | include allow-python2.inc |
@@ -22,8 +20,20 @@ include disable-exec.inc | |||
22 | include disable-interpreters.inc | 20 | include disable-interpreters.inc |
23 | include disable-passwdmgr.inc | 21 | include disable-passwdmgr.inc |
24 | include disable-programs.inc | 22 | include disable-programs.inc |
25 | include disable-xdg.inc | ||
26 | 23 | ||
24 | read-only ${DESKTOP} | ||
25 | mkdir ${HOME}/.config/celluloid | ||
26 | mkdir ${HOME}/.config/gnome-mpv | ||
27 | mkdir ${HOME}/.config/youtube-dl | ||
28 | whitelist ${HOME}/.config/celluloid | ||
29 | whitelist ${HOME}/.config/gnome-mpv | ||
30 | whitelist ${HOME}/.config/youtube-dl | ||
31 | whitelist ${DESKTOP} | ||
32 | whitelist ${DOWNLOADS} | ||
33 | whitelist ${MUSIC} | ||
34 | whitelist ${PICTURES} | ||
35 | whitelist ${VIDEOS} | ||
36 | include whitelist-common.inc | ||
27 | include whitelist-runuser-common.inc | 37 | include whitelist-runuser-common.inc |
28 | include whitelist-usr-share-common.inc | 38 | include whitelist-usr-share-common.inc |
29 | include whitelist-var-common.inc | 39 | include whitelist-var-common.inc |
diff --git a/etc/profile-a-l/gtk-youtube-viewer b/etc/profile-a-l/gtk-youtube-viewer new file mode 100644 index 000000000..023f10d3d --- /dev/null +++ b/etc/profile-a-l/gtk-youtube-viewer | |||
@@ -0,0 +1,18 @@ | |||
1 | # Firejail profile for gtk-youtube-viewer | ||
2 | # Description: Gtk front-end to youtube-viewer | ||
3 | # This file is overwritten after every install/update | ||
4 | # Persistent local customizations | ||
5 | include gtk-youtube-viewer.local | ||
6 | # Persistent global definitions | ||
7 | # include globals.local | ||
8 | |||
9 | ignore quiet | ||
10 | |||
11 | noblacklist /tmp/.X11-unix | ||
12 | noblacklist ${RUNUSER}/wayland-* | ||
13 | noblacklist ${RUNUSER} | ||
14 | |||
15 | include whitelist-runuser-common.inc | ||
16 | |||
17 | # Redirect | ||
18 | include youtube-viewer.profile \ No newline at end of file | ||
diff --git a/etc/profile-a-l/gtk2-youtube-viewer b/etc/profile-a-l/gtk2-youtube-viewer new file mode 100644 index 000000000..331e73218 --- /dev/null +++ b/etc/profile-a-l/gtk2-youtube-viewer | |||
@@ -0,0 +1,18 @@ | |||
1 | # Firejail profile for gtk2-youtube-viewer | ||
2 | # Description: Gtk front-end to youtube-viewer | ||
3 | # This file is overwritten after every install/update | ||
4 | # Persistent local customizations | ||
5 | include gtk2-youtube-viewer.local | ||
6 | # Persistent global definitions | ||
7 | # include globals.local | ||
8 | |||
9 | ignore quiet | ||
10 | |||
11 | noblacklist /tmp/.X11-unix | ||
12 | noblacklist ${RUNUSER}/wayland-* | ||
13 | noblacklist ${RUNUSER} | ||
14 | |||
15 | include whitelist-runuser-common.inc | ||
16 | |||
17 | # Redirect | ||
18 | include youtube-viewer.profile \ No newline at end of file | ||
diff --git a/etc/profile-a-l/gtk3-youtube-viewer b/etc/profile-a-l/gtk3-youtube-viewer new file mode 100644 index 000000000..4c5bde55f --- /dev/null +++ b/etc/profile-a-l/gtk3-youtube-viewer | |||
@@ -0,0 +1,18 @@ | |||
1 | # Firejail profile for gtk3-youtube-viewer | ||
2 | # Description: Gtk front-end to youtube-viewer | ||
3 | # This file is overwritten after every install/update | ||
4 | # Persistent local customizations | ||
5 | include gtk3-youtube-viewer.local | ||
6 | # Persistent global definitions | ||
7 | # include globals.local | ||
8 | |||
9 | ignore quiet | ||
10 | |||
11 | noblacklist /tmp/.X11-unix | ||
12 | noblacklist ${RUNUSER}/wayland-* | ||
13 | noblacklist ${RUNUSER} | ||
14 | |||
15 | include whitelist-runuser-common.inc | ||
16 | |||
17 | # Redirect | ||
18 | include youtube-viewer.profile \ No newline at end of file | ||
diff --git a/etc/profile-m-z/mplayer.profile b/etc/profile-m-z/mplayer.profile index cd25d6c0b..f4f862cb9 100644 --- a/etc/profile-m-z/mplayer.profile +++ b/etc/profile-m-z/mplayer.profile | |||
@@ -7,8 +7,6 @@ include mplayer.local | |||
7 | include globals.local | 7 | include globals.local |
8 | 8 | ||
9 | noblacklist ${HOME}/.mplayer | 9 | noblacklist ${HOME}/.mplayer |
10 | noblacklist ${MUSIC} | ||
11 | noblacklist ${VIDEOS} | ||
12 | 10 | ||
13 | include disable-common.inc | 11 | include disable-common.inc |
14 | include disable-devel.inc | 12 | include disable-devel.inc |
@@ -16,8 +14,16 @@ include disable-exec.inc | |||
16 | include disable-interpreters.inc | 14 | include disable-interpreters.inc |
17 | include disable-passwdmgr.inc | 15 | include disable-passwdmgr.inc |
18 | include disable-programs.inc | 16 | include disable-programs.inc |
19 | include disable-xdg.inc | ||
20 | 17 | ||
18 | read-only ${DESKTOP} | ||
19 | mkdir ${HOME}/.mplayer | ||
20 | whitelist ${HOME}/.mplayer | ||
21 | whitelist ${DESKTOP} | ||
22 | whitelist ${DOWNLOADS} | ||
23 | whitelist ${MUSIC} | ||
24 | whitelist ${PICTURES} | ||
25 | whitelist ${VIDEOS} | ||
26 | include whitelist-common.inc | ||
21 | include whitelist-usr-share-common.inc | 27 | include whitelist-usr-share-common.inc |
22 | include whitelist-var-common.inc | 28 | include whitelist-var-common.inc |
23 | 29 | ||
@@ -36,4 +42,3 @@ shell none | |||
36 | private-bin mplayer | 42 | private-bin mplayer |
37 | private-dev | 43 | private-dev |
38 | private-tmp | 44 | private-tmp |
39 | |||
diff --git a/etc/profile-m-z/mpv.profile b/etc/profile-m-z/mpv.profile index 2fc027257..5ca684eb5 100644 --- a/etc/profile-m-z/mpv.profile +++ b/etc/profile-m-z/mpv.profile | |||
@@ -7,6 +7,10 @@ include mpv.local | |||
7 | # Persistent global definitions | 7 | # Persistent global definitions |
8 | include globals.local | 8 | include globals.local |
9 | 9 | ||
10 | # In order to save screenshots to a persistent location, | ||
11 | # edit ~/.config/mpv/foobar.conf: | ||
12 | # screenshot-directory=~/Pictures | ||
13 | |||
10 | noblacklist ${HOME}/.config/mpv | 14 | noblacklist ${HOME}/.config/mpv |
11 | noblacklist ${HOME}/.config/youtube-dl | 15 | noblacklist ${HOME}/.config/youtube-dl |
12 | noblacklist ${HOME}/.netrc | 16 | noblacklist ${HOME}/.netrc |
@@ -17,10 +21,6 @@ include allow-lua.inc | |||
17 | include allow-python2.inc | 21 | include allow-python2.inc |
18 | include allow-python3.inc | 22 | include allow-python3.inc |
19 | 23 | ||
20 | noblacklist ${MUSIC} | ||
21 | noblacklist ${PICTURES} | ||
22 | noblacklist ${VIDEOS} | ||
23 | |||
24 | include disable-common.inc | 24 | include disable-common.inc |
25 | include disable-devel.inc | 25 | include disable-devel.inc |
26 | include disable-exec.inc | 26 | include disable-exec.inc |
@@ -28,8 +28,20 @@ include disable-interpreters.inc | |||
28 | include disable-passwdmgr.inc | 28 | include disable-passwdmgr.inc |
29 | include disable-programs.inc | 29 | include disable-programs.inc |
30 | include disable-shell.inc | 30 | include disable-shell.inc |
31 | include disable-xdg.inc | ||
32 | 31 | ||
32 | read-only ${DESKTOP} | ||
33 | mkdir ${HOME}/.config/mpv | ||
34 | mkdir ${HOME}/.config/youtube-dl | ||
35 | mkfile ${HOME}/.netrc | ||
36 | whitelist ${HOME}/.config/mpv | ||
37 | whitelist ${HOME}/.config/youtube-dl | ||
38 | whitelist ${HOME}/.netrc | ||
39 | whitelist ${DESKTOP} | ||
40 | whitelist ${DOWNLOADS} | ||
41 | whitelist ${MUSIC} | ||
42 | whitelist ${PICTURES} | ||
43 | whitelist ${VIDEOS} | ||
44 | include whitelist-common.inc | ||
33 | whitelist /usr/share/lua | 45 | whitelist /usr/share/lua |
34 | whitelist /usr/share/lua* | 46 | whitelist /usr/share/lua* |
35 | whitelist /usr/share/vulkan | 47 | whitelist /usr/share/vulkan |
diff --git a/etc/profile-m-z/nomacs.profile b/etc/profile-m-z/nomacs.profile index 7a7ff504a..d081c9cb7 100644 --- a/etc/profile-m-z/nomacs.profile +++ b/etc/profile-m-z/nomacs.profile | |||
@@ -43,5 +43,3 @@ private-cache | |||
43 | private-dev | 43 | private-dev |
44 | private-etc alternatives,ca-certificates,crypto-policies,dconf,drirc,fonts,gtk-3.0,hosts,login.defs,machine-id,pki,resolv.conf,ssl | 44 | private-etc alternatives,ca-certificates,crypto-policies,dconf,drirc,fonts,gtk-3.0,hosts,login.defs,machine-id,pki,resolv.conf,ssl |
45 | private-tmp | 45 | private-tmp |
46 | |||
47 | memory-deny-write-execute | ||
diff --git a/etc/profile-m-z/signal-desktop.profile b/etc/profile-m-z/signal-desktop.profile index b51a86e7d..c28571270 100644 --- a/etc/profile-m-z/signal-desktop.profile +++ b/etc/profile-m-z/signal-desktop.profile | |||
@@ -34,7 +34,6 @@ nodvd | |||
34 | nogroups | 34 | nogroups |
35 | notv | 35 | notv |
36 | nou2f | 36 | nou2f |
37 | novideo | ||
38 | shell none | 37 | shell none |
39 | 38 | ||
40 | disable-mnt | 39 | disable-mnt |
diff --git a/etc/profile-m-z/totem.profile b/etc/profile-m-z/totem.profile index b8f4ca765..abbbba6c3 100644 --- a/etc/profile-m-z/totem.profile +++ b/etc/profile-m-z/totem.profile | |||
@@ -14,9 +14,6 @@ include allow-python3.inc | |||
14 | 14 | ||
15 | noblacklist ${HOME}/.config/totem | 15 | noblacklist ${HOME}/.config/totem |
16 | noblacklist ${HOME}/.local/share/totem | 16 | noblacklist ${HOME}/.local/share/totem |
17 | noblacklist ${MUSIC} | ||
18 | noblacklist ${PICTURES} | ||
19 | noblacklist ${VIDEOS} | ||
20 | 17 | ||
21 | include disable-common.inc | 18 | include disable-common.inc |
22 | include disable-devel.inc | 19 | include disable-devel.inc |
@@ -25,8 +22,18 @@ include disable-interpreters.inc | |||
25 | include disable-passwdmgr.inc | 22 | include disable-passwdmgr.inc |
26 | include disable-programs.inc | 23 | include disable-programs.inc |
27 | include disable-shell.inc | 24 | include disable-shell.inc |
28 | include disable-xdg.inc | ||
29 | 25 | ||
26 | read-only ${DESKTOP} | ||
27 | mkdir ${HOME}/.config/totem | ||
28 | mkdir ${HOME}/.local/share/totem | ||
29 | whitelist ${HOME}/.config/totem | ||
30 | whitelist ${HOME}/.local/share/totem | ||
31 | whitelist ${DESKTOP} | ||
32 | whitelist ${DOWNLOADS} | ||
33 | whitelist ${MUSIC} | ||
34 | whitelist ${PICTURES} | ||
35 | whitelist ${VIDEOS} | ||
36 | include whitelist-common.inc | ||
30 | include whitelist-var-common.inc | 37 | include whitelist-var-common.inc |
31 | 38 | ||
32 | # apparmor - makes settings immutable | 39 | # apparmor - makes settings immutable |
diff --git a/etc/profile-m-z/vlc.profile b/etc/profile-m-z/vlc.profile index 0069ebeae..07a1b5fc0 100644 --- a/etc/profile-m-z/vlc.profile +++ b/etc/profile-m-z/vlc.profile | |||
@@ -9,8 +9,6 @@ include globals.local | |||
9 | noblacklist ${HOME}/.cache/vlc | 9 | noblacklist ${HOME}/.cache/vlc |
10 | noblacklist ${HOME}/.config/vlc | 10 | noblacklist ${HOME}/.config/vlc |
11 | noblacklist ${HOME}/.local/share/vlc | 11 | noblacklist ${HOME}/.local/share/vlc |
12 | noblacklist ${MUSIC} | ||
13 | noblacklist ${VIDEOS} | ||
14 | 12 | ||
15 | include disable-common.inc | 13 | include disable-common.inc |
16 | include disable-devel.inc | 14 | include disable-devel.inc |
@@ -18,8 +16,20 @@ include disable-exec.inc | |||
18 | include disable-interpreters.inc | 16 | include disable-interpreters.inc |
19 | include disable-passwdmgr.inc | 17 | include disable-passwdmgr.inc |
20 | include disable-programs.inc | 18 | include disable-programs.inc |
21 | include disable-xdg.inc | ||
22 | 19 | ||
20 | read-only ${DESKTOP} | ||
21 | mkdir ${HOME}/.cache/vlc | ||
22 | mkdir ${HOME}/.config/vlc | ||
23 | mkdir ${HOME}/.local/share/vlc | ||
24 | whitelist ${HOME}/.cache/vlc | ||
25 | whitelist ${HOME}/.config/vlc | ||
26 | whitelist ${HOME}/.local/share/vlc | ||
27 | whitelist ${DESKTOP} | ||
28 | whitelist ${DOWNLOADS} | ||
29 | whitelist ${MUSIC} | ||
30 | whitelist ${PICTURES} | ||
31 | whitelist ${VIDEOS} | ||
32 | include whitelist-common.inc | ||
23 | include whitelist-var-common.inc | 33 | include whitelist-var-common.inc |
24 | 34 | ||
25 | #apparmor - on Ubuntu 18.04 it refuses to start without dbus access | 35 | #apparmor - on Ubuntu 18.04 it refuses to start without dbus access |
diff --git a/etc/profile-m-z/xplayer.profile b/etc/profile-m-z/xplayer.profile index 28df73ea5..555d8e9a4 100644 --- a/etc/profile-m-z/xplayer.profile +++ b/etc/profile-m-z/xplayer.profile | |||
@@ -7,8 +7,6 @@ include globals.local | |||
7 | 7 | ||
8 | noblacklist ${HOME}/.config/xplayer | 8 | noblacklist ${HOME}/.config/xplayer |
9 | noblacklist ${HOME}/.local/share/xplayer | 9 | noblacklist ${HOME}/.local/share/xplayer |
10 | noblacklist ${MUSIC} | ||
11 | noblacklist ${VIDEOS} | ||
12 | 10 | ||
13 | # Allow python (blacklisted by disable-interpreters.inc) | 11 | # Allow python (blacklisted by disable-interpreters.inc) |
14 | include allow-python2.inc | 12 | include allow-python2.inc |
@@ -20,8 +18,18 @@ include disable-exec.inc | |||
20 | include disable-interpreters.inc | 18 | include disable-interpreters.inc |
21 | include disable-passwdmgr.inc | 19 | include disable-passwdmgr.inc |
22 | include disable-programs.inc | 20 | include disable-programs.inc |
23 | include disable-xdg.inc | ||
24 | 21 | ||
22 | read-only ${DESKTOP} | ||
23 | mkdir ${HOME}/.config/xplayer | ||
24 | mkdir ${HOME}/.local/share/xplayer | ||
25 | whitelist ${HOME}/.config/xplayer | ||
26 | whitelist ${HOME}/.local/share/xplayer | ||
27 | whitelist ${DESKTOP} | ||
28 | whitelist ${DOWNLOADS} | ||
29 | whitelist ${MUSIC} | ||
30 | whitelist ${PICTURES} | ||
31 | whitelist ${VIDEOS} | ||
32 | include whitelist-common.inc | ||
25 | include whitelist-var-common.inc | 33 | include whitelist-var-common.inc |
26 | 34 | ||
27 | # apparmor - makes settings immutable | 35 | # apparmor - makes settings immutable |
diff --git a/etc/profile-m-z/youtube-viewer.profile b/etc/profile-m-z/youtube-viewer.profile new file mode 100644 index 000000000..513cb0f6e --- /dev/null +++ b/etc/profile-m-z/youtube-viewer.profile | |||
@@ -0,0 +1,57 @@ | |||
1 | # Firejail profile for youtube-viewer | ||
2 | # Description: Trizen's CLI Youtube viewer with login support | ||
3 | # This file is overwritten after every install/update | ||
4 | quiet | ||
5 | # Persistent local customizations | ||
6 | include youtube-viewer.local | ||
7 | # Persistent global definitions | ||
8 | include globals.local | ||
9 | |||
10 | blacklist /tmp/.X11-unix | ||
11 | blacklist ${RUNUSER}/wayland-* | ||
12 | blacklist ${RUNUSER} | ||
13 | |||
14 | noblacklist ${HOME}/.config/youtube-viewer | ||
15 | |||
16 | include allow-perl.inc | ||
17 | include allow-python2.inc | ||
18 | include allow-python3.inc | ||
19 | |||
20 | include disable-common.inc | ||
21 | include disable-devel.inc | ||
22 | include disable-exec.inc | ||
23 | include disable-interpreters.inc | ||
24 | include disable-passwdmgr.inc | ||
25 | include disable-programs.inc | ||
26 | include disable-xdg.inc | ||
27 | |||
28 | mkdir ${HOME}/.config/youtube-viewer | ||
29 | whitelist ${HOME}/.config/youtube-viewer | ||
30 | include whitelist-common.inc | ||
31 | include whitelist-usr-share-common.inc | ||
32 | include whitelist-var-common.inc | ||
33 | |||
34 | apparmor | ||
35 | caps.drop all | ||
36 | netfilter | ||
37 | nodvd | ||
38 | nogroups | ||
39 | nonewprivs | ||
40 | noroot | ||
41 | notv | ||
42 | nou2f | ||
43 | novideo | ||
44 | protocol unix,inet,inet6 | ||
45 | seccomp | ||
46 | shell none | ||
47 | tracelog | ||
48 | |||
49 | disable-mnt | ||
50 | # private-bin ffmpeg,ffprobe,firefox,gtk-youtube-viewer,gtk2-youtube-viewer,gtk3-youtube-viewer,mpv,python*,smplayer,sh,which,vlc,youtube-dl,youtube-viewer | ||
51 | private-cache | ||
52 | private-dev | ||
53 | private-etc alsa,alternatives,asound.conf,ca-certificates,crypto-policies,fonts,gtk-2.0,gtk-3.0,host.conf,hostname,hosts,machine-id,mime.types,nsswitch.conf,passwd,pki,pulse,resolv.conf,ssl,X11,xdg | ||
54 | private-tmp | ||
55 | |||
56 | dbus-user none | ||
57 | dbus-system none \ No newline at end of file | ||
diff --git a/mkdeb.sh.in b/mkdeb.sh.in index efb477920..a19dee620 100755 --- a/mkdeb.sh.in +++ b/mkdeb.sh.in | |||
@@ -52,12 +52,12 @@ echo "*****************************************" | |||
52 | mv $INSTALL_DIR/usr/share/doc/firejail/RELNOTES $INSTALL_DIR/usr/share/doc/firejail/changelog.Debian | 52 | mv $INSTALL_DIR/usr/share/doc/firejail/RELNOTES $INSTALL_DIR/usr/share/doc/firejail/changelog.Debian |
53 | gzip -9 -n $INSTALL_DIR/usr/share/doc/firejail/changelog.Debian | 53 | gzip -9 -n $INSTALL_DIR/usr/share/doc/firejail/changelog.Debian |
54 | rm $INSTALL_DIR/usr/share/doc/firejail/COPYING | 54 | rm $INSTALL_DIR/usr/share/doc/firejail/COPYING |
55 | install -m644 platform/debian/copyright $INSTALL_DIR/usr/share/doc/firejail/. | 55 | install -m644 $CODE_DIR/platform/debian/copyright $INSTALL_DIR/usr/share/doc/firejail/. |
56 | mkdir -p $DEBIAN_CTRL_DIR | 56 | mkdir -p $DEBIAN_CTRL_DIR |
57 | sed "s/FIREJAILVER/$VERSION/g" platform/debian/control.$(dpkg-architecture -qDEB_HOST_ARCH) > $DEBIAN_CTRL_DIR/control | 57 | sed "s/FIREJAILVER/$VERSION/g" $CODE_DIR/platform/debian/control.$(dpkg-architecture -qDEB_HOST_ARCH) > $DEBIAN_CTRL_DIR/control |
58 | 58 | ||
59 | mkdir -p $INSTALL_DIR/usr/share/lintian/overrides/ | 59 | mkdir -p $INSTALL_DIR/usr/share/lintian/overrides/ |
60 | install -m644 platform/debian/firejail.lintian-overrides $INSTALL_DIR/usr/share/lintian/overrides/firejail | 60 | install -m644 $CODE_DIR/platform/debian/firejail.lintian-overrides $INSTALL_DIR/usr/share/lintian/overrides/firejail |
61 | 61 | ||
62 | find $INSTALL_DIR/etc -type f | sed "s,^$INSTALL_DIR,," | LC_ALL=C sort > $DEBIAN_CTRL_DIR/conffiles | 62 | find $INSTALL_DIR/etc -type f | sed "s,^$INSTALL_DIR,," | LC_ALL=C sort > $DEBIAN_CTRL_DIR/conffiles |
63 | chmod 644 $DEBIAN_CTRL_DIR/conffiles | 63 | chmod 644 $DEBIAN_CTRL_DIR/conffiles |
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config index 05c5681d5..0574daae6 100644 --- a/src/firecfg/firecfg.config +++ b/src/firecfg/firecfg.config | |||
@@ -327,6 +327,9 @@ gradio | |||
327 | gramps | 327 | gramps |
328 | gravity-beams-and-evaporating-stars | 328 | gravity-beams-and-evaporating-stars |
329 | gthumb | 329 | gthumb |
330 | gtk-youtube-viewer | ||
331 | gtk2-youtube-viewer | ||
332 | gtk3-youtube-viewer | ||
330 | guayadeque | 333 | guayadeque |
331 | gucharmap | 334 | gucharmap |
332 | gummi | 335 | gummi |
@@ -816,6 +819,7 @@ xviewer | |||
816 | yandex-browser | 819 | yandex-browser |
817 | yelp | 820 | yelp |
818 | youtube-dl | 821 | youtube-dl |
822 | youtube-viewer | ||
819 | zaproxy | 823 | zaproxy |
820 | zart | 824 | zart |
821 | zathura | 825 | zathura |
diff --git a/src/firejail/arp.c b/src/firejail/arp.c index 3714af9a3..f88d0a1dd 100644 --- a/src/firejail/arp.c +++ b/src/firejail/arp.c | |||
@@ -239,9 +239,7 @@ int arp_check(const char *dev, uint32_t destaddr) { | |||
239 | } | 239 | } |
240 | } | 240 | } |
241 | 241 | ||
242 | // it will never get here! | 242 | __builtin_unreachable(); |
243 | close(sock); | ||
244 | return -1; | ||
245 | } | 243 | } |
246 | 244 | ||
247 | // assign a random IP address and check it | 245 | // assign a random IP address and check it |
diff --git a/src/firejail/bandwidth.c b/src/firejail/bandwidth.c index edef823fd..6fd0b53ef 100644 --- a/src/firejail/bandwidth.c +++ b/src/firejail/bandwidth.c | |||
@@ -327,6 +327,15 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in | |||
327 | devname = strdup(buf + len + 1); | 327 | devname = strdup(buf + len + 1); |
328 | if (!devname) | 328 | if (!devname) |
329 | errExit("strdup"); | 329 | errExit("strdup"); |
330 | // double-check device name | ||
331 | size_t i; | ||
332 | for (i = 0; devname[i]; i++) { | ||
333 | if (isalnum((unsigned char) devname[i]) == 0 && | ||
334 | devname[i] != '-') { | ||
335 | fprintf(stderr, "Error: name of network device is invalid\n"); | ||
336 | exit(1); | ||
337 | } | ||
338 | } | ||
330 | // check device in namespace | 339 | // check device in namespace |
331 | if (if_nametoindex(devname) == 0) { | 340 | if (if_nametoindex(devname) == 0) { |
332 | fprintf(stderr, "Error: cannot find network device %s\n", devname); | 341 | fprintf(stderr, "Error: cannot find network device %s\n", devname); |
@@ -354,6 +363,7 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in | |||
354 | } | 363 | } |
355 | bandwidth_remove(pid, devname); | 364 | bandwidth_remove(pid, devname); |
356 | } | 365 | } |
366 | else assert(strcmp(command, "status") == 0); | ||
357 | 367 | ||
358 | // build fshaper.sh command | 368 | // build fshaper.sh command |
359 | char *cmd = NULL; | 369 | char *cmd = NULL; |
@@ -375,26 +385,16 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in | |||
375 | } | 385 | } |
376 | assert(cmd); | 386 | assert(cmd); |
377 | 387 | ||
378 | // wipe out environment variables | ||
379 | environ = NULL; | ||
380 | |||
381 | //************************ | 388 | //************************ |
382 | // build command | 389 | // build command |
383 | //************************ | 390 | //************************ |
384 | // elevate privileges | ||
385 | if (setreuid(0, 0)) | ||
386 | errExit("setreuid"); | ||
387 | if (setregid(0, 0)) | ||
388 | errExit("setregid"); | ||
389 | |||
390 | char *arg[4]; | 391 | char *arg[4]; |
391 | arg[0] = "/bin/sh"; | 392 | arg[0] = "/bin/sh"; |
392 | arg[1] = "-c"; | 393 | arg[1] = "-c"; |
393 | arg[2] = cmd; | 394 | arg[2] = cmd; |
394 | arg[3] = NULL; | 395 | arg[3] = NULL; |
395 | clearenv(); | 396 | clearenv(); |
396 | execvp(arg[0], arg); | 397 | sbox_exec_v(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, arg); |
397 | 398 | ||
398 | // it will never get here | 399 | // it will never get here!! |
399 | errExit("execvp"); | ||
400 | } | 400 | } |
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index 5d6b4af66..f6b3b3252 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c | |||
@@ -229,6 +229,8 @@ int checkcfg(int val) { | |||
229 | #ifdef HAVE_SECCOMP | 229 | #ifdef HAVE_SECCOMP |
230 | if (strcmp(ptr + 21, "kill") == 0) | 230 | if (strcmp(ptr + 21, "kill") == 0) |
231 | cfg_val[CFG_SECCOMP_ERROR_ACTION] = SECCOMP_RET_KILL; | 231 | cfg_val[CFG_SECCOMP_ERROR_ACTION] = SECCOMP_RET_KILL; |
232 | else if (strcmp(ptr + 21, "log") == 0) | ||
233 | cfg_val[CFG_SECCOMP_ERROR_ACTION] = SECCOMP_RET_LOG; | ||
232 | else { | 234 | else { |
233 | cfg_val[CFG_SECCOMP_ERROR_ACTION] = errno_find_name(ptr + 21); | 235 | cfg_val[CFG_SECCOMP_ERROR_ACTION] = errno_find_name(ptr + 21); |
234 | if (cfg_val[CFG_SECCOMP_ERROR_ACTION] == -1) | 236 | if (cfg_val[CFG_SECCOMP_ERROR_ACTION] == -1) |
diff --git a/src/firejail/chroot.c b/src/firejail/chroot.c index cae52e20b..5fc6c8298 100644 --- a/src/firejail/chroot.c +++ b/src/firejail/chroot.c | |||
@@ -165,7 +165,8 @@ void fs_chroot(const char *rootdir) { | |||
165 | close(fd); | 165 | close(fd); |
166 | 166 | ||
167 | // x11 | 167 | // x11 |
168 | if (getenv("FIREJAIL_X11")) { | 168 | // if users want this mount, they should set FIREJAIL_CHROOT_X11 |
169 | if (getenv("FIREJAIL_X11") || getenv("FIREJAIL_CHROOT_X11")) { | ||
169 | if (arg_debug) | 170 | if (arg_debug) |
170 | printf("Mounting /tmp/.X11-unix on chroot /tmp/.X11-unix\n"); | 171 | printf("Mounting /tmp/.X11-unix on chroot /tmp/.X11-unix\n"); |
171 | check_subdir(parentfd, "tmp/.X11-unix", 0); | 172 | check_subdir(parentfd, "tmp/.X11-unix", 0); |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 54a1023ab..49d19e33d 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -186,7 +186,7 @@ typedef struct config_t { | |||
186 | char *seccomp_list_drop, *seccomp_list_drop32; // seccomp drop list | 186 | char *seccomp_list_drop, *seccomp_list_drop32; // seccomp drop list |
187 | char *seccomp_list_keep, *seccomp_list_keep32; // seccomp keep list | 187 | char *seccomp_list_keep, *seccomp_list_keep32; // seccomp keep list |
188 | char *protocol; // protocol list | 188 | char *protocol; // protocol list |
189 | char *seccomp_error_action; // error action: kill or errno | 189 | char *seccomp_error_action; // error action: kill, log or errno |
190 | 190 | ||
191 | // rlimits | 191 | // rlimits |
192 | long long unsigned rlimit_cpu; | 192 | long long unsigned rlimit_cpu; |
@@ -371,14 +371,14 @@ char *guess_shell(void); | |||
371 | 371 | ||
372 | // sandbox.c | 372 | // sandbox.c |
373 | int sandbox(void* sandbox_arg); | 373 | int sandbox(void* sandbox_arg); |
374 | void start_application(int no_sandbox, FILE *fp); | 374 | void start_application(int no_sandbox, FILE *fp) __attribute__((noreturn)); |
375 | void set_apparmor(void); | 375 | void set_apparmor(void); |
376 | 376 | ||
377 | // network_main.c | 377 | // network_main.c |
378 | void net_configure_sandbox_ip(Bridge *br); | 378 | void net_configure_sandbox_ip(Bridge *br); |
379 | void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child); | 379 | void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child); |
380 | void net_check_cfg(void); | 380 | void net_check_cfg(void); |
381 | void net_dns_print(pid_t pid); | 381 | void net_dns_print(pid_t pid) __attribute__((noreturn)); |
382 | void network_main(pid_t child); | 382 | void network_main(pid_t child); |
383 | void net_print(pid_t pid); | 383 | void net_print(pid_t pid); |
384 | 384 | ||
@@ -453,13 +453,12 @@ void profile_add_ignore(const char *str); | |||
453 | void list(void); | 453 | void list(void); |
454 | void tree(void); | 454 | void tree(void); |
455 | void top(void); | 455 | void top(void); |
456 | void netstats(void); | ||
457 | 456 | ||
458 | // usage.c | 457 | // usage.c |
459 | void usage(void); | 458 | void usage(void); |
460 | 459 | ||
461 | // join.c | 460 | // join.c |
462 | void join(pid_t pid, int argc, char **argv, int index); | 461 | void join(pid_t pid, int argc, char **argv, int index) __attribute__((noreturn)); |
463 | bool is_ready_for_join(const pid_t pid); | 462 | bool is_ready_for_join(const pid_t pid); |
464 | void check_join_permission(pid_t pid); | 463 | void check_join_permission(pid_t pid); |
465 | pid_t switch_to_child(pid_t pid); | 464 | pid_t switch_to_child(pid_t pid); |
@@ -486,7 +485,7 @@ int macro_id(const char *name); | |||
486 | 485 | ||
487 | 486 | ||
488 | // util.c | 487 | // util.c |
489 | void errLogExit(char* fmt, ...); | 488 | void errLogExit(char* fmt, ...) __attribute__((noreturn)); |
490 | void fwarning(char* fmt, ...); | 489 | void fwarning(char* fmt, ...); |
491 | void fmessage(char* fmt, ...); | 490 | void fmessage(char* fmt, ...); |
492 | void drop_privs(int nogroups); | 491 | void drop_privs(int nogroups); |
@@ -584,7 +583,7 @@ int seccomp_load(const char *fname); | |||
584 | int seccomp_filter_drop(bool native); | 583 | int seccomp_filter_drop(bool native); |
585 | int seccomp_filter_keep(bool native); | 584 | int seccomp_filter_keep(bool native); |
586 | int seccomp_filter_mdwx(bool native); | 585 | int seccomp_filter_mdwx(bool native); |
587 | void seccomp_print_filter(pid_t pid); | 586 | void seccomp_print_filter(pid_t pid) __attribute__((noreturn)); |
588 | 587 | ||
589 | // caps.c | 588 | // caps.c |
590 | void seccomp_load_file_list(void); | 589 | void seccomp_load_file_list(void); |
@@ -595,7 +594,7 @@ void caps_set(uint64_t caps); | |||
595 | void caps_check_list(const char *clist, void (*callback)(int)); | 594 | void caps_check_list(const char *clist, void (*callback)(int)); |
596 | void caps_drop_list(const char *clist); | 595 | void caps_drop_list(const char *clist); |
597 | void caps_keep_list(const char *clist); | 596 | void caps_keep_list(const char *clist); |
598 | void caps_print_filter(pid_t pid); | 597 | void caps_print_filter(pid_t pid) __attribute__((noreturn)); |
599 | void caps_drop_dac_override(void); | 598 | void caps_drop_dac_override(void); |
600 | 599 | ||
601 | // fs_trace.c | 600 | // fs_trace.c |
@@ -618,7 +617,7 @@ void read_cpu_list(const char *str); | |||
618 | void set_cpu_affinity(void); | 617 | void set_cpu_affinity(void); |
619 | void load_cpu(const char *fname); | 618 | void load_cpu(const char *fname); |
620 | void save_cpu(void); | 619 | void save_cpu(void); |
621 | void cpu_print_filter(pid_t pid); | 620 | void cpu_print_filter(pid_t pid) __attribute__((noreturn)); |
622 | 621 | ||
623 | // cgroup.c | 622 | // cgroup.c |
624 | void save_cgroup(void); | 623 | void save_cgroup(void); |
@@ -640,7 +639,7 @@ void netns(const char *nsname); | |||
640 | void netns_mounts(const char *nsname); | 639 | void netns_mounts(const char *nsname); |
641 | 640 | ||
642 | // bandwidth.c | 641 | // bandwidth.c |
643 | void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up); | 642 | void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up) __attribute__((noreturn)); |
644 | void network_set_run_file(pid_t pid); | 643 | void network_set_run_file(pid_t pid); |
645 | 644 | ||
646 | // fs_etc.c | 645 | // fs_etc.c |
@@ -650,7 +649,7 @@ void fs_private_dir_list(const char *private_dir, const char *private_run_dir, c | |||
650 | // no_sandbox.c | 649 | // no_sandbox.c |
651 | int check_namespace_virt(void); | 650 | int check_namespace_virt(void); |
652 | int check_kernel_procs(void); | 651 | int check_kernel_procs(void); |
653 | void run_no_sandbox(int argc, char **argv); | 652 | void run_no_sandbox(int argc, char **argv) __attribute__((noreturn)); |
654 | 653 | ||
655 | #define MAX_ENVS 256 // some sane maximum number of environment variables | 654 | #define MAX_ENVS 256 // some sane maximum number of environment variables |
656 | #define MAX_ENV_LEN (PATH_MAX + 32) // FOOBAR=SOME_PATH | 655 | #define MAX_ENV_LEN (PATH_MAX + 32) // FOOBAR=SOME_PATH |
@@ -681,7 +680,7 @@ void fs_private_lib(void); | |||
681 | // protocol.c | 680 | // protocol.c |
682 | void protocol_filter_save(void); | 681 | void protocol_filter_save(void); |
683 | void protocol_filter_load(const char *fname); | 682 | void protocol_filter_load(const char *fname); |
684 | void protocol_print_filter(pid_t pid); | 683 | void protocol_print_filter(pid_t pid) __attribute__((noreturn)); |
685 | 684 | ||
686 | // restrict_users.c | 685 | // restrict_users.c |
687 | void restrict_users(void); | 686 | void restrict_users(void); |
@@ -693,7 +692,7 @@ void fs_logger2int(const char *msg1, int d); | |||
693 | void fs_logger3(const char *msg1, const char *msg2, const char *msg3); | 692 | void fs_logger3(const char *msg1, const char *msg2, const char *msg3); |
694 | void fs_logger_print(void); | 693 | void fs_logger_print(void); |
695 | void fs_logger_change_owner(void); | 694 | void fs_logger_change_owner(void); |
696 | void fs_logger_print_log(pid_t pid); | 695 | void fs_logger_print_log(pid_t pid) __attribute__((noreturn)); |
697 | 696 | ||
698 | // run_symlink.c | 697 | // run_symlink.c |
699 | void run_symlink(int argc, char **argv, int run_as_is); | 698 | void run_symlink(int argc, char **argv, int run_as_is); |
@@ -719,21 +718,24 @@ void fs_mkfile(const char *name); | |||
719 | 718 | ||
720 | void fs_x11(void); | 719 | void fs_x11(void); |
721 | int x11_display(void); | 720 | int x11_display(void); |
722 | void x11_start(int argc, char **argv); | 721 | void x11_start(int argc, char **argv) __attribute__((noreturn)); |
723 | void x11_start_xpra(int argc, char **argv); | 722 | void x11_start_xpra(int argc, char **argv) __attribute__((noreturn)); |
724 | void x11_start_xephyr(int argc, char **argv); | 723 | void x11_start_xephyr(int argc, char **argv) __attribute__((noreturn)); |
725 | void x11_block(void); | 724 | void x11_block(void); |
726 | void x11_start_xvfb(int argc, char **argv); | 725 | void x11_start_xvfb(int argc, char **argv) __attribute__((noreturn)); |
727 | void x11_xorg(void); | 726 | void x11_xorg(void); |
728 | 727 | ||
729 | // ls.c | 728 | // ls.c |
730 | enum { | 729 | enum { |
731 | SANDBOX_FS_LS = 0, | 730 | SANDBOX_FS_LS = 0, |
731 | SANDBOX_FS_CAT, | ||
732 | SANDBOX_FS_GET, | 732 | SANDBOX_FS_GET, |
733 | SANDBOX_FS_PUT, | 733 | SANDBOX_FS_PUT, |
734 | SANDBOX_FS_MAX // this should always be the last entry | 734 | SANDBOX_FS_MAX // this should always be the last entry |
735 | }; | 735 | }; |
736 | void sandboxfs(int op, pid_t pid, const char *path1, const char *path2); | 736 | void ls(const char *path); |
737 | void cat(const char *path); | ||
738 | void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) __attribute__((noreturn)); | ||
737 | 739 | ||
738 | // checkcfg.c | 740 | // checkcfg.c |
739 | #define DEFAULT_ARP_PROBES 2 | 741 | #define DEFAULT_ARP_PROBES 2 |
@@ -839,7 +841,7 @@ void build_appimage_cmdline(char **command_line, char **window_title, int argc, | |||
839 | // run sbox | 841 | // run sbox |
840 | int sbox_run(unsigned filter, int num, ...); | 842 | int sbox_run(unsigned filter, int num, ...); |
841 | int sbox_run_v(unsigned filter, char * const arg[]); | 843 | int sbox_run_v(unsigned filter, char * const arg[]); |
842 | void sbox_exec_v(unsigned filter, char * const arg[]); | 844 | void sbox_exec_v(unsigned filter, char * const arg[]) __attribute__((noreturn)); |
843 | 845 | ||
844 | // run_files.c | 846 | // run_files.c |
845 | void delete_run_files(pid_t pid); | 847 | void delete_run_files(pid_t pid); |
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c index fbce72429..00edc5f88 100644 --- a/src/firejail/fs_dev.c +++ b/src/firejail/fs_dev.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <dirent.h> | 25 | #include <dirent.h> |
26 | #include <fcntl.h> | 26 | #include <fcntl.h> |
27 | #include <pwd.h> | 27 | #include <pwd.h> |
28 | #include <errno.h> | ||
28 | #ifndef _BSD_SOURCE | 29 | #ifndef _BSD_SOURCE |
29 | #define _BSD_SOURCE | 30 | #define _BSD_SOURCE |
30 | #endif | 31 | #endif |
@@ -148,7 +149,7 @@ static void create_char_dev(const char *path, mode_t mode, int major, int minor) | |||
148 | return; | 149 | return; |
149 | 150 | ||
150 | errexit: | 151 | errexit: |
151 | fprintf(stderr, "Error: cannot create %s device\n", path); | 152 | fprintf(stderr, "Error: cannot create %s device: %s\n", path, strerror(errno)); |
152 | exit(1); | 153 | exit(1); |
153 | } | 154 | } |
154 | 155 | ||
diff --git a/src/firejail/join.c b/src/firejail/join.c index 4c8555f29..f202d1a9c 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c | |||
@@ -588,7 +588,7 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
588 | 588 | ||
589 | start_application(0, NULL); | 589 | start_application(0, NULL); |
590 | 590 | ||
591 | // it will never get here!!! | 591 | __builtin_unreachable(); |
592 | } | 592 | } |
593 | EUID_USER(); | 593 | EUID_USER(); |
594 | 594 | ||
diff --git a/src/firejail/ls.c b/src/firejail/ls.c index aa33d838b..4d0a001b6 100644 --- a/src/firejail/ls.c +++ b/src/firejail/ls.c | |||
@@ -34,18 +34,12 @@ | |||
34 | static uid_t c_uid = 0; | 34 | static uid_t c_uid = 0; |
35 | static char *c_uid_name = NULL; | 35 | static char *c_uid_name = NULL; |
36 | 36 | ||
37 | static void print_file_or_dir(const char *path, const char *fname, int separator) { | 37 | static void print_file_or_dir(const char *path, const char *fname) { |
38 | assert(fname); | 38 | assert(fname); |
39 | 39 | ||
40 | char *name; | 40 | char *name; |
41 | if (separator) { | 41 | if (asprintf(&name, "%s/%s", path, fname) == -1) |
42 | if (asprintf(&name, "%s/%s", path, fname) == -1) | 42 | errExit("asprintf"); |
43 | errExit("asprintf"); | ||
44 | } | ||
45 | else { | ||
46 | if (asprintf(&name, "%s%s", path, fname) == -1) | ||
47 | errExit("asprintf"); | ||
48 | } | ||
49 | 43 | ||
50 | struct stat s; | 44 | struct stat s; |
51 | if (stat(name, &s) == -1) { | 45 | if (stat(name, &s) == -1) { |
@@ -178,13 +172,81 @@ static void print_directory(const char *path) { | |||
178 | errExit("scandir"); | 172 | errExit("scandir"); |
179 | else { | 173 | else { |
180 | for (i = 0; i < n; i++) { | 174 | for (i = 0; i < n; i++) { |
181 | print_file_or_dir(path, namelist[i]->d_name, 0); | 175 | print_file_or_dir(path, namelist[i]->d_name); |
182 | free(namelist[i]); | 176 | free(namelist[i]); |
183 | } | 177 | } |
184 | } | 178 | } |
185 | free(namelist); | 179 | free(namelist); |
186 | } | 180 | } |
187 | 181 | ||
182 | void ls(const char *path) { | ||
183 | EUID_ASSERT(); | ||
184 | assert(path); | ||
185 | |||
186 | char *rp = realpath(path, NULL); | ||
187 | if (!rp || access(rp, R_OK) == -1) { | ||
188 | fprintf(stderr, "Error: cannot access %s\n", path); | ||
189 | exit(1); | ||
190 | } | ||
191 | if (arg_debug) | ||
192 | printf("ls %s\n", rp); | ||
193 | |||
194 | // list directory contents | ||
195 | struct stat s; | ||
196 | if (stat(rp, &s) == -1) { | ||
197 | fprintf(stderr, "Error: cannot access %s\n", rp); | ||
198 | exit(1); | ||
199 | } | ||
200 | if (S_ISDIR(s.st_mode)) | ||
201 | print_directory(rp); | ||
202 | else { | ||
203 | char *split = strrchr(rp, '/'); | ||
204 | if (split) { | ||
205 | *split = '\0'; | ||
206 | char *rp2 = split + 1; | ||
207 | if (arg_debug) | ||
208 | printf("path %s, file %s\n", rp, rp2); | ||
209 | print_file_or_dir(rp, rp2); | ||
210 | } | ||
211 | } | ||
212 | free(rp); | ||
213 | } | ||
214 | |||
215 | void cat(const char *path) { | ||
216 | EUID_ASSERT(); | ||
217 | assert(path); | ||
218 | |||
219 | if (arg_debug) | ||
220 | printf("cat %s\n", path); | ||
221 | FILE *fp = fopen(path, "r"); | ||
222 | if (!fp) { | ||
223 | fprintf(stderr, "Error: cannot read %s\n", path); | ||
224 | exit(1); | ||
225 | } | ||
226 | int fd = fileno(fp); | ||
227 | if (fd == -1) | ||
228 | errExit("fileno"); | ||
229 | struct stat s; | ||
230 | if (fstat(fd, &s) == -1) | ||
231 | errExit("fstat"); | ||
232 | if (!S_ISREG(s.st_mode)) { | ||
233 | fprintf(stderr, "Error: %s is not a regular file\n", path); | ||
234 | exit(1); | ||
235 | } | ||
236 | bool tty = isatty(STDOUT_FILENO); | ||
237 | |||
238 | int c; | ||
239 | while ((c = fgetc(fp)) != EOF) { | ||
240 | // file is untrusted | ||
241 | // replace control characters when printing to a terminal | ||
242 | if (tty && c != '\t' && c != '\n' && iscntrl((unsigned char) c)) | ||
243 | c = '?'; | ||
244 | fputc(c, stdout); | ||
245 | } | ||
246 | fflush(stdout); | ||
247 | fclose(fp); | ||
248 | } | ||
249 | |||
188 | char *expand_path(const char *path) { | 250 | char *expand_path(const char *path) { |
189 | char *fname = NULL; | 251 | char *fname = NULL; |
190 | if (*path == '/') { | 252 | if (*path == '/') { |
@@ -219,14 +281,14 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) { | |||
219 | check_join_permission(pid); | 281 | check_join_permission(pid); |
220 | 282 | ||
221 | // expand paths | 283 | // expand paths |
222 | char *fname1 = expand_path(path1);; | 284 | char *fname1 = expand_path(path1); |
223 | char *fname2 = NULL; | 285 | char *fname2 = NULL; |
224 | if (path2 != NULL) { | 286 | if (path2 != NULL) { |
225 | fname2 = expand_path(path2); | 287 | fname2 = expand_path(path2); |
226 | } | 288 | } |
227 | if (arg_debug) { | 289 | if (arg_debug) { |
228 | printf("file1 %s\n", fname1); | 290 | printf("file1 %s\n", fname1); |
229 | printf("file2 %s\n", fname2); | 291 | printf("file2 %s\n", fname2 ? fname2 : "(null)"); |
230 | } | 292 | } |
231 | 293 | ||
232 | // sandbox root directory | 294 | // sandbox root directory |
@@ -234,57 +296,36 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) { | |||
234 | if (asprintf(&rootdir, "/proc/%d/root", pid) == -1) | 296 | if (asprintf(&rootdir, "/proc/%d/root", pid) == -1) |
235 | errExit("asprintf"); | 297 | errExit("asprintf"); |
236 | 298 | ||
237 | if (op == SANDBOX_FS_LS) { | 299 | if (op == SANDBOX_FS_LS || op == SANDBOX_FS_CAT) { |
238 | EUID_ROOT(); | 300 | pid_t child = fork(); |
239 | // chroot | 301 | if (child < 0) |
240 | if (chroot(rootdir) < 0) | 302 | errExit("fork"); |
241 | errExit("chroot"); | 303 | if (child == 0) { |
242 | if (chdir("/") < 0) | 304 | EUID_ROOT(); |
243 | errExit("chdir"); | 305 | // chroot |
244 | 306 | if (chroot(rootdir) < 0) | |
245 | // drop privileges | 307 | errExit("chroot"); |
246 | drop_privs(0); | 308 | if (chdir("/") < 0) |
247 | 309 | errExit("chdir"); | |
248 | // check access | ||
249 | if (access(fname1, R_OK) == -1) { | ||
250 | fprintf(stderr, "Error: Cannot access %s\n", fname1); | ||
251 | exit(1); | ||
252 | } | ||
253 | /* coverity[toctou] */ | ||
254 | char *rp = realpath(fname1, NULL); | ||
255 | if (!rp) { | ||
256 | fprintf(stderr, "Error: Cannot access %s\n", fname1); | ||
257 | exit(1); | ||
258 | } | ||
259 | if (arg_debug) | ||
260 | printf("realpath %s\n", rp); | ||
261 | |||
262 | 310 | ||
263 | // list directory contents | 311 | // drop privileges |
264 | struct stat s; | 312 | drop_privs(0); |
265 | if (stat(rp, &s) == -1) { | ||
266 | fprintf(stderr, "Error: Cannot access %s\n", rp); | ||
267 | exit(1); | ||
268 | } | ||
269 | if (S_ISDIR(s.st_mode)) { | ||
270 | char *dir; | ||
271 | if (asprintf(&dir, "%s/", rp) == -1) | ||
272 | errExit("asprintf"); | ||
273 | 313 | ||
274 | print_directory(dir); | 314 | if (op == SANDBOX_FS_LS) |
275 | free(dir); | 315 | ls(fname1); |
276 | } | 316 | else |
277 | else { | 317 | cat(fname1); |
278 | char *split = strrchr(rp, '/'); | 318 | #ifdef HAVE_GCOV |
279 | if (split) { | 319 | __gcov_flush(); |
280 | *split = '\0'; | 320 | #endif |
281 | char *rp2 = split + 1; | 321 | _exit(0); |
282 | if (arg_debug) | ||
283 | printf("path %s, file %s\n", rp, rp2); | ||
284 | print_file_or_dir(rp, rp2, 1); | ||
285 | } | ||
286 | } | 322 | } |
287 | free(rp); | 323 | // wait for the child to finish |
324 | int status = 0; | ||
325 | waitpid(child, &status, 0); | ||
326 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0); | ||
327 | else | ||
328 | exit(1); | ||
288 | } | 329 | } |
289 | 330 | ||
290 | // get file from sandbox and store it in the current directory | 331 | // get file from sandbox and store it in the current directory |
@@ -303,10 +344,12 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) { | |||
303 | // create a user-owned temporary file in /run/firejail directory | 344 | // create a user-owned temporary file in /run/firejail directory |
304 | char tmp_fname[] = "/run/firejail/tmpget-XXXXXX"; | 345 | char tmp_fname[] = "/run/firejail/tmpget-XXXXXX"; |
305 | int fd = mkstemp(tmp_fname); | 346 | int fd = mkstemp(tmp_fname); |
306 | if (fd != -1) { | 347 | if (fd == -1) { |
307 | SET_PERMS_FD(fd, getuid(), getgid(), 0600); | 348 | fprintf(stderr, "Error: cannot create temporary file %s\n", tmp_fname); |
308 | close(fd); | 349 | exit(1); |
309 | } | 350 | } |
351 | SET_PERMS_FD(fd, getuid(), getgid(), 0600); | ||
352 | close(fd); | ||
310 | 353 | ||
311 | // copy the source file into the temporary file - we need to chroot | 354 | // copy the source file into the temporary file - we need to chroot |
312 | pid_t child = fork(); | 355 | pid_t child = fork(); |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 4aa5311a2..1ffa6158c 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -811,6 +811,8 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
811 | } | 811 | } |
812 | 812 | ||
813 | // list directory contents | 813 | // list directory contents |
814 | if (!arg_debug) | ||
815 | arg_quiet = 1; | ||
814 | pid_t pid = require_pid(argv[i] + 5); | 816 | pid_t pid = require_pid(argv[i] + 5); |
815 | sandboxfs(SANDBOX_FS_LS, pid, path, NULL); | 817 | sandboxfs(SANDBOX_FS_LS, pid, path, NULL); |
816 | exit(0); | 818 | exit(0); |
@@ -818,6 +820,35 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
818 | else | 820 | else |
819 | exit_err_feature("file transfer"); | 821 | exit_err_feature("file transfer"); |
820 | } | 822 | } |
823 | else if (strncmp(argv[i], "--cat=", 6) == 0) { | ||
824 | if (checkcfg(CFG_FILE_TRANSFER)) { | ||
825 | logargs(argc, argv); | ||
826 | if (arg_private_cwd) { | ||
827 | fprintf(stderr, "Error: --cat and --private-cwd options are mutually exclusive\n"); | ||
828 | exit(1); | ||
829 | } | ||
830 | |||
831 | if ((i + 2) != argc) { | ||
832 | fprintf(stderr, "Error: invalid --cat option, path expected\n"); | ||
833 | exit(1); | ||
834 | } | ||
835 | char *path = argv[i + 1]; | ||
836 | invalid_filename(path, 0); // no globbing | ||
837 | if (strstr(path, "..")) { | ||
838 | fprintf(stderr, "Error: invalid file name %s\n", path); | ||
839 | exit(1); | ||
840 | } | ||
841 | |||
842 | // write file contents to stdout | ||
843 | if (!arg_debug) | ||
844 | arg_quiet = 1; | ||
845 | pid_t pid = require_pid(argv[i] + 6); | ||
846 | sandboxfs(SANDBOX_FS_CAT, pid, path, NULL); | ||
847 | exit(0); | ||
848 | } | ||
849 | else | ||
850 | exit_err_feature("file transfer"); | ||
851 | } | ||
821 | #endif | 852 | #endif |
822 | else if (strncmp(argv[i], "--join=", 7) == 0) { | 853 | else if (strncmp(argv[i], "--join=", 7) == 0) { |
823 | if (checkcfg(CFG_JOIN) || getuid() == 0) { | 854 | if (checkcfg(CFG_JOIN) || getuid() == 0) { |
@@ -1159,8 +1190,7 @@ int main(int argc, char **argv, char **envp) { | |||
1159 | 1190 | ||
1160 | // start the program directly without sandboxing | 1191 | // start the program directly without sandboxing |
1161 | run_no_sandbox(argc, argv); | 1192 | run_no_sandbox(argc, argv); |
1162 | // it will never get here! | 1193 | __builtin_unreachable(); |
1163 | assert(0); | ||
1164 | } | 1194 | } |
1165 | } | 1195 | } |
1166 | EUID_ASSERT(); | 1196 | EUID_ASSERT(); |
@@ -1446,6 +1476,8 @@ int main(int argc, char **argv, char **envp) { | |||
1446 | if (config_seccomp_error_action == -1) { | 1476 | if (config_seccomp_error_action == -1) { |
1447 | if (strcmp(argv[i] + 23, "kill") == 0) | 1477 | if (strcmp(argv[i] + 23, "kill") == 0) |
1448 | arg_seccomp_error_action = SECCOMP_RET_KILL; | 1478 | arg_seccomp_error_action = SECCOMP_RET_KILL; |
1479 | else if (strcmp(argv[i] + 23, "log") == 0) | ||
1480 | arg_seccomp_error_action = SECCOMP_RET_LOG; | ||
1449 | else { | 1481 | else { |
1450 | arg_seccomp_error_action = errno_find_name(argv[i] + 23); | 1482 | arg_seccomp_error_action = errno_find_name(argv[i] + 23); |
1451 | if (arg_seccomp_error_action == -1) | 1483 | if (arg_seccomp_error_action == -1) |
diff --git a/src/firejail/output.c b/src/firejail/output.c index 0e961bb61..36cb905cb 100644 --- a/src/firejail/output.c +++ b/src/firejail/output.c | |||
@@ -122,7 +122,8 @@ void check_output(int argc, char **argv) { | |||
122 | } | 122 | } |
123 | bool found_separator = false; | 123 | bool found_separator = false; |
124 | /* copy argv into args, but drop --output(-stderr) arguments */ | 124 | /* copy argv into args, but drop --output(-stderr) arguments */ |
125 | for (int i = 0, j = 0; i < argc; i++) { | 125 | int j; |
126 | for (i = 0, j = 0; i < argc; i++) { | ||
126 | if (!found_separator && i > 0) { | 127 | if (!found_separator && i > 0) { |
127 | if (strncmp(argv[i], "--output=", 9) == 0) { | 128 | if (strncmp(argv[i], "--output=", 9) == 0) { |
128 | continue; | 129 | continue; |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 70acd8a2a..970033899 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -991,6 +991,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
991 | if (config_seccomp_error_action == -1) { | 991 | if (config_seccomp_error_action == -1) { |
992 | if (strcmp(ptr + 21, "kill") == 0) | 992 | if (strcmp(ptr + 21, "kill") == 0) |
993 | arg_seccomp_error_action = SECCOMP_RET_KILL; | 993 | arg_seccomp_error_action = SECCOMP_RET_KILL; |
994 | else if (strcmp(ptr + 21, "log") == 0) | ||
995 | arg_seccomp_error_action = SECCOMP_RET_LOG; | ||
994 | else { | 996 | else { |
995 | arg_seccomp_error_action = errno_find_name(ptr + 21); | 997 | arg_seccomp_error_action = errno_find_name(ptr + 21); |
996 | if (arg_seccomp_error_action == -1) | 998 | if (arg_seccomp_error_action == -1) |
diff --git a/src/firejail/protocol.c b/src/firejail/protocol.c index 6402afbc6..a1594d6b9 100644 --- a/src/firejail/protocol.c +++ b/src/firejail/protocol.c | |||
@@ -90,7 +90,7 @@ void protocol_print_filter(pid_t pid) { | |||
90 | exit(0); | 90 | exit(0); |
91 | #else | 91 | #else |
92 | fwarning("--protocol not supported on this platform\n"); | 92 | fwarning("--protocol not supported on this platform\n"); |
93 | return; | 93 | exit(1); |
94 | #endif | 94 | #endif |
95 | } | 95 | } |
96 | 96 | ||
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 2314d5744..81d535762 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -140,6 +140,20 @@ void set_apparmor(void) { | |||
140 | } | 140 | } |
141 | #endif | 141 | #endif |
142 | 142 | ||
143 | #ifdef HAVE_SECCOMP | ||
144 | void seccomp_debug(void) { | ||
145 | if (arg_debug == 0) | ||
146 | return; | ||
147 | |||
148 | EUID_USER(); | ||
149 | printf("Seccomp directory:\n"); | ||
150 | ls(RUN_SECCOMP_DIR); | ||
151 | printf("Active seccomp files:\n"); | ||
152 | cat(RUN_SECCOMP_LIST); | ||
153 | EUID_ROOT(); | ||
154 | } | ||
155 | #endif | ||
156 | |||
143 | static void save_nogroups(void) { | 157 | static void save_nogroups(void) { |
144 | if (arg_nogroups == 0) | 158 | if (arg_nogroups == 0) |
145 | return; | 159 | return; |
@@ -197,32 +211,6 @@ static FILE *create_ready_for_join_file(void) { | |||
197 | } | 211 | } |
198 | } | 212 | } |
199 | 213 | ||
200 | #ifdef HAVE_SECCOMP | ||
201 | static void seccomp_debug(void) { | ||
202 | if (arg_debug == 0) | ||
203 | return; | ||
204 | |||
205 | pid_t child = fork(); | ||
206 | if (child < 0) | ||
207 | errExit("fork"); | ||
208 | if (child == 0) { | ||
209 | // dropping privs before calling system(3) | ||
210 | drop_privs(1); | ||
211 | printf("Seccomp directory:\n"); | ||
212 | int rv = system("ls -l " RUN_SECCOMP_DIR); | ||
213 | (void) rv; | ||
214 | printf("Active seccomp files:\n"); | ||
215 | rv = system("cat " RUN_SECCOMP_LIST); | ||
216 | (void) rv; | ||
217 | #ifdef HAVE_GCOV | ||
218 | __gcov_flush(); | ||
219 | #endif | ||
220 | _exit(0); | ||
221 | } | ||
222 | waitpid(child, NULL, 0); | ||
223 | } | ||
224 | #endif | ||
225 | |||
226 | static void sandbox_if_up(Bridge *br) { | 214 | static void sandbox_if_up(Bridge *br) { |
227 | assert(br); | 215 | assert(br); |
228 | if (!br->configured) | 216 | if (!br->configured) |
@@ -666,7 +654,8 @@ int sandbox(void* sandbox_arg) { | |||
666 | // ... and mount a tmpfs on top of /run/firejail/mnt directory | 654 | // ... and mount a tmpfs on top of /run/firejail/mnt directory |
667 | preproc_mount_mnt_dir(); | 655 | preproc_mount_mnt_dir(); |
668 | // bind-mount firejail binaries and helper programs | 656 | // bind-mount firejail binaries and helper programs |
669 | if (mount(LIBDIR "/firejail", RUN_FIREJAIL_LIB_DIR, "none", MS_BIND, NULL) < 0) | 657 | if (mount(LIBDIR "/firejail", RUN_FIREJAIL_LIB_DIR, NULL, MS_BIND, NULL) < 0 || |
658 | mount(NULL, RUN_FIREJAIL_LIB_DIR, NULL, MS_RDONLY|MS_NOSUID|MS_NODEV|MS_BIND|MS_REMOUNT, NULL) < 0) | ||
670 | errExit("mounting " RUN_FIREJAIL_LIB_DIR); | 659 | errExit("mounting " RUN_FIREJAIL_LIB_DIR); |
671 | 660 | ||
672 | //**************************** | 661 | //**************************** |
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c index cf3d3aeed..a92d62940 100644 --- a/src/firejail/sbox.c +++ b/src/firejail/sbox.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #define O_PATH 010000000 | 31 | #define O_PATH 010000000 |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | static int sbox_do_exec_v(unsigned filtermask, char * const arg[]) { | 34 | static int __attribute__((noreturn)) sbox_do_exec_v(unsigned filtermask, char * const arg[]) { |
35 | // build a new, clean environment | 35 | // build a new, clean environment |
36 | int env_index = 0; | 36 | int env_index = 0; |
37 | char *new_environment[256] = { NULL }; | 37 | char *new_environment[256] = { NULL }; |
diff --git a/src/firejail/shutdown.c b/src/firejail/shutdown.c index a7d0b2fbe..7e9628007 100644 --- a/src/firejail/shutdown.c +++ b/src/firejail/shutdown.c | |||
@@ -63,7 +63,9 @@ void shut(pid_t pid) { | |||
63 | sleep(1); | 63 | sleep(1); |
64 | monsec--; | 64 | monsec--; |
65 | 65 | ||
66 | EUID_ROOT(); | ||
66 | FILE *fp = fopen(monfile, "r"); | 67 | FILE *fp = fopen(monfile, "r"); |
68 | EUID_USER(); | ||
67 | if (!fp) { | 69 | if (!fp) { |
68 | killdone = 1; | 70 | killdone = 1; |
69 | break; | 71 | break; |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 4ab464289..2390706f2 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -47,6 +47,9 @@ static char *usage_str = | |||
47 | " --caps.drop=capability,capability - blacklist capabilities filter.\n" | 47 | " --caps.drop=capability,capability - blacklist capabilities filter.\n" |
48 | " --caps.keep=capability,capability - whitelist capabilities filter.\n" | 48 | " --caps.keep=capability,capability - whitelist capabilities filter.\n" |
49 | " --caps.print=name|pid - print the caps filter.\n" | 49 | " --caps.print=name|pid - print the caps filter.\n" |
50 | #ifdef HAVE_FILE_TRANSFER | ||
51 | " --cat=name|pid filename - print content of file from sandbox container.\n" | ||
52 | #endif | ||
50 | " --cgroup=tasks-file - place the sandbox in the specified control group.\n" | 53 | " --cgroup=tasks-file - place the sandbox in the specified control group.\n" |
51 | #ifdef HAVE_CHROOT | 54 | #ifdef HAVE_CHROOT |
52 | " --chroot=dirname - chroot into directory.\n" | 55 | " --chroot=dirname - chroot into directory.\n" |
@@ -224,7 +227,8 @@ static char *usage_str = | |||
224 | " --seccomp.print=name|pid - print the seccomp filter for the sandbox\n" | 227 | " --seccomp.print=name|pid - print the seccomp filter for the sandbox\n" |
225 | "\tidentified by name or PID.\n" | 228 | "\tidentified by name or PID.\n" |
226 | " --seccomp.32[.drop,.keep][=syscall] - like above but for 32 bit architecture.\n" | 229 | " --seccomp.32[.drop,.keep][=syscall] - like above but for 32 bit architecture.\n" |
227 | " --seccomp-error-action=errno|kill - change error code or kill process.\n" | 230 | " --seccomp-error-action=errno|kill|log - change error code, kill process\n" |
231 | "\tor log the attempt.\n" | ||
228 | #endif | 232 | #endif |
229 | " --shell=none - run the program directly without a user shell.\n" | 233 | " --shell=none - run the program directly without a user shell.\n" |
230 | " --shell=program - set default user shell.\n" | 234 | " --shell=program - set default user shell.\n" |
diff --git a/src/firejail/x11.c b/src/firejail/x11.c index 1ecb688af..e10abad4e 100644 --- a/src/firejail/x11.c +++ b/src/firejail/x11.c | |||
@@ -682,7 +682,7 @@ static char * get_title_arg_str() { | |||
682 | } | 682 | } |
683 | 683 | ||
684 | 684 | ||
685 | void x11_start_xpra_old(int argc, char **argv, int display, char *display_str) { | 685 | static void __attribute__((noreturn)) x11_start_xpra_old(int argc, char **argv, int display, char *display_str) { |
686 | EUID_ASSERT(); | 686 | EUID_ASSERT(); |
687 | int i; | 687 | int i; |
688 | struct stat s; | 688 | struct stat s; |
@@ -921,7 +921,7 @@ void x11_start_xpra_old(int argc, char **argv, int display, char *display_str) { | |||
921 | } | 921 | } |
922 | 922 | ||
923 | 923 | ||
924 | void x11_start_xpra_new(int argc, char **argv, char *display_str) { | 924 | static void __attribute__((noreturn)) x11_start_xpra_new(int argc, char **argv, char *display_str) { |
925 | EUID_ASSERT(); | 925 | EUID_ASSERT(); |
926 | int i; | 926 | int i; |
927 | pid_t server = 0; | 927 | pid_t server = 0; |
diff --git a/src/firemon/firemon.h b/src/firemon/firemon.h index 7a55a64fb..3fba486eb 100644 --- a/src/firemon/firemon.h +++ b/src/firemon/firemon.h | |||
@@ -46,13 +46,13 @@ void firemon_sleep(int st); | |||
46 | 46 | ||
47 | 47 | ||
48 | // procevent.c | 48 | // procevent.c |
49 | void procevent(pid_t pid); | 49 | void procevent(pid_t pid) __attribute__((noreturn)); |
50 | 50 | ||
51 | // usage.c | 51 | // usage.c |
52 | void usage(void); | 52 | void usage(void); |
53 | 53 | ||
54 | // top.c | 54 | // top.c |
55 | void top(void); | 55 | void top(void) __attribute__((noreturn)); |
56 | 56 | ||
57 | // list.c | 57 | // list.c |
58 | void list(void); | 58 | void list(void); |
@@ -82,7 +82,7 @@ void cgroup(pid_t pid, int print_procs); | |||
82 | void tree(pid_t pid); | 82 | void tree(pid_t pid); |
83 | 83 | ||
84 | // netstats.c | 84 | // netstats.c |
85 | void netstats(void); | 85 | void netstats(void) __attribute__((noreturn)); |
86 | 86 | ||
87 | // x11.c | 87 | // x11.c |
88 | void x11(pid_t pid, int print_procs); | 88 | void x11(pid_t pid, int print_procs); |
diff --git a/src/firemon/procevent.c b/src/firemon/procevent.c index 7dd08444e..45964d3a2 100644 --- a/src/firemon/procevent.c +++ b/src/firemon/procevent.c | |||
@@ -220,7 +220,7 @@ errexit: | |||
220 | } | 220 | } |
221 | 221 | ||
222 | 222 | ||
223 | static int procevent_monitor(const int sock, pid_t mypid) { | 223 | static void __attribute__((noreturn)) procevent_monitor(const int sock, pid_t mypid) { |
224 | ssize_t len; | 224 | ssize_t len; |
225 | struct nlmsghdr *nlmsghdr; | 225 | struct nlmsghdr *nlmsghdr; |
226 | 226 | ||
@@ -246,8 +246,7 @@ static int procevent_monitor(const int sock, pid_t mypid) { | |||
246 | 246 | ||
247 | int rv = select(max, &readfds, NULL, NULL, &tv); | 247 | int rv = select(max, &readfds, NULL, NULL, &tv); |
248 | if (rv == -1) { | 248 | if (rv == -1) { |
249 | fprintf(stderr, "recv: %s\n", strerror(errno)); | 249 | errExit("recv"); |
250 | return -1; | ||
251 | } | 250 | } |
252 | 251 | ||
253 | // timeout | 252 | // timeout |
@@ -259,7 +258,7 @@ static int procevent_monitor(const int sock, pid_t mypid) { | |||
259 | 258 | ||
260 | 259 | ||
261 | if ((len = recv(sock, buf, sizeof(buf), 0)) == 0) | 260 | if ((len = recv(sock, buf, sizeof(buf), 0)) == 0) |
262 | return 0; | 261 | exit(0); |
263 | if (len == -1) { | 262 | if (len == -1) { |
264 | if (errno == EINTR) | 263 | if (errno == EINTR) |
265 | continue; | 264 | continue; |
@@ -271,7 +270,7 @@ static int procevent_monitor(const int sock, pid_t mypid) { | |||
271 | } | 270 | } |
272 | else { | 271 | else { |
273 | fprintf(stderr,"Error: rx socket recv call, errno %d, %s\n", errno, strerror(errno)); | 272 | fprintf(stderr,"Error: rx socket recv call, errno %d, %s\n", errno, strerror(errno)); |
274 | return -1; | 273 | exit(1); |
275 | } | 274 | } |
276 | } | 275 | } |
277 | 276 | ||
@@ -497,7 +496,7 @@ static int procevent_monitor(const int sock, pid_t mypid) { | |||
497 | exit(0); | 496 | exit(0); |
498 | } | 497 | } |
499 | } | 498 | } |
500 | return 0; | 499 | __builtin_unreachable(); |
501 | } | 500 | } |
502 | 501 | ||
503 | void procevent(pid_t pid) { | 502 | void procevent(pid_t pid) { |
@@ -515,6 +514,4 @@ void procevent(pid_t pid) { | |||
515 | } | 514 | } |
516 | 515 | ||
517 | procevent_monitor(sock, pid); // it will never return from here | 516 | procevent_monitor(sock, pid); // it will never return from here |
518 | assert(0); | ||
519 | close(sock); // quiet static analyzers | ||
520 | } | 517 | } |
diff --git a/src/fseccomp/main.c b/src/fseccomp/main.c index 13eb3dfe7..f505ca0f3 100644 --- a/src/fseccomp/main.c +++ b/src/fseccomp/main.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include "fseccomp.h" | 20 | #include "fseccomp.h" |
21 | #include "../include/seccomp.h" | 21 | #include "../include/seccomp.h" |
22 | int arg_quiet = 0; | 22 | int arg_quiet = 0; |
23 | int arg_seccomp_error_action = EPERM; // error action: errno or kill | 23 | int arg_seccomp_error_action = EPERM; // error action: errno, log or kill |
24 | 24 | ||
25 | static void usage(void) { | 25 | static void usage(void) { |
26 | printf("Usage:\n"); | 26 | printf("Usage:\n"); |
@@ -83,6 +83,8 @@ printf("\n"); | |||
83 | if (error_action) { | 83 | if (error_action) { |
84 | if (strcmp(error_action, "kill") == 0) | 84 | if (strcmp(error_action, "kill") == 0) |
85 | arg_seccomp_error_action = SECCOMP_RET_KILL; | 85 | arg_seccomp_error_action = SECCOMP_RET_KILL; |
86 | else if (strcmp(error_action, "log") == 0) | ||
87 | arg_seccomp_error_action = SECCOMP_RET_LOG; | ||
86 | else { | 88 | else { |
87 | arg_seccomp_error_action = errno_find_name(error_action); | 89 | arg_seccomp_error_action = errno_find_name(error_action); |
88 | if (arg_seccomp_error_action == -1) | 90 | if (arg_seccomp_error_action == -1) |
diff --git a/src/include/seccomp.h b/src/include/seccomp.h index 50920ce3a..29b858c70 100644 --- a/src/include/seccomp.h +++ b/src/include/seccomp.h | |||
@@ -274,7 +274,7 @@ struct seccomp_data { | |||
274 | #define RETURN_ERRNO(nr) \ | 274 | #define RETURN_ERRNO(nr) \ |
275 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO | nr) | 275 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO | nr) |
276 | 276 | ||
277 | extern int arg_seccomp_error_action; // error action: errno or kill | 277 | extern int arg_seccomp_error_action; // error action: errno, log or kill |
278 | #define KILL_OR_RETURN_ERRNO \ | 278 | #define KILL_OR_RETURN_ERRNO \ |
279 | BPF_STMT(BPF_RET+BPF_K, arg_seccomp_error_action) | 279 | BPF_STMT(BPF_RET+BPF_K, arg_seccomp_error_action) |
280 | 280 | ||
diff --git a/src/include/syscall.h b/src/include/syscall.h index 89b54170e..489da0600 100644 --- a/src/include/syscall.h +++ b/src/include/syscall.h | |||
@@ -32,7 +32,7 @@ void filter_add_blacklist_override(int fd, int syscall, int arg, void *ptrarg, b | |||
32 | // errno.c | 32 | // errno.c |
33 | void errno_print(void); | 33 | void errno_print(void); |
34 | int errno_find_name(const char *name); | 34 | int errno_find_name(const char *name); |
35 | char *errno_find_nr(int nr); | 35 | const char *errno_find_nr(int nr); |
36 | 36 | ||
37 | // syscall.c | 37 | // syscall.c |
38 | void syscall_print(void); | 38 | void syscall_print(void); |
diff --git a/src/lib/errno.c b/src/lib/errno.c index d38c197ad..881c3b27e 100644 --- a/src/lib/errno.c +++ b/src/lib/errno.c | |||
@@ -183,7 +183,7 @@ int errno_find_name(const char *name) { | |||
183 | return -1; | 183 | return -1; |
184 | } | 184 | } |
185 | 185 | ||
186 | char *errno_find_nr(int nr) { | 186 | const char *errno_find_nr(int nr) { |
187 | int i; | 187 | int i; |
188 | int elems = sizeof(errnolist) / sizeof(errnolist[0]); | 188 | int elems = sizeof(errnolist) / sizeof(errnolist[0]); |
189 | for (i = 0; i < elems; i++) { | 189 | for (i = 0; i < elems; i++) { |
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index 7b5653942..0784e7fd7 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt | |||
@@ -433,8 +433,10 @@ Enable seccomp filter and whitelist the system calls in the list. | |||
433 | \fBseccomp.32.keep syscall,syscall,syscall | 433 | \fBseccomp.32.keep syscall,syscall,syscall |
434 | Enable seccomp filter and whitelist the system calls in the list for 32 bit system calls on a 64 bit architecture system. | 434 | Enable seccomp filter and whitelist the system calls in the list for 32 bit system calls on a 64 bit architecture system. |
435 | .TP | 435 | .TP |
436 | \fBseccomp-error-action kill | ERRNO | 436 | \fBseccomp-error-action kill | log | ERRNO |
437 | Return a different error instead of EPERM to the process or kill it when an attempt is made to call a blocked system call. | 437 | Return a different error instead of EPERM to the process, kill it when |
438 | an attempt is made to call a blocked system call, or allow but log the | ||
439 | attempt. | ||
438 | .TP | 440 | .TP |
439 | \fBx11 | 441 | \fBx11 |
440 | Enable X11 sandboxing. | 442 | Enable X11 sandboxing. |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 69cd4a7bc..3b7ba4e3d 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -273,6 +273,10 @@ $ firejail \-\-list | |||
273 | $ firejail \-\-caps.print=3272 | 273 | $ firejail \-\-caps.print=3272 |
274 | 274 | ||
275 | .TP | 275 | .TP |
276 | \fB\-\-cat=name|pid filename | ||
277 | Print content of file from sandbox container, see FILE TRANSFER section for more details. | ||
278 | |||
279 | .TP | ||
276 | \fB\-\-cgroup=tasks-file | 280 | \fB\-\-cgroup=tasks-file |
277 | Place the sandbox in the specified control group. tasks-file is the full path of cgroup tasks file. | 281 | Place the sandbox in the specified control group. tasks-file is the full path of cgroup tasks file. |
278 | .br | 282 | .br |
@@ -344,7 +348,7 @@ $ firejail --dbus-system=filter --dbus-system.log --dbus-log=dbus.txt | |||
344 | 348 | ||
345 | .TP | 349 | .TP |
346 | \fB\-\-dbus-system=filter|none | 350 | \fB\-\-dbus-system=filter|none |
347 | Set system DBus sandboxing policy. | 351 | Set system DBus sandboxing policy. |
348 | .br | 352 | .br |
349 | 353 | ||
350 | .br | 354 | .br |
@@ -1059,7 +1063,7 @@ that are both writable and executable, to change mappings to be | |||
1059 | executable, or to create executable shared memory. The filter examines | 1063 | executable, or to create executable shared memory. The filter examines |
1060 | the arguments of mmap, mmap2, mprotect, pkey_mprotect, memfd_create | 1064 | the arguments of mmap, mmap2, mprotect, pkey_mprotect, memfd_create |
1061 | and shmat system calls and returns error EPERM to the process (or | 1065 | and shmat system calls and returns error EPERM to the process (or |
1062 | kills it, see \-\-seccomp-error-action below) if necessary. | 1066 | kills it or log the attempt, see \-\-seccomp-error-action below) if necessary. |
1063 | .br | 1067 | .br |
1064 | 1068 | ||
1065 | .br | 1069 | .br |
@@ -2122,8 +2126,8 @@ Instead of dropping the syscall by returning EPERM, another error | |||
2122 | number can be returned using \fBsyscall:errno\fR syntax. This can be | 2126 | number can be returned using \fBsyscall:errno\fR syntax. This can be |
2123 | also changed globally with \-\-seccomp-error-action or | 2127 | also changed globally with \-\-seccomp-error-action or |
2124 | in /etc/firejail/firejail.config file. The process can also be killed | 2128 | in /etc/firejail/firejail.config file. The process can also be killed |
2125 | by using \fBsyscall:kill\fR syntax. | 2129 | by using \fBsyscall:kill\fR syntax, or the attempt may be logged with |
2126 | 2130 | \fBsyscall:log\fR. | |
2127 | .br | 2131 | .br |
2128 | 2132 | ||
2129 | .br | 2133 | .br |
@@ -2193,7 +2197,8 @@ Instead of dropping the syscall by returning EPERM, another error | |||
2193 | number can be returned using \fBsyscall:errno\fR syntax. This can be | 2197 | number can be returned using \fBsyscall:errno\fR syntax. This can be |
2194 | also changed globally with \-\-seccomp-error-action or | 2198 | also changed globally with \-\-seccomp-error-action or |
2195 | in /etc/firejail/firejail.config file. The process can also be killed | 2199 | in /etc/firejail/firejail.config file. The process can also be killed |
2196 | by using \fBsyscall:kill\fR syntax. | 2200 | by using \fBsyscall:kill\fR syntax, or the attempt may be logged with |
2201 | \fBsyscall:log\fR. | ||
2197 | .br | 2202 | .br |
2198 | 2203 | ||
2199 | .br | 2204 | .br |
@@ -2402,7 +2407,8 @@ By default, if a seccomp filter blocks a system call, the process gets | |||
2402 | EPERM as the error. With \-\-seccomp-error-action=error, another error | 2407 | EPERM as the error. With \-\-seccomp-error-action=error, another error |
2403 | number can be returned, for example ENOSYS or EACCES. The process can | 2408 | number can be returned, for example ENOSYS or EACCES. The process can |
2404 | also be killed (like in versions <0.9.63 of Firejail) by using | 2409 | also be killed (like in versions <0.9.63 of Firejail) by using |
2405 | \-\-seccomp-error-action=kill syntax. Not killing the process weakens | 2410 | \-\-seccomp-error-action=kill syntax, or the attempt may be logged |
2411 | with \-\-seccomp-error-action=log. Not killing the process weakens | ||
2406 | Firejail slightly when trying to contain intrusion, but it may also | 2412 | Firejail slightly when trying to contain intrusion, but it may also |
2407 | allow tighter filters if the only alternative is to allow a system | 2413 | allow tighter filters if the only alternative is to allow a system |
2408 | call. | 2414 | call. |
@@ -3029,6 +3035,12 @@ These features allow the user to inspect the filesystem container of an existing | |||
3029 | and transfer files between the container and the host filesystem. | 3035 | and transfer files between the container and the host filesystem. |
3030 | 3036 | ||
3031 | .TP | 3037 | .TP |
3038 | \fB\-\-cat=name|pid filename | ||
3039 | Write content of a container file to standard out. The container is specified by name or PID. | ||
3040 | If standard out is a terminal, all ASCII control characters except new line and horizontal tab | ||
3041 | are replaced. | ||
3042 | |||
3043 | .TP | ||
3032 | \fB\-\-get=name|pid filename | 3044 | \fB\-\-get=name|pid filename |
3033 | Retrieve the container file and store it on the host in the current working directory. | 3045 | Retrieve the container file and store it on the host in the current working directory. |
3034 | The container is specified by name or PID. | 3046 | The container is specified by name or PID. |
@@ -3072,6 +3084,10 @@ $ firejail \-\-get=mybrowser ~/Downloads/xpra-clipboard.png | |||
3072 | $ firejail \-\-put=mybrowser xpra-clipboard.png ~/Downloads/xpra-clipboard.png | 3084 | $ firejail \-\-put=mybrowser xpra-clipboard.png ~/Downloads/xpra-clipboard.png |
3073 | .br | 3085 | .br |
3074 | 3086 | ||
3087 | .br | ||
3088 | $ firejail \-\-cat=mybrowser ~/.bashrc | ||
3089 | .br | ||
3090 | |||
3075 | .SH MONITORING | 3091 | .SH MONITORING |
3076 | Option \-\-list prints a list of all sandboxes. The format | 3092 | Option \-\-list prints a list of all sandboxes. The format |
3077 | for each process entry is as follows: | 3093 | for each process entry is as follows: |
@@ -3259,7 +3275,7 @@ Homepage: https://firejail.wordpress.com | |||
3259 | \&\flfirejail-profile\fR\|(5), | 3275 | \&\flfirejail-profile\fR\|(5), |
3260 | \&\flfirejail-login\fR\|(5), | 3276 | \&\flfirejail-login\fR\|(5), |
3261 | \&\flfirejail-users\fR\|(5), | 3277 | \&\flfirejail-users\fR\|(5), |
3262 | .UR https://github.com/netblue30/firejail/wiki | 3278 | .UR https://github.com/netblue30/firejail/wiki |
3263 | .UE , | 3279 | .UE , |
3264 | .UR https://github.com/netblue30/firejail | 3280 | .UR https://github.com/netblue30/firejail |
3265 | .UE | 3281 | .UE |
diff --git a/test/environment/rlimit-profile.exp b/test/environment/rlimit-profile.exp index 721e2196e..63b01a38c 100755 --- a/test/environment/rlimit-profile.exp +++ b/test/environment/rlimit-profile.exp | |||
@@ -30,7 +30,7 @@ expect { | |||
30 | } | 30 | } |
31 | expect { | 31 | expect { |
32 | timeout {puts "TESTING ERROR 1.4\n";exit} | 32 | timeout {puts "TESTING ERROR 1.4\n";exit} |
33 | "Max address space 123456789012 123456789012" | 33 | "Max address space 1234567890 1234567890" |
34 | } | 34 | } |
35 | expect { | 35 | expect { |
36 | timeout {puts "TESTING ERROR 1.5\n";exit} | 36 | timeout {puts "TESTING ERROR 1.5\n";exit} |
diff --git a/test/environment/rlimit.exp b/test/environment/rlimit.exp index 757faf1f9..c80f2857c 100755 --- a/test/environment/rlimit.exp +++ b/test/environment/rlimit.exp | |||
@@ -8,7 +8,7 @@ cd /home | |||
8 | spawn $env(SHELL) | 8 | spawn $env(SHELL) |
9 | match_max 100000 | 9 | match_max 100000 |
10 | 10 | ||
11 | send -- "firejail --rlimit-fsize=1024 --rlimit-nproc=1000 --rlimit-nofile=500 --rlimit-sigpending=200 --rlimit-as=123456789012\r" | 11 | send -- "firejail --rlimit-fsize=1024 --rlimit-nproc=1000 --rlimit-nofile=500 --rlimit-sigpending=200 --rlimit-as=1234567890\r" |
12 | expect { | 12 | expect { |
13 | timeout {puts "TESTING ERROR 0\n";exit} | 13 | timeout {puts "TESTING ERROR 0\n";exit} |
14 | "Child process initialized" | 14 | "Child process initialized" |
@@ -30,7 +30,7 @@ expect { | |||
30 | } | 30 | } |
31 | expect { | 31 | expect { |
32 | timeout {puts "TESTING ERROR 1.4\n";exit} | 32 | timeout {puts "TESTING ERROR 1.4\n";exit} |
33 | "Max address space 123456789012 123456789012" | 33 | "Max address space 1234567890 1234567890" |
34 | } | 34 | } |
35 | expect { | 35 | expect { |
36 | timeout {puts "TESTING ERROR 1.5\n";exit} | 36 | timeout {puts "TESTING ERROR 1.5\n";exit} |
diff --git a/test/environment/rlimit.profile b/test/environment/rlimit.profile index a569edc6d..2f1134e6c 100644 --- a/test/environment/rlimit.profile +++ b/test/environment/rlimit.profile | |||
@@ -2,4 +2,4 @@ rlimit-fsize 1024 | |||
2 | rlimit-nproc 1000 | 2 | rlimit-nproc 1000 |
3 | rlimit-nofile 500 | 3 | rlimit-nofile 500 |
4 | rlimit-sigpending 200 | 4 | rlimit-sigpending 200 |
5 | rlimit-as 123456789012 | 5 | rlimit-as 1234567890 |
diff --git a/test/fs/private-lib.exp b/test/fs/private-lib.exp index ed04de1f9..574ca7ab4 100755 --- a/test/fs/private-lib.exp +++ b/test/fs/private-lib.exp | |||
@@ -30,8 +30,8 @@ after 100 | |||
30 | send -- "cd /lib; find .\r" | 30 | send -- "cd /lib; find .\r" |
31 | expect { | 31 | expect { |
32 | timeout {puts "TESTING ERROR 5\n";exit} | 32 | timeout {puts "TESTING ERROR 5\n";exit} |
33 | "modules" {puts "TESTING ERROR 6\n";exit} | 33 | "./modules" {puts "TESTING ERROR 6\n";exit} |
34 | "firmware" {puts "TESTING ERROR 7\n";exit} | 34 | "./firmware" {puts "TESTING ERROR 7\n";exit} |
35 | "libc.so" | 35 | "libc.so" |
36 | } | 36 | } |
37 | after 100 | 37 | after 100 |