aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README12
-rw-r--r--README.md26
-rw-r--r--RELNOTES15
-rw-r--r--etc/Cryptocat.profile2
-rw-r--r--etc/disable-common.inc24
-rw-r--r--etc/disable-programs.inc9
-rw-r--r--etc/gnome-mplayer.profile2
-rw-r--r--etc/login.users6
-rw-r--r--etc/start-tor-browser.profile2
-rw-r--r--etc/uudeview.profile2
-rw-r--r--etc/uzbl-browser.profile29
-rw-r--r--etc/vlc.profile2
-rw-r--r--etc/xmms.profile18
-rw-r--r--platform/debian/conffiles2
-rw-r--r--src/bash_completion/firejail.bash_completion4
-rw-r--r--src/firejail/firejail.h12
-rw-r--r--src/firejail/fs.c21
-rw-r--r--src/firejail/fs_etc.c4
-rw-r--r--src/firejail/fs_hostname.c51
-rw-r--r--src/firejail/main.c19
-rw-r--r--src/firejail/netns.c114
-rw-r--r--src/firejail/profile.c14
-rw-r--r--src/firejail/sandbox.c62
-rw-r--r--src/firejail/usage.c2
-rw-r--r--src/firejail/util.c91
-rw-r--r--src/man/firejail-profile.txt11
-rw-r--r--src/man/firejail.txt30
27 files changed, 513 insertions, 73 deletions
diff --git a/README b/README
index 67d9a555f..687eab4e0 100644
--- a/README
+++ b/README
@@ -83,6 +83,7 @@ Fred-Barclay (https://github.com/Fred-Barclay)
83 - added xed and pluma profiles 83 - added xed and pluma profiles
84 - added Cryptocat profile 84 - added Cryptocat profile
85 - added wireshark profile 85 - added wireshark profile
86 - uudeview profile fix
86valoq (https://github.com/valoq) 87valoq (https://github.com/valoq)
87 - lots of profile fixes 88 - lots of profile fixes
88 - added support for /srv in --whitelist feature 89 - added support for /srv in --whitelist feature
@@ -97,6 +98,14 @@ valoq (https://github.com/valoq)
97 - added skanlite, ssh-agent, transmission-cli, tracker, transmission-show, w3m, xfburn, xpra profiles 98 - added skanlite, ssh-agent, transmission-cli, tracker, transmission-show, w3m, xfburn, xpra profiles
98 - added wget profile 99 - added wget profile
99 - disable gnupg and systemd directories under /run/user 100 - disable gnupg and systemd directories under /run/user
101Igor Bukanov (https://github.com/ibukanov)
102 - found/fiixed privilege escalation in --hosts-file option
103Cat (https://github.com/ecat3)
104 - prevent tmux connecting to an existing session
105Zack Weinberg (https://github.com/zackw)
106 - sdded support for joining a persistent, named network namespace
107GSI (https://github.com/GSI)
108 - added Uzbl browser profile
100Mike Frysinger (vapier@gentoo.org) 109Mike Frysinger (vapier@gentoo.org)
101 - Gentoo compile patch 110 - Gentoo compile patch
102Jericho (https://github.com/attritionorg) 111Jericho (https://github.com/attritionorg)
@@ -113,6 +122,7 @@ thewisenerd (https://github.com/thewisenerd)
113SYN-cook (https://github.com/SYN-cook) 122SYN-cook (https://github.com/SYN-cook)
114 - keepass/keepassx browser fixes 123 - keepass/keepassx browser fixes
115 - disable-common.inc fixes 124 - disable-common.inc fixes
125 - blacklist GNOME keyring and Konqueror
116thewisenerd (https://github.com/thewisenerd) 126thewisenerd (https://github.com/thewisenerd)
117 - appimage: pass commandline arguments 127 - appimage: pass commandline arguments
118KOLANICH (https://github.com/KOLANICH) 128KOLANICH (https://github.com/KOLANICH)
@@ -224,6 +234,8 @@ KellerFuchs (https://github.com/KellerFuchs)
224 - disable-common.inc additions 234 - disable-common.inc additions
225 - make mutt and msmtp's rc files read-only 235 - make mutt and msmtp's rc files read-only
226 - added support for .local profile files in /etc/firejail 236 - added support for .local profile files in /etc/firejail
237 - fixed Cryptocat profile
238 - make ~/.local read-only
227ValdikSS (https://github.com/ValdikSS) 239ValdikSS (https://github.com/ValdikSS)
228 - Psi+, Corebird, Konversation profiles 240 - Psi+, Corebird, Konversation profiles
229 - various profile fixes 241 - various profile fixes
diff --git a/README.md b/README.md
index f4fa7282f..07de69e42 100644
--- a/README.md
+++ b/README.md
@@ -51,7 +51,9 @@ Use this issue to request new profiles: https://github.com/netblue30/firejail/is
51````` 51`````
52 52
53````` 53`````
54## AppImage type 2 support 54## AppImage
55
56Added AppImage type 2 support, and support for passing command line arguments to appimages.
55````` 57`````
56 58
57````` 59`````
@@ -75,9 +77,9 @@ Use this issue to request new profiles: https://github.com/netblue30/firejail/is
75 Example: 77 Example:
76 # firejail --private-srv=www /etc/init.d/apache2 start 78 # firejail --private-srv=www /etc/init.d/apache2 start
77 79
78 --machine-id 80 --machine-id
79 Preserve id number in /etc/machine-id file. By default a new 81 Spoof id number in /etc/machine-id file - a new random id is
80 random id is generated inside the sandbox. 82 generated inside the sandbox.
81 83
82 Example: 84 Example:
83 $ firejail --machine-id 85 $ firejail --machine-id
@@ -89,7 +91,21 @@ Use this issue to request new profiles: https://github.com/netblue30/firejail/is
89 Example: 91 Example:
90 $ firejail --allow-private-blacklist --private=~/priv-dir 92 $ firejail --allow-private-blacklist --private=~/priv-dir
91 --blacklist=~/.mozilla 93 --blacklist=~/.mozilla
94
95 --hosts-file=file
96 Use file as /etc/hosts.
97
98 Example:
99 $ firejail --hosts-file=~/myhosts firefox
92 100
101 --writable-var-log
102 Use the real /var/log directory, not a clone. By default, a
103 tmpfs is mounted on top of /var/log directory, and a skeleton
104 filesystem is created based on the original /var/log.
105
106 Example:
107 $ sudo firejail --writable-var-log
108
93````` 109`````
94## New Profiles 110## New Profiles
95xiphos, Tor Browser Bundle, display (imagemagik), Wire, mumble, zoom, Guayadeque, qemu, keypass2, 111xiphos, Tor Browser Bundle, display (imagemagik), Wire, mumble, zoom, Guayadeque, qemu, keypass2,
@@ -98,5 +114,5 @@ gjs, gnome-books, gnome-clocks, gnome-documents, gnome-maps, gnome-music, gnome-
98goobox, gpa, gpg, gpg-agent, highlight, img2txt, k3b, kate, lynx, mediainfo, nautilus, odt2txt, pdftotext, 114goobox, gpa, gpg, gpg-agent, highlight, img2txt, k3b, kate, lynx, mediainfo, nautilus, odt2txt, pdftotext,
99simple-scan, skanlite, ssh-agent, tracker, transmission-cli, transmission-show, w3m, xfburn, xpra, wget, 115simple-scan, skanlite, ssh-agent, tracker, transmission-cli, transmission-show, w3m, xfburn, xpra, wget,
100xed, pluma, Cryptocat, Bless, Gnome 2048, Gnome Calculator, Gnome Contacts, JD-GUI, Lollypop, MultiMC5, 116xed, pluma, Cryptocat, Bless, Gnome 2048, Gnome Calculator, Gnome Contacts, JD-GUI, Lollypop, MultiMC5,
101PDFSam, Pithos, Xonotic, wireshark, keepassx2, QupZilla, FossaMail 117PDFSam, Pithos, Xonotic, wireshark, keepassx2, QupZilla, FossaMail, Uzbl browser, xmms
102 118
diff --git a/RELNOTES b/RELNOTES
index 7d0bbaf61..16360bc64 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -14,23 +14,26 @@ firejail (0.9.45) baseline; urgency=low
14 * security: split file copying in private option in a separate executable 14 * security: split file copying in private option in a separate executable
15 * security: root exploit found by Sebastian Krahmer (CVE-2017-5180) 15 * security: root exploit found by Sebastian Krahmer (CVE-2017-5180)
16 * feature: disable gnupg and systemd directories under /run/user 16 * feature: disable gnupg and systemd directories under /run/user
17 * feature: allow root user access to /dev/shm (--noblacklist=/dev/shm)
18 * feature: AppImage type 2 support
19 * feature: test coverage (gcov) support 17 * feature: test coverage (gcov) support
18 * feature: allow root user access to /dev/shm (--noblacklist=/dev/shm)
20 * feature: private /opt directory (--private-opt, profile support) 19 * feature: private /opt directory (--private-opt, profile support)
21 * feature: private /srv directory (--private-srv, profile support) 20 * feature: private /srv directory (--private-srv, profile support)
22 * feature: spoof machine-id 21 * feature: spoof machine-id (--machine-id, profile support)
22 * feature: allow blacklists under --private (--allow-private-blacklist, profile support)
23 * feature: user-defined /etc/hosts file (--hosts-file, profile support)
24 * feature: support for the real /var/log directory (--writable-var-log, profile support)
23 * feature: config support for firejail prompt in terminals 25 * feature: config support for firejail prompt in terminals
26 * feature: AppImage type 2 support
24 * feature: pass command line arguments to appimages 27 * feature: pass command line arguments to appimages
25 * feature: --allow-private-blacklist option 28 * feature: allow non-seccomp setup for OverlayFS sandboxes - more work to come
26 * feature: allow non-seccomp setup for OverlayFS sandboxes
27 * feature: added a number o Python scripts for handling sandboxes 29 * feature: added a number o Python scripts for handling sandboxes
28 * feature: allow local customization using .local files under /etc/firejail 30 * feature: allow local customization using .local files under /etc/firejail
29 * new profiles: xiphos, Tor Browser Bundle, display (imagemagik), Wire, 31 * new profiles: xiphos, Tor Browser Bundle, display (imagemagik), Wire,
30 * new profiles: mumble, zoom, Guayadeque, qemu, keypass2, xed, pluma, 32 * new profiles: mumble, zoom, Guayadeque, qemu, keypass2, xed, pluma,
31 * new profiles: Cryptocat, Bless, Gnome 2048, Gnome Calculator, 33 * new profiles: Cryptocat, Bless, Gnome 2048, Gnome Calculator,
32 * new profiles: Gnome Contacts, JD-GUI, Lollypop, MultiMC5, PDFSam, Pithos, 34 * new profiles: Gnome Contacts, JD-GUI, Lollypop, MultiMC5, PDFSam, Pithos,
33 * new profies: Xonotic, wireshark, keepassx2, QupZilla, FossaMail 35 * new profies: Xonotic, wireshark, keepassx2, QupZilla, FossaMail,
36 * new profiles: Uzbl browser
34 * bugfixes 37 * bugfixes
35 -- netblue30 <netblue30@yahoo.com> Sun, 23 Oct 2016 08:00:00 -0500 38 -- netblue30 <netblue30@yahoo.com> Sun, 23 Oct 2016 08:00:00 -0500
36 39
diff --git a/etc/Cryptocat.profile b/etc/Cryptocat.profile
index 3db34c03c..b61b88f68 100644
--- a/etc/Cryptocat.profile
+++ b/etc/Cryptocat.profile
@@ -1,4 +1,4 @@
1# Firejail profile for 1# Firejail profile for Cryptocat
2noblacklist ${HOME}/.config/Cryptocat 2noblacklist ${HOME}/.config/Cryptocat
3 3
4include /etc/firejail/disable-common.inc 4include /etc/firejail/disable-common.inc
diff --git a/etc/disable-common.inc b/etc/disable-common.inc
index 5a281a91f..64a39296e 100644
--- a/etc/disable-common.inc
+++ b/etc/disable-common.inc
@@ -75,12 +75,9 @@ blacklist /etc/profile.d
75blacklist /etc/rc.local 75blacklist /etc/rc.local
76blacklist /etc/anacrontab 76blacklist /etc/anacrontab
77 77
78# General startup files 78# Startup files
79read-only ${HOME}/.xinitrc 79read-only ${HOME}/.xinitrc
80read-only ${HOME}/.xserverrc 80read-only ${HOME}/.xserverrc
81read-only ${HOME}/.profile
82
83# Shell startup files
84read-only ${HOME}/.antigen 81read-only ${HOME}/.antigen
85read-only ${HOME}/.bash_login 82read-only ${HOME}/.bash_login
86read-only ${HOME}/.bashrc 83read-only ${HOME}/.bashrc
@@ -99,6 +96,12 @@ read-only ${HOME}/.tcshrc
99read-only ${HOME}/.cshrc 96read-only ${HOME}/.cshrc
100read-only ${HOME}/.csh_files 97read-only ${HOME}/.csh_files
101read-only ${HOME}/.profile 98read-only ${HOME}/.profile
99read-only ${HOME}/.forward
100read-only ${HOME}/.login
101read-only ${HOME}/.logout
102read-only ${HOME}/.pgpkey
103read-only ${HOME}/.plan
104read-only ${HOME}/.project
102 105
103# Initialization files that allow arbitrary command execution 106# Initialization files that allow arbitrary command execution
104read-only ${HOME}/.caffrc 107read-only ${HOME}/.caffrc
@@ -124,8 +127,16 @@ read-only ${HOME}/.reportbugrc
124read-only ${HOME}/.xmonad 127read-only ${HOME}/.xmonad
125read-only ${HOME}/.xscreensaver 128read-only ${HOME}/.xscreensaver
126 129
127# The user ~/bin directory can override commands such as ls 130# Make directories commonly found in $PATH read-only
128read-only ${HOME}/bin 131read-only ${HOME}/bin
132read-only ${HOME}/.gem
133read-only ${HOME}/.luarocks
134read-only ${HOME}/.npm-packages
135
136# Make the contents of ~/.local read-only,
137# except the commonly-used ~/.local/share
138read-only ${HOME}/.local
139read-write ${HOME}/.local/share
129 140
130# top secret 141# top secret
131blacklist ${HOME}/.ecryptfs 142blacklist ${HOME}/.ecryptfs
@@ -133,6 +144,7 @@ blacklist ${HOME}/.Private
133blacklist ${HOME}/.ssh 144blacklist ${HOME}/.ssh
134blacklist ${HOME}/.cert 145blacklist ${HOME}/.cert
135blacklist ${HOME}/.gnome2/keyrings 146blacklist ${HOME}/.gnome2/keyrings
147blacklist ${HOME}/.local/share/keyrings
136blacklist ${HOME}/.kde4/share/apps/kwallet 148blacklist ${HOME}/.kde4/share/apps/kwallet
137blacklist ${HOME}/.kde/share/apps/kwallet 149blacklist ${HOME}/.kde/share/apps/kwallet
138blacklist ${HOME}/.local/share/kwalletd 150blacklist ${HOME}/.local/share/kwalletd
@@ -202,6 +214,8 @@ blacklist /usr/lib64/virtualbox
202 214
203# prevent lxterminal connecting to an existing lxterminal session 215# prevent lxterminal connecting to an existing lxterminal session
204blacklist /tmp/.lxterminal-socket* 216blacklist /tmp/.lxterminal-socket*
217# prevent tmux connecting to an existing session
218blacklist /tmp/tmux-*
205 219
206# disable terminals running as server resulting in sandbox escape 220# disable terminals running as server resulting in sandbox escape
207blacklist ${PATH}/gnome-terminal 221blacklist ${PATH}/gnome-terminal
diff --git a/etc/disable-programs.inc b/etc/disable-programs.inc
index 96bf1464b..b307978da 100644
--- a/etc/disable-programs.inc
+++ b/etc/disable-programs.inc
@@ -177,8 +177,17 @@ blacklist ${HOME}/.icedove
177blacklist ${HOME}/.inkscape 177blacklist ${HOME}/.inkscape
178blacklist ${HOME}/.jitsi 178blacklist ${HOME}/.jitsi
179blacklist ${HOME}/.kde/share/apps/gwenview 179blacklist ${HOME}/.kde/share/apps/gwenview
180blacklist ${HOME}/.kde/share/apps/kcookiejar
181blacklist ${HOME}/.kde/share/apps/khtml
182blacklist ${HOME}/.kde/share/apps/konqsidebartng
183blacklist ${HOME}/.kde/share/apps/konqueror
180blacklist ${HOME}/.kde/share/apps/okular 184blacklist ${HOME}/.kde/share/apps/okular
181blacklist ${HOME}/.kde/share/config/gwenviewrc 185blacklist ${HOME}/.kde/share/config/gwenviewrc
186blacklist ${HOME}/.kde/share/config/kcookiejarrc
187blacklist ${HOME}/.kde/share/config/khtmlrc
188blacklist ${HOME}/.kde/share/config/konq_history
189blacklist ${HOME}/.kde/share/config/konqsidebartngrc
190blacklist ${HOME}/.kde/share/config/konquerorrc
182blacklist ${HOME}/.kde/share/config/okularpartrc 191blacklist ${HOME}/.kde/share/config/okularpartrc
183blacklist ${HOME}/.kde/share/config/okularrc 192blacklist ${HOME}/.kde/share/config/okularrc
184blacklist ${HOME}/.killingfloor 193blacklist ${HOME}/.killingfloor
diff --git a/etc/gnome-mplayer.profile b/etc/gnome-mplayer.profile
index 488c7e0b8..25d2da085 100644
--- a/etc/gnome-mplayer.profile
+++ b/etc/gnome-mplayer.profile
@@ -12,6 +12,6 @@ protocol unix,inet,inet6
12seccomp 12seccomp
13shell none 13shell none
14 14
15private-bin gnome-mplayer,mplayer 15# private-bin gnome-mplayer,mplayer
16private-dev 16private-dev
17private-tmp 17private-tmp
diff --git a/etc/login.users b/etc/login.users
index bc6ac4b09..81f12c6b1 100644
--- a/etc/login.users
+++ b/etc/login.users
@@ -9,6 +9,12 @@
9# 9#
10# netblue:--net=none --protocol=unix 10# netblue:--net=none --protocol=unix
11# 11#
12# Wildcard patterns are accepted in the user name field:
13#
14# user*: --private
15#
16# The example will do --private for user1, user2, and so on.
17#
12# The extra arguments are inserted into program command line if firejail 18# The extra arguments are inserted into program command line if firejail
13# was started as a login shell. 19# was started as a login shell.
14 20
diff --git a/etc/start-tor-browser.profile b/etc/start-tor-browser.profile
index ee19cee25..16ef754f6 100644
--- a/etc/start-tor-browser.profile
+++ b/etc/start-tor-browser.profile
@@ -14,7 +14,7 @@ seccomp
14shell none 14shell none
15tracelog 15tracelog
16 16
17private-bin bash,grep,sed,tail,env,gpg,id,readlink,dirname,test,mkdir,ln,sed,cp,rm,getconf 17private-bin bash,grep,tail,env,gpg,id,readlink,dirname,test,mkdir,ln,sed,cp,rm,getconf
18private-etc fonts 18private-etc fonts
19private-dev 19private-dev
20private-tmp 20private-tmp
diff --git a/etc/uudeview.profile b/etc/uudeview.profile
index d5b750a13..d4b54067d 100644
--- a/etc/uudeview.profile
+++ b/etc/uudeview.profile
@@ -3,7 +3,6 @@ quiet
3ignore noroot 3ignore noroot
4include /etc/firejail/default.profile 4include /etc/firejail/default.profile
5 5
6blacklist /etc
7 6
8hostname uudeview 7hostname uudeview
9net none 8net none
@@ -13,3 +12,4 @@ tracelog
13 12
14private-bin uudeview 13private-bin uudeview
15private-dev 14private-dev
15private-etc ld.so.preload
diff --git a/etc/uzbl-browser.profile b/etc/uzbl-browser.profile
new file mode 100644
index 000000000..8dc90982e
--- /dev/null
+++ b/etc/uzbl-browser.profile
@@ -0,0 +1,29 @@
1# Firejail profile for uzbl-browser
2
3noblacklist ~/.config/uzbl
4noblacklist ~/.gnupg
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc
8
9caps.drop all
10netfilter
11nonewprivs
12noroot
13protocol unix,inet,inet6
14seccomp
15tracelog
16
17mkdir ~/.config/uzbl
18whitelist ~/.config/uzbl
19mkdir ~/.local/share/uzbl
20whitelist ~/.local/share/uzbl
21
22whitelist ${DOWNLOADS}
23
24mkdir ~/.gnupg
25whitelist ~/.gnupg
26mkdir ~/.password-store
27whitelist ~/.password-store
28
29include /etc/firejail/whitelist-common.inc
diff --git a/etc/vlc.profile b/etc/vlc.profile
index 2fd763f25..df9fcab03 100644
--- a/etc/vlc.profile
+++ b/etc/vlc.profile
@@ -8,7 +8,7 @@ include /etc/firejail/disable-passwdmgr.inc
8 8
9caps.drop all 9caps.drop all
10netfilter 10netfilter
11nogroups 11# nogroups
12nonewprivs 12nonewprivs
13noroot 13noroot
14protocol unix,inet,inet6,netlink 14protocol unix,inet,inet6,netlink
diff --git a/etc/xmms.profile b/etc/xmms.profile
new file mode 100644
index 000000000..0d57f2f90
--- /dev/null
+++ b/etc/xmms.profile
@@ -0,0 +1,18 @@
1# Firejail profile for XMMS
2noblacklist ${HOME}/.xmms
3
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10netfilter
11nonewprivs
12noroot
13protocol unix,inet,inet6
14seccomp
15shell none
16
17private-bin xmms
18private-dev
diff --git a/platform/debian/conffiles b/platform/debian/conffiles
index 56a5c8e7e..61e72583e 100644
--- a/platform/debian/conffiles
+++ b/platform/debian/conffiles
@@ -242,3 +242,5 @@
242/etc/firejail/qupzilla.profile 242/etc/firejail/qupzilla.profile
243/etc/firejail/FossaMail.profile 243/etc/firejail/FossaMail.profile
244/etc/firejail/fossamail.profile 244/etc/firejail/fossamail.profile
245/etc/firejail/uzbl-browser.profile
246/etc/firejail/xmms.profile
diff --git a/src/bash_completion/firejail.bash_completion b/src/bash_completion/firejail.bash_completion
index d3dcd57d0..0f71c74dc 100644
--- a/src/bash_completion/firejail.bash_completion
+++ b/src/bash_completion/firejail.bash_completion
@@ -23,6 +23,10 @@ _firejail()
23 _filedir 23 _filedir
24 return 0 24 return 0
25 ;; 25 ;;
26 --hosts-file)
27 _filedir
28 return 0
29 ;;
26 --chroot) 30 --chroot)
27 _filedir -d 31 _filedir -d
28 return 0 32 return 0
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 722d5c05e..7e5412630 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -213,6 +213,7 @@ typedef struct config_t {
213 // networking 213 // networking
214 char *name; // sandbox name 214 char *name; // sandbox name
215 char *hostname; // host name 215 char *hostname; // host name
216 char *hosts_file; // hosts file to be installed in the sandbox
216 uint32_t defaultgw; // default gateway 217 uint32_t defaultgw; // default gateway
217 Bridge bridge0; 218 Bridge bridge0;
218 Bridge bridge1; 219 Bridge bridge1;
@@ -317,6 +318,7 @@ extern int arg_netfilter; // enable netfilter
317extern int arg_netfilter6; // enable netfilter6 318extern int arg_netfilter6; // enable netfilter6
318extern char *arg_netfilter_file; // netfilter file 319extern char *arg_netfilter_file; // netfilter file
319extern char *arg_netfilter6_file; // netfilter file 320extern char *arg_netfilter6_file; // netfilter file
321extern char *arg_netns; // "ip netns"-created network namespace to use
320extern int arg_doubledash; // double dash 322extern int arg_doubledash; // double dash
321extern int arg_shell_none; // run the program directly without a shell 323extern int arg_shell_none; // run the program directly without a shell
322extern int arg_private_dev; // private dev directory 324extern int arg_private_dev; // private dev directory
@@ -336,6 +338,7 @@ extern int arg_nice; // nice value configured
336extern int arg_ipc; // enable ipc namespace 338extern int arg_ipc; // enable ipc namespace
337extern int arg_writable_etc; // writable etc 339extern int arg_writable_etc; // writable etc
338extern int arg_writable_var; // writable var 340extern int arg_writable_var; // writable var
341extern int arg_writable_var_log; // writable /var/log
339extern int arg_appimage; // appimage 342extern int arg_appimage; // appimage
340extern int arg_audit; // audit 343extern int arg_audit; // audit
341extern char *arg_audit_prog; // audit 344extern char *arg_audit_prog; // audit
@@ -451,6 +454,7 @@ void logargs(int argc, char **argv) ;
451void logerr(const char *msg); 454void logerr(const char *msg);
452int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); 455int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode);
453void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); 456void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode);
457void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode);
454void touch_file_as_user(const char *fname, uid_t uid, gid_t gid, mode_t mode); 458void touch_file_as_user(const char *fname, uid_t uid, gid_t gid, mode_t mode);
455int is_dir(const char *fname); 459int is_dir(const char *fname);
456int is_link(const char *fname); 460int is_link(const char *fname);
@@ -536,6 +540,9 @@ void fs_trace(void);
536// fs_hostname.c 540// fs_hostname.c
537void fs_hostname(const char *hostname); 541void fs_hostname(const char *hostname);
538void fs_resolvconf(void); 542void fs_resolvconf(void);
543char *fs_check_hosts_fiile(const char *fname);
544void fs_store_hosts_file(void);
545void fs_mount_hosts_file(void);
539 546
540// rlimit.c 547// rlimit.c
541void set_rlimits(void); 548void set_rlimits(void);
@@ -560,6 +567,11 @@ void check_netfilter_file(const char *fname);
560void netfilter(const char *fname); 567void netfilter(const char *fname);
561void netfilter6(const char *fname); 568void netfilter6(const char *fname);
562 569
570// netns.c
571void check_netns(const char *nsname);
572void netns(const char *nsname);
573void netns_mounts(const char *nsname);
574
563// bandwidth.c 575// bandwidth.c
564void bandwidth_del_run_file(pid_t pid); 576void bandwidth_del_run_file(pid_t pid);
565void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up); 577void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up);
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 0da4cc111..69b9d77bc 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -20,6 +20,7 @@
20#include "firejail.h" 20#include "firejail.h"
21#include <sys/mount.h> 21#include <sys/mount.h>
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <sys/wait.h>
23#include <linux/limits.h> 24#include <linux/limits.h>
24#include <fnmatch.h> 25#include <fnmatch.h>
25#include <glob.h> 26#include <glob.h>
@@ -681,11 +682,13 @@ void fs_basic_fs(void) {
681 fs_rdonly("/usr"); 682 fs_rdonly("/usr");
682 683
683 // update /var directory in order to support multiple sandboxes running on the same root directory 684 // update /var directory in order to support multiple sandboxes running on the same root directory
684// if (!arg_private_dev)
685// fs_dev_shm();
686 fs_var_lock(); 685 fs_var_lock();
687 fs_var_tmp(); 686 fs_var_tmp();
688 fs_var_log(); 687 if (!arg_writable_var_log)
688 fs_var_log();
689 else
690 fs_rdwr("/var/log");
691
689 fs_var_lib(); 692 fs_var_lib();
690 fs_var_cache(); 693 fs_var_cache();
691 fs_var_utmp(); 694 fs_var_utmp();
@@ -995,7 +998,11 @@ void fs_overlayfs(void) {
995// fs_dev_shm(); 998// fs_dev_shm();
996 fs_var_lock(); 999 fs_var_lock();
997 fs_var_tmp(); 1000 fs_var_tmp();
998 fs_var_log(); 1001 if (!arg_writable_var_log)
1002 fs_var_log();
1003 else
1004 fs_rdwr("/var/log");
1005
999 fs_var_lib(); 1006 fs_var_lib();
1000 fs_var_cache(); 1007 fs_var_cache();
1001 fs_var_utmp(); 1008 fs_var_utmp();
@@ -1225,7 +1232,11 @@ void fs_chroot(const char *rootdir) {
1225// fs_dev_shm(); 1232// fs_dev_shm();
1226 fs_var_lock(); 1233 fs_var_lock();
1227 fs_var_tmp(); 1234 fs_var_tmp();
1228 fs_var_log(); 1235 if (!arg_writable_var_log)
1236 fs_var_log();
1237 else
1238 fs_rdwr("/var/log");
1239
1229 fs_var_lib(); 1240 fs_var_lib();
1230 fs_var_cache(); 1241 fs_var_cache();
1231 fs_var_utmp(); 1242 fs_var_utmp();
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c
index 479383af2..f14e90deb 100644
--- a/src/firejail/fs_etc.c
+++ b/src/firejail/fs_etc.c
@@ -31,8 +31,8 @@ void fs_machineid(void) {
31 uint32_t u32[4]; 31 uint32_t u32[4];
32 } mid; 32 } mid;
33 33
34 // if --machine-id flag is active, do nothing 34 // if --machine-id flag is inactive, do nothing
35 if (arg_machineid) 35 if (arg_machineid == 0)
36 return; 36 return;
37 37
38 // init random number generator 38 // init random number generator
diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c
index b2e1b4a99..3b586b276 100644
--- a/src/firejail/fs_hostname.c
+++ b/src/firejail/fs_hostname.c
@@ -42,7 +42,7 @@ void fs_hostname(const char *hostname) {
42 } 42 }
43 43
44 // create a new /etc/hosts 44 // create a new /etc/hosts
45 if (stat("/etc/hosts", &s) == 0) { 45 if (cfg.hosts_file == NULL && stat("/etc/hosts", &s) == 0) {
46 if (arg_debug) 46 if (arg_debug)
47 printf("Creating a new /etc/hosts file\n"); 47 printf("Creating a new /etc/hosts file\n");
48 // copy /etc/host into our new file, and modify it on the fly 48 // copy /etc/host into our new file, and modify it on the fly
@@ -79,9 +79,7 @@ void fs_hostname(const char *hostname) {
79 fclose(fp2); 79 fclose(fp2);
80 80
81 // bind-mount the file on top of /etc/hostname 81 // bind-mount the file on top of /etc/hostname
82 if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0) 82 fs_mount_hosts_file();
83 errExit("mount bind /etc/hosts");
84 fs_logger("create /etc/hosts");
85 } 83 }
86 return; 84 return;
87 85
@@ -129,4 +127,49 @@ void fs_resolvconf(void) {
129 } 127 }
130} 128}
131 129
130char *fs_check_hosts_fiile(const char *fname) {
131 assert(fname);
132 invalid_filename(fname);
133 char *rv = expand_home(fname, cfg.homedir);
134
135 // no a link
136 if (is_link(rv))
137 goto errexit;
132 138
139 // the user has read access to the file
140 if (access(rv, R_OK))
141 goto errexit;
142
143 return rv;
144errexit:
145 fprintf(stderr, "Error: invalid file %s\n", fname);
146 exit(1);
147}
148
149void fs_store_hosts_file(void) {
150 copy_file_from_user_to_root(cfg.hosts_file, RUN_HOSTS_FILE, 0, 0, 0644); // root needed
151}
152
153void fs_mount_hosts_file(void) {
154 // check /etc/hosts file
155 struct stat s;
156 if (stat("/etc/hosts", &s) == -1)
157 goto errexit;
158 // not a link
159 if (is_link("/etc/hosts"))
160 goto errexit;
161 // owned by root
162 if (s.st_uid != 0)
163 goto errexit;
164
165 // bind-mount the file on top of /etc/hostname
166 if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0)
167 errExit("mount bind /etc/hosts");
168 fs_logger("create /etc/hosts");
169 return;
170
171errexit:
172 fprintf(stderr, "Error: invalid /etc/hosts file\n");
173 exit(1);
174}
175
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 84bf5e8e6..7c6568903 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -85,6 +85,7 @@ int arg_netfilter; // enable netfilter
85int arg_netfilter6; // enable netfilter6 85int arg_netfilter6; // enable netfilter6
86char *arg_netfilter_file = NULL; // netfilter file 86char *arg_netfilter_file = NULL; // netfilter file
87char *arg_netfilter6_file = NULL; // netfilter6 file 87char *arg_netfilter6_file = NULL; // netfilter6 file
88char *arg_netns = NULL; // "ip netns"-created network namespace to use
88int arg_doubledash = 0; // double dash 89int arg_doubledash = 0; // double dash
89int arg_shell_none = 0; // run the program directly without a shell 90int arg_shell_none = 0; // run the program directly without a shell
90int arg_private_dev = 0; // private dev directory 91int arg_private_dev = 0; // private dev directory
@@ -113,7 +114,8 @@ int arg_x11_block = 0; // block X11
113int arg_x11_xorg = 0; // use X11 security extention 114int arg_x11_xorg = 0; // use X11 security extention
114int arg_allusers = 0; // all user home directories visible 115int arg_allusers = 0; // all user home directories visible
115int arg_machineid = 0; // preserve /etc/machine-id 116int arg_machineid = 0; // preserve /etc/machine-id
116int arg_allow_private_blacklist = 0; // blacklist things in private directories 117int arg_allow_private_blacklist = 0; // blacklist things in private directories
118int arg_writable_var_log; // writable /var/log
117 119
118int login_shell = 0; 120int login_shell = 0;
119 121
@@ -1487,6 +1489,9 @@ int main(int argc, char **argv) {
1487 else if (strcmp(argv[i], "--writable-var") == 0) { 1489 else if (strcmp(argv[i], "--writable-var") == 0) {
1488 arg_writable_var = 1; 1490 arg_writable_var = 1;
1489 } 1491 }
1492 else if (strcmp(argv[i], "--writable-var-log") == 0) {
1493 arg_writable_var_log = 1;
1494 }
1490 else if (strcmp(argv[i], "--machine-id") == 0) { 1495 else if (strcmp(argv[i], "--machine-id") == 0) {
1491 arg_machineid = 1; 1496 arg_machineid = 1;
1492 } 1497 }
@@ -1946,6 +1951,9 @@ int main(int argc, char **argv) {
1946 return 1; 1951 return 1;
1947 } 1952 }
1948 } 1953 }
1954
1955 else if (strncmp(argv[i], "--hosts-file=", 13) == 0)
1956 cfg.hosts_file = fs_check_hosts_fiile(argv[i] + 13);
1949 1957
1950#ifdef HAVE_NETWORK 1958#ifdef HAVE_NETWORK
1951 else if (strcmp(argv[i], "--netfilter") == 0) { 1959 else if (strcmp(argv[i], "--netfilter") == 0) {
@@ -1999,6 +2007,15 @@ int main(int argc, char **argv) {
1999 else 2007 else
2000 exit_err_feature("networking"); 2008 exit_err_feature("networking");
2001 } 2009 }
2010
2011 else if (strncmp(argv[i], "--netns=", 8) == 0) {
2012 if (checkcfg(CFG_NETWORK)) {
2013 arg_netns = argv[i] + 8;
2014 check_netns(arg_netns);
2015 }
2016 else
2017 exit_err_feature("networking");
2018 }
2002#endif 2019#endif
2003 //************************************* 2020 //*************************************
2004 // command 2021 // command
diff --git a/src/firejail/netns.c b/src/firejail/netns.c
new file mode 100644
index 000000000..477d56b3d
--- /dev/null
+++ b/src/firejail/netns.c
@@ -0,0 +1,114 @@
1/*
2 * Copyright (C) 2017 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20#include "firejail.h"
21#include <stdio.h>
22#include <string.h>
23#include <errno.h>
24#include <sys/types.h>
25#include <sys/mount.h>
26#include <sys/stat.h>
27#include <sys/syscall.h>
28#include <dirent.h>
29#include <fcntl.h>
30#include <sched.h>
31#include <unistd.h>
32
33static char *netns_control_file(const char *nsname) {
34 char *rv = 0;
35 if (asprintf(&rv, "/var/run/netns/%s", nsname) <= 0)
36 errExit("asprintf");
37 return rv;
38}
39
40static char *netns_etc_dir(const char *nsname) {
41 char *rv = 0;
42 if (asprintf(&rv, "/etc/netns/%s", nsname) <= 0)
43 errExit("asprintf");
44 return rv;
45}
46
47void check_netns(const char *nsname) {
48 if (strchr(nsname, '/') || strstr(nsname, "..")) {
49 fprintf(stderr, "Error: invalid netns name %s\n", nsname);
50 exit(1);
51 }
52 invalid_filename(nsname);
53 char *control_file = netns_control_file(nsname);
54
55 EUID_ASSERT();
56
57 struct stat st;
58 if (lstat(control_file, &st)) {
59 fprintf(stderr, "Error: invalid netns '%s' (%s: %s)\n",
60 nsname, control_file, strerror(errno));
61 exit(1);
62 }
63 if (!S_ISREG(st.st_mode)) {
64 fprintf(stderr, "Error: invalid netns '%s' (%s: not a regular file)\n",
65 nsname, control_file);
66 exit(1);
67 }
68 free(control_file);
69}
70
71void netns(const char *nsname) {
72 char *control_file = netns_control_file(nsname);
73 int nsfd = open(control_file, O_RDONLY|O_CLOEXEC);
74 if (nsfd < 0) {
75 fprintf(stderr, "Error: cannot open netns '%s' (%s: %s)\n",
76 nsname, control_file, strerror(errno));
77 exit(1);
78 }
79 if (syscall(__NR_setns, nsfd, CLONE_NEWNET) < 0) {
80 fprintf(stderr, "Error: cannot join netns '%s': %s\n",
81 nsname, strerror(errno));
82 exit(1);
83 }
84 close(nsfd);
85 free(control_file);
86}
87
88void netns_mounts(const char *nsname) {
89 char *etcdir = netns_etc_dir(nsname);
90 char *netns_name, *etc_name;
91 struct dirent *entry;
92 DIR *dir;
93
94 dir = opendir(etcdir);
95 if (!dir) {
96 free(etcdir);
97 return;
98 }
99 while ((entry = readdir(dir))) {
100 if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
101 continue;
102 if (asprintf(&netns_name, "%s/%s", etcdir, entry->d_name) < 0 ||
103 asprintf(&etc_name, "/etc/%s", entry->d_name) < 0)
104 errExit("asprintf");
105 if (mount(netns_name, etc_name, "none", MS_BIND, 0) < 0) {
106 fprintf(stderr, "Warning: bind %s -> %s failed: %s\n",
107 netns_name, etc_name, strerror(errno));
108 }
109 free(netns_name);
110 free(etc_name);
111 }
112 closedir(dir);
113 free(etcdir);
114}
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 33b6eab91..4856b31ae 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -215,6 +215,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
215 arg_no3d = 1; 215 arg_no3d = 1;
216 return 0; 216 return 0;
217 } 217 }
218 else if (strcmp(ptr, "allow-private-blacklist") == 0) {
219 arg_allow_private_blacklist = 1;
220 return 0;
221 }
218 else if (strcmp(ptr, "netfilter") == 0) { 222 else if (strcmp(ptr, "netfilter") == 0) {
219#ifdef HAVE_NETWORK 223#ifdef HAVE_NETWORK
220 if (checkcfg(CFG_NETWORK)) 224 if (checkcfg(CFG_NETWORK))
@@ -602,6 +606,12 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
602 return 0; 606 return 0;
603 } 607 }
604 608
609 // hosts-file
610 if (strncmp(ptr, "hosts-file ", 11) == 0) {
611 cfg.hosts_file = fs_check_hosts_fiile(ptr + 11);
612 return 0;
613 }
614
605 // dns 615 // dns
606 if (strncmp(ptr, "dns ", 4) == 0) { 616 if (strncmp(ptr, "dns ", 4) == 0) {
607 uint32_t dns; 617 uint32_t dns;
@@ -663,6 +673,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
663 arg_writable_var = 1; 673 arg_writable_var = 1;
664 return 0; 674 return 0;
665 } 675 }
676 if (strcmp(ptr, "writable-var-log") == 0) {
677 arg_writable_var_log = 1;
678 return 0;
679 }
666 680
667 // private directory 681 // private directory
668 if (strncmp(ptr, "private ", 8) == 0) { 682 if (strncmp(ptr, "private ", 8) == 0) {
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 493877db3..e56526f34 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -386,7 +386,7 @@ static void enforce_filters(void) {
386 } 386 }
387 387
388 // disable all capabilities 388 // disable all capabilities
389 if (arg_caps_default_filter || arg_caps_list) 389 if (arg_caps_default_filter || arg_caps_list && !arg_quiet)
390 fprintf(stderr, "Warning: all capabilities disabled for a regular user in chroot\n"); 390 fprintf(stderr, "Warning: all capabilities disabled for a regular user in chroot\n");
391 arg_caps_drop_all = 1; 391 arg_caps_drop_all = 1;
392 392
@@ -467,6 +467,11 @@ int sandbox(void* sandbox_arg) {
467 if (arg_debug) 467 if (arg_debug)
468 printf("Network namespace enabled, only loopback interface available\n"); 468 printf("Network namespace enabled, only loopback interface available\n");
469 } 469 }
470 else if (arg_netns) {
471 netns(arg_netns);
472 if (arg_debug)
473 printf("Network namespace '%s' activated\n", arg_netns);
474 }
470 else if (any_bridge_configured() || any_interface_configured()) { 475 else if (any_bridge_configured() || any_interface_configured()) {
471 // configure lo and eth0...eth3 476 // configure lo and eth0...eth3
472 net_if_up("lo"); 477 net_if_up("lo");
@@ -515,7 +520,8 @@ int sandbox(void* sandbox_arg) {
515 if (cfg.defaultgw) { 520 if (cfg.defaultgw) {
516 // set the default route 521 // set the default route
517 if (net_add_route(0, 0, cfg.defaultgw)) { 522 if (net_add_route(0, 0, cfg.defaultgw)) {
518 fprintf(stderr, "Warning: cannot configure default route\n"); 523 if (!arg_quiet)
524 fprintf(stderr, "Warning: cannot configure default route\n");
519 gw_cfg_failed = 1; 525 gw_cfg_failed = 1;
520 } 526 }
521 } 527 }
@@ -582,6 +588,10 @@ int sandbox(void* sandbox_arg) {
582 if (arg_trace || arg_tracelog || mask_x11_abstract_socket) 588 if (arg_trace || arg_tracelog || mask_x11_abstract_socket)
583 fs_trace_preload(); 589 fs_trace_preload();
584 590
591 // store hosts file
592 if (cfg.hosts_file)
593 fs_store_hosts_file();
594
585 //**************************** 595 //****************************
586 // configure filesystem 596 // configure filesystem
587 //**************************** 597 //****************************
@@ -620,19 +630,29 @@ int sandbox(void* sandbox_arg) {
620#ifdef HAVE_OVERLAYFS 630#ifdef HAVE_OVERLAYFS
621 if (arg_overlay) { 631 if (arg_overlay) {
622 fs_overlayfs(); 632 fs_overlayfs();
633
634//todo - bring it back for overlay-named
635#if 0
636 fs_overlayfs();
637 // force caps and seccomp if not started as root
638 if (getuid() != 0) {
639 enforce_filters();
640#ifdef HAVE_SECCOMP
641 enforce_seccomp = 1;
642#endif
643 }
644 else
645 arg_seccomp = 1;
646#endif
647
648
649
623 } 650 }
624 else 651 else
625#endif 652#endif
626 fs_basic_fs(); 653 fs_basic_fs();
627 654
628 //**************************** 655 //****************************
629 // set hostname in /etc/hostname
630 //****************************
631 if (cfg.hostname) {
632 fs_hostname(cfg.hostname);
633 }
634
635 //****************************
636 // private mode 656 // private mode
637 //**************************** 657 //****************************
638 if (arg_private) { 658 if (arg_private) {
@@ -729,6 +749,22 @@ int sandbox(void* sandbox_arg) {
729 EUID_ROOT(); 749 EUID_ROOT();
730 } 750 }
731 } 751 }
752
753
754 //****************************
755 // hosts and hostname
756 //****************************
757 if (cfg.hostname)
758 fs_hostname(cfg.hostname);
759
760 if (cfg.hosts_file)
761 fs_mount_hosts_file();
762
763 //****************************
764 // /etc overrides from the network namespace
765 //****************************
766 if (arg_netns)
767 netns_mounts(arg_netns);
732 768
733 //**************************** 769 //****************************
734 // update /proc, /sys, /dev, /boot directorymy 770 // update /proc, /sys, /dev, /boot directorymy
@@ -812,7 +848,8 @@ int sandbox(void* sandbox_arg) {
812 int rv = nice(cfg.nice); 848 int rv = nice(cfg.nice);
813 (void) rv; 849 (void) rv;
814 if (errno) { 850 if (errno) {
815 fprintf(stderr, "Warning: cannot set nice value\n"); 851 if (!arg_quiet)
852 fprintf(stderr, "Warning: cannot set nice value\n");
816 errno = 0; 853 errno = 0;
817 } 854 }
818 } 855 }
@@ -868,7 +905,8 @@ int sandbox(void* sandbox_arg) {
868 if (arg_noroot) { 905 if (arg_noroot) {
869 int rv = unshare(CLONE_NEWUSER); 906 int rv = unshare(CLONE_NEWUSER);
870 if (rv == -1) { 907 if (rv == -1) {
871 fprintf(stderr, "Warning: cannot create a new user namespace, going forward without it...\n"); 908 if (!arg_quiet)
909 fprintf(stderr, "Warning: cannot create a new user namespace, going forward without it...\n");
872 drop_privs(arg_nogroups); 910 drop_privs(arg_nogroups);
873 arg_noroot = 0; 911 arg_noroot = 0;
874 } 912 }
@@ -899,7 +937,7 @@ int sandbox(void* sandbox_arg) {
899 if (arg_nonewprivs) { 937 if (arg_nonewprivs) {
900 int no_new_privs = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); 938 int no_new_privs = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
901 939
902 if(no_new_privs != 0) 940 if(no_new_privs != 0 && !arg_quiet)
903 fprintf(stderr, "Warning: NO_NEW_PRIVS disabled, it requires a Linux kernel version 3.5 or newer.\n"); 941 fprintf(stderr, "Warning: NO_NEW_PRIVS disabled, it requires a Linux kernel version 3.5 or newer.\n");
904 else if (arg_debug) 942 else if (arg_debug)
905 printf("NO_NEW_PRIVS set\n"); 943 printf("NO_NEW_PRIVS set\n");
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index 9f4dfd44c..15ba22d4d 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -78,6 +78,7 @@ void usage(void) {
78 printf(" --get=name|pid filename - get a file from sandbox container.\n"); 78 printf(" --get=name|pid filename - get a file from sandbox container.\n");
79 printf(" --help, -? - this help screen.\n"); 79 printf(" --help, -? - this help screen.\n");
80 printf(" --hostname=name - set sandbox hostname.\n"); 80 printf(" --hostname=name - set sandbox hostname.\n");
81 printf(" --hosts-file=file - use file as /etc/hosts.\n");
81 printf(" --ignore=command - ignore command in profile files.\n"); 82 printf(" --ignore=command - ignore command in profile files.\n");
82#ifdef HAVE_NETWORK 83#ifdef HAVE_NETWORK
83 printf(" --interface=name - move interface in sandbox.\n"); 84 printf(" --interface=name - move interface in sandbox.\n");
@@ -191,6 +192,7 @@ void usage(void) {
191#endif 192#endif
192 printf(" --writable-etc - /etc directory is mounted read-write.\n"); 193 printf(" --writable-etc - /etc directory is mounted read-write.\n");
193 printf(" --writable-var - /var directory is mounted read-write.\n"); 194 printf(" --writable-var - /var directory is mounted read-write.\n");
195 printf(" --writable-var-log - use the real /var/log directory, not a clone.\n");
194 printf(" --x11 - enable X11 sandboxing. The software checks first if Xpra is\n"); 196 printf(" --x11 - enable X11 sandboxing. The software checks first if Xpra is\n");
195 printf("\tinstalled, then it checks if Xephyr is installed. If all fails, it will\n"); 197 printf("\tinstalled, then it checks if Xephyr is installed. If all fails, it will\n");
196 printf("\tattempt to use X11 security extension.\n"); 198 printf("\tattempt to use X11 security extension.\n");
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 10000e912..44891ce2d 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -169,6 +169,25 @@ void logerr(const char *msg) {
169 closelog(); 169 closelog();
170} 170}
171 171
172static int copy_file_by_fd(int src, int dst) {
173 assert(src >= 0);
174 assert(dst >= 0);
175
176 ssize_t len;
177 static const int BUFLEN = 1024;
178 unsigned char buf[BUFLEN];
179 while ((len = read(src, buf, BUFLEN)) > 0) {
180 int done = 0;
181 while (done != len) {
182 int rv = write(dst, buf + done, len - done);
183 if (rv == -1)
184 return -1;
185 done += rv;
186 }
187 }
188 fflush(0);
189 return 0;
190}
172 191
173// return -1 if error, 0 if no error; if destname already exists, return error 192// return -1 if error, 0 if no error; if destname already exists, return error
174int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode) { 193int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode) {
@@ -190,33 +209,16 @@ int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, m
190 return -1; 209 return -1;
191 } 210 }
192 211
193 // copy 212 int errors = copy_file_by_fd(src, dst);
194 ssize_t len; 213 if (!errors) {
195 static const int BUFLEN = 1024; 214 if (fchown(dst, uid, gid) == -1)
196 unsigned char buf[BUFLEN]; 215 errExit("fchown");
197 while ((len = read(src, buf, BUFLEN)) > 0) { 216 if (fchmod(dst, mode) == -1)
198 int done = 0; 217 errExit("fchmod");
199 while (done != len) {
200 int rv = write(dst, buf + done, len - done);
201 if (rv == -1) {
202 close(src);
203 close(dst);
204 return -1;
205 }
206
207 done += rv;
208 }
209 } 218 }
210 fflush(0);
211
212 if (fchown(dst, uid, gid) == -1)
213 errExit("fchown");
214 if (fchmod(dst, mode) == -1)
215 errExit("fchmod");
216
217 close(src); 219 close(src);
218 close(dst); 220 close(dst);
219 return 0; 221 return errors;
220} 222}
221 223
222// return -1 if error, 0 if no error 224// return -1 if error, 0 if no error
@@ -241,6 +243,45 @@ void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid
241 waitpid(child, NULL, 0); 243 waitpid(child, NULL, 0);
242} 244}
243 245
246void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode) {
247 // open destination
248 int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
249 if (dst < 0) {
250 fprintf(stderr, "Warning: cannot open destination file %s, file not copied\n", destname);
251 return;
252 }
253
254 pid_t child = fork();
255 if (child < 0)
256 errExit("fork");
257 if (child == 0) {
258 // drop privileges
259 drop_privs(0);
260
261 int src = open(srcname, O_RDONLY);
262 if (src < 0) {
263 fprintf(stderr, "Warning: cannot open source file %s, file not copied\n", srcname);
264 } else {
265 if (copy_file_by_fd(src, dst)) {
266 fprintf(stderr, "Warning: cannot copy %s\n", srcname);
267 }
268 close(src);
269 }
270 close(dst);
271#ifdef HAVE_GCOV
272 __gcov_flush();
273#endif
274 _exit(0);
275 }
276 // wait for the child to finish
277 waitpid(child, NULL, 0);
278 if (fchown(dst, uid, gid) == -1)
279 errExit("fchown");
280 if (fchmod(dst, mode) == -1)
281 errExit("fchmod");
282 close(dst);
283}
284
244// return -1 if error, 0 if no error 285// return -1 if error, 0 if no error
245void touch_file_as_user(const char *fname, uid_t uid, gid_t gid, mode_t mode) { 286void touch_file_as_user(const char *fname, uid_t uid, gid_t gid, mode_t mode) {
246 pid_t child = fork(); 287 pid_t child = fork();
@@ -864,4 +905,4 @@ errexit:
864 close(fd); 905 close(fd);
865 fprintf(stderr, "Error: cannot read %s\n", fname); 906 fprintf(stderr, "Error: cannot read %s\n", fname);
866 exit(1); 907 exit(1);
867} \ No newline at end of file 908}
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt
index 8fd4562b0..90dca19bf 100644
--- a/src/man/firejail-profile.txt
+++ b/src/man/firejail-profile.txt
@@ -244,6 +244,11 @@ Mount /etc directory read-write.
244.TP 244.TP
245\fBwritable-var 245\fBwritable-var
246Mount /var directory read-write. 246Mount /var directory read-write.
247.TP
248\fBwritable-var-log
249Use the real /var/log directory, not a clone. By default, a tmpfs is mounted on top of /var/log
250directory, and a skeleton filesystem is created based on the original /var/log.
251
247.SH Security filters 252.SH Security filters
248The following security filters are currently implemented: 253The following security filters are currently implemented:
249 254
@@ -392,6 +397,10 @@ Set a DNS server for the sandbox. Up to three DNS servers can be defined.
392Set a hostname for the sandbox. 397Set a hostname for the sandbox.
393 398
394.TP 399.TP
400\fBhosts-file file
401Use file as /etc/hosts.
402
403.TP
395\fBip address 404\fBip address
396Assign IP addresses to the last network interface defined by a net command. A 405Assign IP addresses to the last network interface defined by a net command. A
397default gateway is assigned by default. 406default gateway is assigned by default.
@@ -452,7 +461,7 @@ Assign MAC addresses to the last network interface defined by a net command.
452 461
453.TP 462.TP
454\fBmachine-id 463\fBmachine-id
455Preserve id number in /etc/machine-id file. By default a new random id is generated inside the sandbox. 464Spoof id number in /etc/machine-id file - a new random id is generated inside the sandbox.
456 465
457.TP 466.TP
458\fBmtu number 467\fBmtu number
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 69d28c788..993186476 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -192,7 +192,7 @@ Define a custom blacklist Linux capabilities filter.
192.br 192.br
193Example: 193Example:
194.br 194.br
195$ firejail \-\-caps.keep=net_broadcast,net_admin,net_raw 195$ firejail \-\-caps.drop=net_broadcast,net_admin,net_raw
196 196
197.TP 197.TP
198\fB\-\-caps.keep=capability,capability,capability 198\fB\-\-caps.keep=capability,capability,capability
@@ -469,6 +469,16 @@ Example:
469$ firejail \-\-hostname=officepc firefox 469$ firejail \-\-hostname=officepc firefox
470 470
471.TP 471.TP
472\fB\-\-hosts-file=file
473Use file as /etc/hosts.
474.br
475
476.br
477Example:
478.br
479$ firejail \-\-hosts-file=~/myhosts firefox
480
481.TP
472\fB\-\-ignore=command 482\fB\-\-ignore=command
473Ignore command in profile file. 483Ignore command in profile file.
474.br 484.br
@@ -678,7 +688,7 @@ $ firejail \-\-net=eth0 \-\-mac=00:11:22:33:44:55 firefox
678 688
679.TP 689.TP
680\fB\-\-machine-id 690\fB\-\-machine-id
681Preserve id number in /etc/machine-id file. By default a new random id is generated inside the sandbox. 691Spoof id number in /etc/machine-id file - a new random id is generated inside the sandbox.
682.br 692.br
683 693
684.br 694.br
@@ -761,6 +771,11 @@ Example:
761$ firejail \-\-net=none vlc 771$ firejail \-\-net=none vlc
762 772
763.TP 773.TP
774\fB\-\-netns=name
775Run the program in a named, persistent network namespace. These can
776be created and configured using "ip netns".
777
778.TP
764\fB\-\-netfilter 779\fB\-\-netfilter
765Enable a default client network filter in the new network namespace. 780Enable a default client network filter in the new network namespace.
766New network namespaces are created using \-\-net option. If a new network namespaces is not created, 781New network namespaces are created using \-\-net option. If a new network namespaces is not created,
@@ -1710,6 +1725,17 @@ Example:
1710.br 1725.br
1711$ sudo firejail --writable-var 1726$ sudo firejail --writable-var
1712 1727
1728.TP
1729\fB\-\-writable-var-log
1730Use the real /var/log directory, not a clone. By default, a tmpfs is mounted on top of /var/log
1731directory, and a skeleton filesystem is created based on the original /var/log.
1732.br
1733
1734.br
1735Example:
1736.br
1737$ sudo firejail --writable-var-log
1738
1713 1739
1714.TP 1740.TP
1715\fB\-\-x11 1741\fB\-\-x11