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