New upstream version 0.9.42~rc2
Reiner Herrmann
7 years ago
0 | all: apps firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 firejail-config.5 | |
0 | all: apps man | |
1 | 1 | MYLIBS = src/lib |
2 | APPS = src/firejail src/firemon src/firecfg src/libtrace src/libtracelog src/ftee src/libtracelog src/faudit | |
2 | APPS = src/firejail src/firemon src/firecfg src/libtrace src/libtracelog src/ftee src/faudit | |
3 | MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 firejail-config.5 | |
3 | 4 | |
4 | 5 | prefix=@prefix@ |
5 | 6 | exec_prefix=@exec_prefix@ |
13 | 14 | NAME=@PACKAGE_NAME@ |
14 | 15 | PACKAGE_TARNAME=@PACKAGE_TARNAME@ |
15 | 16 | DOCDIR=@docdir@ |
17 | HAVE_APPARMOR=@HAVE_APPARMOR@ | |
18 | BUSYBOX_WORKAROUND=@BUSYBOX_WORKAROUND@ | |
16 | 19 | |
17 | 20 | .PHONY: mylibs $(MYLIBS) |
18 | 21 | mylibs: $(MYLIBS) |
24 | 27 | $(APPS): $(MYLIBS) |
25 | 28 | $(MAKE) -C $@ |
26 | 29 | |
27 | firemon.1: src/man/firemon.txt | |
28 | ./mkman.sh $(VERSION) src/man/firemon.txt firemon.1 | |
29 | firejail.1: src/man/firejail.txt | |
30 | ./mkman.sh $(VERSION) src/man/firejail.txt firejail.1 | |
31 | firecfg.1: src/man/firecfg.txt | |
32 | ./mkman.sh $(VERSION) src/man/firecfg.txt firecfg.1 | |
33 | firejail-profile.5: src/man/firejail-profile.txt | |
34 | ./mkman.sh $(VERSION) src/man/firejail-profile.txt firejail-profile.5 | |
35 | firejail-login.5: src/man/firejail-login.txt | |
36 | ./mkman.sh $(VERSION) src/man/firejail-login.txt firejail-login.5 | |
37 | firejail-config.5: src/man/firejail-config.txt | |
38 | ./mkman.sh $(VERSION) src/man/firejail-config.txt firejail-config.5 | |
30 | $(MANPAGES): $(wildcard src/man/*.txt) | |
31 | ./mkman.sh $(VERSION) src/man/$(basename $@).txt $@ | |
32 | ||
33 | man: $(MANPAGES) | |
39 | 34 | |
40 | 35 | clean: |
41 | for dir in $(APPS); do \ | |
36 | for dir in $(APPS) $(MYLIBS); do \ | |
42 | 37 | $(MAKE) -C $$dir clean; \ |
43 | 38 | done |
44 | for dir in $(MYLIBS); do \ | |
45 | $(MAKE) -C $$dir clean; \ | |
46 | done | |
47 | rm -f firejail.1 firejail.1.gz firemon.1 firemon.1.gz firecfg.1 firecfg.gz firejail-profile.5 firejail-profile.5.gz firejail-login.5 firejail-login.5.gz firejail-config.5 firejail-config.5.gz firejail*.rpm | |
39 | rm -f $(MANPAGES) $(MANPAGES:%=%.gz) firejail*.rpm | |
48 | 40 | rm -f test/utils/index.html* |
49 | 41 | rm -f test/utils/wget-log |
50 | 42 | rm -f test/utils/lstesting |
56 | 48 | rm -f test/environment/wget-log |
57 | 49 | rm -f test/sysutils/firejail_t* |
58 | 50 | cd test/compile; ./compile.sh --clean; cd ../.. |
59 | cd test/dist-compile; ./compile.sh --clean; cd ../.. | |
60 | 51 | |
61 | 52 | distclean: clean |
62 | for dir in $(APPS); do \ | |
53 | for dir in $(APPS) $(MYLIBS); do \ | |
63 | 54 | $(MAKE) -C $$dir distclean; \ |
64 | 55 | done |
65 | for dir in $(MYLIBS); do \ | |
66 | $(MAKE) -C $$dir distclean; \ | |
67 | done | |
68 | rm -fr Makefile autom4te.cache config.log config.status config.h | |
56 | rm -fr Makefile autom4te.cache config.log config.status config.h uids.h | |
69 | 57 | |
70 | 58 | realinstall: |
71 | 59 | # firejail executable |
90 | 78 | install -c -m 0644 README $(DESTDIR)/$(DOCDIR)/. |
91 | 79 | install -c -m 0644 RELNOTES $(DESTDIR)/$(DOCDIR)/. |
92 | 80 | # etc files |
93 | ./mketc.sh $(sysconfdir) | |
81 | ./mketc.sh $(sysconfdir) $(BUSYBOX_WORKAROUND) | |
94 | 82 | install -m 0755 -d $(DESTDIR)/$(sysconfdir)/firejail |
95 | install -c -m 0644 .etc/audacious.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
96 | install -c -m 0644 .etc/clementine.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
97 | install -c -m 0644 .etc/epiphany.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
98 | install -c -m 0644 .etc/qtox.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
99 | install -c -m 0644 .etc/polari.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
100 | install -c -m 0644 .etc/gnome-mplayer.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
101 | install -c -m 0644 .etc/rhythmbox.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
102 | install -c -m 0644 .etc/totem.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
103 | install -c -m 0644 .etc/firefox.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
104 | install -c -m 0644 .etc/firefox-esr.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
105 | install -c -m 0644 .etc/icedove.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
106 | install -c -m 0644 .etc/iceweasel.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
107 | install -c -m 0644 .etc/midori.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
108 | install -c -m 0644 .etc/evince.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
109 | install -c -m 0644 .etc/chromium-browser.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
110 | install -c -m 0644 .etc/chromium.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
111 | install -c -m 0644 .etc/google-chrome.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
112 | install -c -m 0644 .etc/google-chrome-stable.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
113 | install -c -m 0644 .etc/google-chrome-beta.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
114 | install -c -m 0644 .etc/google-chrome-unstable.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
115 | install -c -m 0644 .etc/disable-common.inc $(DESTDIR)/$(sysconfdir)/firejail/. | |
116 | install -c -m 0644 .etc/dropbox.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
117 | install -c -m 0644 .etc/opera.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
118 | install -c -m 0644 .etc/opera-beta.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
119 | install -c -m 0644 .etc/thunderbird.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
120 | install -c -m 0644 .etc/transmission-gtk.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
121 | install -c -m 0644 .etc/transmission-qt.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
122 | install -c -m 0644 .etc/vlc.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
123 | install -c -m 0644 .etc/deluge.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
124 | install -c -m 0644 .etc/qbittorrent.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
125 | install -c -m 0644 .etc/default.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
126 | install -c -m 0644 .etc/pidgin.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
127 | install -c -m 0644 .etc/xchat.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
128 | install -c -m 0644 .etc/empathy.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
129 | install -c -m 0644 .etc/server.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
130 | install -c -m 0644 .etc/icecat.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
131 | install -c -m 0644 .etc/quassel.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
132 | install -c -m 0644 .etc/deadbeef.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
133 | install -c -m 0644 .etc/filezilla.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
134 | install -c -m 0644 .etc/fbreader.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
135 | install -c -m 0644 .etc/spotify.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
136 | install -c -m 0644 .etc/steam.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
137 | install -c -m 0644 .etc/skype.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
138 | install -c -m 0644 .etc/wine.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
139 | install -c -m 0644 .etc/disable-devel.inc $(DESTDIR)/$(sysconfdir)/firejail/. | |
140 | install -c -m 0644 .etc/conkeror.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
141 | install -c -m 0644 .etc/unbound.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
142 | install -c -m 0644 .etc/dnscrypt-proxy.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
143 | install -c -m 0644 .etc/whitelist-common.inc $(DESTDIR)/$(sysconfdir)/firejail/. | |
144 | install -c -m 0644 .etc/nolocal.net $(DESTDIR)/$(sysconfdir)/firejail/. | |
145 | install -c -m 0644 .etc/webserver.net $(DESTDIR)/$(sysconfdir)/firejail/. | |
146 | install -c -m 0644 .etc/bitlbee.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
147 | install -c -m 0644 .etc/weechat.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
148 | install -c -m 0644 .etc/weechat-curses.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
149 | install -c -m 0644 .etc/hexchat.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
150 | install -c -m 0644 .etc/rtorrent.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
151 | install -c -m 0644 .etc/parole.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
152 | install -c -m 0644 .etc/kmail.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
153 | install -c -m 0644 .etc/seamonkey.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
154 | install -c -m 0644 .etc/seamonkey-bin.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
155 | install -c -m 0644 .etc/telegram.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
156 | install -c -m 0644 .etc/mathematica.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
157 | install -c -m 0644 .etc/Mathematica.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
158 | install -c -m 0644 .etc/uget-gtk.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
159 | install -c -m 0644 .etc/mupen64plus.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
160 | install -c -m 0644 .etc/disable-programs.inc $(DESTDIR)/$(sysconfdir)/firejail/. | |
161 | install -c -m 0644 .etc/disable-passwdmgr.inc $(DESTDIR)/$(sysconfdir)/firejail/. | |
162 | install -c -m 0644 .etc/lxterminal.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
163 | install -c -m 0644 .etc/cherrytree.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
164 | install -c -m 0644 .etc/wesnoth.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
165 | install -c -m 0644 .etc/hedgewars.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
166 | install -c -m 0644 .etc/vivaldi.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
167 | install -c -m 0644 .etc/vivaldi-beta.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
168 | install -c -m 0644 .etc/atril.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
169 | install -c -m 0644 .etc/qutebrowser.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
170 | install -c -m 0644 .etc/flashpeak-slimjet.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
171 | install -c -m 0644 .etc/ssh.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
172 | install -c -m 0644 .etc/openbox.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
173 | install -c -m 0644 .etc/dillo.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
174 | install -c -m 0644 .etc/cmus.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
175 | install -c -m 0644 .etc/dnsmasq.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
176 | install -c -m 0644 .etc/palemoon.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
177 | install -c -m 0644 .etc/icedove.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
178 | install -c -m 0644 .etc/abrowser.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
179 | install -c -m 0644 .etc/0ad.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
180 | install -c -m 0644 .etc/netsurf.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
181 | install -c -m 0644 .etc/warzone2100.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
182 | install -c -m 0644 .etc/okular.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
183 | install -c -m 0644 .etc/gwenview.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
184 | install -c -m 0644 .etc/gpredict.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
185 | install -c -m 0644 .etc/aweather.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
186 | install -c -m 0644 .etc/stellarium.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
187 | install -c -m 0644 .etc/google-play-music-desktop-player.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
188 | install -c -m 0644 .etc/quiterss.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
189 | install -c -m 0644 .etc/cyberfox.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
190 | install -c -m 0644 .etc/snap.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
191 | install -c -m 0644 .etc/xplayer.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
192 | install -c -m 0644 .etc/xreader.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
193 | install -c -m 0644 .etc/xviewer.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
194 | install -c -m 0644 .etc/mcabber.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
195 | install -c -m 0644 .etc/corebird.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
196 | install -c -m 0644 .etc/konversation.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
197 | install -c -m 0644 .etc/psi-plus.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
198 | install -c -m 0644 .etc/brave.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
199 | install -c -m 0644 .etc/gitter.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
200 | install -c -m 0644 .etc/gthumb.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
201 | install -c -m 0644 .etc/mpv.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
202 | install -c -m 0644 .etc/franz.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
203 | install -c -m 0644 .etc/libreoffice.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
204 | install -c -m 0644 .etc/localc.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
205 | install -c -m 0644 .etc/lodraw.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
206 | install -c -m 0644 .etc/loffice.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
207 | install -c -m 0644 .etc/lofromtemplate.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
208 | install -c -m 0644 .etc/loimpress.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
209 | install -c -m 0644 .etc/lomath.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
210 | install -c -m 0644 .etc/loweb.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
211 | install -c -m 0644 .etc/lowriter.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
212 | install -c -m 0644 .etc/pix.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
213 | install -c -m 0644 .etc/soffice.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
214 | install -c -m 0644 .etc/audacity.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
215 | install -c -m 0644 .etc/cpio.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
216 | install -c -m 0644 .etc/gzip.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
217 | install -c -m 0644 .etc/xzdec.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
218 | install -c -m 0644 .etc/strings.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
219 | install -c -m 0644 .etc/xz.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
220 | install -c -m 0644 .etc/less.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
221 | install -c -m 0644 .etc/Telegram.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
222 | install -c -m 0644 .etc/atom-beta.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
223 | install -c -m 0644 .etc/atom.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
224 | install -c -m 0644 .etc/jitsi.profile $(DESTDIR)/$(sysconfdir)/firejail/. | |
83 | for file in .etc/* etc/firejail.config; do \ | |
84 | install -c -m 0644 $$file $(DESTDIR)/$(sysconfdir)/firejail; \ | |
85 | done | |
225 | 86 | sh -c "if [ ! -f $(DESTDIR)/$(sysconfdir)/firejail/login.users ]; then install -c -m 0644 etc/login.users $(DESTDIR)/$(sysconfdir)/firejail/.; fi;" |
226 | install -c -m 0644 etc/firejail.config $(DESTDIR)/$(sysconfdir)/firejail/. | |
227 | 87 | rm -fr .etc |
88 | ifeq ($(HAVE_APPARMOR),-DHAVE_APPARMOR) | |
89 | # install apparmor profile | |
90 | sh -c "if [ ! -d $(DESTDIR)/$(sysconfdir)/apparmor.d ]; then install -d -m 755 $(DESTDIR)/$(sysconfdir)/apparmor.d; fi;" | |
91 | install -c -m 0644 etc/firejail-default $(DESTDIR)/$(sysconfdir)/apparmor.d/. | |
92 | endif | |
228 | 93 | # man pages |
229 | rm -f firejail.1.gz | |
230 | gzip -9n firejail.1 | |
231 | rm -f firemon.1.gz | |
232 | gzip -9n firemon.1 | |
233 | rm -f firecfg.1.gz | |
234 | gzip -9n firecfg.1 | |
235 | rm -f firejail-profile.5.gz | |
236 | gzip -9n firejail-profile.5 | |
237 | rm -f firejail-login.5.gz | |
238 | gzip -9n firejail-login.5 | |
239 | rm -f firejail-config.5.gz | |
240 | gzip -9n firejail-config.5 | |
241 | 94 | install -m 0755 -d $(DESTDIR)/$(mandir)/man1 |
242 | install -c -m 0644 firejail.1.gz $(DESTDIR)/$(mandir)/man1/. | |
243 | install -c -m 0644 firemon.1.gz $(DESTDIR)/$(mandir)/man1/. | |
244 | install -c -m 0644 firecfg.1.gz $(DESTDIR)/$(mandir)/man1/. | |
245 | 95 | install -m 0755 -d $(DESTDIR)/$(mandir)/man5 |
246 | install -c -m 0644 firejail-profile.5.gz $(DESTDIR)/$(mandir)/man5/. | |
247 | install -c -m 0644 firejail-login.5.gz $(DESTDIR)/$(mandir)/man5/. | |
248 | install -c -m 0644 firejail-config.5.gz $(DESTDIR)/$(mandir)/man5/. | |
249 | rm -f firejail.1.gz firemon.1.gz firecfg.1.gz firejail-profile.5.gz firejail-login.5.gz firejail-config.5.gz | |
96 | for man in $(MANPAGES); do \ | |
97 | rm -f $$man.gz; \ | |
98 | gzip -9n $$man; \ | |
99 | case "$$man" in \ | |
100 | *.1) install -c -m 0644 $$man.gz $(DESTDIR)/$(mandir)/man1/; ;; \ | |
101 | *.5) install -c -m 0644 $$man.gz $(DESTDIR)/$(mandir)/man5/; ;; \ | |
102 | esac; \ | |
103 | done | |
104 | rm -f $(MANPAGES) $(MANPAGES:%=%.gz) | |
250 | 105 | # bash completion |
251 | 106 | install -m 0755 -d $(DESTDIR)/$(datarootdir)/bash-completion/completions |
252 | 107 | install -c -m 0644 src/bash_completion/firejail.bash_completion $(DESTDIR)/$(datarootdir)/bash-completion/completions/firejail |
272 | 127 | rm -f $(DESTDIR)/$(bindir)/firecfg |
273 | 128 | rm -fr $(DESTDIR)/$(libdir)/firejail |
274 | 129 | rm -fr $(DESTDIR)/$(datarootdir)/doc/firejail |
275 | rm -f $(DESTDIR)/$(mandir)/man1/firejail.1* | |
276 | rm -f $(DESTDIR)/$(mandir)/man1/firemon.1* | |
277 | rm -f $(DESTDIR)/$(mandir)/man1/firecfg.1* | |
278 | rm -f $(DESTDIR)/$(mandir)/man5/firejail-profile.5* | |
279 | rm -f $(DESTDIR)/$(mandir)/man5/firejail-login.5* | |
280 | rm -f $(DESTDIR)/$(mandir)/man5/firejail-config.5* | |
130 | for man in $(MANPAGES); do \ | |
131 | rm -f $(DESTDIR)/$(mandir)/man5/$$man*; \ | |
132 | rm -f $(DESTDIR)/$(mandir)/man1/$$man*; \ | |
133 | done | |
281 | 134 | rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firejail |
282 | 135 | rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firemon |
283 | 136 | rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg |
284 | 137 | |
138 | DISTFILES = "src etc platform configure configure.ac Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh mkuid.sh COPYING README RELNOTES" | |
139 | DISTFILES_TEST = "test/apps test/apps-x11 test/environment test/profiles test/utils test/compile test/filters test/network test/fs test/sysutils" | |
140 | ||
285 | 141 | dist: |
286 | 142 | make distclean |
287 | rm -fr $(NAME)-$(VERSION) $(NAME)-$(VERSION).tar.bz2 | |
288 | mkdir $(NAME)-$(VERSION) | |
289 | cd $(NAME)-$(VERSION); cp -a ../src .; cp -a ../etc .; cp -a ../platform .; rm -fr src/tools; cd .. | |
290 | cd $(NAME)-$(VERSION); cp -a ../configure .; cp -a ../configure.ac .; cp -a ../Makefile.in .; cp -a ../install.sh .; cp -a ../mkman.sh .; cp -a ../mketc.sh .; cp -a ../mkdeb.sh .;cd .. | |
291 | cd $(NAME)-$(VERSION); cp -a ../COPYING .; cp -a ../README .; cp -a ../RELNOTES .; cd .. | |
292 | cd $(NAME)-$(VERSION); mkdir -p test; cp -a ../test/profiles test/.; cd .. | |
293 | cd $(NAME)-$(VERSION); mkdir -p test; cp -a ../test/apps test/.; cd .. | |
294 | cd $(NAME)-$(VERSION); mkdir -p test; cp -a ../test/utils test/.; cd .. | |
295 | cd $(NAME)-$(VERSION); mkdir -p test; cp -a ../test/apps-x11 test/.; cd .. | |
296 | cd $(NAME)-$(VERSION); mkdir -p test; cp -a ../test/environment test/.; cd .. | |
297 | cd $(NAME)-$(VERSION); mkdir -p test; cp -a ../test/compile test/.; cd .. | |
298 | cd $(NAME)-$(VERSION); mkdir -p test; cp -a ../test/dist-compile test/.; cd .. | |
299 | cd $(NAME)-$(VERSION); mkdir -p test; cp -a ../test/filters test/.; cd .. | |
300 | cd $(NAME)-$(VERSION); mkdir -p test; cp -a ../test/network test/.; cd .. | |
301 | cd $(NAME)-$(VERSION); mkdir -p test; cp -a ../test/fs test/.; cd .. | |
302 | cd $(NAME)-$(VERSION); rm -fr `find . -name .svn`; rm -fr $(NAME)-$(VERSION); cd .. | |
303 | tar -cjvf $(NAME)-$(VERSION).tar.bz2 $(NAME)-$(VERSION) | |
143 | rm -fr $(NAME)-$(VERSION) $(NAME)-$(VERSION).tar.xz | |
144 | mkdir -p $(NAME)-$(VERSION)/test | |
145 | cp -a "$(DISTFILES)" $(NAME)-$(VERSION) | |
146 | cp -a "$(DISTFILES_TEST)" $(NAME)-$(VERSION)/test | |
147 | rm -rf $(NAME)-$(VERSION)/src/tools | |
148 | find $(NAME)-$(VERSION) -name .svn -delete | |
149 | tar -cJvf $(NAME)-$(VERSION).tar.xz $(NAME)-$(VERSION) | |
304 | 150 | rm -fr $(NAME)-$(VERSION) |
305 | 151 | |
306 | 152 | deb: dist |
312 | 158 | install-snap: snap |
313 | 159 | sudo snap remove faudit; sudo snap install faudit*.snap |
314 | 160 | |
315 | github-compile: | |
316 | cd test/compile; ./compile.sh | |
317 | ||
318 | dist-compile: dist | |
319 | cd test/dist-compile; ./compile.sh $(NAME)-$(VERSION) | |
161 | test-compile: dist | |
162 | cd test/compile; ./compile.sh $(NAME)-$(VERSION) | |
320 | 163 | |
321 | 164 | .PHONY: rpms |
322 | 165 | rpms: |
360 | 203 | test-fs: |
361 | 204 | cd test/fs; ./fs.sh | grep TESTING |
362 | 205 | |
363 | test: test-profiles test-fs test-utils test-environment test-sysutils test-apps test-apps-x11 test-filters | |
206 | test: test-profiles test-fs test-utils test-environment test-apps test-apps-x11 test-filters | |
364 | 207 | echo "TEST COMPLETE" |
24 | 24 | - clang-analyzer fixes |
25 | 25 | - Debian reproducible build |
26 | 26 | - unit testing framework |
27 | Niklas Haas (https://github.com/haasn) | |
28 | - blacklisting for keybase.io's client | |
27 | - moved build to .xz | |
28 | - detached signatures for source archive | |
29 | - recursive mkdir | |
29 | 30 | Aleksey Manevich (https://github.com/manevich) |
30 | 31 | - several profile fixes |
31 | 32 | - fix problem with relative path in storage_find function |
32 | 33 | - fix build for systems without bash |
33 | 34 | - fix double quotes/single quotes problem |
35 | - big rework of argument processing subsystem | |
36 | - --join fixes | |
37 | - spliting up cmdline.c | |
38 | - Busybox support | |
39 | - X11 support rewrite | |
40 | - gether shell selection code in one place | |
41 | - fixed several TOCTOU security problems | |
42 | greigdp (https://github.com/greigdp) | |
43 | - Gajim IM client profile | |
44 | - fix Slack profile | |
45 | Icaro Perseo (https://github.com/icaroperseo) | |
46 | - Icecat profile | |
47 | - several profile fixes | |
48 | hamzadis (https://github.com/hamzadis) | |
49 | - added --overlay-named=name and --overlay-path=path | |
50 | Gaman Gabriel (https://github.com/stelariusinfinitek) | |
51 | - inox profile | |
52 | greigdp (https://github.com/greigdp) | |
53 | - fixed spotify profile | |
54 | - added Slack profile | |
55 | Laurent Declercq (https://github.com/nuxwin) | |
56 | - fixed test for shell interpreter in chroots | |
57 | Franco (nextime) Lanza (https://github.com/nextime) | |
58 | - added --private-template | |
59 | xee5ch (https://github.com/xee5ch) | |
60 | - skypeforlinux profile | |
61 | Peter Hogg (https://github.com/pigmonkey) | |
62 | - WeeChat profile | |
63 | - rtorrent profile | |
64 | - bitlbee profile fixes | |
65 | Thomas Jarosch (https://github.com/thomasjfox) | |
66 | - disable keepassx in disable-passwdmgr.inc | |
67 | - added uudeview profile | |
68 | - added tar (gtar), unzip and unrar profile | |
69 | - added file profile | |
70 | - improved profile list | |
71 | - fixed small variable glitch in stat64() / lstat64() (libtracelog) | |
72 | - added lstat() / lstat64() support to libtrace | |
73 | - include mkuid.sh in make dist | |
74 | Niklas Haas (https://github.com/haasn) | |
75 | - blacklisting for keybase.io's client | |
34 | 76 | Fred-Barclay (https://github.com/Fred-Barclay) |
35 | 77 | - added Vivaldi, Atril profiles |
36 | 78 | - added PaleMoon profile |
58 | 100 | - several private-bin conversions |
59 | 101 | - added jitsi profile |
60 | 102 | - pidgin private-bin conversion |
103 | - added eom profile | |
104 | - added gnome-chess profile | |
61 | 105 | Jaykishan Mutkawoa (https://github.com/jmutkawoa) |
62 | 106 | - cpio profile |
63 | 107 | Paupiah Yash (https://github.com/CaffeinatedStud) |
101 | 145 | - Hedegewars profile |
102 | 146 | - manpage fixes |
103 | 147 | - fixed firecfg clean/clear issue |
148 | - found the ugliest bug so far | |
104 | 149 | curiosity-seeker (https://github.com/curiosity-seeker) |
105 | 150 | - tightening unbound and dnscrypt-proxy profiles |
106 | 151 | - dnsmasq profile |
130 | 175 | - man page fixes |
131 | 176 | mahdi1234 (https://github.com/mahdi1234) |
132 | 177 | - cherrytree profile |
178 | - Seamonkey profiles | |
133 | 179 | jrabe (https://github.com/jrabe) |
134 | 180 | - disallow access to kdbx files |
135 | 181 | - Epiphany profile |
148 | 194 | Rahiel Kasim (https://github.com/rahiel) |
149 | 195 | - Mathematica profile |
150 | 196 | - whitelisted Dropbox profile |
197 | - whitelisted keysnail config for firefox | |
151 | 198 | creideiki (https://github.com/creideiki) |
152 | 199 | - make the sandbox process reap all children |
153 | 200 | sinkuu (https://github.com/sinkuu) |
159 | 206 | - manpage work |
160 | 207 | Andrey Alekseenko (https://github.com/al42and) |
161 | 208 | - fixing lintian warnings |
162 | mahdi1234 (https://github.com/mahdi1234) | |
163 | - Seamonkey profiles | |
209 | - fixed Skype profile | |
164 | 210 | Ivan Kozik (https://github.com/ivan) |
165 | 211 | - speed up sandbox exit |
166 | 212 | Christian Stadelmann (https://github.com/genodeftest) |
171 | 217 | - dynamic allocation of noblacklist buffer |
172 | 218 | Veeti Paananen (https://github.com/veeti) |
173 | 219 | - fixed Spotify profile |
174 | Rahiel Kasim (https://github.com/rahiel) | |
175 | - whitelist keysnail config for firefox | |
176 | Peter Hogg (https://github.com/pigmonkey) | |
177 | - WeeChat profile | |
178 | - rtorrent profile | |
179 | 220 | rogshdo (https://github.com/rogshdo) |
180 | 221 | - BitlBee profile |
181 | 222 | Bruno Nova (https://github.com/brunonova) |
183 | 224 | - bash arguments fix |
184 | 225 | Matt Parnell (https://github.com/ilikenwf) |
185 | 226 | - whitelisting for core firefox related functionality |
186 | Andrey Alekseenko (https://github.com/al42and) | |
187 | - fixed Skype profile | |
188 | 227 | Ondra Nekola (https://github.com/satai) |
189 | 228 | - allow firefox theming with non-global themes |
190 | 229 | emacsomancer (https://github.com/emacsomancer) |
0 | firejail (0.9.42~rc1) baseline; urgency=low | |
1 | * deprecated --user option, please use "sudo -u username firejail" instead | |
2 | * --read-write option rework | |
3 | * allow symlinks in home directory for --whitelist option | |
4 | * AppImage support (--appimage) | |
5 | * Sandbox auditing support (--audit) | |
6 | * remove environment variable (--rmenv) | |
7 | * noexec support (--noexec) | |
8 | * Ubuntu snap support | |
9 | * include /dev/snd in --private-dev | |
10 | * added mkfile profile command | |
11 | * seccomp filter updated | |
12 | * compile time and run time support to disable whitelists | |
13 | * compile time support to disable global configuration file | |
14 | * new profiles: Gitter, gThumb, mpv, Franz messenger, LibreOffice | |
15 | * new profiles: pix, audacity, strings, xz, xzdec, gzip, cpio, less | |
16 | * new profiles: Atom Beta, Atom, jitsi | |
17 | -- netblue30 <netblue30@yahoo.com> Thu, 21 Jul 2016 08:00:00 -0500 | |
0 | firejail (0.9.42~rc2) baseline; urgency=low | |
1 | * security: --whitelist deleted files, submitted by Vasya Novikov | |
2 | * security: disable x32 ABI in seccomp, submitted by Jann Horn | |
3 | * security: tighten --chroot, submitted by Jann Horn | |
4 | * security: terminal sandbox escape, submitted by Stephan Sokolow | |
5 | * security: several TOCTOU fixes submitted by Aleksey Manevich | |
6 | * modifs: deprecated --user option, please use "sudo -u username firejail" | |
7 | * modifs: allow symlinks in home directory for --whitelist option | |
8 | * modifs: Firejail prompt is enabled by env variable FIREJAIL_PROMPT="yes" | |
9 | * modifs: recursive mkdir | |
10 | * modifs: include /dev/snd in --private-dev | |
11 | * modifs: seccomp filter update | |
12 | * modifs: release archives moved to .xz format | |
13 | * feature: AppImage support (--appimage) | |
14 | * feature: AppArmor support (--apparmor) | |
15 | * feature: Ubuntu snap support (/etc/firejail/snap.profile) | |
16 | * feature: Sandbox auditing support (--audit) | |
17 | * feature: remove environment variable (--rmenv) | |
18 | * feature: noexec support (--noexec) | |
19 | * feature: clean local overlay storage directory (--overlay-clean) | |
20 | * feature: store and reuse overlay (--overlay-named) | |
21 | * feature: allow debugging inside the sandbox with gdb and strace | |
22 | (--allow-debuggers) | |
23 | * feature: mkfile profile command | |
24 | * feature: quiet profile command | |
25 | * feature: x11 profile command | |
26 | * compile time: Busybox support (--enable-busybox-workaround) | |
27 | * compile time: disable overlayfs (--disable-overlayfs) | |
28 | * compile time: disable whitlisting (--disable-whitelist) | |
29 | * compile time: disable global config (--disable-globalcfg) | |
30 | * run time: enable/disable overlayfs (overlayfs yes/no) | |
31 | * run time: enable/disable quiet as default (quiet-by-default yes/no) | |
32 | * run time: user-defined network filter (netfilter-default) | |
33 | * run time: enable/disable whitelisting (whitelist yes/no) | |
34 | * run time: enable/disable remounting of /proc and /sys | |
35 | (remount-proc-sys yes/no) | |
36 | * run time: enable/disable chroot desktop features (chroot-desktop yes/no) | |
37 | * profiles: Gitter, gThumb, mpv, Franz messenger, LibreOffice | |
38 | * profiles: pix, audacity, xz, xzdec, gzip, cpio, less | |
39 | * profiles: Atom Beta, Atom, jitsi, eom, uudeview | |
40 | * profiles: tar (gtar), unzip, unrar, file, skypeforlinux, | |
41 | * profiles: inox, Slack, gnome-chess. Gajim IM client | |
42 | -- netblue30 <netblue30@yahoo.com> Thu, 26 Aug 2016 08:00:00 -0500 | |
18 | 43 | |
19 | 44 | firejail (0.9.40) baseline; urgency=low |
20 | 45 | * added --nice option |
0 | 0 | #! /bin/sh |
1 | 1 | # Guess values for system-dependent variables and create Makefiles. |
2 | # Generated by GNU Autoconf 2.69 for firejail 0.9.42~rc1. | |
2 | # Generated by GNU Autoconf 2.69 for firejail 0.9.42~rc2. | |
3 | 3 | # |
4 | 4 | # Report bugs to <netblue30@yahoo.com>. |
5 | 5 | # |
579 | 579 | # Identity of this package. |
580 | 580 | PACKAGE_NAME='firejail' |
581 | 581 | PACKAGE_TARNAME='firejail' |
582 | PACKAGE_VERSION='0.9.42~rc1' | |
583 | PACKAGE_STRING='firejail 0.9.42~rc1' | |
582 | PACKAGE_VERSION='0.9.42~rc2' | |
583 | PACKAGE_STRING='firejail 0.9.42~rc2' | |
584 | 584 | PACKAGE_BUGREPORT='netblue30@yahoo.com' |
585 | 585 | PACKAGE_URL='http://firejail.wordpress.com' |
586 | 586 | |
624 | 624 | ac_subst_vars='LTLIBOBJS |
625 | 625 | LIBOBJS |
626 | 626 | HAVE_SECCOMP_H |
627 | EGREP | |
628 | GREP | |
629 | CPP | |
627 | BUSYBOX_WORKAROUND | |
630 | 628 | HAVE_FATAL_WARNINGS |
631 | 629 | HAVE_WHITELIST |
632 | 630 | HAVE_FILE_TRANSFER |
637 | 635 | HAVE_BIND |
638 | 636 | HAVE_CHROOT |
639 | 637 | HAVE_SECCOMP |
638 | HAVE_OVERLAYFS | |
639 | EXTRA_LDFLAGS | |
640 | EGREP | |
641 | GREP | |
642 | CPP | |
643 | HAVE_APPARMOR | |
640 | 644 | RANLIB |
641 | 645 | INSTALL_DATA |
642 | 646 | INSTALL_SCRIPT |
689 | 693 | ac_subst_files='' |
690 | 694 | ac_user_opts=' |
691 | 695 | enable_option_checking |
696 | enable_apparmor | |
697 | enable_overlayfs | |
692 | 698 | enable_seccomp |
693 | 699 | enable_chroot |
694 | 700 | enable_bind |
699 | 705 | enable_file_transfer |
700 | 706 | enable_whitelist |
701 | 707 | enable_fatal_warnings |
708 | enable_busybox_workaround | |
702 | 709 | ' |
703 | 710 | ac_precious_vars='build_alias |
704 | 711 | host_alias |
1249 | 1256 | # Omit some internal or obsolete options to make the list less imposing. |
1250 | 1257 | # This message is too long to be a string in the A/UX 3.1 sh. |
1251 | 1258 | cat <<_ACEOF |
1252 | \`configure' configures firejail 0.9.42~rc1 to adapt to many kinds of systems. | |
1259 | \`configure' configures firejail 0.9.42~rc2 to adapt to many kinds of systems. | |
1253 | 1260 | |
1254 | 1261 | Usage: $0 [OPTION]... [VAR=VALUE]... |
1255 | 1262 | |
1310 | 1317 | |
1311 | 1318 | if test -n "$ac_init_help"; then |
1312 | 1319 | case $ac_init_help in |
1313 | short | recursive ) echo "Configuration of firejail 0.9.42~rc1:";; | |
1320 | short | recursive ) echo "Configuration of firejail 0.9.42~rc2:";; | |
1314 | 1321 | esac |
1315 | 1322 | cat <<\_ACEOF |
1316 | 1323 | |
1318 | 1325 | --disable-option-checking ignore unrecognized --enable/--with options |
1319 | 1326 | --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) |
1320 | 1327 | --enable-FEATURE[=ARG] include FEATURE [ARG=yes] |
1328 | --enable-apparmor enable apparmor | |
1329 | --disable-overlayfs disable overlayfs | |
1321 | 1330 | --disable-seccomp disable seccomp |
1322 | 1331 | --disable-chroot disable chroot |
1323 | 1332 | --disable-bind disable bind |
1331 | 1340 | --disable-file-transfer disable file transfer |
1332 | 1341 | --disable-whitelist disable whitelist |
1333 | 1342 | --enable-fatal-warnings -W -Wall -Werror |
1343 | --enable-busybox-workaround | |
1344 | enable busybox workaround | |
1334 | 1345 | |
1335 | 1346 | Some influential environment variables: |
1336 | 1347 | CC C compiler command |
1409 | 1420 | test -n "$ac_init_help" && exit $ac_status |
1410 | 1421 | if $ac_init_version; then |
1411 | 1422 | cat <<\_ACEOF |
1412 | firejail configure 0.9.42~rc1 | |
1423 | firejail configure 0.9.42~rc2 | |
1413 | 1424 | generated by GNU Autoconf 2.69 |
1414 | 1425 | |
1415 | 1426 | Copyright (C) 2012 Free Software Foundation, Inc. |
1460 | 1471 | as_fn_set_status $ac_retval |
1461 | 1472 | |
1462 | 1473 | } # ac_fn_c_try_compile |
1474 | ||
1475 | # ac_fn_c_try_cpp LINENO | |
1476 | # ---------------------- | |
1477 | # Try to preprocess conftest.$ac_ext, and return whether this succeeded. | |
1478 | ac_fn_c_try_cpp () | |
1479 | { | |
1480 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | |
1481 | if { { ac_try="$ac_cpp conftest.$ac_ext" | |
1482 | case "(($ac_try" in | |
1483 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | |
1484 | *) ac_try_echo=$ac_try;; | |
1485 | esac | |
1486 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | |
1487 | $as_echo "$ac_try_echo"; } >&5 | |
1488 | (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err | |
1489 | ac_status=$? | |
1490 | if test -s conftest.err; then | |
1491 | grep -v '^ *+' conftest.err >conftest.er1 | |
1492 | cat conftest.er1 >&5 | |
1493 | mv -f conftest.er1 conftest.err | |
1494 | fi | |
1495 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | |
1496 | test $ac_status = 0; } > conftest.i && { | |
1497 | test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || | |
1498 | test ! -s conftest.err | |
1499 | }; then : | |
1500 | ac_retval=0 | |
1501 | else | |
1502 | $as_echo "$as_me: failed program was:" >&5 | |
1503 | sed 's/^/| /' conftest.$ac_ext >&5 | |
1504 | ||
1505 | ac_retval=1 | |
1506 | fi | |
1507 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | |
1508 | as_fn_set_status $ac_retval | |
1509 | ||
1510 | } # ac_fn_c_try_cpp | |
1511 | ||
1512 | # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES | |
1513 | # ------------------------------------------------------- | |
1514 | # Tests whether HEADER exists, giving a warning if it cannot be compiled using | |
1515 | # the include files in INCLUDES and setting the cache variable VAR | |
1516 | # accordingly. | |
1517 | ac_fn_c_check_header_mongrel () | |
1518 | { | |
1519 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | |
1520 | if eval \${$3+:} false; then : | |
1521 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 | |
1522 | $as_echo_n "checking for $2... " >&6; } | |
1523 | if eval \${$3+:} false; then : | |
1524 | $as_echo_n "(cached) " >&6 | |
1525 | fi | |
1526 | eval ac_res=\$$3 | |
1527 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 | |
1528 | $as_echo "$ac_res" >&6; } | |
1529 | else | |
1530 | # Is the header compilable? | |
1531 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 | |
1532 | $as_echo_n "checking $2 usability... " >&6; } | |
1533 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
1534 | /* end confdefs.h. */ | |
1535 | $4 | |
1536 | #include <$2> | |
1537 | _ACEOF | |
1538 | if ac_fn_c_try_compile "$LINENO"; then : | |
1539 | ac_header_compiler=yes | |
1540 | else | |
1541 | ac_header_compiler=no | |
1542 | fi | |
1543 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | |
1544 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 | |
1545 | $as_echo "$ac_header_compiler" >&6; } | |
1546 | ||
1547 | # Is the header present? | |
1548 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 | |
1549 | $as_echo_n "checking $2 presence... " >&6; } | |
1550 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
1551 | /* end confdefs.h. */ | |
1552 | #include <$2> | |
1553 | _ACEOF | |
1554 | if ac_fn_c_try_cpp "$LINENO"; then : | |
1555 | ac_header_preproc=yes | |
1556 | else | |
1557 | ac_header_preproc=no | |
1558 | fi | |
1559 | rm -f conftest.err conftest.i conftest.$ac_ext | |
1560 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 | |
1561 | $as_echo "$ac_header_preproc" >&6; } | |
1562 | ||
1563 | # So? What about this header? | |
1564 | case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( | |
1565 | yes:no: ) | |
1566 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 | |
1567 | $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} | |
1568 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 | |
1569 | $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} | |
1570 | ;; | |
1571 | no:yes:* ) | |
1572 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 | |
1573 | $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} | |
1574 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 | |
1575 | $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} | |
1576 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 | |
1577 | $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} | |
1578 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 | |
1579 | $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} | |
1580 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 | |
1581 | $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} | |
1582 | ( $as_echo "## ---------------------------------- ## | |
1583 | ## Report this to netblue30@yahoo.com ## | |
1584 | ## ---------------------------------- ##" | |
1585 | ) | sed "s/^/$as_me: WARNING: /" >&2 | |
1586 | ;; | |
1587 | esac | |
1588 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 | |
1589 | $as_echo_n "checking for $2... " >&6; } | |
1590 | if eval \${$3+:} false; then : | |
1591 | $as_echo_n "(cached) " >&6 | |
1592 | else | |
1593 | eval "$3=\$ac_header_compiler" | |
1594 | fi | |
1595 | eval ac_res=\$$3 | |
1596 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 | |
1597 | $as_echo "$ac_res" >&6; } | |
1598 | fi | |
1599 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | |
1600 | ||
1601 | } # ac_fn_c_check_header_mongrel | |
1602 | ||
1603 | # ac_fn_c_try_run LINENO | |
1604 | # ---------------------- | |
1605 | # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes | |
1606 | # that executables *can* be run. | |
1607 | ac_fn_c_try_run () | |
1608 | { | |
1609 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | |
1610 | if { { ac_try="$ac_link" | |
1611 | case "(($ac_try" in | |
1612 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | |
1613 | *) ac_try_echo=$ac_try;; | |
1614 | esac | |
1615 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | |
1616 | $as_echo "$ac_try_echo"; } >&5 | |
1617 | (eval "$ac_link") 2>&5 | |
1618 | ac_status=$? | |
1619 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | |
1620 | test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' | |
1621 | { { case "(($ac_try" in | |
1622 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | |
1623 | *) ac_try_echo=$ac_try;; | |
1624 | esac | |
1625 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | |
1626 | $as_echo "$ac_try_echo"; } >&5 | |
1627 | (eval "$ac_try") 2>&5 | |
1628 | ac_status=$? | |
1629 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | |
1630 | test $ac_status = 0; }; }; then : | |
1631 | ac_retval=0 | |
1632 | else | |
1633 | $as_echo "$as_me: program exited with status $ac_status" >&5 | |
1634 | $as_echo "$as_me: failed program was:" >&5 | |
1635 | sed 's/^/| /' conftest.$ac_ext >&5 | |
1636 | ||
1637 | ac_retval=$ac_status | |
1638 | fi | |
1639 | rm -rf conftest.dSYM conftest_ipa8_conftest.oo | |
1640 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | |
1641 | as_fn_set_status $ac_retval | |
1642 | ||
1643 | } # ac_fn_c_try_run | |
1644 | ||
1645 | # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES | |
1646 | # ------------------------------------------------------- | |
1647 | # Tests whether HEADER exists and can be compiled using the include files in | |
1648 | # INCLUDES, setting the cache variable VAR accordingly. | |
1649 | ac_fn_c_check_header_compile () | |
1650 | { | |
1651 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | |
1652 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 | |
1653 | $as_echo_n "checking for $2... " >&6; } | |
1654 | if eval \${$3+:} false; then : | |
1655 | $as_echo_n "(cached) " >&6 | |
1656 | else | |
1657 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
1658 | /* end confdefs.h. */ | |
1659 | $4 | |
1660 | #include <$2> | |
1661 | _ACEOF | |
1662 | if ac_fn_c_try_compile "$LINENO"; then : | |
1663 | eval "$3=yes" | |
1664 | else | |
1665 | eval "$3=no" | |
1666 | fi | |
1667 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | |
1668 | fi | |
1669 | eval ac_res=\$$3 | |
1670 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 | |
1671 | $as_echo "$ac_res" >&6; } | |
1672 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | |
1673 | ||
1674 | } # ac_fn_c_check_header_compile | |
1463 | 1675 | |
1464 | 1676 | # ac_fn_c_try_link LINENO |
1465 | 1677 | # ----------------------- |
1506 | 1718 | as_fn_set_status $ac_retval |
1507 | 1719 | |
1508 | 1720 | } # ac_fn_c_try_link |
1509 | ||
1510 | # ac_fn_c_try_cpp LINENO | |
1511 | # ---------------------- | |
1512 | # Try to preprocess conftest.$ac_ext, and return whether this succeeded. | |
1513 | ac_fn_c_try_cpp () | |
1514 | { | |
1515 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | |
1516 | if { { ac_try="$ac_cpp conftest.$ac_ext" | |
1517 | case "(($ac_try" in | |
1518 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | |
1519 | *) ac_try_echo=$ac_try;; | |
1520 | esac | |
1521 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | |
1522 | $as_echo "$ac_try_echo"; } >&5 | |
1523 | (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err | |
1524 | ac_status=$? | |
1525 | if test -s conftest.err; then | |
1526 | grep -v '^ *+' conftest.err >conftest.er1 | |
1527 | cat conftest.er1 >&5 | |
1528 | mv -f conftest.er1 conftest.err | |
1529 | fi | |
1530 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | |
1531 | test $ac_status = 0; } > conftest.i && { | |
1532 | test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || | |
1533 | test ! -s conftest.err | |
1534 | }; then : | |
1535 | ac_retval=0 | |
1536 | else | |
1537 | $as_echo "$as_me: failed program was:" >&5 | |
1538 | sed 's/^/| /' conftest.$ac_ext >&5 | |
1539 | ||
1540 | ac_retval=1 | |
1541 | fi | |
1542 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | |
1543 | as_fn_set_status $ac_retval | |
1544 | ||
1545 | } # ac_fn_c_try_cpp | |
1546 | ||
1547 | # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES | |
1548 | # ------------------------------------------------------- | |
1549 | # Tests whether HEADER exists, giving a warning if it cannot be compiled using | |
1550 | # the include files in INCLUDES and setting the cache variable VAR | |
1551 | # accordingly. | |
1552 | ac_fn_c_check_header_mongrel () | |
1553 | { | |
1554 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | |
1555 | if eval \${$3+:} false; then : | |
1556 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 | |
1557 | $as_echo_n "checking for $2... " >&6; } | |
1558 | if eval \${$3+:} false; then : | |
1559 | $as_echo_n "(cached) " >&6 | |
1560 | fi | |
1561 | eval ac_res=\$$3 | |
1562 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 | |
1563 | $as_echo "$ac_res" >&6; } | |
1564 | else | |
1565 | # Is the header compilable? | |
1566 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 | |
1567 | $as_echo_n "checking $2 usability... " >&6; } | |
1568 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
1569 | /* end confdefs.h. */ | |
1570 | $4 | |
1571 | #include <$2> | |
1572 | _ACEOF | |
1573 | if ac_fn_c_try_compile "$LINENO"; then : | |
1574 | ac_header_compiler=yes | |
1575 | else | |
1576 | ac_header_compiler=no | |
1577 | fi | |
1578 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | |
1579 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 | |
1580 | $as_echo "$ac_header_compiler" >&6; } | |
1581 | ||
1582 | # Is the header present? | |
1583 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 | |
1584 | $as_echo_n "checking $2 presence... " >&6; } | |
1585 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
1586 | /* end confdefs.h. */ | |
1587 | #include <$2> | |
1588 | _ACEOF | |
1589 | if ac_fn_c_try_cpp "$LINENO"; then : | |
1590 | ac_header_preproc=yes | |
1591 | else | |
1592 | ac_header_preproc=no | |
1593 | fi | |
1594 | rm -f conftest.err conftest.i conftest.$ac_ext | |
1595 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 | |
1596 | $as_echo "$ac_header_preproc" >&6; } | |
1597 | ||
1598 | # So? What about this header? | |
1599 | case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( | |
1600 | yes:no: ) | |
1601 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 | |
1602 | $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} | |
1603 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 | |
1604 | $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} | |
1605 | ;; | |
1606 | no:yes:* ) | |
1607 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 | |
1608 | $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} | |
1609 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 | |
1610 | $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} | |
1611 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 | |
1612 | $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} | |
1613 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 | |
1614 | $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} | |
1615 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 | |
1616 | $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} | |
1617 | ( $as_echo "## ---------------------------------- ## | |
1618 | ## Report this to netblue30@yahoo.com ## | |
1619 | ## ---------------------------------- ##" | |
1620 | ) | sed "s/^/$as_me: WARNING: /" >&2 | |
1621 | ;; | |
1622 | esac | |
1623 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 | |
1624 | $as_echo_n "checking for $2... " >&6; } | |
1625 | if eval \${$3+:} false; then : | |
1626 | $as_echo_n "(cached) " >&6 | |
1627 | else | |
1628 | eval "$3=\$ac_header_compiler" | |
1629 | fi | |
1630 | eval ac_res=\$$3 | |
1631 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 | |
1632 | $as_echo "$ac_res" >&6; } | |
1633 | fi | |
1634 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | |
1635 | ||
1636 | } # ac_fn_c_check_header_mongrel | |
1637 | ||
1638 | # ac_fn_c_try_run LINENO | |
1639 | # ---------------------- | |
1640 | # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes | |
1641 | # that executables *can* be run. | |
1642 | ac_fn_c_try_run () | |
1643 | { | |
1644 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | |
1645 | if { { ac_try="$ac_link" | |
1646 | case "(($ac_try" in | |
1647 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | |
1648 | *) ac_try_echo=$ac_try;; | |
1649 | esac | |
1650 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | |
1651 | $as_echo "$ac_try_echo"; } >&5 | |
1652 | (eval "$ac_link") 2>&5 | |
1653 | ac_status=$? | |
1654 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | |
1655 | test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' | |
1656 | { { case "(($ac_try" in | |
1657 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | |
1658 | *) ac_try_echo=$ac_try;; | |
1659 | esac | |
1660 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | |
1661 | $as_echo "$ac_try_echo"; } >&5 | |
1662 | (eval "$ac_try") 2>&5 | |
1663 | ac_status=$? | |
1664 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | |
1665 | test $ac_status = 0; }; }; then : | |
1666 | ac_retval=0 | |
1667 | else | |
1668 | $as_echo "$as_me: program exited with status $ac_status" >&5 | |
1669 | $as_echo "$as_me: failed program was:" >&5 | |
1670 | sed 's/^/| /' conftest.$ac_ext >&5 | |
1671 | ||
1672 | ac_retval=$ac_status | |
1673 | fi | |
1674 | rm -rf conftest.dSYM conftest_ipa8_conftest.oo | |
1675 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | |
1676 | as_fn_set_status $ac_retval | |
1677 | ||
1678 | } # ac_fn_c_try_run | |
1679 | ||
1680 | # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES | |
1681 | # ------------------------------------------------------- | |
1682 | # Tests whether HEADER exists and can be compiled using the include files in | |
1683 | # INCLUDES, setting the cache variable VAR accordingly. | |
1684 | ac_fn_c_check_header_compile () | |
1685 | { | |
1686 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | |
1687 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 | |
1688 | $as_echo_n "checking for $2... " >&6; } | |
1689 | if eval \${$3+:} false; then : | |
1690 | $as_echo_n "(cached) " >&6 | |
1691 | else | |
1692 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
1693 | /* end confdefs.h. */ | |
1694 | $4 | |
1695 | #include <$2> | |
1696 | _ACEOF | |
1697 | if ac_fn_c_try_compile "$LINENO"; then : | |
1698 | eval "$3=yes" | |
1699 | else | |
1700 | eval "$3=no" | |
1701 | fi | |
1702 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | |
1703 | fi | |
1704 | eval ac_res=\$$3 | |
1705 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 | |
1706 | $as_echo "$ac_res" >&6; } | |
1707 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | |
1708 | ||
1709 | } # ac_fn_c_check_header_compile | |
1710 | 1721 | cat >config.log <<_ACEOF |
1711 | 1722 | This file contains any messages produced by compilers while |
1712 | 1723 | running configure, to aid debugging if configure makes a mistake. |
1713 | 1724 | |
1714 | It was created by firejail $as_me 0.9.42~rc1, which was | |
1725 | It was created by firejail $as_me 0.9.42~rc2, which was | |
1715 | 1726 | generated by GNU Autoconf 2.69. Invocation command line was |
1716 | 1727 | |
1717 | 1728 | $ $0 $@ |
3068 | 3079 | fi |
3069 | 3080 | |
3070 | 3081 | |
3071 | HAVE_SECCOMP="" | |
3072 | # Check whether --enable-seccomp was given. | |
3073 | if test "${enable_seccomp+set}" = set; then : | |
3074 | enableval=$enable_seccomp; | |
3075 | fi | |
3076 | ||
3077 | if test "x$enable_seccomp" != "xno"; then : | |
3078 | ||
3079 | HAVE_SECCOMP="-DHAVE_SECCOMP" | |
3080 | ||
3081 | ||
3082 | fi | |
3083 | ||
3084 | HAVE_CHROOT="" | |
3085 | # Check whether --enable-chroot was given. | |
3086 | if test "${enable_chroot+set}" = set; then : | |
3087 | enableval=$enable_chroot; | |
3088 | fi | |
3089 | ||
3090 | if test "x$enable_chroot" != "xno"; then : | |
3091 | ||
3092 | HAVE_CHROOT="-DHAVE_CHROOT" | |
3093 | ||
3094 | ||
3095 | fi | |
3096 | ||
3097 | HAVE_BIND="" | |
3098 | # Check whether --enable-bind was given. | |
3099 | if test "${enable_bind+set}" = set; then : | |
3100 | enableval=$enable_bind; | |
3101 | fi | |
3102 | ||
3103 | if test "x$enable_bind" != "xno"; then : | |
3104 | ||
3105 | HAVE_BIND="-DHAVE_BIND" | |
3106 | ||
3107 | ||
3108 | fi | |
3109 | ||
3110 | HAVE_GLOBALCFG="" | |
3111 | # Check whether --enable-globalcfg was given. | |
3112 | if test "${enable_globalcfg+set}" = set; then : | |
3113 | enableval=$enable_globalcfg; | |
3114 | fi | |
3115 | ||
3116 | if test "x$enable_globalcfg" != "xno"; then : | |
3117 | ||
3118 | HAVE_GLOBALCFG="-DHAVE_GLOBALCFG" | |
3119 | ||
3120 | ||
3121 | fi | |
3122 | ||
3123 | HAVE_NETWORK="" | |
3124 | # Check whether --enable-network was given. | |
3125 | if test "${enable_network+set}" = set; then : | |
3126 | enableval=$enable_network; | |
3127 | fi | |
3128 | ||
3129 | # Check whether --enable-network was given. | |
3130 | if test "${enable_network+set}" = set; then : | |
3131 | enableval=$enable_network; | |
3132 | fi | |
3133 | ||
3134 | if test "x$enable_network" != "xno"; then : | |
3135 | ||
3136 | HAVE_NETWORK="-DHAVE_NETWORK" | |
3137 | if test "x$enable_network" = "xrestricted"; then : | |
3138 | ||
3139 | HAVE_NETWORK="$HAVE_NETWORK -DHAVE_NETWORK_RESTRICTED" | |
3140 | ||
3141 | fi | |
3142 | ||
3143 | ||
3144 | fi | |
3145 | ||
3146 | HAVE_USERNS="" | |
3147 | # Check whether --enable-userns was given. | |
3148 | if test "${enable_userns+set}" = set; then : | |
3149 | enableval=$enable_userns; | |
3150 | fi | |
3151 | ||
3152 | if test "x$enable_userns" != "xno"; then : | |
3153 | ||
3154 | HAVE_USERNS="-DHAVE_USERNS" | |
3155 | ||
3156 | ||
3157 | fi | |
3158 | ||
3159 | HAVE_X11="" | |
3160 | # Check whether --enable-x11 was given. | |
3161 | if test "${enable_x11+set}" = set; then : | |
3162 | enableval=$enable_x11; | |
3163 | fi | |
3164 | ||
3165 | if test "x$enable_x11" != "xno"; then : | |
3166 | ||
3167 | HAVE_X11="-DHAVE_X11" | |
3168 | ||
3169 | ||
3170 | fi | |
3171 | ||
3172 | HAVE_FILE_TRANSFER="" | |
3173 | # Check whether --enable-file-transfer was given. | |
3174 | if test "${enable_file_transfer+set}" = set; then : | |
3175 | enableval=$enable_file_transfer; | |
3176 | fi | |
3177 | ||
3178 | if test "x$enable_file_transfer" != "xno"; then : | |
3179 | ||
3180 | HAVE_FILE_TRANSFER="-DHAVE_FILE_TRANSFER" | |
3181 | ||
3182 | ||
3183 | fi | |
3184 | ||
3185 | HAVE_WHITELIST="" | |
3186 | # Check whether --enable-whitelist was given. | |
3187 | if test "${enable_whitelist+set}" = set; then : | |
3188 | enableval=$enable_whitelist; | |
3189 | fi | |
3190 | ||
3191 | if test "x$enable_whitelist" != "xno"; then : | |
3192 | ||
3193 | HAVE_WHITELIST="-DHAVE_WHITELIST" | |
3194 | ||
3195 | ||
3196 | fi | |
3197 | ||
3198 | HAVE_FATAL_WARNINGS="" | |
3199 | # Check whether --enable-fatal_warnings was given. | |
3200 | if test "${enable_fatal_warnings+set}" = set; then : | |
3201 | enableval=$enable_fatal_warnings; | |
3202 | fi | |
3203 | ||
3204 | if test "x$enable_fatal_warnings" = "xyes"; then : | |
3205 | ||
3206 | HAVE_FATAL_WARNINGS="-W -Wall -Werror" | |
3207 | ||
3208 | ||
3209 | fi | |
3210 | ||
3211 | ||
3212 | # checking pthread library | |
3213 | ||
3214 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5 | |
3215 | $as_echo_n "checking for main in -lpthread... " >&6; } | |
3216 | if ${ac_cv_lib_pthread_main+:} false; then : | |
3217 | $as_echo_n "(cached) " >&6 | |
3218 | else | |
3219 | ac_check_lib_save_LIBS=$LIBS | |
3220 | LIBS="-lpthread $LIBS" | |
3221 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
3222 | /* end confdefs.h. */ | |
3223 | ||
3224 | ||
3225 | int | |
3226 | main () | |
3227 | { | |
3228 | return main (); | |
3229 | ; | |
3230 | return 0; | |
3231 | } | |
3232 | _ACEOF | |
3233 | if ac_fn_c_try_link "$LINENO"; then : | |
3234 | ac_cv_lib_pthread_main=yes | |
3235 | else | |
3236 | ac_cv_lib_pthread_main=no | |
3237 | fi | |
3238 | rm -f core conftest.err conftest.$ac_objext \ | |
3239 | conftest$ac_exeext conftest.$ac_ext | |
3240 | LIBS=$ac_check_lib_save_LIBS | |
3241 | fi | |
3242 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5 | |
3243 | $as_echo "$ac_cv_lib_pthread_main" >&6; } | |
3244 | if test "x$ac_cv_lib_pthread_main" = xyes; then : | |
3245 | cat >>confdefs.h <<_ACEOF | |
3246 | #define HAVE_LIBPTHREAD 1 | |
3247 | _ACEOF | |
3248 | ||
3249 | LIBS="-lpthread $LIBS" | |
3250 | ||
3251 | else | |
3252 | as_fn_error $? "*** POSIX thread support not installed ***" "$LINENO" 5 | |
3253 | fi | |
3082 | # Allow to build without apparmor support by calling: | |
3083 | # ./configure --disable-apparmor | |
3084 | # This makes it possible to run snaps in devmode on almost any host, | |
3085 | # regardless of the kernel version. | |
3086 | HAVE_APPARMOR="" | |
3087 | # Check whether --enable-apparmor was given. | |
3088 | if test "${enable_apparmor+set}" = set; then : | |
3089 | enableval=$enable_apparmor; | |
3090 | fi | |
3091 | ||
3092 | if test "x$enable_apparmor" = "xyes"; then : | |
3093 | ||
3094 | HAVE_APPARMOR="-DHAVE_APPARMOR" | |
3095 | ||
3096 | ||
3097 | fi | |
3098 | ||
3254 | 3099 | |
3255 | 3100 | ac_ext=c |
3256 | 3101 | ac_cpp='$CPP $CPPFLAGS' |
3649 | 3494 | done |
3650 | 3495 | |
3651 | 3496 | |
3497 | if test "x$enable_apparmor" = "xyes"; then : | |
3498 | ||
3499 | ac_fn_c_check_header_mongrel "$LINENO" "sys/apparmor.h" "ac_cv_header_sys_apparmor_h" "$ac_includes_default" | |
3500 | if test "x$ac_cv_header_sys_apparmor_h" = xyes; then : | |
3501 | ||
3502 | else | |
3503 | as_fn_error $? "Couldn't find sys/apparmor.h... please install apparmor user space library and development files " "$LINENO" 5 | |
3504 | fi | |
3505 | ||
3506 | ||
3507 | ||
3508 | fi | |
3509 | if test "x$enable_apparmor" = "xyes"; then : | |
3510 | ||
3511 | EXTRA_LDFLAGS="-lapparmor" | |
3512 | ||
3513 | fi | |
3514 | ||
3515 | ||
3516 | HAVE_OVERLAYFS="" | |
3517 | # Check whether --enable-overlayfs was given. | |
3518 | if test "${enable_overlayfs+set}" = set; then : | |
3519 | enableval=$enable_overlayfs; | |
3520 | fi | |
3521 | ||
3522 | if test "x$enable_overlayfs" != "xno"; then : | |
3523 | ||
3524 | HAVE_OVERLAYFS="-DHAVE_OVERLAYFS" | |
3525 | ||
3526 | ||
3527 | fi | |
3528 | ||
3529 | HAVE_SECCOMP="" | |
3530 | # Check whether --enable-seccomp was given. | |
3531 | if test "${enable_seccomp+set}" = set; then : | |
3532 | enableval=$enable_seccomp; | |
3533 | fi | |
3534 | ||
3535 | if test "x$enable_seccomp" != "xno"; then : | |
3536 | ||
3537 | HAVE_SECCOMP="-DHAVE_SECCOMP" | |
3538 | ||
3539 | ||
3540 | fi | |
3541 | ||
3542 | HAVE_CHROOT="" | |
3543 | # Check whether --enable-chroot was given. | |
3544 | if test "${enable_chroot+set}" = set; then : | |
3545 | enableval=$enable_chroot; | |
3546 | fi | |
3547 | ||
3548 | if test "x$enable_chroot" != "xno"; then : | |
3549 | ||
3550 | HAVE_CHROOT="-DHAVE_CHROOT" | |
3551 | ||
3552 | ||
3553 | fi | |
3554 | ||
3555 | HAVE_BIND="" | |
3556 | # Check whether --enable-bind was given. | |
3557 | if test "${enable_bind+set}" = set; then : | |
3558 | enableval=$enable_bind; | |
3559 | fi | |
3560 | ||
3561 | if test "x$enable_bind" != "xno"; then : | |
3562 | ||
3563 | HAVE_BIND="-DHAVE_BIND" | |
3564 | ||
3565 | ||
3566 | fi | |
3567 | ||
3568 | HAVE_GLOBALCFG="" | |
3569 | # Check whether --enable-globalcfg was given. | |
3570 | if test "${enable_globalcfg+set}" = set; then : | |
3571 | enableval=$enable_globalcfg; | |
3572 | fi | |
3573 | ||
3574 | if test "x$enable_globalcfg" != "xno"; then : | |
3575 | ||
3576 | HAVE_GLOBALCFG="-DHAVE_GLOBALCFG" | |
3577 | ||
3578 | ||
3579 | fi | |
3580 | ||
3581 | HAVE_NETWORK="" | |
3582 | # Check whether --enable-network was given. | |
3583 | if test "${enable_network+set}" = set; then : | |
3584 | enableval=$enable_network; | |
3585 | fi | |
3586 | ||
3587 | # Check whether --enable-network was given. | |
3588 | if test "${enable_network+set}" = set; then : | |
3589 | enableval=$enable_network; | |
3590 | fi | |
3591 | ||
3592 | if test "x$enable_network" != "xno"; then : | |
3593 | ||
3594 | HAVE_NETWORK="-DHAVE_NETWORK" | |
3595 | if test "x$enable_network" = "xrestricted"; then : | |
3596 | ||
3597 | HAVE_NETWORK="$HAVE_NETWORK -DHAVE_NETWORK_RESTRICTED" | |
3598 | ||
3599 | fi | |
3600 | ||
3601 | ||
3602 | fi | |
3603 | ||
3604 | HAVE_USERNS="" | |
3605 | # Check whether --enable-userns was given. | |
3606 | if test "${enable_userns+set}" = set; then : | |
3607 | enableval=$enable_userns; | |
3608 | fi | |
3609 | ||
3610 | if test "x$enable_userns" != "xno"; then : | |
3611 | ||
3612 | HAVE_USERNS="-DHAVE_USERNS" | |
3613 | ||
3614 | ||
3615 | fi | |
3616 | ||
3617 | HAVE_X11="" | |
3618 | # Check whether --enable-x11 was given. | |
3619 | if test "${enable_x11+set}" = set; then : | |
3620 | enableval=$enable_x11; | |
3621 | fi | |
3622 | ||
3623 | if test "x$enable_x11" != "xno"; then : | |
3624 | ||
3625 | HAVE_X11="-DHAVE_X11" | |
3626 | ||
3627 | ||
3628 | fi | |
3629 | ||
3630 | HAVE_FILE_TRANSFER="" | |
3631 | # Check whether --enable-file-transfer was given. | |
3632 | if test "${enable_file_transfer+set}" = set; then : | |
3633 | enableval=$enable_file_transfer; | |
3634 | fi | |
3635 | ||
3636 | if test "x$enable_file_transfer" != "xno"; then : | |
3637 | ||
3638 | HAVE_FILE_TRANSFER="-DHAVE_FILE_TRANSFER" | |
3639 | ||
3640 | ||
3641 | fi | |
3642 | ||
3643 | HAVE_WHITELIST="" | |
3644 | # Check whether --enable-whitelist was given. | |
3645 | if test "${enable_whitelist+set}" = set; then : | |
3646 | enableval=$enable_whitelist; | |
3647 | fi | |
3648 | ||
3649 | if test "x$enable_whitelist" != "xno"; then : | |
3650 | ||
3651 | HAVE_WHITELIST="-DHAVE_WHITELIST" | |
3652 | ||
3653 | ||
3654 | fi | |
3655 | ||
3656 | HAVE_FATAL_WARNINGS="" | |
3657 | # Check whether --enable-fatal_warnings was given. | |
3658 | if test "${enable_fatal_warnings+set}" = set; then : | |
3659 | enableval=$enable_fatal_warnings; | |
3660 | fi | |
3661 | ||
3662 | if test "x$enable_fatal_warnings" = "xyes"; then : | |
3663 | ||
3664 | HAVE_FATAL_WARNINGS="-W -Wall -Werror" | |
3665 | ||
3666 | ||
3667 | fi | |
3668 | ||
3669 | BUSYBOX_WORKAROUND="no" | |
3670 | # Check whether --enable-busybox-workaround was given. | |
3671 | if test "${enable_busybox_workaround+set}" = set; then : | |
3672 | enableval=$enable_busybox_workaround; | |
3673 | fi | |
3674 | ||
3675 | if test "x$enable_busybox_workaround" = "xyes"; then : | |
3676 | ||
3677 | BUSYBOX_WORKAROUND="yes" | |
3678 | ||
3679 | ||
3680 | fi | |
3681 | ||
3682 | ||
3683 | ||
3684 | # checking pthread library | |
3685 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5 | |
3686 | $as_echo_n "checking for main in -lpthread... " >&6; } | |
3687 | if ${ac_cv_lib_pthread_main+:} false; then : | |
3688 | $as_echo_n "(cached) " >&6 | |
3689 | else | |
3690 | ac_check_lib_save_LIBS=$LIBS | |
3691 | LIBS="-lpthread $LIBS" | |
3692 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
3693 | /* end confdefs.h. */ | |
3694 | ||
3695 | ||
3696 | int | |
3697 | main () | |
3698 | { | |
3699 | return main (); | |
3700 | ; | |
3701 | return 0; | |
3702 | } | |
3703 | _ACEOF | |
3704 | if ac_fn_c_try_link "$LINENO"; then : | |
3705 | ac_cv_lib_pthread_main=yes | |
3706 | else | |
3707 | ac_cv_lib_pthread_main=no | |
3708 | fi | |
3709 | rm -f core conftest.err conftest.$ac_objext \ | |
3710 | conftest$ac_exeext conftest.$ac_ext | |
3711 | LIBS=$ac_check_lib_save_LIBS | |
3712 | fi | |
3713 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5 | |
3714 | $as_echo "$ac_cv_lib_pthread_main" >&6; } | |
3715 | if test "x$ac_cv_lib_pthread_main" = xyes; then : | |
3716 | cat >>confdefs.h <<_ACEOF | |
3717 | #define HAVE_LIBPTHREAD 1 | |
3718 | _ACEOF | |
3719 | ||
3720 | LIBS="-lpthread $LIBS" | |
3721 | ||
3722 | else | |
3723 | as_fn_error $? "*** POSIX thread support not installed ***" "$LINENO" 5 | |
3724 | fi | |
3725 | ||
3652 | 3726 | ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" |
3653 | 3727 | if test "x$ac_cv_header_pthread_h" = xyes; then : |
3654 | 3728 | |
3671 | 3745 | if test "$prefix" = /usr; then |
3672 | 3746 | sysconfdir="/etc" |
3673 | 3747 | fi |
3748 | ||
3749 | # extract UID_MIN and GID_MIN from login.def | |
3750 | ./mkuid.sh | |
3674 | 3751 | |
3675 | 3752 | ac_config_files="$ac_config_files Makefile src/lib/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile" |
3676 | 3753 | |
4216 | 4293 | # report actual input values of CONFIG_FILES etc. instead of their |
4217 | 4294 | # values after options handling. |
4218 | 4295 | ac_log=" |
4219 | This file was extended by firejail $as_me 0.9.42~rc1, which was | |
4296 | This file was extended by firejail $as_me 0.9.42~rc2, which was | |
4220 | 4297 | generated by GNU Autoconf 2.69. Invocation command line was |
4221 | 4298 | |
4222 | 4299 | CONFIG_FILES = $CONFIG_FILES |
4270 | 4347 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 |
4271 | 4348 | ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" |
4272 | 4349 | ac_cs_version="\\ |
4273 | firejail config.status 0.9.42~rc1 | |
4350 | firejail config.status 0.9.42~rc2 | |
4274 | 4351 | configured by $0, generated by GNU Autoconf 2.69, |
4275 | 4352 | with options \\"\$ac_cs_config\\" |
4276 | 4353 | |
4851 | 4928 | echo " sysconfdir: $sysconfdir" |
4852 | 4929 | echo " seccomp: $HAVE_SECCOMP" |
4853 | 4930 | echo " <linux/seccomp.h>: $HAVE_SECCOMP_H" |
4931 | echo " apparmor: $HAVE_APPARMOR" | |
4854 | 4932 | echo " global config: $HAVE_GLOBALCFG" |
4855 | 4933 | echo " chroot: $HAVE_CHROOT" |
4856 | 4934 | echo " bind: $HAVE_BIND" |
4859 | 4937 | echo " X11 sandboxing support: $HAVE_X11" |
4860 | 4938 | echo " whitelisting: $HAVE_WHITELIST" |
4861 | 4939 | echo " file transfer support: $HAVE_FILE_TRANSFER" |
4940 | echo " overlayfs support: $HAVE_OVERLAYFS" | |
4862 | 4941 | echo " fatal warnings: $HAVE_FATAL_WARNINGS" |
4942 | echo " busybox workaround: $BUSYBOX_WORKAROUND" | |
4943 | printf " uid_min: "; grep UID_MIN uids.h | |
4944 | printf " gid_min: "; grep GID_MIN uids.h | |
4945 | printf " EXTRA_LDFLAGS: $EXTRA_LDFLAGS" | |
4863 | 4946 | echo |
4864 | 4947 | |
4865 | 4948 | |
4949 |
0 | 0 | AC_PREREQ([2.68]) |
1 | AC_INIT(firejail, 0.9.42~rc1, netblue30@yahoo.com, , http://firejail.wordpress.com) | |
1 | AC_INIT(firejail, 0.9.42~rc2, netblue30@yahoo.com, , http://firejail.wordpress.com) | |
2 | 2 | AC_CONFIG_SRCDIR([src/firejail/main.c]) |
3 | 3 | #AC_CONFIG_HEADERS([config.h]) |
4 | 4 | |
7 | 7 | #AC_PROG_CXX |
8 | 8 | AC_PROG_INSTALL |
9 | 9 | AC_PROG_RANLIB |
10 | ||
11 | # Allow to build without apparmor support by calling: | |
12 | # ./configure --disable-apparmor | |
13 | # This makes it possible to run snaps in devmode on almost any host, | |
14 | # regardless of the kernel version. | |
15 | HAVE_APPARMOR="" | |
16 | AC_ARG_ENABLE([apparmor], | |
17 | AS_HELP_STRING([--enable-apparmor], [enable apparmor])) | |
18 | AS_IF([test "x$enable_apparmor" = "xyes"], [ | |
19 | HAVE_APPARMOR="-DHAVE_APPARMOR" | |
20 | AC_SUBST(HAVE_APPARMOR) | |
21 | ]) | |
22 | ||
23 | AS_IF([test "x$enable_apparmor" = "xyes"], [ | |
24 | AC_CHECK_HEADER(sys/apparmor.h, , [AC_MSG_ERROR( | |
25 | [Couldn't find sys/apparmor.h... please install apparmor user space library and development files] )]) | |
26 | ]) | |
27 | AS_IF([test "x$enable_apparmor" = "xyes"], [ | |
28 | EXTRA_LDFLAGS="-lapparmor" | |
29 | ]) | |
30 | AC_SUBST([EXTRA_LDFLAGS]) | |
31 | ||
32 | HAVE_OVERLAYFS="" | |
33 | AC_ARG_ENABLE([overlayfs], | |
34 | AS_HELP_STRING([--disable-overlayfs], [disable overlayfs])) | |
35 | AS_IF([test "x$enable_overlayfs" != "xno"], [ | |
36 | HAVE_OVERLAYFS="-DHAVE_OVERLAYFS" | |
37 | AC_SUBST(HAVE_OVERLAYFS) | |
38 | ]) | |
10 | 39 | |
11 | 40 | HAVE_SECCOMP="" |
12 | 41 | AC_ARG_ENABLE([seccomp], |
93 | 122 | AC_SUBST(HAVE_FATAL_WARNINGS) |
94 | 123 | ]) |
95 | 124 | |
125 | BUSYBOX_WORKAROUND="no" | |
126 | AC_ARG_ENABLE([busybox-workaround], | |
127 | AS_HELP_STRING([--enable-busybox-workaround], [enable busybox workaround])) | |
128 | AS_IF([test "x$enable_busybox_workaround" = "xyes"], [ | |
129 | BUSYBOX_WORKAROUND="yes" | |
130 | AC_SUBST(BUSYBOX_WORKAROUND) | |
131 | ]) | |
132 | ||
133 | ||
96 | 134 | |
97 | 135 | # checking pthread library |
98 | 136 | AC_CHECK_LIB([pthread], [main], [], AC_MSG_ERROR([*** POSIX thread support not installed ***])) |
105 | 143 | sysconfdir="/etc" |
106 | 144 | fi |
107 | 145 | |
146 | # extract UID_MIN and GID_MIN from login.def | |
147 | ./mkuid.sh | |
148 | ||
108 | 149 | AC_OUTPUT(Makefile src/lib/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile) |
109 | 150 | |
110 | 151 | echo |
113 | 154 | echo " sysconfdir: $sysconfdir" |
114 | 155 | echo " seccomp: $HAVE_SECCOMP" |
115 | 156 | echo " <linux/seccomp.h>: $HAVE_SECCOMP_H" |
157 | echo " apparmor: $HAVE_APPARMOR" | |
116 | 158 | echo " global config: $HAVE_GLOBALCFG" |
117 | 159 | echo " chroot: $HAVE_CHROOT" |
118 | 160 | echo " bind: $HAVE_BIND" |
121 | 163 | echo " X11 sandboxing support: $HAVE_X11" |
122 | 164 | echo " whitelisting: $HAVE_WHITELIST" |
123 | 165 | echo " file transfer support: $HAVE_FILE_TRANSFER" |
166 | echo " overlayfs support: $HAVE_OVERLAYFS" | |
124 | 167 | echo " fatal warnings: $HAVE_FATAL_WARNINGS" |
168 | echo " busybox workaround: $BUSYBOX_WORKAROUND" | |
169 | printf " uid_min: "; grep UID_MIN uids.h | |
170 | printf " gid_min: "; grep GID_MIN uids.h | |
171 | printf " EXTRA_LDFLAGS: $EXTRA_LDFLAGS" | |
125 | 172 | echo |
126 | 173 | |
127 | 174 | |
175 |
7 | 7 | include /etc/firejail/disable-programs.inc |
8 | 8 | |
9 | 9 | # Whitelists |
10 | mkdir ~/.cache | |
11 | 10 | mkdir ~/.cache/0ad |
12 | 11 | whitelist ~/.cache/0ad |
13 | 12 | |
14 | mkdir ~/.config | |
15 | 13 | mkdir ~/.config/0ad |
16 | 14 | whitelist ~/.config/0ad |
17 | 15 | |
18 | mkdir ~/.local | |
19 | mkdir ~/.local/share | |
20 | 16 | mkdir ~/.local/share/0ad |
21 | 17 | whitelist ~/.local/share/0ad |
22 | 18 |
0 | # Firejail profile for Cyberfox (based on Mozilla Firefox) | |
1 | ||
2 | include /etc/firejail/cyberfox.profile |
16 | 16 | whitelist ${DOWNLOADS} |
17 | 17 | mkdir ~/.mozilla |
18 | 18 | whitelist ~/.mozilla |
19 | mkdir ~/.cache | |
20 | mkdir ~/.cache/mozilla | |
21 | 19 | mkdir ~/.cache/mozilla/abrowser |
22 | 20 | whitelist ~/.cache/mozilla/abrowser |
23 | 21 | whitelist ~/dwhelper |
5 | 5 | include /etc/firejail/disable-programs.inc |
6 | 6 | |
7 | 7 | # Whitelist |
8 | mkdir ~/.config | |
9 | 8 | mkdir ~/.config/aweather |
10 | 9 | whitelist ~/.config/aweather |
11 | 10 |
13 | 13 | |
14 | 14 | whitelist ${DOWNLOADS} |
15 | 15 | |
16 | mkdir ~/.config | |
17 | 16 | mkdir ~/.config/brave |
18 | 17 | whitelist ~/.config/brave |
6 | 6 | include /etc/firejail/disable-passwdmgr.inc |
7 | 7 | |
8 | 8 | whitelist ${HOME}/cherrytree |
9 | mkdir ~/.config | |
10 | 9 | mkdir ~/.config/cherrytree |
11 | 10 | whitelist ${HOME}/.config/cherrytree/ |
12 | mkdir ~/.local | |
13 | 11 | mkdir ~/.local/share |
14 | 12 | whitelist ${HOME}/.local/share/ |
15 | 13 |
10 | 10 | netfilter |
11 | 11 | |
12 | 12 | whitelist ${DOWNLOADS} |
13 | mkdir ~/.config | |
14 | 13 | mkdir ~/.config/chromium |
15 | 14 | whitelist ~/.config/chromium |
16 | mkdir ~/.cache | |
17 | 15 | mkdir ~/.cache/chromium |
18 | 16 | whitelist ~/.cache/chromium |
19 | 17 | mkdir ~/.pki |
0 | 0 | # cpio profile |
1 | 1 | # /sbin and /usr/sbin are visible inside the sandbox |
2 | 2 | # /boot is not visible and /var is heavily modified |
3 | ||
3 | quiet | |
4 | 4 | noblacklist /sbin |
5 | 5 | noblacklist /usr/sbin |
6 | 6 | include /etc/firejail/disable-common.inc |
0 | 0 | # Firejail profile for Cyberfox (based on Mozilla Firefox) |
1 | 1 | |
2 | noblacklist ~/.8pecxstudios/cyberfox | |
2 | noblacklist ~/.8pecxstudios | |
3 | 3 | noblacklist ~/.cache/8pecxstudios |
4 | 4 | include /etc/firejail/disable-common.inc |
5 | 5 | include /etc/firejail/disable-programs.inc |
16 | 16 | whitelist ${DOWNLOADS} |
17 | 17 | mkdir ~/.8pecxstudios |
18 | 18 | whitelist ~/.8pecxstudios |
19 | mkdir ~/.cache | |
20 | 19 | mkdir ~/.cache/8pecxstudios |
21 | mkdir ~/.cache/8pecxstudios/cyberfox | |
22 | whitelist ~/.cache/8pecxstudios/cyberfox | |
20 | whitelist ~/.cache/8pecxstudios | |
23 | 21 | whitelist ~/dwhelper |
24 | 22 | whitelist ~/.zotero |
25 | 23 | whitelist ~/.vimperatorrc |
13 | 13 | blacklist ${HOME}/.kde4/Autostart |
14 | 14 | blacklist ${HOME}/.kde4/share/autostart |
15 | 15 | blacklist ${HOME}/.kde/Autostart |
16 | blacklist ${HOME}/.kde/share/autostart | |
16 | 17 | blacklist ${HOME}/.config/plasma-workspace/shutdown |
17 | 18 | blacklist ${HOME}/.config/plasma-workspace/env |
18 | 19 | blacklist ${HOME}/.config/lxsession/LXDE/autostart |
153 | 154 | # prevent lxterminal connecting to an existing lxterminal session |
154 | 155 | blacklist /tmp/.lxterminal-socket* |
155 | 156 | |
156 | # disable terminals running as server | |
157 | # disable terminals running as server resulting in sandbox escape | |
157 | 158 | blacklist ${PATH}/gnome-terminal |
158 | 159 | blacklist ${PATH}/gnome-terminal.wrapper |
159 | 160 | blacklist ${PATH}/xfce4-terminal |
2 | 2 | blacklist ${HOME}/.keepassx |
3 | 3 | blacklist ${HOME}/.password-store |
4 | 4 | blacklist ${HOME}/keepassx.kdbx |
5 | blacklist ${HOME}/.config/keepassx | |
5 | 6 |
19 | 19 | blacklist ${HOME}/.config/xviewer |
20 | 20 | blacklist ${HOME}/.config/libreoffice |
21 | 21 | blacklist ${HOME}/.config/pix |
22 | blacklist ${HOME}/.config/mate/eom | |
22 | 23 | blacklist ${HOME}/.kde/share/apps/okular |
23 | 24 | blacklist ${HOME}/.kde/share/config/okularrc |
24 | 25 | blacklist ${HOME}/.kde/share/config/okularpartrc |
58 | 59 | blacklist ${HOME}/.config/qutebrowser |
59 | 60 | blacklist ${HOME}/.8pecxstudios |
60 | 61 | blacklist ${HOME}/.config/brave |
62 | blacklist ${HOME}/.config/inox | |
61 | 63 | |
62 | 64 | # Instant Messaging |
63 | 65 | blacklist ${HOME}/.config/hexchat |
69 | 71 | blacklist ${HOME}/.weechat |
70 | 72 | blacklist ${HOME}/.config/xchat |
71 | 73 | blacklist ${HOME}/.Skype |
74 | blacklist ${HOME}/.config/skypeforlinux | |
72 | 75 | blacklist ${HOME}/.config/tox |
73 | 76 | blacklist ${HOME}/.TelegramDesktop |
74 | 77 | blacklist ${HOME}/.config/Gitter |
75 | 78 | blacklist ${HOME}/.config/Franz |
76 | 79 | blacklist ${HOME}/.jitsi |
80 | blacklist ${HOME}/.config/Slack | |
81 | blacklist ${HOME}/.cache/gajim | |
82 | blacklist ${HOME}/.local/share/gajim | |
83 | blacklist ${HOME}/.config/gajim | |
77 | 84 | |
78 | 85 | # Games |
79 | 86 | blacklist ${HOME}/.hedgewars |
125 | 132 | blacklist ${HOME}/.local/share/totem |
126 | 133 | blacklist ${HOME}/.local/share/psi+ |
127 | 134 | blacklist ${HOME}/.local/share/pix |
135 | blacklist ${HOME}/.local/share/gnome-chess | |
136 | ||
137 | # ssh | |
138 | blacklist /tmp/ssh-* |
16 | 16 | mkdir ~/.dropbox-dist |
17 | 17 | whitelist ~/.dropbox-dist |
18 | 18 | |
19 | mkdir ~/.config/autostart | |
20 | 19 | mkfile ~/.config/autostart/dropbox.desktop |
21 | 20 | whitelist ~/.config/autostart/dropbox.desktop |
0 | # Firejail profile for Eye of Mate (eom) | |
1 | noblacklist ~/.config/mate/eom | |
2 | ||
3 | include /etc/firejail/disable-common.inc | |
4 | include /etc/firejail/disable-programs.inc | |
5 | include /etc/firejail/disable-devel.inc | |
6 | include /etc/firejail/disable-passwdmgr.inc | |
7 | ||
8 | caps.drop all | |
9 | nogroups | |
10 | nonewprivs | |
11 | noroot | |
12 | nosound | |
13 | protocol unix | |
14 | seccomp | |
15 | shell none | |
16 | tracelog | |
17 | ||
18 | private-bin eom | |
19 | private-dev |
7 | 7 | include /etc/firejail/disable-devel.inc |
8 | 8 | |
9 | 9 | whitelist ${DOWNLOADS} |
10 | mkdir ${HOME}/.local | |
11 | mkdir ${HOME}/.local/share | |
12 | 10 | mkdir ${HOME}/.local/share/epiphany |
13 | 11 | whitelist ${HOME}/.local/share/epiphany |
14 | mkdir ${HOME}/.config | |
15 | 12 | mkdir ${HOME}/.config/epiphany |
16 | 13 | whitelist ${HOME}/.config/epiphany |
17 | mkdir ${HOME}/.cache | |
18 | 14 | mkdir ${HOME}/.cache/epiphany |
19 | 15 | whitelist ${HOME}/.cache/epiphany |
20 | 16 | include /etc/firejail/whitelist-common.inc |
0 | # file profile | |
1 | quiet | |
2 | ignore noroot | |
3 | include /etc/firejail/default.profile | |
4 | ||
5 | tracelog | |
6 | net none | |
7 | shell none | |
8 | private-bin file | |
9 | private-dev | |
10 | private-etc magic.mgc,magic,localtime | |
11 | hostname file | |
12 | nosound |
16 | 16 | whitelist ${DOWNLOADS} |
17 | 17 | mkdir ~/.mozilla |
18 | 18 | whitelist ~/.mozilla |
19 | mkdir ~/.cache | |
20 | mkdir ~/.cache/mozilla | |
21 | 19 | mkdir ~/.cache/mozilla/firefox |
22 | 20 | whitelist ~/.cache/mozilla/firefox |
23 | 21 | whitelist ~/dwhelper |
0 | ######################################### | |
1 | # Generic Firejail AppArmor profile | |
2 | ######################################### | |
3 | ||
4 | ########## | |
5 | # A simple PID declaration based on Ubuntu's @{pid} | |
6 | # Ubuntu keeps it under tunables/kernelvars and include it via tunables/global. | |
7 | # We don't know if this definition is available outside Debian and Ubuntu, so | |
8 | # we declare our own here. | |
9 | ########## | |
10 | @{PID}={[1-9],[1-9][0-9],[1-9][0-9][0-9],[1-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9][0-9]} | |
11 | ||
12 | profile firejail-default { | |
13 | ||
14 | ########## | |
15 | # D-Bus is a huge security hole. Uncomment this line if you need D-Bus | |
16 | # functionality. | |
17 | ########## | |
18 | #dbus, | |
19 | ||
20 | ########## | |
21 | # Mask /proc and /sys information leakage. The configuration here is barely | |
22 | # enough to run "top" or "ps aux". | |
23 | ########## | |
24 | / r, | |
25 | /[^proc,^sys]** mrwlk, | |
26 | /{,var/}run/ r, | |
27 | /{,var/}run/** r, | |
28 | /{,var/}run/user/**/dconf/ rw, | |
29 | /{,var/}run/user/**/dconf/user rw, | |
30 | /{,var/}run/user/**/pulse/ rw, | |
31 | /{,var/}run/user/**/pulse/** rw, | |
32 | /{,var/}run/firejail/mnt/fslogger r, | |
33 | /{run,dev}/shm/ r, | |
34 | /{run,dev}/shm/** rmwk, | |
35 | ||
36 | /proc/ r, | |
37 | /proc/meminfo r, | |
38 | /proc/cpuinfo r, | |
39 | /proc/filesystems r, | |
40 | /proc/uptime r, | |
41 | /proc/loadavg r, | |
42 | /proc/stat r, | |
43 | ||
44 | /proc/@{PID}/ r, | |
45 | /proc/@{PID}/fd/ r, | |
46 | /proc/@{PID}/task/ r, | |
47 | /proc/@{PID}/cmdline r, | |
48 | /proc/@{PID}/comm r, | |
49 | /proc/@{PID}/stat r, | |
50 | /proc/@{PID}/statm r, | |
51 | /proc/@{PID}/status r, | |
52 | /proc/@{PID}/task/@{PID}/stat r, | |
53 | /proc/sys/kernel/pid_max r, | |
54 | /proc/sys/kernel/shmmax r, | |
55 | /proc/sys/vm/overcommit_memory r, | |
56 | /proc/sys/vm/overcommit_ratio r, | |
57 | ||
58 | /sys/ r, | |
59 | /sys/bus/ r, | |
60 | /sys/bus/** r, | |
61 | /sys/class/ r, | |
62 | /sys/class/** r, | |
63 | /sys/devices/ r, | |
64 | /sys/devices/** r, | |
65 | ||
66 | /proc/@{PID}/maps r, | |
67 | /proc/@{PID}/mounts r, | |
68 | /proc/@{PID}/mountinfo r, | |
69 | /proc/@{PID}/oom_score_adj r, | |
70 | ||
71 | ########## | |
72 | # Allow running programs only from well-known system directories. If you need | |
73 | # to run programs from your home directory, uncomment /home line. | |
74 | ########## | |
75 | /lib/** ix, | |
76 | /lib64/** ix, | |
77 | /bin/** ix, | |
78 | /sbin/** ix, | |
79 | /usr/bin/** ix, | |
80 | /usr/sbin/** ix, | |
81 | /usr/local/** ix, | |
82 | /usr/lib/** ix, | |
83 | /usr/games/** ix, | |
84 | /opt/** ix, | |
85 | #/home/** ix, | |
86 | ||
87 | ########## | |
88 | # Allow all networking functionality, and control it from Firejail. | |
89 | ########## | |
90 | network inet, | |
91 | network inet6, | |
92 | network unix, | |
93 | network netlink, | |
94 | network raw, | |
95 | ||
96 | ########## | |
97 | # There is no equivalent in Firejail for filtering signals. | |
98 | ########## | |
99 | signal, | |
100 | ||
101 | ########## | |
102 | # We let Firejail deal with capabilities. | |
103 | ########## | |
104 | capability chown, | |
105 | capability dac_override, | |
106 | capability dac_read_search, | |
107 | capability fowner, | |
108 | capability fsetid, | |
109 | capability kill, | |
110 | capability setgid, | |
111 | capability setuid, | |
112 | capability setpcap, | |
113 | capability linux_immutable, | |
114 | capability net_bind_service, | |
115 | capability net_broadcast, | |
116 | capability net_admin, | |
117 | capability net_raw, | |
118 | capability ipc_lock, | |
119 | capability ipc_owner, | |
120 | capability sys_module, | |
121 | capability sys_rawio, | |
122 | capability sys_chroot, | |
123 | capability sys_ptrace, | |
124 | capability sys_pacct, | |
125 | capability sys_admin, | |
126 | capability sys_boot, | |
127 | capability sys_nice, | |
128 | capability sys_resource, | |
129 | capability sys_time, | |
130 | capability sys_tty_config, | |
131 | capability mknod, | |
132 | capability lease, | |
133 | capability audit_write, | |
134 | capability audit_control, | |
135 | capability setfcap, | |
136 | capability mac_override, | |
137 | capability mac_admin, | |
138 | ||
139 | ########## | |
140 | # We let Firejail deal with mount/umount functionality. | |
141 | ########## | |
142 | mount, | |
143 | remount, | |
144 | umount, | |
145 | pivot_root, | |
146 | ||
147 | } | |
148 |
8 | 8 | # Enable or disable chroot support, default enabled. |
9 | 9 | # chroot yes |
10 | 10 | |
11 | # Use chroot for desktop programs, default enabled. The sandbox will have full | |
12 | # access to system's /dev directory in order to allow video acceleration, | |
13 | # and it will harden the rest of the chroot tree. | |
14 | # chroot-desktop yes | |
15 | ||
11 | 16 | # Enable or disable file transfer support, default enabled. |
12 | 17 | # file-transfer yes |
13 | 18 | |
14 | 19 | # Force use of nonewprivs. This mitigates the possibility of |
15 | 20 | # a user abusing firejail's features to trick a privileged (suid |
16 | 21 | # or file capabilities) process into loading code or configuration |
17 | # that is partially under their control. Default disabled | |
22 | # that is partially under their control. Default disabled. | |
18 | 23 | # force-nonewprivs no |
19 | 24 | |
20 | 25 | # Enable or disable networking features, default enabled. |
21 | 26 | # network yes |
27 | ||
28 | # Enable or disable overlayfs features, default enabled. | |
29 | # overlayfs yes | |
30 | ||
31 | # Enable --quiet as default every time the sandbox is started. Default disabled. | |
32 | # quiet-by-default no | |
33 | ||
34 | # Remount /proc and /sys inside the sandbox, default enabled. | |
35 | # remount-proc-sys yes | |
22 | 36 | |
23 | 37 | # Enable or disable restricted network support, default disabled. If enabled, |
24 | 38 | # networking features should also be enabled (network yes). |
25 | 39 | # Restricted networking grants access to --interface, --net=ethXXX and |
26 | 40 | # --netfilter only to root user. Regular users are only allowed --net=none. |
27 | 41 | # restricted-network no |
42 | ||
43 | # Change default netfilter configuration. When using --netfilter option without | |
44 | # a file argument, the default filter is hardcoded (see man 1 firejail). This | |
45 | # configuration entry allows the user to change the default by specifying | |
46 | # a file containing the filter configuration. The filter file format is the | |
47 | # format of iptables-save and iptable-restore commands. Example: | |
48 | # netfilter-default /etc/iptables.iptables.rules | |
28 | 49 | |
29 | 50 | # Enable or disable seccomp support, default enabled. |
30 | 51 | # seccomp yes |
21 | 21 | seccomp |
22 | 22 | |
23 | 23 | whitelist ${DOWNLOADS} |
24 | mkdir ~/.config | |
25 | 24 | mkdir ~/.config/slimjet |
26 | 25 | whitelist ~/.config/slimjet |
27 | mkdir ~/.cache | |
28 | 26 | mkdir ~/.cache/slimjet |
29 | 27 | whitelist ~/.cache/slimjet |
30 | 28 | mkdir ~/.pki |
13 | 13 | noroot |
14 | 14 | |
15 | 15 | whitelist ${DOWNLOADS} |
16 | mkdir ~/.config | |
17 | 16 | mkdir ~/.config/Franz |
18 | 17 | whitelist ~/.config/Franz |
19 | mkdir ~/.cache | |
20 | 18 | mkdir ~/.cache/Franz |
21 | 19 | whitelist ~/.cache/Franz |
22 | 20 | mkdir ~/.pki |
0 | # Firejail profile for Gajim | |
1 | ||
2 | mkdir ${HOME}/.cache/gajim | |
3 | mkdir ${HOME}/.local/share/gajim | |
4 | mkdir ${HOME}/.config/gajim | |
5 | mkdir ${HOME}/Downloads | |
6 | ||
7 | # Allow the local python 2.7 site packages, in case any plugins are using these | |
8 | mkdir ${HOME}/.local/lib/python2.7/site-packages/ | |
9 | whitelist ${HOME}/.local/lib/python2.7/site-packages/ | |
10 | read-only ${HOME}/.local/lib/python2.7/site-packages/ | |
11 | ||
12 | whitelist ${HOME}/.cache/gajim | |
13 | whitelist ${HOME}/.local/share/gajim | |
14 | whitelist ${HOME}/.config/gajim | |
15 | whitelist ${HOME}/Downloads | |
16 | ||
17 | include /etc/firejail/disable-common.inc | |
18 | include /etc/firejail/disable-passwdmgr.inc | |
19 | include /etc/firejail/disable-programs.inc | |
20 | include /etc/firejail/disable-devel.inc | |
21 | ||
22 | caps.drop all | |
23 | netfilter | |
24 | nonewprivs | |
25 | nogroups | |
26 | noroot | |
27 | protocol unix,inet,inet6 | |
28 | seccomp | |
29 | shell none | |
30 | ||
31 | #private-bin python2.7 gajim | |
32 | private-dev |
0 | # Firejail profile for gnome-chess | |
1 | noblacklist /.local/share/gnome-chess | |
2 | ||
3 | include /etc/firejail/disable-common.inc | |
4 | include /etc/firejail/disable-devel.inc | |
5 | include /etc/firejail/disable-programs.inc | |
6 | include /etc/firejail/disable-passwdmgr.inc | |
7 | ||
8 | caps.drop all | |
9 | nogroups | |
10 | nonewprivs | |
11 | noroot | |
12 | nosound | |
13 | protocol unix | |
14 | seccomp | |
15 | shell none | |
16 | tracelog | |
17 | ||
18 | private-bin fairymax,gnome-chess,hoichess | |
19 | private-dev | |
20 | private-etc fonts,gnome-chess | |
21 | private-tmp |
4 | 4 | include /etc/firejail/disable-passwdmgr.inc |
5 | 5 | |
6 | 6 | caps.drop all |
7 | nogroups | |
7 | 8 | nonewprivs |
8 | 9 | noroot |
9 | 10 | protocol unix,inet,inet6 |
10 | 11 | seccomp |
12 | shell none | |
11 | 13 | |
12 | shell none | |
13 | 14 | private-bin gnome-mplayer |
15 | private-dev | |
16 | private-tmp |
10 | 10 | netfilter |
11 | 11 | |
12 | 12 | whitelist ${DOWNLOADS} |
13 | mkdir ~/.config | |
14 | 13 | mkdir ~/.config/google-chrome-beta |
15 | 14 | whitelist ~/.config/google-chrome-beta |
16 | mkdir ~/.cache | |
17 | 15 | mkdir ~/.cache/google-chrome-beta |
18 | 16 | whitelist ~/.cache/google-chrome-beta |
19 | 17 | mkdir ~/.pki |
10 | 10 | netfilter |
11 | 11 | |
12 | 12 | whitelist ${DOWNLOADS} |
13 | mkdir ~/.config | |
14 | 13 | mkdir ~/.config/google-chrome-unstable |
15 | 14 | whitelist ~/.config/google-chrome-unstable |
16 | mkdir ~/.cache | |
17 | 15 | mkdir ~/.cache/google-chrome-unstable |
18 | 16 | whitelist ~/.cache/google-chrome-unstable |
19 | 17 | mkdir ~/.pki |
10 | 10 | netfilter |
11 | 11 | |
12 | 12 | whitelist ${DOWNLOADS} |
13 | mkdir ~/.config | |
14 | 13 | mkdir ~/.config/google-chrome |
15 | 14 | whitelist ~/.config/google-chrome |
16 | mkdir ~/.cache | |
17 | 15 | mkdir ~/.cache/google-chrome |
18 | 16 | whitelist ~/.cache/google-chrome |
19 | 17 | mkdir ~/.pki |
5 | 5 | include /etc/firejail/disable-programs.inc |
6 | 6 | |
7 | 7 | # Whitelist |
8 | mkdir ~/.config | |
9 | 8 | mkdir ~/.config/Gpredict |
10 | 9 | whitelist ~/.config/Gpredict |
11 | 10 | |
15 | 14 | nogroups |
16 | 15 | noroot |
17 | 16 | nosound |
18 | protocol unix,inet,inet6,netlink | |
17 | protocol unix,inet,inet6 | |
19 | 18 | seccomp |
20 | 19 | shell none |
21 | 20 | tracelog |
22 | 21 | |
23 | 22 | private-bin gpredict |
24 | 23 | private-dev |
24 | private-tmp |
6 | 6 | include /etc/firejail/disable-passwdmgr.inc |
7 | 7 | |
8 | 8 | caps.drop all |
9 | nogroups | |
9 | 10 | nonewprivs |
10 | nogroups | |
11 | 11 | noroot |
12 | 12 | nosound |
13 | 13 | protocol unix |
18 | 18 | private-bin gthumb |
19 | 19 | whitelist /tmp/.X11-unix |
20 | 20 | private-dev |
21 | private-tmp |
0 | 0 | # gzip profile |
1 | quiet | |
2 | ignore noroot | |
1 | 3 | include /etc/firejail/default.profile |
2 | 4 | tracelog |
3 | 5 | net none |
6 | 6 | include /etc/firejail/disable-passwdmgr.inc |
7 | 7 | |
8 | 8 | caps.drop all |
9 | netfilter | |
10 | nogroups | |
9 | 11 | nonewprivs |
10 | 12 | noroot |
11 | private-dev | |
12 | 13 | seccomp |
13 | 14 | tracelog |
15 | ||
16 | private-dev | |
17 | private-tmp | |
14 | 18 | |
15 | 19 | mkdir ~/.hedgewars |
16 | 20 | whitelist ~/.hedgewars |
6 | 6 | include /etc/firejail/disable-devel.inc |
7 | 7 | |
8 | 8 | caps.drop all |
9 | netfilter | |
10 | nogroups | |
9 | 11 | nonewprivs |
10 | 12 | noroot |
11 | netfilter | |
13 | nosound | |
12 | 14 | protocol unix,inet,inet6 |
13 | 15 | seccomp |
14 | 16 | |
15 | mkdir ~/.config | |
16 | 17 | mkdir ~/.config/hexchat |
17 | 18 | whitelist ~/.config/hexchat |
18 | 19 | include /etc/firejail/whitelist-common.inc |
19 | 20 | |
20 | 21 | # private-bin requires perl, python, etc. |
22 | private-dev | |
23 | private-tmp |
0 | 0 | # Firejail profile for GNU Icecat |
1 | include /etc/firejail/firefox.profile | |
1 | ||
2 | noblacklist ~/.mozilla | |
3 | noblacklist ~/.cache/mozilla | |
4 | include /etc/firejail/disable-common.inc | |
5 | include /etc/firejail/disable-programs.inc | |
6 | include /etc/firejail/disable-devel.inc | |
7 | ||
8 | caps.drop all | |
9 | netfilter | |
10 | nonewprivs | |
11 | noroot | |
12 | protocol unix,inet,inet6,netlink | |
13 | seccomp | |
14 | tracelog | |
15 | ||
16 | whitelist ${DOWNLOADS} | |
17 | mkdir ~/.mozilla | |
18 | whitelist ~/.mozilla | |
19 | mkdir ~/.cache/mozilla/icecat | |
20 | whitelist ~/.cache/mozilla/icecat | |
21 | whitelist ~/dwhelper | |
22 | whitelist ~/.zotero | |
23 | whitelist ~/.vimperatorrc | |
24 | whitelist ~/.vimperator | |
25 | whitelist ~/.pentadactylrc | |
26 | whitelist ~/.pentadactyl | |
27 | whitelist ~/.keysnail.js | |
28 | whitelist ~/.config/gnome-mplayer | |
29 | whitelist ~/.cache/gnome-mplayer/plugin | |
30 | whitelist ~/.pki | |
31 | ||
32 | # lastpass, keepassx | |
33 | whitelist ~/.keepassx | |
34 | whitelist ~/.config/keepassx | |
35 | whitelist ~/keepassx.kdbx | |
36 | whitelist ~/.lastpass | |
37 | whitelist ~/.config/lastpass | |
38 | ||
39 | ||
40 | #silverlight | |
41 | whitelist ~/.wine-pipelight | |
42 | whitelist ~/.wine-pipelight64 | |
43 | whitelist ~/.config/pipelight-widevine | |
44 | whitelist ~/.config/pipelight-silverlight5.1 | |
45 | ||
46 | include /etc/firejail/whitelist-common.inc | |
47 | ||
48 | # experimental features | |
49 | #private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,gtk-2.0,pango,fonts,iceweasel,firefox,adobe,mime.types,mailcap,asound.conf,pulse | |
50 |
10 | 10 | whitelist ~/.icedove |
11 | 11 | |
12 | 12 | noblacklist ~/.cache/icedove |
13 | mkdir ~/.cache | |
14 | 13 | mkdir ~/.cache/icedove |
15 | 14 | whitelist ~/.cache/icedove |
16 | 15 |
0 | # Inox browser profile | |
1 | noblacklist ~/.config/inox | |
2 | noblacklist ~/.cache/inox | |
3 | include /etc/firejail/disable-common.inc | |
4 | include /etc/firejail/disable-programs.inc | |
5 | ||
6 | netfilter | |
7 | ||
8 | whitelist ${DOWNLOADS} | |
9 | mkdir ~/.config/inox | |
10 | whitelist ~/.config/inox | |
11 | mkdir ~/.cache/inox | |
12 | whitelist ~/.cache/inox | |
13 | mkdir ~/.pki | |
14 | whitelist ~/.pki | |
15 | ||
16 | # lastpass, keepassx | |
17 | whitelist ~/.keepassx | |
18 | whitelist ~/.config/keepassx | |
19 | whitelist ~/keepassx.kdbx | |
20 | whitelist ~/.lastpass | |
21 | whitelist ~/.config/lastpass | |
22 | ||
23 | include /etc/firejail/whitelist-common.inc |
8 | 8 | caps.drop all |
9 | 9 | netfilter |
10 | 10 | nonewprivs |
11 | nogroups | |
11 | 12 | noroot |
12 | 13 | protocol unix,inet,inet6,netlink |
13 | 14 | seccomp |
14 | 15 | tracelog |
16 | ||
17 | private-dev | |
18 | private-tmp |
6 | 6 | |
7 | 7 | caps.drop all |
8 | 8 | netfilter |
9 | nogroups | |
9 | 10 | noroot |
10 | 11 | seccomp |
11 | 12 | protocol unix,inet,inet6 |
13 | ||
14 | private-tmp |
0 | 0 | # less profile |
1 | quiet | |
2 | ignore noroot | |
1 | 3 | include /etc/firejail/default.profile |
2 | 4 | tracelog |
3 | 5 | net none |
7 | 7 | include /etc/firejail/disable-devel.inc |
8 | 8 | include /etc/firejail/disable-passwdmgr.inc |
9 | 9 | |
10 | mkdir ${HOME}/.local | |
11 | mkdir ${HOME}/.local/share | |
12 | 10 | mkdir ${HOME}/.local/share/mupen64plus |
13 | 11 | whitelist ${HOME}/.local/share/mupen64plus/ |
14 | mkdir ${HOME}/.config | |
15 | 12 | mkdir ${HOME}/.config/mupen64plus |
16 | 13 | whitelist ${HOME}/.config/mupen64plus/ |
17 | 14 |
14 | 14 | tracelog |
15 | 15 | |
16 | 16 | whitelist ${DOWNLOADS} |
17 | mkdir ~/.config | |
18 | 17 | mkdir ~/.config/netsurf |
19 | 18 | whitelist ~/.config/netsurf |
20 | mkdir ~/.cache | |
21 | 19 | mkdir ~/.cache/netsurf |
22 | 20 | whitelist ~/.cache/netsurf |
23 | 21 |
3 | 3 | :OUTPUT ACCEPT [0:0] |
4 | 4 | |
5 | 5 | ################################################################### |
6 | # Client filter rejecting local network traffic, with the exception of DNS traffic | |
6 | # Client filter rejecting local network traffic, with the exception of | |
7 | # DNS traffic | |
7 | 8 | # |
8 | 9 | # Usage: |
9 | 10 | # firejail --net=eth0 --netfilter=/etc/firejail/nolocal.net firefox |
7 | 7 | netfilter |
8 | 8 | |
9 | 9 | whitelist ${DOWNLOADS} |
10 | mkdir ~/.config | |
11 | 10 | mkdir ~/.config/opera-beta |
12 | 11 | whitelist ~/.config/opera-beta |
13 | mkdir ~/.cache | |
14 | 12 | mkdir ~/.cache/opera-beta |
15 | 13 | whitelist ~/.cache/opera-beta |
16 | 14 | mkdir ~/.pki |
8 | 8 | netfilter |
9 | 9 | |
10 | 10 | whitelist ${DOWNLOADS} |
11 | mkdir ~/.config | |
12 | 11 | mkdir ~/.config/opera |
13 | 12 | whitelist ~/.config/opera |
14 | mkdir ~/.cache | |
15 | 13 | mkdir ~/.cache/opera |
16 | 14 | whitelist ~/.cache/opera |
17 | 15 | mkdir ~/.opera |
8 | 8 | whitelist ${DOWNLOADS} |
9 | 9 | mkdir ~/.moonchild productions |
10 | 10 | whitelist ~/.moonchild productions |
11 | mkdir ~/.cache | |
12 | mkdir ~/.cache/moonchild productions | |
13 | 11 | mkdir ~/.cache/moonchild productions/pale moon |
14 | 12 | whitelist ~/.cache/moonchild productions/pale moon |
15 | 13 |
2 | 2 | include /etc/firejail/disable-programs.inc |
3 | 3 | include /etc/firejail/disable-devel.inc |
4 | 4 | |
5 | mkdir ${HOME}/.local | |
6 | mkdir ${HOME}/.local/share/ | |
7 | 5 | mkdir ${HOME}/.local/share/Empathy |
8 | 6 | whitelist ${HOME}/.local/share/Empathy |
9 | 7 | mkdir ${HOME}/.local/share/telepathy |
10 | 8 | whitelist ${HOME}/.local/share/telepathy |
11 | 9 | mkdir ${HOME}/.local/share/TpLogger |
12 | 10 | whitelist ${HOME}/.local/share/TpLogger |
13 | mkdir ${HOME}/.config | |
14 | 11 | mkdir ${HOME}/.config/telepathy-account-widgets |
15 | 12 | whitelist ${HOME}/.config/telepathy-account-widgets |
16 | mkdir ${HOME}/.cache | |
17 | 13 | mkdir ${HOME}/.cache/telepathy |
18 | 14 | whitelist ${HOME}/.cache/telepathy |
19 | 15 | mkdir ${HOME}/.purple |
6 | 6 | include /etc/firejail/disable-passwdmgr.inc |
7 | 7 | |
8 | 8 | whitelist ${DOWNLOADS} |
9 | mkdir ~/.config | |
10 | 9 | mkdir ~/.config/psi+ |
11 | 10 | whitelist ~/.config/psi+ |
12 | mkdir ~/.local | |
13 | mkdir ~/.local/share | |
14 | 11 | mkdir ~/.local/share/psi+ |
15 | 12 | whitelist ~/.local/share/psi+ |
16 | mkdir ~/.cache | |
17 | 13 | mkdir ~/.cache/psi+ |
18 | 14 | whitelist ~/.cache/psi+ |
19 | 15 |
3 | 3 | include /etc/firejail/disable-devel.inc |
4 | 4 | |
5 | 5 | whitelist ${HOME}/quiterssfeeds.opml |
6 | mkdir ~/.config | |
7 | 6 | mkdir ~/.config/QuiteRss |
8 | 7 | whitelist ${HOME}/.config/QuiteRss/ |
9 | 8 | whitelist ${HOME}/.config/QuiteRssrc |
10 | mkdir ~/.local | |
11 | 9 | mkdir ~/.local/share |
12 | 10 | whitelist ${HOME}/.local/share/ |
13 | mkdir ~/.cache | |
14 | 11 | mkdir ~/.cache/QuiteRss |
15 | 12 | whitelist ${HOME}/.cache/QuiteRss |
16 | 13 |
16 | 16 | whitelist ${DOWNLOADS} |
17 | 17 | mkdir ~/.config/qutebrowser |
18 | 18 | whitelist ~/.config/qutebrowser |
19 | mkdir ~/.cache | |
20 | 19 | mkdir ~/.cache/qutebrowser |
21 | 20 | whitelist ~/.cache/qutebrowser |
22 | 21 | include /etc/firejail/whitelist-common.inc |
13 | 13 | tracelog |
14 | 14 | |
15 | 15 | whitelist ${DOWNLOADS} |
16 | mkdir ~/.mozilla | |
17 | 16 | mkdir ~/.mozilla/seamonkey |
18 | 17 | whitelist ~/.mozilla/seamonkey |
19 | mkdir ~/.cache | |
20 | mkdir ~/.cache/mozilla | |
21 | 18 | mkdir ~/.cache/mozilla/seamonkey |
22 | 19 | whitelist ~/.cache/mozilla/seamonkey |
23 | 20 | whitelist ~/dwhelper |
0 | # skypeforlinux profile | |
1 | noblacklist ${HOME}/.config/skypeforlinux | |
2 | include /etc/firejail/disable-common.inc | |
3 | include /etc/firejail/disable-programs.inc | |
4 | include /etc/firejail/disable-passwdmgr.inc | |
5 | ||
6 | caps.drop all | |
7 | netfilter | |
8 | noroot | |
9 | seccomp | |
10 | protocol unix,inet,inet6,netlink |
0 | noblacklist ${HOME}/.config/Slack | |
1 | noblacklist ${HOME}/Downloads | |
2 | ||
3 | include /etc/firejail/disable-common.inc | |
4 | include /etc/firejail/disable-programs.inc | |
5 | include /etc/firejail/disable-devel.inc | |
6 | include /etc/firejail/disable-passwdmgr.inc | |
7 | ||
8 | mkdir ${HOME}/.config | |
9 | mkdir ${HOME}/.config/Slack | |
10 | whitelist ${HOME}/.config/Slack | |
11 | whitelist ${HOME}/Downloads | |
12 | ||
13 | protocol unix,inet,inet6,netlink | |
14 | private-dev | |
15 | private-tmp | |
16 | private-etc fonts,resolv.conf,ld.so.conf,ld.so.cache,localtime | |
17 | name slack | |
18 | blacklist /var | |
19 | ||
20 | include /etc/firejail/whitelist-common.inc | |
21 | ||
22 | caps.drop all | |
23 | seccomp | |
24 | netfilter | |
25 | nonewprivs | |
26 | nogroups | |
27 | noroot | |
28 | shell none | |
29 | private-bin slack |
9 | 9 | # Whitelist the folders needed by Spotify - This is more restrictive |
10 | 10 | # than a blacklist though, but this is all spotify requires for |
11 | 11 | # streaming audio |
12 | mkdir ${HOME}/.config | |
13 | 12 | mkdir ${HOME}/.config/spotify |
14 | 13 | whitelist ${HOME}/.config/spotify |
15 | mkdir ${HOME}/.local | |
16 | mkdir ${HOME}/.local/share | |
17 | 14 | mkdir ${HOME}/.local/share/spotify |
18 | 15 | whitelist ${HOME}/.local/share/spotify |
19 | mkdir ${HOME}/.cache | |
20 | 16 | mkdir ${HOME}/.cache/spotify |
21 | 17 | whitelist ${HOME}/.cache/spotify |
22 | 18 | include /etc/firejail/whitelist-common.inc |
30 | 26 | seccomp |
31 | 27 | shell none |
32 | 28 | |
33 | private-bin spotify | |
29 | #private-bin spotify | |
34 | 30 | private-dev |
0 | 0 | # ssh client |
1 | 1 | noblacklist ~/.ssh |
2 | noblacklist /tmp/ssh-* | |
2 | 3 | |
3 | 4 | include /etc/firejail/disable-common.inc |
4 | 5 | include /etc/firejail/disable-programs.inc |
8 | 8 | # Whitelist |
9 | 9 | mkdir ~/.stellarium |
10 | 10 | whitelist ~/.stellarium |
11 | mkdir ~/.config | |
12 | 11 | mkdir ~/.config/stellarium |
13 | 12 | whitelist ~/.config/stellarium |
14 | 13 |
0 | 0 | # strings profile |
1 | quiet | |
2 | ignore noroot | |
1 | 3 | include /etc/firejail/default.profile |
2 | 4 | tracelog |
3 | 5 | net none |
5 | 7 | private-dev |
6 | 8 | private-tmp |
7 | 9 | nosound |
10 |
0 | # tar profile | |
1 | quiet | |
2 | ignore noroot | |
3 | include /etc/firejail/default.profile | |
4 | ||
5 | tracelog | |
6 | net none | |
7 | shell none | |
8 | ||
9 | # support compressed archives | |
10 | private-bin sh,tar,gtar,compress,gzip,lzma,xz,bzip2,lbzip2,lzip,lzop | |
11 | private-dev | |
12 | private-etc passwd,group,localtime | |
13 | hostname tar | |
14 | nosound |
10 | 10 | whitelist ~/.thunderbird |
11 | 11 | |
12 | 12 | noblacklist ~/.cache/thunderbird |
13 | mkdir ~/.cache | |
14 | 13 | mkdir ~/.cache/thunderbird |
15 | 14 | whitelist ~/.cache/thunderbird |
16 | 15 |
12 | 12 | seccomp |
13 | 13 | |
14 | 14 | whitelist ${DOWNLOADS} |
15 | mkdir ~/.config | |
16 | 15 | mkdir ~/.config/uGet |
17 | 16 | whitelist ~/.config/uGet |
18 | 17 | include /etc/firejail/whitelist-common.inc |
0 | # unrar profile | |
1 | quiet | |
2 | ignore noroot | |
3 | include /etc/firejail/default.profile | |
4 | ||
5 | tracelog | |
6 | net none | |
7 | shell none | |
8 | private-bin unrar | |
9 | private-dev | |
10 | private-etc passwd,group,localtime | |
11 | hostname unrar | |
12 | nosound |
0 | # unzip profile | |
1 | quiet | |
2 | ignore noroot | |
3 | include /etc/firejail/default.profile | |
4 | ||
5 | tracelog | |
6 | net none | |
7 | shell none | |
8 | private-bin unzip | |
9 | private-dev | |
10 | private-etc passwd,group,localtime | |
11 | hostname unzip | |
12 | nosound |
0 | # uudeview profile | |
1 | # the default profile will disable root user, enable seccomp filter etc. | |
2 | quiet | |
3 | ignore noroot | |
4 | include /etc/firejail/default.profile | |
5 | ||
6 | tracelog | |
7 | net none | |
8 | shell none | |
9 | private-bin uudeview | |
10 | private-dev | |
11 | private-tmp | |
12 | private-etc nonexisting_fakefile_for_empty_etc | |
13 | hostname uudeview | |
14 | nosound |
8 | 8 | nonewprivs |
9 | 9 | |
10 | 10 | whitelist ${DOWNLOADS} |
11 | mkdir ~/.config | |
12 | 11 | mkdir ~/.config/vivaldi |
13 | 12 | whitelist ~/.config/vivaldi |
14 | mkdir ~/.cache | |
15 | 13 | mkdir ~/.cache/vivaldi |
16 | 14 | whitelist ~/.cache/vivaldi |
17 | 15 | include /etc/firejail/whitelist-common.inc |
7 | 7 | |
8 | 8 | caps.drop all |
9 | 9 | netfilter |
10 | nogroups | |
10 | 11 | nonewprivs |
11 | 12 | noroot |
12 | 13 | protocol unix,inet,inet6 |
13 | 14 | seccomp |
15 | shell none | |
16 | tracelog | |
14 | 17 | |
15 | ||
16 | # to test | |
17 | shell none | |
18 | 18 | private-bin vlc,cvlc,nvlc,rvlc,qvlc,svlc |
17 | 17 | |
18 | 18 | whitelist /tmp/.X11-unix |
19 | 19 | |
20 | mkdir ${HOME}/.local | |
21 | mkdir ${HOME}/.local/share | |
22 | 20 | mkdir ${HOME}/.local/share/wesnoth |
23 | mkdir ${HOME}/.config | |
24 | 21 | mkdir ${HOME}/.config/wesnoth |
25 | mkdir ${HOME}/.cache | |
26 | 22 | mkdir ${HOME}/.cache/wesnoth |
27 | 23 | whitelist ${HOME}/.local/share/wesnoth |
28 | 24 | whitelist ${HOME}/.config/wesnoth |
19 | 19 | # gtk |
20 | 20 | whitelist ~/.gtkrc |
21 | 21 | whitelist ~/.gtkrc-2.0 |
22 | whitelist ~/.config/gtk-2.0 | |
22 | 23 | whitelist ~/.config/gtk-3.0 |
23 | 24 | whitelist ~/.themes |
25 | whitelist ~/.kde/share/config/gtkrc | |
26 | whitelist ~/.kde/share/config/gtkrc-2.0 | |
24 | 27 | |
25 | 28 | # dconf |
26 | mkdir ~/.config | |
27 | 29 | mkdir ~/.config/dconf |
28 | 30 | whitelist ~/.config/dconf |
0 | 0 | # xzdec profile |
1 | quiet | |
2 | ignore noroot | |
1 | 3 | include /etc/firejail/default.profile |
2 | 4 | tracelog |
3 | 5 | net none |
2 | 2 | # a code archive should already be available |
3 | 3 | |
4 | 4 | TOP=`pwd` |
5 | CODE_ARCHIVE="$1-$2.tar.bz2" | |
5 | CODE_ARCHIVE="$1-$2.tar.xz" | |
6 | 6 | CODE_DIR="$1-$2" |
7 | 7 | INSTALL_DIR="${INSTALL_DIR}${CODE_DIR}/debian" |
8 | 8 | DEBIAN_CTRL_DIR="${DEBIAN_CTRL_DIR}${CODE_DIR}/debian/DEBIAN" |
14 | 14 | echo "debian control directory: $DEBIAN_CTRL_DIR" |
15 | 15 | echo "*****************************************" |
16 | 16 | |
17 | tar -xjvf $CODE_ARCHIVE | |
17 | tar -xJvf $CODE_ARCHIVE | |
18 | 18 | #mkdir -p $INSTALL_DIR |
19 | 19 | cd $CODE_DIR |
20 | 20 | ./configure --prefix=/usr |
1 | 1 | rm -fr .etc |
2 | 2 | mkdir .etc |
3 | 3 | |
4 | result=$(echo $1 | sed 's/\//\\\//g') | |
5 | echo $result | |
6 | ||
7 | FILES=`ls etc/*.profile` | |
8 | for file in $FILES | |
4 | for file in etc/*.profile etc/*.inc etc/*.net; | |
9 | 5 | do |
10 | sed "s/\/etc\/firejail/$result\/firejail/g" $file > .$file | |
6 | sed "s;/etc/firejail;$1/firejail;g" $file > .$file | |
11 | 7 | done |
12 | 8 | |
13 | FILES=`ls etc/*.inc` | |
14 | for file in $FILES | |
15 | do | |
16 | sed "s/\/etc\/firejail/$result\/firejail/g" $file > .$file | |
17 | done | |
18 | ||
19 | FILES=`ls etc/*.net` | |
20 | for file in $FILES | |
21 | do | |
22 | sed "s/\/etc\/firejail/$result\/firejail/g" $file > .$file | |
23 | done | |
9 | if [ "x$2" = "xyes" ] | |
10 | then | |
11 | sed -i -e ' | |
12 | 1i# Workaround for systems where common UNIX utilities are symlinks to busybox.\ | |
13 | # If this is not your case you can remove --enable-busybox-workaround from\ | |
14 | # ./configure options, for added security.\ | |
15 | noblacklist \${PATH}/mount\ | |
16 | noblacklist \${PATH}/umount\ | |
17 | noblacklist \${PATH}/su\ | |
18 | noblacklist \${PATH}/sudo\ | |
19 | noblacklist \${PATH}/nc\ | |
20 | ' .etc/disable-common.inc | |
21 | fi |
0 | #!/bin/bash | |
1 | ||
2 | echo "extracting UID_MIN and GID_MIN" | |
3 | echo "#ifndef FIREJAIL_UIDS_H" > uids.h | |
4 | echo "#define FIREJAIL_UIDS_H" >> uids.h | |
5 | ||
6 | if [ -f /etc/login.defs ] | |
7 | then | |
8 | echo "// using values extracted from /etc/login.defs" >> uids.h | |
9 | UID_MIN=`awk '/^\s*UID_MIN\s*([0-9]*).*?$/ {print $2}' /etc/login.defs` | |
10 | GID_MIN=`awk '/^\s*GID_MIN\s*([0-9]*).*?$/ {print $2}' /etc/login.defs` | |
11 | echo "#define UID_MIN $UID_MIN" >> uids.h | |
12 | echo "#define GID_MIN $GID_MIN" >> uids.h | |
13 | else | |
14 | echo "// using default values" >> uids.h | |
15 | echo "#define UID_MIN 1000" >> uids.h | |
16 | echo "#define GID_MIN 1000" >> uids.h | |
17 | fi | |
18 | ||
19 | echo "#endif" >> uids.h |
0 | /etc/firejail/0ad.profile | |
1 | /etc/firejail/Cyberfox.profile | |
2 | /etc/firejail/Mathematica.profile | |
3 | /etc/firejail/Telegram.profile | |
4 | /etc/firejail/abrowser.profile | |
5 | /etc/firejail/atom-beta.profile | |
6 | /etc/firejail/atom.profile | |
7 | /etc/firejail/atril.profile | |
8 | /etc/firejail/audacious.profile | |
9 | /etc/firejail/audacity.profile | |
10 | /etc/firejail/aweather.profile | |
11 | /etc/firejail/bitlbee.profile | |
12 | /etc/firejail/brave.profile | |
13 | /etc/firejail/cherrytree.profile | |
14 | /etc/firejail/chromium-browser.profile | |
15 | /etc/firejail/chromium.profile | |
16 | /etc/firejail/clementine.profile | |
17 | /etc/firejail/cmus.profile | |
18 | /etc/firejail/conkeror.profile | |
19 | /etc/firejail/corebird.profile | |
20 | /etc/firejail/cpio.profile | |
21 | /etc/firejail/cyberfox.profile | |
22 | /etc/firejail/deadbeef.profile | |
23 | /etc/firejail/default.profile | |
24 | /etc/firejail/deluge.profile | |
25 | /etc/firejail/dillo.profile | |
26 | /etc/firejail/disable-common.inc | |
27 | /etc/firejail/disable-devel.inc | |
28 | /etc/firejail/disable-passwdmgr.inc | |
29 | /etc/firejail/disable-programs.inc | |
30 | /etc/firejail/dnscrypt-proxy.profile | |
31 | /etc/firejail/dnsmasq.profile | |
32 | /etc/firejail/dropbox.profile | |
33 | /etc/firejail/empathy.profile | |
34 | /etc/firejail/eom.profile | |
35 | /etc/firejail/epiphany.profile | |
0 | 36 | /etc/firejail/evince.profile |
1 | /etc/firejail/chromium.profile | |
2 | /etc/firejail/chromium-browser.profile | |
37 | /etc/firejail/fbreader.profile | |
38 | /etc/firejail/file.profile | |
39 | /etc/firejail/filezilla.profile | |
40 | /etc/firejail/firefox-esr.profile | |
41 | /etc/firejail/firefox.profile | |
42 | /etc/firejail/firejail.config | |
43 | /etc/firejail/flashpeak-slimjet.profile | |
44 | /etc/firejail/franz.profile | |
45 | /etc/firejail/gajim.profile | |
46 | /etc/firejail/gitter.profile | |
47 | /etc/firejail/gnome-chess.profile | |
48 | /etc/firejail/gnome-mplayer.profile | |
49 | /etc/firejail/google-chrome-beta.profile | |
50 | /etc/firejail/google-chrome-stable.profile | |
51 | /etc/firejail/google-chrome-unstable.profile | |
3 | 52 | /etc/firejail/google-chrome.profile |
4 | /etc/firejail/google-chrome-stable.profile | |
5 | /etc/firejail/google-chrome-beta.profile | |
6 | /etc/firejail/google-chrome-unstable.profile | |
7 | /etc/firejail/midori.profile | |
53 | /etc/firejail/google-play-music-desktop-player.profile | |
54 | /etc/firejail/gpredict.profile | |
55 | /etc/firejail/gtar.profile | |
56 | /etc/firejail/gthumb.profile | |
57 | /etc/firejail/gwenview.profile | |
58 | /etc/firejail/gzip.profile | |
59 | /etc/firejail/hedgewars.profile | |
60 | /etc/firejail/hexchat.profile | |
61 | /etc/firejail/icecat.profile | |
8 | 62 | /etc/firejail/icedove.profile |
9 | 63 | /etc/firejail/iceweasel.profile |
10 | /etc/firejail/dropbox.profile | |
11 | /etc/firejail/login.users | |
12 | /etc/firejail/firefox.profile | |
13 | /etc/firejail/firefox-esr.profile | |
14 | /etc/firejail/opera.profile | |
15 | /etc/firejail/opera-beta.profile | |
16 | /etc/firejail/thunderbird.profile | |
17 | /etc/firejail/transmission-gtk.profile | |
18 | /etc/firejail/transmission-qt.profile | |
19 | /etc/firejail/vlc.profile | |
20 | /etc/firejail/audacious.profile | |
21 | /etc/firejail/clementine.profile | |
22 | /etc/firejail/epiphany.profile | |
23 | /etc/firejail/qtox.profile | |
24 | /etc/firejail/polari.profile | |
25 | /etc/firejail/gnome-mplayer.profile | |
26 | /etc/firejail/rhythmbox.profile | |
27 | /etc/firejail/totem.profile | |
28 | /etc/firejail/deluge.profile | |
29 | /etc/firejail/qbittorrent.profile | |
30 | /etc/firejail/default.profile | |
31 | /etc/firejail/xchat.profile | |
32 | /etc/firejail/server.profile | |
33 | /etc/firejail/quassel.profile | |
34 | /etc/firejail/pidgin.profile | |
35 | /etc/firejail/filezilla.profile | |
36 | /etc/firejail/empathy.profile | |
37 | /etc/firejail/disable-common.inc | |
38 | /etc/firejail/deadbeef.profile | |
39 | /etc/firejail/icecat.profile | |
40 | /etc/firejail/fbreader.profile | |
41 | /etc/firejail/spotify.profile | |
42 | /etc/firejail/skype.profile | |
43 | /etc/firejail/steam.profile | |
44 | /etc/firejail/wine.profile | |
45 | /etc/firejail/disable-devel.inc | |
46 | /etc/firejail/conkeror.profile | |
47 | /etc/firejail/unbound.profile | |
48 | /etc/firejail/dnscrypt-proxy.profile | |
49 | /etc/firejail/whitelist-common.inc | |
50 | /etc/firejail/nolocal.net | |
51 | /etc/firejail/webserver.net | |
52 | /etc/firejail/bitlbee.profile | |
53 | /etc/firejail/weechat.profile | |
54 | /etc/firejail/weechat-curses.profile | |
55 | /etc/firejail/hexchat.profile | |
56 | /etc/firejail/rtorrent.profile | |
57 | /etc/firejail/parole.profile | |
64 | /etc/firejail/inox.profile | |
65 | /etc/firejail/jitsi.profile | |
58 | 66 | /etc/firejail/kmail.profile |
59 | /etc/firejail/seamonkey.profile | |
60 | /etc/firejail/seamonkey-bin.profile | |
61 | /etc/firejail/telegram.profile | |
62 | /etc/firejail/mathematica.profile | |
63 | /etc/firejail/Mathematica.profile | |
64 | /etc/firejail/uget-gtk.profile | |
65 | /etc/firejail/mupen64plus.profile | |
66 | /etc/firejail/lxterminal.profile | |
67 | /etc/firejail/cherrytree.profile | |
68 | /etc/firejail/wesnoth.profile | |
69 | /etc/firejail/hedgewars.profile | |
70 | /etc/firejail/vivaldi.profile | |
71 | /etc/firejail/vivaldi-beta.profile | |
72 | /etc/firejail/atril.profile | |
73 | /etc/firejail/firejail.config | |
74 | /etc/firejail/qutebrowser.profile | |
75 | /etc/firejail/flashpeak-slimjet.profile | |
76 | /etc/firejail/ssh.profile | |
77 | /etc/firejail/openbox.profile | |
78 | /etc/firejail/disable-programs.inc | |
79 | /etc/firejail/disable-passwdmgr.inc | |
80 | /etc/firejail/dillo.profile | |
81 | /etc/firejail/cmus.profile | |
82 | /etc/firejail/dnsmasq.profile | |
83 | /etc/firejail/palemoon.profile | |
84 | /etc/firejail/abrowser.profile | |
85 | /etc/firejail/0ad.profile | |
86 | /etc/firejail/netsurf.profile | |
87 | /etc/firejail/warzone2100.profile | |
88 | /etc/firejail/okular.profile | |
89 | /etc/firejail/gwenview.profile | |
90 | /etc/firejail/gpredict.profile | |
91 | /etc/firejail/aweather.profile | |
92 | /etc/firejail/stellarium.profile | |
93 | /etc/firejail/google-play-music-desktop-player.profile | |
94 | /etc/firejail/quiterss.profile | |
95 | /etc/firejail/cyberfox.profile | |
96 | /etc/firejail/snap.profile | |
97 | /etc/firejail/xplayer.profile | |
98 | /etc/firejail/xreader.profile | |
99 | /etc/firejail/xviewer.profile | |
100 | /etc/firejail/mcabber.profile | |
101 | /etc/firejail/corebird.profile | |
102 | 67 | /etc/firejail/konversation.profile |
103 | /etc/firejail/psi-plus.profile | |
104 | /etc/firejail/brave.profile | |
105 | /etc/firejail/gitter.profile | |
106 | /etc/firejail/gthumb.profile | |
107 | /etc/firejail/mpv.profile | |
108 | /etc/firejail/franz.profile | |
68 | /etc/firejail/less.profile | |
109 | 69 | /etc/firejail/libreoffice.profile |
110 | 70 | /etc/firejail/localc.profile |
111 | 71 | /etc/firejail/lodraw.profile |
112 | 72 | /etc/firejail/loffice.profile |
113 | 73 | /etc/firejail/lofromtemplate.profile |
74 | /etc/firejail/login.users | |
114 | 75 | /etc/firejail/loimpress.profile |
115 | 76 | /etc/firejail/lomath.profile |
116 | 77 | /etc/firejail/loweb.profile |
117 | 78 | /etc/firejail/lowriter.profile |
79 | /etc/firejail/lxterminal.profile | |
80 | /etc/firejail/mathematica.profile | |
81 | /etc/firejail/mcabber.profile | |
82 | /etc/firejail/midori.profile | |
83 | /etc/firejail/mpv.profile | |
84 | /etc/firejail/mupen64plus.profile | |
85 | /etc/firejail/netsurf.profile | |
86 | /etc/firejail/nolocal.net | |
87 | /etc/firejail/okular.profile | |
88 | /etc/firejail/openbox.profile | |
89 | /etc/firejail/opera-beta.profile | |
90 | /etc/firejail/opera.profile | |
91 | /etc/firejail/palemoon.profile | |
92 | /etc/firejail/parole.profile | |
93 | /etc/firejail/pidgin.profile | |
118 | 94 | /etc/firejail/pix.profile |
95 | /etc/firejail/polari.profile | |
96 | /etc/firejail/psi-plus.profile | |
97 | /etc/firejail/qbittorrent.profile | |
98 | /etc/firejail/qtox.profile | |
99 | /etc/firejail/quassel.profile | |
100 | /etc/firejail/quiterss.profile | |
101 | /etc/firejail/qutebrowser.profile | |
102 | /etc/firejail/rhythmbox.profile | |
103 | /etc/firejail/rtorrent.profile | |
104 | /etc/firejail/seamonkey-bin.profile | |
105 | /etc/firejail/seamonkey.profile | |
106 | /etc/firejail/server.profile | |
107 | /etc/firejail/skype.profile | |
108 | /etc/firejail/skypeforlinux.profile | |
109 | /etc/firejail/slack.profile | |
110 | /etc/firejail/snap.profile | |
119 | 111 | /etc/firejail/soffice.profile |
120 | /etc/firejail/audacity.profile | |
121 | /etc/firejail/cpio.profile | |
122 | /etc/firejail/gzip.profile | |
112 | /etc/firejail/spotify.profile | |
113 | /etc/firejail/ssh.profile | |
114 | /etc/firejail/steam.profile | |
115 | /etc/firejail/stellarium.profile | |
116 | /etc/firejail/tar.profile | |
117 | /etc/firejail/telegram.profile | |
118 | /etc/firejail/thunderbird.profile | |
119 | /etc/firejail/totem.profile | |
120 | /etc/firejail/transmission-gtk.profile | |
121 | /etc/firejail/transmission-qt.profile | |
122 | /etc/firejail/uget-gtk.profile | |
123 | /etc/firejail/unbound.profile | |
124 | /etc/firejail/unrar.profile | |
125 | /etc/firejail/unzip.profile | |
126 | /etc/firejail/uudeview.profile | |
127 | /etc/firejail/vivaldi-beta.profile | |
128 | /etc/firejail/vivaldi.profile | |
129 | /etc/firejail/vlc.profile | |
130 | /etc/firejail/warzone2100.profile | |
131 | /etc/firejail/webserver.net | |
132 | /etc/firejail/weechat-curses.profile | |
133 | /etc/firejail/weechat.profile | |
134 | /etc/firejail/wesnoth.profile | |
135 | /etc/firejail/whitelist-common.inc | |
136 | /etc/firejail/wine.profile | |
137 | /etc/firejail/xchat.profile | |
138 | /etc/firejail/xplayer.profile | |
139 | /etc/firejail/xreader.profile | |
140 | /etc/firejail/xviewer.profile | |
141 | /etc/firejail/xz.profile | |
123 | 142 | /etc/firejail/xzdec.profile |
124 | 143 | /etc/firejail/strings.profile |
125 | /etc/firejail/xz.profile | |
126 | /etc/firejail/less.profile | |
127 | /etc/firejail/Telegram.profile | |
128 | /etc/firejail/atom-beta.profile | |
129 | /etc/firejail/atom.profile | |
130 | /etc/firejail/jitsi.profile |
62 | 62 | if (ptr) |
63 | 63 | *ptr = '\0'; |
64 | 64 | check_session_bus(sockfile); |
65 | ||
66 | sockfile -= 13; | |
67 | 65 | } |
68 | 66 | free(bus); |
69 | 67 | } |
43 | 43 | void files_test(void) { |
44 | 44 | struct passwd *pw = getpwuid(getuid()); |
45 | 45 | if (!pw) { |
46 | fprintf(stderr, "Error: cannot retrive user account information\n"); | |
46 | fprintf(stderr, "Error: cannot retrieve user account information\n"); | |
47 | 47 | return; |
48 | 48 | } |
49 | 49 |
85 | 85 | printf("pivot_root... "); fflush(0); |
86 | 86 | syscall_run("pivot_root"); |
87 | 87 | |
88 | #if defined(__i386__) || defined(__x86_64__) | |
88 | 89 | printf("iopl... "); fflush(0); |
89 | 90 | syscall_run("iopl"); |
90 | 91 | |
91 | 92 | printf("ioperm... "); fflush(0); |
92 | 93 | syscall_run("ioperm"); |
93 | ||
94 | #endif | |
94 | 95 | printf("\n"); |
95 | 96 | } |
96 | 97 | else |
19 | 19 | #include "faudit.h" |
20 | 20 | #include <sys/ptrace.h> |
21 | 21 | #include <sys/swap.h> |
22 | #if defined(__i386__) || defined(__x86_64__) | |
22 | 23 | #include <sys/io.h> |
24 | #endif | |
23 | 25 | #include <sys/wait.h> |
24 | 26 | extern int init_module(void *module_image, unsigned long len, |
25 | 27 | const char *param_values); |
68 | 70 | pivot_root(NULL, NULL); |
69 | 71 | printf("\nUGLY: pivot_root syscall permitted.\n"); |
70 | 72 | } |
73 | #if defined(__i386__) || defined(__x86_64__) | |
71 | 74 | else if (strcmp(argv[2], "iopl") == 0) { |
72 | 75 | iopl(0L); |
73 | 76 | printf("\nUGLY: iopl syscall permitted.\n"); |
76 | 79 | ioperm(0, 0, 0); |
77 | 80 | printf("\nUGLY: ioperm syscall permitted.\n"); |
78 | 81 | } |
82 | #endif | |
79 | 83 | exit(0); |
80 | 84 | } |
81 | 85 |
39 | 39 | netsurf |
40 | 40 | opera-beta |
41 | 41 | opera |
42 | palemoon | |
42 | 43 | qutebrowser |
43 | 44 | seamonkey |
44 | 45 | seamonkey-bin |
76 | 77 | |
77 | 78 | # games |
78 | 79 | 0ad |
80 | gnome-chess | |
79 | 81 | hedgewars |
80 | 82 | steam |
81 | 83 | wesnot |
97 | 99 | vlc |
98 | 100 | xplayer |
99 | 101 | xviewer |
102 | eom | |
100 | 103 | |
101 | 104 | # news readers |
102 | 105 | quiterss |
109 | 112 | gwenview |
110 | 113 | gthumb |
111 | 114 | libreoffice |
115 | localc | |
112 | 116 | lodraw |
113 | 117 | loffice |
114 | 118 | lofromtemplate |
115 | loimpres | |
119 | loimpress | |
116 | 120 | lomath |
117 | 121 | loweb |
118 | 122 | lowriter |
25 | 25 | #include <sys/stat.h> |
26 | 26 | #include <unistd.h> |
27 | 27 | #include "../include/common.h" |
28 | static int arg_debug = 0; | |
28 | 29 | |
29 | 30 | static void usage(void) { |
30 | 31 | printf("firecfg - version %s\n\n", VERSION); |
36 | 37 | printf("DESKTOP INTEGRATION section in man 1 firejail.\n\n"); |
37 | 38 | printf("Usage: firecfg [OPTIONS]\n\n"); |
38 | 39 | printf(" --clean - remove all firejail symbolic links.\n\n"); |
40 | printf(" --debug - print debug messages.\n\n"); | |
39 | 41 | printf(" --help, -? - this help screen.\n\n"); |
40 | 42 | printf(" --list - list all firejail symbolic links.\n\n"); |
41 | 43 | printf(" --version - print program version and exit.\n\n"); |
66 | 68 | errExit("asprintf"); |
67 | 69 | |
68 | 70 | struct stat s; |
69 | if (stat(fname, &s) == 0) | |
71 | if (stat(fname, &s) == 0) { | |
72 | if (arg_debug) | |
73 | printf("found %s in directory %s\n", program, directory); | |
70 | 74 | retval = 1; |
71 | ||
75 | } | |
76 | ||
72 | 77 | free(fname); |
73 | 78 | return retval; |
74 | 79 | } |
205 | 210 | errExit("asprintf"); |
206 | 211 | |
207 | 212 | struct stat s; |
208 | if (stat(fname, &s) == 0) | |
209 | ; //printf("%s already present\n", fname); | |
213 | if (stat(fname, &s) == 0) { | |
214 | printf("%s is already present, skipping...\n", fname); | |
215 | } | |
210 | 216 | else { |
211 | 217 | int rv = symlink(firejail_exec, fname); |
212 | 218 | if (rv) { |
288 | 294 | usage(); |
289 | 295 | return 0; |
290 | 296 | } |
297 | else if (strcmp(argv[i], "--debug") == 0) | |
298 | arg_debug = 1; | |
291 | 299 | else if (strcmp(argv[i], "--version") == 0) { |
292 | 300 | printf("firecfg version %s\n\n", VERSION); |
293 | 301 | return 0; |
17 | 17 | HAVE_FILE_TRANSFER=@HAVE_FILE_TRANSFER@ |
18 | 18 | HAVE_WHITELIST=@HAVE_WHITELIST@ |
19 | 19 | HAVE_GLOBALCFG=@HAVE_GLOBALCFG@ |
20 | HAVE_APPARMOR=@HAVE_APPARMOR@ | |
21 | HAVE_OVERLAYFS=@HAVE_OVERLAYFS@ | |
22 | EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@ | |
20 | 23 | |
21 | 24 | H_FILE_LIST = $(sort $(wildcard *.[h])) |
22 | 25 | C_FILE_LIST = $(sort $(wildcard *.c)) |
23 | 26 | OBJS = $(C_FILE_LIST:.c=.o) |
24 | 27 | BINOBJS = $(foreach file, $(OBJS), $file) |
25 | CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security | |
28 | CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security | |
26 | 29 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread |
27 | 30 | |
28 | 31 | %.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/libnetlink.h ../include/pid.h |
29 | 32 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ |
30 | 33 | |
31 | 34 | firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o |
32 | $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/libnetlink.o ../lib/common.o $(LIBS) | |
35 | $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/libnetlink.o ../lib/common.o $(LIBS) $(EXTRA_LDFLAGS) | |
33 | 36 | |
34 | 37 | clean:; rm -f *.o firejail firejail.1 firejail.1.gz |
35 | 38 |
38 | 38 | assert(appimage_path); |
39 | 39 | assert(devloop == NULL); // don't call this twice! |
40 | 40 | EUID_ASSERT(); |
41 | ||
41 | ||
42 | 42 | // check appimage_path |
43 | 43 | if (access(appimage_path, R_OK) == -1) { |
44 | 44 | fprintf(stderr, "Error: cannot access AppImage file\n"); |
45 | 45 | exit(1); |
46 | 46 | } |
47 | ||
47 | ||
48 | // open as user to prevent race condition | |
49 | int ffd = open(appimage_path, O_RDONLY|O_CLOEXEC); | |
50 | if (ffd == -1) | |
51 | errExit("open"); | |
52 | ||
48 | 53 | EUID_ROOT(); |
49 | ||
54 | ||
50 | 55 | // find or allocate a free loop device to use |
51 | 56 | int cfd = open("/dev/loop-control", O_RDWR); |
52 | 57 | int devnr = ioctl(cfd, LOOP_CTL_GET_FREE); |
58 | 63 | if (asprintf(&devloop, "/dev/loop%d", devnr) == -1) |
59 | 64 | errExit("asprintf"); |
60 | 65 | |
61 | int ffd = open(appimage_path, O_RDONLY|O_CLOEXEC); | |
62 | 66 | int lfd = open(devloop, O_RDONLY); |
63 | 67 | if (ioctl(lfd, LOOP_SET_FD, ffd) == -1) { |
64 | 68 | fprintf(stderr, "Error: cannot configure the loopback device\n"); |
67 | 71 | close(lfd); |
68 | 72 | close(ffd); |
69 | 73 | |
74 | EUID_USER(); | |
75 | ||
76 | // creates directory with perms 0700 | |
70 | 77 | char dirname[] = "/tmp/firejail-mnt-XXXXXX"; |
71 | 78 | mntdir = strdup(mkdtemp(dirname)); |
72 | 79 | if (mntdir == NULL) { |
73 | 80 | fprintf(stderr, "Error: cannot create temporary directory\n"); |
74 | 81 | exit(1); |
75 | 82 | } |
76 | mkdir(mntdir, 755); | |
77 | if (chown(mntdir, getuid(), getgid()) == -1) | |
78 | errExit("chown"); | |
79 | if (chmod(mntdir, 755) == -1) | |
80 | errExit("chmod"); | |
83 | ASSERT_PERMS(mntdir, getuid(), getgid(), 0700); | |
81 | 84 | |
82 | 85 | char *mode; |
83 | if (asprintf(&mode, "mode=755,uid=%d,gid=%d", getuid(), getgid()) == -1) | |
86 | if (asprintf(&mode, "mode=700,uid=%d,gid=%d", getuid(), getgid()) == -1) | |
84 | 87 | errExit("asprintf"); |
85 | 88 | |
89 | EUID_ROOT(); | |
86 | 90 | if (mount(devloop, mntdir, "iso9660",MS_MGC_VAL|MS_RDONLY, mode) < 0) |
87 | 91 | errExit("mounting appimage"); |
88 | 92 |
129 | 129 | /* coverity[toctou] */ |
130 | 130 | FILE *fp = fopen(fname, "w"); |
131 | 131 | if (fp) { |
132 | SET_PERMS_STREAM(fp, 0, 0, 0644); | |
132 | 133 | fclose(fp); |
133 | ||
134 | /* coverity[toctou] */ | |
135 | if (chmod(fname, 0644) == -1) | |
136 | errExit("chmod"); | |
137 | /* coverity[toctou] */ | |
138 | if (chown(fname, 0, 0) == -1) | |
139 | errExit("chown"); | |
140 | 134 | } |
141 | 135 | else { |
142 | 136 | fprintf(stderr, "Error: cannot create bandwidth file\n"); |
179 | 173 | fprintf(fp, "%s:%s\n", cfg.bridge2.dev, cfg.bridge2.devsandbox); |
180 | 174 | if (cfg.bridge3.configured) |
181 | 175 | fprintf(fp, "%s:%s\n", cfg.bridge3.dev, cfg.bridge3.devsandbox); |
176 | ||
177 | SET_PERMS_STREAM(fp, 0, 0, 0644); | |
182 | 178 | fclose(fp); |
183 | ||
184 | if (chmod(fname, 0644) == -1) | |
185 | errExit("chmod"); | |
186 | if (chown(fname, 0, 0) == -1) | |
187 | errExit("chown"); | |
188 | 179 | } |
189 | 180 | else { |
190 | 181 | fprintf(stderr, "Error: cannot create network map file\n"); |
458 | 449 | if (setregid(0, 0)) |
459 | 450 | errExit("setregid"); |
460 | 451 | |
452 | if (!cfg.shell) | |
453 | cfg.shell = guess_shell(); | |
454 | if (!cfg.shell) { | |
455 | fprintf(stderr, "Error: no POSIX shell found, please use --shell command line option\n"); | |
456 | exit(1); | |
457 | } | |
458 | ||
461 | 459 | char *arg[4]; |
462 | arg[0] = "/bin/bash"; | |
460 | arg[0] = cfg.shell; | |
463 | 461 | arg[1] = "-c"; |
464 | 462 | arg[2] = cmd; |
465 | 463 | arg[3] = NULL; |
466 | execvp("/bin/bash", arg); | |
464 | execvp(arg[0], arg); | |
467 | 465 | |
468 | 466 | // it will never get here |
469 | exit(0); | |
470 | } | |
467 | errExit("execvp"); | |
468 | } |
29 | 29 | if (fp) { |
30 | 30 | fprintf(fp, "%s", cfg.cgroup); |
31 | 31 | fflush(0); |
32 | SET_PERMS_STREAM(fp, 0, 0, 0644); | |
32 | 33 | if (fclose(fp)) |
33 | 34 | goto errout; |
34 | if (chown(RUN_CGROUP_CFG, 0, 0) < 0) | |
35 | errExit("chown"); | |
36 | 35 | } |
37 | 36 | else |
38 | 37 | goto errout; |
25 | 25 | static int cfg_val[CFG_MAX]; |
26 | 26 | char *xephyr_screen = "800x600"; |
27 | 27 | char *xephyr_extra_params = ""; |
28 | char *netfilter_default = NULL; | |
28 | 29 | |
29 | 30 | int checkcfg(int val) { |
30 | EUID_ASSERT(); | |
31 | 31 | assert(val < CFG_MAX); |
32 | 32 | int line = 0; |
33 | 33 | |
36 | 36 | int i; |
37 | 37 | for (i = 0; i < CFG_MAX; i++) |
38 | 38 | cfg_val[i] = 1; // most of them are enabled by default |
39 | ||
40 | 39 | cfg_val[CFG_RESTRICTED_NETWORK] = 0; // disabled by default |
41 | 40 | cfg_val[CFG_FORCE_NONEWPRIVS] = 0; // disabled by default |
42 | 41 | |
48 | 47 | FILE *fp = fopen(fname, "r"); |
49 | 48 | if (!fp) { |
50 | 49 | #ifdef HAVE_GLOBALCFG |
51 | fprintf(stderr, "Warning: Firejail configuration file %s not found\n", fname); | |
50 | fprintf(stderr, "Error: Firejail configuration file %s not found\n", fname); | |
52 | 51 | exit(1); |
53 | 52 | #else |
54 | 53 | initialized = 1; |
56 | 55 | #endif |
57 | 56 | } |
58 | 57 | |
58 | // if the file exists, it should be owned by root | |
59 | struct stat s; | |
60 | if (stat(fname, &s) == -1) | |
61 | errExit("stat"); | |
62 | if (s.st_uid != 0 || s.st_gid != 0) { | |
63 | fprintf(stderr, "Error: configuration file should be owned by root\n"); | |
64 | exit(1); | |
65 | } | |
66 | ||
59 | 67 | // read configuration file |
60 | 68 | char buf[MAX_READ]; |
61 | 69 | while (fgets(buf,MAX_READ, fp)) { |
158 | 166 | else |
159 | 167 | goto errout; |
160 | 168 | } |
169 | // netfilter | |
170 | else if (strncmp(ptr, "netfilter-default ", 18) == 0) { | |
171 | char *fname = ptr + 18; | |
172 | while (*fname == ' ' || *fname == '\t') | |
173 | ptr++; | |
174 | char *end = strchr(fname, ' '); | |
175 | if (end) | |
176 | *end = '\0'; | |
177 | ||
178 | // is the file present? | |
179 | struct stat s; | |
180 | if (stat(fname, &s) == -1) { | |
181 | fprintf(stderr, "Error: netfilter-default file %s not available\n", fname); | |
182 | exit(1); | |
183 | } | |
184 | ||
185 | netfilter_default = strdup(fname); | |
186 | if (!netfilter_default) | |
187 | errExit("strdup"); | |
188 | if (arg_debug) | |
189 | printf("netfilter default file %s\n", fname); | |
190 | } | |
161 | 191 | |
162 | 192 | // Xephyr screen size |
163 | 193 | else if (strncmp(ptr, "xephyr-screen ", 14) == 0) { |
187 | 217 | if (!xephyr_extra_params) |
188 | 218 | errExit("strdup"); |
189 | 219 | } |
190 | ||
220 | ||
221 | // quiet by default | |
222 | else if (strncmp(ptr, "quiet-by-default ", 17) == 0) { | |
223 | if (strcmp(ptr + 17, "yes") == 0) | |
224 | arg_quiet = 1; | |
225 | } | |
226 | // remount /proc and /sys | |
227 | else if (strncmp(ptr, "remount-proc-sys ", 17) == 0) { | |
228 | if (strcmp(ptr + 17, "yes") == 0) | |
229 | cfg_val[CFG_REMOUNT_PROC_SYS] = 1; | |
230 | else if (strcmp(ptr + 17, "no") == 0) | |
231 | cfg_val[CFG_REMOUNT_PROC_SYS] = 0; | |
232 | else | |
233 | goto errout; | |
234 | } | |
235 | else if (strncmp(ptr, "overlayfs ", 10) == 0) { | |
236 | if (strcmp(ptr + 10, "yes") == 0) | |
237 | cfg_val[CFG_OVERLAYFS] = 1; | |
238 | else if (strcmp(ptr + 10, "no") == 0) | |
239 | cfg_val[CFG_OVERLAYFS] = 0; | |
240 | else | |
241 | goto errout; | |
242 | } | |
243 | else if (strncmp(ptr, "chroot-desktop ", 15) == 0) { | |
244 | if (strcmp(ptr + 15, "yes") == 0) | |
245 | cfg_val[CFG_CHROOT_DESKTOP] = 1; | |
246 | else if (strcmp(ptr + 15, "no") == 0) | |
247 | cfg_val[CFG_CHROOT_DESKTOP] = 0; | |
248 | else | |
249 | goto errout; | |
250 | } | |
191 | 251 | else |
192 | 252 | goto errout; |
193 | 253 | |
206 | 266 | exit(1); |
207 | 267 | } |
208 | 268 | |
269 | ||
270 | void print_compiletime_support(void) { | |
271 | printf("Compile time support:\n"); | |
272 | printf("\t- AppArmor support is %s\n", | |
273 | #ifdef HAVE_APPARMOR | |
274 | "enabled" | |
275 | #else | |
276 | "disabled" | |
277 | #endif | |
278 | ); | |
279 | ||
280 | ||
281 | printf("\t- bind support is %s\n", | |
282 | #ifdef HAVE_BIND | |
283 | "enabled" | |
284 | #else | |
285 | "disabled" | |
286 | #endif | |
287 | ); | |
288 | ||
289 | printf("\t- chroot support is %s\n", | |
290 | #ifdef HAVE_CHROOT | |
291 | "enabled" | |
292 | #else | |
293 | "disabled" | |
294 | #endif | |
295 | ); | |
296 | ||
297 | printf("\t- overlayfs support is %s\n", | |
298 | #ifdef HAVE_OVERLAYFS | |
299 | "enabled" | |
300 | #else | |
301 | "disabled" | |
302 | #endif | |
303 | ); | |
304 | ||
305 | printf("\t- file and directory whitelisting support is %s\n", | |
306 | #ifdef HAVE_WHITELIST | |
307 | "enabled" | |
308 | #else | |
309 | "disabled" | |
310 | #endif | |
311 | ); | |
312 | ||
313 | printf("\t- file transfer support is %s\n", | |
314 | #ifdef HAVE_FILE_TRANSFER | |
315 | "enabled" | |
316 | #else | |
317 | "disabled" | |
318 | #endif | |
319 | ); | |
320 | ||
321 | printf("\t- networking support is %s\n", | |
322 | #ifdef HAVE_NETWORK | |
323 | "enabled" | |
324 | #else | |
325 | "disabled" | |
326 | #endif | |
327 | ); | |
328 | ||
329 | ||
330 | #ifdef HAVE_NETWORK_RESTRICTED | |
331 | printf("\t- networking features are available only to root user\n"); | |
332 | #endif | |
333 | ||
334 | printf("\t- seccomp-bpf support is %s\n", | |
335 | #ifdef HAVE_SECCOMP | |
336 | "enabled" | |
337 | #else | |
338 | "disabled" | |
339 | #endif | |
340 | ); | |
341 | ||
342 | printf("\t- user namespace support is %s\n", | |
343 | #ifdef HAVE_USERNS | |
344 | "enabled" | |
345 | #else | |
346 | "disabled" | |
347 | #endif | |
348 | ); | |
349 | ||
350 | printf("\t- X11 sandboxing support is %s\n", | |
351 | #ifdef HAVE_X11 | |
352 | "enabled" | |
353 | #else | |
354 | "disabled" | |
355 | #endif | |
356 | ); | |
357 | } |
0 | /* | |
1 | * Copyright (C) 2014-2016 Firejail Authors | |
2 | * | |
3 | * This file is part of firejail project | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation; either version 2 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along | |
16 | * with this program; if not, write to the Free Software Foundation, Inc., | |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 | */ | |
19 | ||
20 | #include "firejail.h" | |
21 | #include <string.h> | |
22 | #include <stdbool.h> | |
23 | #include <stdio.h> | |
24 | #include <linux/limits.h> | |
25 | #include <assert.h> | |
26 | #include <errno.h> | |
27 | ||
28 | static int cmdline_length(int argc, char **argv, int index) { | |
29 | assert(index != -1); | |
30 | ||
31 | unsigned i,j; | |
32 | int len = 0; | |
33 | unsigned argcnt = argc - index; | |
34 | bool in_quotes = false; | |
35 | ||
36 | for (i = 0; i < argcnt; i++) { | |
37 | in_quotes = false; | |
38 | for (j = 0; j < strlen(argv[i + index]); j++) { | |
39 | if (argv[i + index][j] == '\'') { | |
40 | if (in_quotes) | |
41 | len++; | |
42 | if (j > 0 && argv[i + index][j-1] == '\'') | |
43 | len++; | |
44 | else | |
45 | len += 3; | |
46 | in_quotes = false; | |
47 | } else { | |
48 | if (!in_quotes) | |
49 | len++; | |
50 | len++; | |
51 | in_quotes = true; | |
52 | } | |
53 | } | |
54 | if (in_quotes) { | |
55 | len++; | |
56 | } | |
57 | if (strlen(argv[i + index]) == 0) { | |
58 | len += 2; | |
59 | } | |
60 | len++; | |
61 | } | |
62 | ||
63 | return len; | |
64 | } | |
65 | ||
66 | static void quote_cmdline(char *command_line, char *window_title, int len, int argc, char **argv, int index) { | |
67 | assert(index != -1); | |
68 | ||
69 | unsigned i,j; | |
70 | unsigned argcnt = argc - index; | |
71 | bool in_quotes = false; | |
72 | char *ptr1 = command_line; | |
73 | char *ptr2 = window_title; | |
74 | ||
75 | for (i = 0; i < argcnt; i++) { | |
76 | ||
77 | // enclose args by single quotes, | |
78 | // and since single quote can't be represented in single quoted text | |
79 | // each occurence of it should be enclosed by double quotes | |
80 | in_quotes = false; | |
81 | for (j = 0; j < strlen(argv[i + index]); j++) { | |
82 | // single quote | |
83 | if (argv[i + index][j] == '\'') { | |
84 | if (in_quotes) { | |
85 | // close quotes | |
86 | ptr1[0] = '\''; | |
87 | ptr1++; | |
88 | } | |
89 | // previous char was single quote too | |
90 | if (j > 0 && argv[i + index][j-1] == '\'') { | |
91 | ptr1--; | |
92 | sprintf(ptr1, "\'\""); | |
93 | } | |
94 | // this first in series | |
95 | else | |
96 | { | |
97 | sprintf(ptr1, "\"\'\""); | |
98 | } | |
99 | ptr1 += strlen(ptr1); | |
100 | in_quotes = false; | |
101 | } | |
102 | // anything other | |
103 | else | |
104 | { | |
105 | if (!in_quotes) { | |
106 | // open quotes | |
107 | ptr1[0] = '\''; | |
108 | ptr1++; | |
109 | } | |
110 | ptr1[0] = argv[i + index][j]; | |
111 | ptr1++; | |
112 | in_quotes = true; | |
113 | } | |
114 | } | |
115 | // close quotes | |
116 | if (in_quotes) { | |
117 | ptr1[0] = '\''; | |
118 | ptr1++; | |
119 | } | |
120 | // handle empty argument case | |
121 | if (strlen(argv[i + index]) == 0) { | |
122 | sprintf(ptr1, "\'\'"); | |
123 | ptr1 += strlen(ptr1); | |
124 | } | |
125 | // add space | |
126 | sprintf(ptr1, " "); | |
127 | ptr1 += strlen(ptr1); | |
128 | ||
129 | sprintf(ptr2, "%s ", argv[i + index]); | |
130 | ptr2 += strlen(ptr2); | |
131 | } | |
132 | ||
133 | assert((unsigned) len == strlen(command_line)); | |
134 | } | |
135 | ||
136 | void build_cmdline(char **command_line, char **window_title, int argc, char **argv, int index) { | |
137 | // index == -1 could happen if we have --shell=none and no program was specified | |
138 | // the program should exit with an error before entering this function | |
139 | assert(index != -1); | |
140 | ||
141 | int len = cmdline_length(argc, argv, index); | |
142 | if (len > ARG_MAX) { | |
143 | errno = E2BIG; | |
144 | errExit("cmdline_length"); | |
145 | } | |
146 | ||
147 | *command_line = malloc(len + 1); | |
148 | if (!*command_line) | |
149 | errExit("malloc"); | |
150 | *window_title = malloc(len + 1); | |
151 | if (!*window_title) | |
152 | errExit("malloc"); | |
153 | ||
154 | quote_cmdline(*command_line, *window_title, len, argc, argv, index); | |
155 | ||
156 | assert(*command_line); | |
157 | assert(*window_title); | |
158 | } |
77 | 77 | FILE *fp = fopen(RUN_CPU_CFG, "w"); |
78 | 78 | if (fp) { |
79 | 79 | fprintf(fp, "%x\n", cfg.cpus); |
80 | SET_PERMS_STREAM(fp, 0, 0, 0600); | |
80 | 81 | fclose(fp); |
81 | if (chmod(RUN_CPU_CFG, 0600) < 0) | |
82 | errExit("chmod"); | |
83 | if (chown(RUN_CPU_CFG, 0, 0) < 0) | |
84 | errExit("chown"); | |
85 | 82 | } |
86 | 83 | else { |
87 | 84 | fprintf(stderr, "Error: cannot save cpu affinity mask\n"); |
120 | 120 | errExit("setenv"); |
121 | 121 | if (setenv("container", "firejail", 1) < 0) // LXC sets container=lxc, |
122 | 122 | errExit("setenv"); |
123 | if (arg_zsh && setenv("SHELL", "/usr/bin/zsh", 1) < 0) | |
124 | errExit("setenv"); | |
125 | if (arg_csh && setenv("SHELL", "/bin/csh", 1) < 0) | |
126 | errExit("setenv"); | |
123 | if (!cfg.shell) | |
124 | cfg.shell = guess_shell(); | |
127 | 125 | if (cfg.shell && setenv("SHELL", cfg.shell, 1) < 0) |
128 | 126 | errExit("setenv"); |
127 | ||
129 | 128 | // set prompt color to green |
130 | //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' | |
131 | if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0) | |
132 | errExit("setenv"); | |
129 | char *prompt = getenv("FIREJAIL_PROMPT"); | |
130 | if (prompt && strcmp(prompt, "yes") == 0) { | |
131 | //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' | |
132 | if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0) | |
133 | errExit("setenv"); | |
134 | } | |
133 | 135 | |
134 | // build the window title and set it | |
135 | char *title; | |
136 | if (asprintf(&title, "\033]0;firejail %s\007\n", cfg.window_title) == -1) | |
137 | errExit("asprintf"); | |
138 | printf("%s", title); | |
139 | free(title); | |
136 | // set the window title | |
137 | printf("\033]0;firejail %s\007", cfg.window_title); | |
138 | fflush(0); | |
140 | 139 | } |
141 | 140 | |
142 | 141 | // parse and store the environment setting |
21 | 21 | #include "../include/common.h" |
22 | 22 | #include "../include/euid_common.h" |
23 | 23 | |
24 | // debug restricted shell | |
25 | //#define DEBUG_RESTRICTED_SHELL | |
24 | 26 | |
25 | 27 | // filesystem |
26 | 28 | #define RUN_FIREJAIL_BASEDIR "/run" |
72 | 74 | #define DEFAULT_ROOT_PROFILE "server" |
73 | 75 | #define MAX_INCLUDE_LEVEL 6 // include levels in profile files |
74 | 76 | |
77 | ||
78 | #define ASSERT_PERMS(file, uid, gid, mode) \ | |
79 | do { \ | |
80 | assert(file);\ | |
81 | struct stat s;\ | |
82 | if (stat(file, &s) == -1) errExit("stat");\ | |
83 | assert(s.st_uid == uid);\ | |
84 | assert(s.st_gid == gid);\ | |
85 | assert((s.st_mode & 07777) == (mode));\ | |
86 | } while (0) | |
87 | #define ASSERT_PERMS_FD(fd, uid, gid, mode) \ | |
88 | do { \ | |
89 | struct stat s;\ | |
90 | if (stat(fd, &s) == -1) errExit("stat");\ | |
91 | assert(s.st_uid == uid);\ | |
92 | assert(s.st_gid == gid);\ | |
93 | assert((s.st_mode & 07777) == (mode));\ | |
94 | } while (0) | |
95 | #define ASSERT_PERMS_STREAM(file, uid, gid, mode) \ | |
96 | do { \ | |
97 | int fd = fileno(file);\ | |
98 | if (fd == -1) errExit("fileno");\ | |
99 | ASSERT_PERMS_FD(fd, uid, gid, (mode));\ | |
100 | } while (0) | |
101 | ||
102 | #define SET_PERMS_FD(fd, uid, gid, mode) \ | |
103 | do { \ | |
104 | if (fchmod(fd, (mode)) == -1) errExit("chmod");\ | |
105 | if (fchown(fd, uid, gid) == -1) errExit("chown");\ | |
106 | } while (0) | |
107 | #define SET_PERMS_STREAM(stream, uid, gid, mode) \ | |
108 | do { \ | |
109 | int fd = fileno(stream);\ | |
110 | if (fd == -1) errExit("fileno");\ | |
111 | SET_PERMS_FD(fd, uid, gid, (mode));\ | |
112 | } while (0) | |
113 | #define SET_PERMS_STREAM_NOERR(stream, uid, gid, mode) \ | |
114 | do { \ | |
115 | int fd = fileno(stream);\ | |
116 | if (fd == -1) continue;\ | |
117 | int rv = fchmod(fd, (mode));\ | |
118 | (void) rv;\ | |
119 | rv = fchown(fd, uid, gid);\ | |
120 | (void) rv;\ | |
121 | } while (0) | |
122 | ||
75 | 123 | // main.c |
76 | 124 | typedef struct bridge_t { |
77 | 125 | // on the host |
135 | 183 | char *bin_private_keep; // keep list for private bin directory |
136 | 184 | char *cwd; // current working directory |
137 | 185 | char *overlay_dir; |
186 | char *private_template; // template dir for tmpfs home | |
138 | 187 | |
139 | 188 | // networking |
140 | 189 | char *name; // sandbox name |
211 | 260 | void clear_run_files(pid_t pid); |
212 | 261 | |
213 | 262 | extern int arg_private; // mount private /home |
263 | extern int arg_private_template; // private /home template | |
214 | 264 | extern int arg_debug; // print debug messages |
215 | 265 | extern int arg_debug_check_filename; // print debug messages for filename checking |
216 | 266 | extern int arg_debug_blacklists; // print debug messages for blacklists |
218 | 268 | extern int arg_nonetwork; // --net=none |
219 | 269 | extern int arg_command; // -c |
220 | 270 | extern int arg_overlay; // overlay option |
221 | extern int arg_overlay_keep; // place overlay diff directory in ~/.firejail | |
222 | extern int arg_zsh; // use zsh as default shell | |
223 | extern int arg_csh; // use csh as default shell | |
271 | extern int arg_overlay_keep; // place overlay diff in a known directory | |
272 | extern int arg_overlay_reuse; // allow the reuse of overlays | |
224 | 273 | |
225 | 274 | extern int arg_seccomp; // enable default seccomp filter |
226 | 275 | |
262 | 311 | extern int arg_appimage; // appimage |
263 | 312 | extern int arg_audit; // audit |
264 | 313 | extern char *arg_audit_prog; // audit |
265 | ||
314 | extern int arg_apparmor; // apparmor | |
315 | extern int arg_allow_debuggers; // allow debuggers | |
316 | ||
317 | extern int login_shell; | |
266 | 318 | extern int parent_to_child_fds[2]; |
267 | 319 | extern int child_to_parent_fds[2]; |
268 | 320 | extern pid_t sandbox_pid; |
273 | 325 | |
274 | 326 | // main.c |
275 | 327 | void check_user_namespace(void); |
328 | char *guess_shell(void); | |
276 | 329 | |
277 | 330 | // sandbox.c |
278 | 331 | int sandbox(void* sandbox_arg); |
332 | void start_application(void); | |
279 | 333 | |
280 | 334 | // network_main.c |
281 | 335 | void net_configure_bridge(Bridge *br, char *dev_name); |
319 | 373 | // build a basic read-only filesystem |
320 | 374 | void fs_basic_fs(void); |
321 | 375 | // mount overlayfs on top of / directory |
376 | char *fs_check_overlay_dir(const char *subdirname, int allow_reuse); | |
322 | 377 | void fs_overlayfs(void); |
323 | 378 | // chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf |
324 | 379 | void fs_chroot(const char *rootdir); |
353 | 408 | void shut_name(const char *name); |
354 | 409 | |
355 | 410 | // restricted_shell.c |
356 | extern char *restricted_user; | |
357 | 411 | int restricted_shell(const char *user); |
358 | 412 | |
359 | 413 | // arp.c |
377 | 431 | void logmsg(const char *msg); |
378 | 432 | void logargs(int argc, char **argv) ; |
379 | 433 | void logerr(const char *msg); |
380 | int copy_file(const char *srcname, const char *destname); | |
434 | int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); | |
381 | 435 | int is_dir(const char *fname); |
382 | 436 | int is_link(const char *fname); |
383 | 437 | char *line_remove_spaces(const char *buf); |
394 | 448 | void invalid_filename(const char *fname); |
395 | 449 | uid_t get_tty_gid(void); |
396 | 450 | uid_t get_audio_gid(void); |
451 | int remove_directory(const char *path); | |
397 | 452 | |
398 | 453 | // fs_var.c |
399 | 454 | void fs_var_log(void); // mounting /var/log |
415 | 470 | void fs_private(void); |
416 | 471 | // private mode (--private=homedir) |
417 | 472 | void fs_private_homedir(void); |
473 | // private template (--private-template=templatedir) | |
474 | void fs_private_template(void); | |
418 | 475 | // check new private home directory (--private= option) - exit if it fails |
419 | 476 | void fs_check_private_dir(void); |
420 | ||
477 | // check new private template home directory (--private-template= option) exit if it fails | |
478 | void fs_check_private_template(void); | |
421 | 479 | |
422 | 480 | // seccomp.c |
423 | 481 | int seccomp_filter_drop(int enforce_seccomp); |
578 | 636 | #define CFG_FORCE_NONEWPRIVS 8 |
579 | 637 | #define CFG_WHITELIST 9 |
580 | 638 | #define CFG_XEPHYR_WINDOW_TITLE 10 |
581 | #define CFG_MAX 11 // this should always be the last entry | |
639 | #define CFG_REMOUNT_PROC_SYS 11 | |
640 | #define CFG_OVERLAYFS 12 | |
641 | #define CFG_CHROOT_DESKTOP 13 | |
642 | #define CFG_MAX 14 // this should always be the last entry | |
582 | 643 | extern char *xephyr_screen; |
583 | 644 | extern char *xephyr_extra_params; |
645 | extern char *netfilter_default; | |
584 | 646 | int checkcfg(int val); |
647 | void print_compiletime_support(void); | |
585 | 648 | |
586 | 649 | // appimage.c |
587 | 650 | void appimage_set(const char *appimage_path); |
588 | 651 | void appimage_clear(void); |
589 | 652 | const char *appimage_getdir(void); |
590 | 653 | |
654 | // cmdline.c | |
655 | void build_cmdline(char **command_line, char **window_title, int argc, char **argv, int index); | |
656 | ||
591 | 657 | #endif |
592 | 658 |
28 | 28 | |
29 | 29 | static void fs_rdwr(const char *dir); |
30 | 30 | |
31 | static void create_dir_as_root(const char *dir, mode_t mode) { | |
32 | assert(dir); | |
33 | if (arg_debug) | |
34 | printf("Creating %s directory\n", dir); | |
35 | ||
36 | if (mkdir(dir, mode) == -1) | |
37 | errExit("mkdir"); | |
38 | ||
39 | ASSERT_PERMS(dir, 0, 0, mode); | |
40 | } | |
41 | ||
31 | 42 | static void create_empty_dir(void) { |
32 | 43 | struct stat s; |
33 | 44 | |
34 | 45 | if (stat(RUN_RO_DIR, &s)) { |
35 | 46 | /* coverity[toctou] */ |
36 | int rv = mkdir(RUN_RO_DIR, S_IRUSR | S_IXUSR); | |
37 | if (rv == -1) | |
38 | errExit("mkdir"); | |
39 | if (chown(RUN_RO_DIR, 0, 0) < 0) | |
40 | errExit("chown"); | |
47 | if (mkdir(RUN_RO_DIR, S_IRUSR | S_IXUSR) == -1) | |
48 | errExit("mkdir"); | |
49 | ASSERT_PERMS(RUN_RO_DIR, 0, 0, S_IRUSR | S_IXUSR); | |
41 | 50 | } |
42 | 51 | } |
43 | 52 | |
49 | 58 | FILE *fp = fopen(RUN_RO_FILE, "w"); |
50 | 59 | if (!fp) |
51 | 60 | errExit("fopen"); |
61 | ||
62 | SET_PERMS_STREAM(fp, 0, 0, S_IRUSR); | |
52 | 63 | fclose(fp); |
53 | if (chown(RUN_RO_FILE, 0, 0) < 0) | |
54 | errExit("chown"); | |
55 | if (chmod(RUN_RO_FILE, S_IRUSR) < 0) | |
56 | errExit("chown"); | |
57 | 64 | } |
58 | 65 | } |
59 | 66 | |
63 | 70 | |
64 | 71 | // CentOS 6 doesn't have /run directory |
65 | 72 | if (stat(RUN_FIREJAIL_BASEDIR, &s)) { |
66 | if (arg_debug) | |
67 | printf("Creating %s directory\n", RUN_FIREJAIL_BASEDIR); | |
68 | /* coverity[toctou] */ | |
69 | int rv = mkdir(RUN_FIREJAIL_BASEDIR, 0755); | |
70 | if (rv == -1) | |
71 | errExit("mkdir"); | |
72 | if (chown(RUN_FIREJAIL_BASEDIR, 0, 0) < 0) | |
73 | errExit("chown"); | |
74 | if (chmod(RUN_FIREJAIL_BASEDIR, 0755) < 0) | |
75 | errExit("chmod"); | |
73 | create_dir_as_root(RUN_FIREJAIL_BASEDIR, 0755); | |
76 | 74 | } |
77 | 75 | else { // check /tmp/firejail directory belongs to root end exit if doesn't! |
78 | 76 | if (s.st_uid != 0 || s.st_gid != 0) { |
82 | 80 | } |
83 | 81 | |
84 | 82 | if (stat(RUN_FIREJAIL_DIR, &s)) { |
85 | if (arg_debug) | |
86 | printf("Creating %s directory\n", RUN_FIREJAIL_DIR); | |
87 | /* coverity[toctou] */ | |
88 | int rv = mkdir(RUN_FIREJAIL_DIR, 0755); | |
89 | if (rv == -1) | |
90 | errExit("mkdir"); | |
91 | if (chown(RUN_FIREJAIL_DIR, 0, 0) < 0) | |
92 | errExit("chown"); | |
93 | if (chmod(RUN_FIREJAIL_DIR, 0755) < 0) | |
94 | errExit("chmod"); | |
83 | create_dir_as_root(RUN_FIREJAIL_DIR, 0755); | |
95 | 84 | } |
96 | 85 | |
97 | 86 | if (stat(RUN_FIREJAIL_NETWORK_DIR, &s)) { |
98 | if (arg_debug) | |
99 | printf("Creating %s directory\n", RUN_FIREJAIL_NETWORK_DIR); | |
100 | ||
101 | if (mkdir(RUN_FIREJAIL_NETWORK_DIR, 0755) == -1) | |
102 | errExit("mkdir"); | |
103 | if (chown(RUN_FIREJAIL_NETWORK_DIR, 0, 0) < 0) | |
104 | errExit("chown"); | |
105 | if (chmod(RUN_FIREJAIL_NETWORK_DIR, 0755) < 0) | |
106 | errExit("chmod"); | |
87 | create_dir_as_root(RUN_FIREJAIL_NETWORK_DIR, 0755); | |
107 | 88 | } |
108 | 89 | |
109 | 90 | if (stat(RUN_FIREJAIL_BANDWIDTH_DIR, &s)) { |
110 | if (arg_debug) | |
111 | printf("Creating %s directory\n", RUN_FIREJAIL_BANDWIDTH_DIR); | |
112 | if (mkdir(RUN_FIREJAIL_BANDWIDTH_DIR, 0755) == -1) | |
113 | errExit("mkdir"); | |
114 | if (chown(RUN_FIREJAIL_BANDWIDTH_DIR, 0, 0) < 0) | |
115 | errExit("chown"); | |
116 | if (chmod(RUN_FIREJAIL_BANDWIDTH_DIR, 0755) < 0) | |
117 | errExit("chmod"); | |
91 | create_dir_as_root(RUN_FIREJAIL_BANDWIDTH_DIR, 0755); | |
118 | 92 | } |
119 | 93 | |
120 | 94 | if (stat(RUN_FIREJAIL_NAME_DIR, &s)) { |
121 | if (arg_debug) | |
122 | printf("Creating %s directory\n", RUN_FIREJAIL_NAME_DIR); | |
123 | if (mkdir(RUN_FIREJAIL_NAME_DIR, 0755) == -1) | |
124 | errExit("mkdir"); | |
125 | if (chown(RUN_FIREJAIL_NAME_DIR, 0, 0) < 0) | |
126 | errExit("chown"); | |
127 | if (chmod(RUN_FIREJAIL_NAME_DIR, 0755) < 0) | |
128 | errExit("chmod"); | |
95 | create_dir_as_root(RUN_FIREJAIL_NAME_DIR, 0755); | |
129 | 96 | } |
130 | 97 | |
131 | 98 | if (stat(RUN_FIREJAIL_X11_DIR, &s)) { |
132 | if (arg_debug) | |
133 | printf("Creating %s directory\n", RUN_FIREJAIL_X11_DIR); | |
134 | if (mkdir(RUN_FIREJAIL_X11_DIR, 0755) == -1) | |
135 | errExit("mkdir"); | |
136 | if (chown(RUN_FIREJAIL_X11_DIR, 0, 0) < 0) | |
137 | errExit("chown"); | |
138 | if (chmod(RUN_FIREJAIL_X11_DIR, 0755) < 0) | |
139 | errExit("chmod"); | |
99 | create_dir_as_root(RUN_FIREJAIL_X11_DIR, 0755); | |
140 | 100 | } |
141 | 101 | |
142 | 102 | create_empty_dir(); |
159 | 119 | |
160 | 120 | // create /run/firejail/mnt directory |
161 | 121 | if (stat(RUN_MNT_DIR, &s)) { |
162 | if (arg_debug) | |
163 | printf("Creating %s directory\n", RUN_MNT_DIR); | |
164 | /* coverity[toctou] */ | |
165 | int rv = mkdir(RUN_MNT_DIR, 0755); | |
166 | if (rv == -1) | |
167 | errExit("mkdir"); | |
168 | if (chown(RUN_MNT_DIR, 0, 0) < 0) | |
169 | errExit("chown"); | |
170 | if (chmod(RUN_MNT_DIR, 0755) < 0) | |
171 | errExit("chmod"); | |
122 | create_dir_as_root(RUN_MNT_DIR, 0755); | |
172 | 123 | } |
173 | 124 | |
174 | 125 | // ... and mount tmpfs on top of it |
201 | 152 | fprintf(stderr, "Error: invalid /bin/cp file\n"); |
202 | 153 | exit(1); |
203 | 154 | } |
204 | int rv = copy_file(fname, RUN_CP_COMMAND); | |
155 | int rv = copy_file(fname, RUN_CP_COMMAND, 0, 0, 0755); | |
205 | 156 | if (rv) { |
206 | 157 | fprintf(stderr, "Error: cannot access /bin/cp\n"); |
207 | 158 | exit(1); |
208 | 159 | } |
209 | /* coverity[toctou] */ | |
210 | if (chown(RUN_CP_COMMAND, 0, 0)) | |
211 | errExit("chown"); | |
212 | if (chmod(RUN_CP_COMMAND, 0755)) | |
213 | errExit("chmod"); | |
160 | ASSERT_PERMS(RUN_CP_COMMAND, 0, 0, 0755); | |
214 | 161 | |
215 | 162 | free(fname); |
216 | 163 | } |
477 | 424 | |
478 | 425 | // Process noblacklist command |
479 | 426 | if (strncmp(entry->data, "noblacklist ", 12) == 0) { |
480 | if (noblacklist_c >= noblacklist_m) { | |
481 | noblacklist_m *= 2; | |
482 | noblacklist = realloc(noblacklist, sizeof(*noblacklist) * noblacklist_m); | |
483 | if (noblacklist == NULL) | |
484 | errExit("failed increasing memory for noblacklist entries");} | |
485 | noblacklist[noblacklist_c++] = expand_home(entry->data + 12, homedir); | |
427 | char **paths = build_paths(); | |
428 | ||
429 | char *enames[sizeof(paths)+1] = {0}; | |
430 | int i = 0; | |
431 | ||
432 | if (strncmp(entry->data + 12, "${PATH}", 7) == 0) { | |
433 | // expand ${PATH} macro | |
434 | while (paths[i] != NULL) { | |
435 | if (asprintf(&enames[i], "%s%s", paths[i], entry->data + 19) == -1) | |
436 | errExit("asprintf"); | |
437 | i++; | |
438 | } | |
439 | } else { | |
440 | // expand ${HOME} macro if found or pass as is | |
441 | enames[0] = expand_home(entry->data + 12, homedir); | |
442 | enames[1] = NULL; | |
443 | } | |
444 | ||
445 | i = 0; | |
446 | while (enames[i] != NULL) { | |
447 | if (noblacklist_c >= noblacklist_m) { | |
448 | noblacklist_m *= 2; | |
449 | noblacklist = realloc(noblacklist, sizeof(*noblacklist) * noblacklist_m); | |
450 | if (noblacklist == NULL) | |
451 | errExit("failed increasing memory for noblacklist entries"); | |
452 | } | |
453 | noblacklist[noblacklist_c++] = enames[i]; | |
454 | i++; | |
455 | } | |
456 | ||
457 | while (enames[i] != NULL) { | |
458 | free(enames[i]); | |
459 | } | |
460 | ||
486 | 461 | entry = entry->next; |
487 | 462 | continue; |
488 | 463 | } |
715 | 690 | } |
716 | 691 | |
717 | 692 | // disable firejail configuration in /etc/firejail and in ~/.config/firejail |
718 | static void disable_firejail_config(void) { | |
719 | struct stat s; | |
720 | // if (stat("/etc/firejail", &s) == 0) | |
721 | // disable_file(BLACKLIST_FILE, "/etc/firejail"); | |
693 | static void disable_config(void) { | |
694 | struct stat s; | |
722 | 695 | |
723 | 696 | char *fname; |
724 | 697 | if (asprintf(&fname, "%s/.config/firejail", cfg.homedir) == -1) |
726 | 699 | if (stat(fname, &s) == 0) |
727 | 700 | disable_file(BLACKLIST_FILE, fname); |
728 | 701 | free(fname); |
729 | ||
730 | // if (stat("/usr/local/etc/firejail", &s) == 0) | |
731 | // disable_file(BLACKLIST_FILE, "/usr/local/etc/firejail"); | |
732 | // | |
733 | // if (strcmp(PREFIX, "/usr/local")) { | |
734 | // if (asprintf(&fname, "%s/etc/firejail", PREFIX) == -1) | |
735 | // errExit("asprintf"); | |
736 | // if (stat(fname, &s) == 0) | |
737 | // disable_file(BLACKLIST_FILE, fname); | |
738 | // free(fname); | |
739 | // } | |
740 | ||
741 | 702 | |
742 | 703 | // disable run time information |
743 | 704 | if (stat(RUN_FIREJAIL_NETWORK_DIR, &s) == 0) |
753 | 714 | |
754 | 715 | // build a basic read-only filesystem |
755 | 716 | void fs_basic_fs(void) { |
717 | uid_t uid = getuid(); | |
718 | ||
756 | 719 | if (arg_debug) |
757 | 720 | printf("Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr"); |
758 | 721 | if (!arg_writable_etc) { |
759 | 722 | fs_rdonly("/etc"); |
760 | fs_noexec("/etc"); | |
723 | if (uid) | |
724 | fs_noexec("/etc"); | |
761 | 725 | if (arg_debug) printf(", /etc"); |
762 | 726 | } |
763 | 727 | if (!arg_writable_var) { |
764 | 728 | fs_rdonly("/var"); |
765 | fs_noexec("/var"); | |
729 | if (uid) | |
730 | fs_noexec("/var"); | |
766 | 731 | if (arg_debug) printf(", /var"); |
767 | 732 | } |
768 | 733 | if (arg_debug) printf("\n"); |
790 | 755 | // when starting as root, firejail config is not disabled; |
791 | 756 | // this mode could be used to install and test new software by chaining |
792 | 757 | // firejail sandboxes (firejail --force) |
793 | if (getuid() != 0) | |
794 | disable_firejail_config(); | |
795 | } | |
758 | if (uid) | |
759 | disable_config(); | |
760 | } | |
761 | ||
762 | ||
763 | ||
764 | #ifdef HAVE_OVERLAYFS | |
765 | char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) { | |
766 | struct stat s; | |
767 | char *dirname; | |
768 | ||
769 | // create ~/.firejail directory | |
770 | if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1) | |
771 | errExit("asprintf"); | |
772 | if (stat(dirname, &s) == -1) { | |
773 | /* coverity[toctou] */ | |
774 | if (mkdir(dirname, 0700)) | |
775 | errExit("mkdir"); | |
776 | ASSERT_PERMS(dirname, getuid(), getgid(), 0700); | |
777 | } | |
778 | else if (is_link(dirname)) { | |
779 | fprintf(stderr, "Error: invalid ~/.firejail directory\n"); | |
780 | exit(1); | |
781 | } | |
782 | free(dirname); | |
783 | ||
784 | // check overlay directory | |
785 | if (asprintf(&dirname, "%s/.firejail/%s", cfg.homedir, subdirname) == -1) | |
786 | errExit("asprintf"); | |
787 | if (is_link(dirname)) { | |
788 | fprintf(stderr, "Error: overlay directory is a symbolic link\n"); | |
789 | exit(1); | |
790 | } | |
791 | if (allow_reuse == 0) { | |
792 | if (stat(dirname, &s) == 0) { | |
793 | fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname); | |
794 | exit(1); | |
795 | } | |
796 | } | |
797 | ||
798 | return dirname; | |
799 | } | |
800 | ||
796 | 801 | |
797 | 802 | |
798 | 803 | // mount overlayfs on top of / directory |
855 | 860 | errExit("asprintf"); |
856 | 861 | if (mkdir(oroot, 0755)) |
857 | 862 | errExit("mkdir"); |
858 | if (chown(oroot, 0, 0) < 0) | |
859 | errExit("chown"); | |
860 | if (chmod(oroot, 0755) < 0) | |
861 | errExit("chmod"); | |
862 | ||
863 | ASSERT_PERMS(oroot, 0, 0, 0755); | |
864 | ||
865 | struct stat s; | |
863 | 866 | char *basedir = RUN_MNT_DIR; |
864 | 867 | if (arg_overlay_keep) { |
865 | 868 | // set base for working and diff directories |
866 | 869 | basedir = cfg.overlay_dir; |
867 | if (mkdir(basedir, 0755) != 0) { | |
868 | fprintf(stderr, "Error: cannot create overlay directory\n"); | |
869 | exit(1); | |
870 | ||
871 | // does the overlay exist? | |
872 | if (stat(basedir, &s) == 0) { | |
873 | if (arg_overlay_reuse == 0) { | |
874 | fprintf(stderr, "Error: overlay directory exists, but reuse is not allowed\n"); | |
875 | exit(1); | |
876 | } | |
877 | } | |
878 | else { | |
879 | if (mkdir(basedir, 0755) != 0) { | |
880 | fprintf(stderr, "Error: cannot create overlay directory\n"); | |
881 | exit(1); | |
882 | } | |
870 | 883 | } |
871 | 884 | } |
872 | 885 | |
873 | 886 | char *odiff; |
874 | 887 | if(asprintf(&odiff, "%s/odiff", basedir) == -1) |
875 | 888 | errExit("asprintf"); |
876 | if (mkdir(odiff, 0755)) | |
877 | errExit("mkdir"); | |
889 | ||
890 | // no need to check arg_overlay_reuse | |
891 | if (stat(odiff, &s) != 0) { | |
892 | if (mkdir(odiff, 0755)) | |
893 | errExit("mkdir"); | |
894 | } | |
895 | ||
878 | 896 | if (chown(odiff, 0, 0) < 0) |
879 | 897 | errExit("chown"); |
880 | 898 | if (chmod(odiff, 0755) < 0) |
883 | 901 | char *owork; |
884 | 902 | if(asprintf(&owork, "%s/owork", basedir) == -1) |
885 | 903 | errExit("asprintf"); |
886 | if (mkdir(owork, 0755)) | |
887 | errExit("mkdir"); | |
904 | ||
905 | // no need to check arg_overlay_reuse | |
906 | if (stat(owork, &s) != 0) { | |
907 | if (mkdir(owork, 0755)) | |
908 | errExit("mkdir"); | |
909 | } | |
910 | ||
888 | 911 | if (chown(owork, 0, 0) < 0) |
889 | 912 | errExit("chown"); |
890 | 913 | if (chmod(owork, 0755) < 0) |
940 | 963 | |
941 | 964 | if(asprintf(&hdiff, "%s/hdiff", basedir) == -1) |
942 | 965 | errExit("asprintf"); |
943 | if (mkdir(hdiff, S_IRWXU | S_IRWXG | S_IRWXO)) | |
944 | errExit("mkdir"); | |
966 | ||
967 | // no need to check arg_overlay_reuse | |
968 | if (stat(hdiff, &s) != 0) { | |
969 | if (mkdir(hdiff, S_IRWXU | S_IRWXG | S_IRWXO)) | |
970 | errExit("mkdir"); | |
971 | } | |
972 | ||
945 | 973 | if (chown(hdiff, 0, 0) < 0) |
946 | 974 | errExit("chown"); |
947 | 975 | if (chmod(hdiff, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) |
949 | 977 | |
950 | 978 | if(asprintf(&hwork, "%s/hwork", basedir) == -1) |
951 | 979 | errExit("asprintf"); |
952 | if (mkdir(hwork, S_IRWXU | S_IRWXG | S_IRWXO)) | |
953 | errExit("mkdir"); | |
980 | ||
981 | // no need to check arg_overlay_reuse | |
982 | if (stat(hwork, &s) != 0) { | |
983 | if (mkdir(hwork, S_IRWXU | S_IRWXG | S_IRWXO)) | |
984 | errExit("mkdir"); | |
985 | } | |
986 | ||
954 | 987 | if (chown(hwork, 0, 0) < 0) |
955 | 988 | errExit("chown"); |
956 | 989 | if (chmod(hwork, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) |
992 | 1025 | fs_logger("whitelist /run"); |
993 | 1026 | |
994 | 1027 | // mount-bind /tmp/.X11-unix directory |
995 | struct stat s; | |
996 | 1028 | if (stat("/tmp/.X11-unix", &s) == 0) { |
997 | 1029 | if (arg_debug) |
998 | 1030 | printf("Mounting /tmp/.X11-unix\n"); |
1027 | 1059 | // this mode could be used to install and test new software by chaining |
1028 | 1060 | // firejail sandboxes (firejail --force) |
1029 | 1061 | if (getuid() != 0) |
1030 | disable_firejail_config(); | |
1062 | disable_config(); | |
1031 | 1063 | |
1032 | 1064 | // cleanup and exit |
1033 | 1065 | free(option); |
1034 | 1066 | free(oroot); |
1035 | 1067 | free(odiff); |
1036 | 1068 | } |
1037 | ||
1069 | #endif | |
1038 | 1070 | |
1039 | 1071 | |
1040 | 1072 | #ifdef HAVE_CHROOT |
1044 | 1076 | assert(rootdir); |
1045 | 1077 | struct stat s; |
1046 | 1078 | char *name; |
1079 | ||
1080 | // rootdir has to be owned by root | |
1081 | if (stat(rootdir, &s) != 0) { | |
1082 | fprintf(stderr, "Error: cannot find chroot directory\n"); | |
1083 | return 1; | |
1084 | } | |
1085 | if (s.st_uid != 0) { | |
1086 | fprintf(stderr, "Error: chroot directory should be owned by root\n"); | |
1087 | return 1; | |
1088 | } | |
1047 | 1089 | |
1048 | 1090 | // check /dev |
1049 | 1091 | if (asprintf(&name, "%s/dev", rootdir) == -1) |
1082 | 1124 | free(name); |
1083 | 1125 | |
1084 | 1126 | // check /bin/bash |
1085 | if (asprintf(&name, "%s/bin/bash", rootdir) == -1) | |
1086 | errExit("asprintf"); | |
1087 | if (stat(name, &s) == -1) { | |
1088 | fprintf(stderr, "Error: cannot find /bin/bash in chroot directory\n"); | |
1089 | return 1; | |
1090 | } | |
1091 | free(name); | |
1127 | // if (asprintf(&name, "%s/bin/bash", rootdir) == -1) | |
1128 | // errExit("asprintf"); | |
1129 | // if (stat(name, &s) == -1) { | |
1130 | // fprintf(stderr, "Error: cannot find /bin/bash in chroot directory\n"); | |
1131 | // return 1; | |
1132 | // } | |
1133 | // free(name); | |
1092 | 1134 | |
1093 | 1135 | // check x11 socket directory |
1094 | 1136 | if (getenv("FIREJAIL_X11")) { |
1109 | 1151 | void fs_chroot(const char *rootdir) { |
1110 | 1152 | assert(rootdir); |
1111 | 1153 | |
1112 | // mount-bind a /dev in rootdir | |
1113 | char *newdev; | |
1114 | if (asprintf(&newdev, "%s/dev", rootdir) == -1) | |
1115 | errExit("asprintf"); | |
1116 | if (arg_debug) | |
1117 | printf("Mounting /dev on %s\n", newdev); | |
1118 | if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0) | |
1119 | errExit("mounting /dev"); | |
1120 | free(newdev); | |
1121 | ||
1122 | // x11 | |
1123 | if (getenv("FIREJAIL_X11")) { | |
1124 | char *newx11; | |
1125 | if (asprintf(&newx11, "%s/tmp/.X11-unix", rootdir) == -1) | |
1154 | if (checkcfg(CFG_CHROOT_DESKTOP)) { | |
1155 | // mount-bind a /dev in rootdir | |
1156 | char *newdev; | |
1157 | if (asprintf(&newdev, "%s/dev", rootdir) == -1) | |
1126 | 1158 | errExit("asprintf"); |
1127 | 1159 | if (arg_debug) |
1128 | printf("Mounting /tmp/.X11-unix on %s\n", newx11); | |
1129 | if (mount("/tmp/.X11-unix", newx11, NULL, MS_BIND|MS_REC, NULL) < 0) | |
1130 | errExit("mounting /tmp/.X11-unix"); | |
1131 | free(newx11); | |
1132 | } | |
1133 | ||
1134 | // some older distros don't have a /run directory | |
1135 | // create one by default | |
1136 | // no exit on error, let the user deal with any problems | |
1137 | char *rundir; | |
1138 | if (asprintf(&rundir, "%s/run", rootdir) == -1) | |
1139 | errExit("asprintf"); | |
1140 | if (!is_dir(rundir)) { | |
1141 | int rv = mkdir(rundir, 0755); | |
1142 | (void) rv; | |
1143 | rv = chown(rundir, 0, 0); | |
1144 | (void) rv; | |
1145 | } | |
1146 | ||
1147 | // copy /etc/resolv.conf in chroot directory | |
1148 | // if resolv.conf in chroot is a symbolic link, this will fail | |
1149 | // no exit on error, let the user deal with the problem | |
1150 | char *fname; | |
1151 | if (asprintf(&fname, "%s/etc/resolv.conf", rootdir) == -1) | |
1152 | errExit("asprintf"); | |
1153 | if (arg_debug) | |
1154 | printf("Updating /etc/resolv.conf in %s\n", fname); | |
1155 | if (is_link(fname)) { | |
1156 | fprintf(stderr, "Error: invalid %s file\n", fname); | |
1157 | exit(1); | |
1158 | } | |
1159 | if (copy_file("/etc/resolv.conf", fname) == -1) | |
1160 | fprintf(stderr, "Warning: /etc/resolv.conf not initialized\n"); | |
1161 | ||
1160 | printf("Mounting /dev on %s\n", newdev); | |
1161 | if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0) | |
1162 | errExit("mounting /dev"); | |
1163 | free(newdev); | |
1164 | ||
1165 | // x11 | |
1166 | if (getenv("FIREJAIL_X11")) { | |
1167 | char *newx11; | |
1168 | if (asprintf(&newx11, "%s/tmp/.X11-unix", rootdir) == -1) | |
1169 | errExit("asprintf"); | |
1170 | if (arg_debug) | |
1171 | printf("Mounting /tmp/.X11-unix on %s\n", newx11); | |
1172 | if (mount("/tmp/.X11-unix", newx11, NULL, MS_BIND|MS_REC, NULL) < 0) | |
1173 | errExit("mounting /tmp/.X11-unix"); | |
1174 | free(newx11); | |
1175 | } | |
1176 | ||
1177 | // some older distros don't have a /run directory | |
1178 | // create one by default | |
1179 | // no exit on error, let the user deal with any problems | |
1180 | char *rundir; | |
1181 | if (asprintf(&rundir, "%s/run", rootdir) == -1) | |
1182 | errExit("asprintf"); | |
1183 | if (!is_dir(rundir)) { | |
1184 | int rv = mkdir(rundir, 0755); | |
1185 | (void) rv; | |
1186 | rv = chown(rundir, 0, 0); | |
1187 | (void) rv; | |
1188 | } | |
1189 | ||
1190 | // copy /etc/resolv.conf in chroot directory | |
1191 | // if resolv.conf in chroot is a symbolic link, this will fail | |
1192 | // no exit on error, let the user deal with the problem | |
1193 | char *fname; | |
1194 | if (asprintf(&fname, "%s/etc/resolv.conf", rootdir) == -1) | |
1195 | errExit("asprintf"); | |
1196 | if (arg_debug) | |
1197 | printf("Updating /etc/resolv.conf in %s\n", fname); | |
1198 | if (is_link(fname)) { | |
1199 | fprintf(stderr, "Error: invalid %s file\n", fname); | |
1200 | exit(1); | |
1201 | } | |
1202 | if (copy_file("/etc/resolv.conf", fname, 0, 0, 0644) == -1) | |
1203 | fprintf(stderr, "Warning: /etc/resolv.conf not initialized\n"); | |
1204 | } | |
1205 | ||
1162 | 1206 | // chroot into the new directory |
1163 | 1207 | if (arg_debug) |
1164 | 1208 | printf("Chrooting into %s\n", rootdir); |
1167 | 1211 | // mount a new tmpfs in /run/firejail/mnt - the old one was lost in chroot |
1168 | 1212 | fs_build_remount_mnt_dir(); |
1169 | 1213 | |
1170 | // update /var directory in order to support multiple sandboxes running on the same root directory | |
1171 | if (!arg_private_dev) | |
1172 | fs_dev_shm(); | |
1173 | fs_var_lock(); | |
1174 | fs_var_tmp(); | |
1175 | fs_var_log(); | |
1176 | fs_var_lib(); | |
1177 | fs_var_cache(); | |
1178 | fs_var_utmp(); | |
1179 | ||
1180 | // don't leak user information | |
1181 | restrict_users(); | |
1182 | ||
1183 | // when starting as root, firejail config is not disabled; | |
1184 | // this mode could be used to install and test new software by chaining | |
1185 | // firejail sandboxes (firejail --force) | |
1186 | if (getuid() != 0) | |
1187 | disable_firejail_config(); | |
1214 | if (checkcfg(CFG_CHROOT_DESKTOP)) { | |
1215 | // update /var directory in order to support multiple sandboxes running on the same root directory | |
1216 | if (!arg_private_dev) | |
1217 | fs_dev_shm(); | |
1218 | fs_var_lock(); | |
1219 | fs_var_tmp(); | |
1220 | fs_var_log(); | |
1221 | fs_var_lib(); | |
1222 | fs_var_cache(); | |
1223 | fs_var_utmp(); | |
1224 | ||
1225 | // don't leak user information | |
1226 | restrict_users(); | |
1227 | ||
1228 | // when starting as root, firejail config is not disabled; | |
1229 | // this mode could be used to install and test new software by chaining | |
1230 | // firejail sandboxes (firejail --force) | |
1231 | if (getuid() != 0) | |
1232 | disable_config(); | |
1233 | } | |
1188 | 1234 | } |
1189 | 1235 | #endif |
1190 | 1236 |
27 | 27 | "/usr/local/bin", |
28 | 28 | "/usr/bin", |
29 | 29 | "/bin", |
30 | "/usr/games", | |
31 | "/usr/local/games", | |
30 | 32 | "/usr/local/sbin", |
31 | 33 | "/usr/sbin", |
32 | 34 | "/sbin", |
75 | 77 | } |
76 | 78 | |
77 | 79 | if (!fname) { |
78 | // fprintf(stderr, "Warning: file %s not found\n", name); | |
80 | if (arg_debug) | |
81 | fprintf(stderr, "Warning: file %s not found\n", name); | |
79 | 82 | return NULL; |
80 | 83 | } |
81 | 84 | |
135 | 138 | ptr = strrchr(newlist, ','); |
136 | 139 | assert(ptr); |
137 | 140 | *ptr = '\0'; |
138 | if (notfound) | |
141 | if (notfound && !arg_quiet) | |
139 | 142 | fprintf(stderr, "Warning: not all executables from --private-bin list were found. The current list is %s\n", newlist); |
140 | 143 | |
141 | 144 | cfg.bin_private_keep = newlist; |
145 | 148 | } |
146 | 149 | |
147 | 150 | static void duplicate(char *fname) { |
148 | char *cmd; | |
149 | 151 | char *path = check_dir_or_file(fname); |
150 | 152 | if (!path) |
151 | 153 | return; |
171 | 173 | } |
172 | 174 | else { |
173 | 175 | // copy the file |
174 | if (asprintf(&cmd, "%s -a %s %s/%s", RUN_CP_COMMAND, actual_path, RUN_BIN_DIR, fname) == -1) | |
175 | errExit("asprintf"); | |
176 | 176 | if (arg_debug) |
177 | printf("%s\n", cmd); | |
178 | if (system(cmd)) | |
179 | errExit("system cp -a"); | |
180 | free(cmd); | |
177 | printf("running: %s -a %s %s/%s", RUN_CP_COMMAND, actual_path, RUN_BIN_DIR, fname); | |
178 | ||
179 | pid_t child = fork(); | |
180 | if (child < 0) | |
181 | errExit("fork"); | |
182 | if (child == 0) { | |
183 | char *f; | |
184 | if (asprintf(&f, "%s/%s", RUN_BIN_DIR, fname) == -1) | |
185 | errExit("asprintf"); | |
186 | execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", actual_path, f, NULL); | |
187 | } | |
188 | // wait for the child to finish | |
189 | waitpid(child, NULL, 0); | |
190 | ||
181 | 191 | } |
182 | 192 | free(actual_path); |
183 | 193 | } |
192 | 202 | |
193 | 203 | // create /tmp/firejail/mnt/bin directory |
194 | 204 | fs_build_mnt_dir(); |
195 | int rv = mkdir(RUN_BIN_DIR, 0755); | |
196 | if (rv == -1) | |
205 | if (mkdir(RUN_BIN_DIR, 0755) == -1) | |
197 | 206 | errExit("mkdir"); |
198 | if (chown(RUN_BIN_DIR, 0, 0) < 0) | |
199 | errExit("chown"); | |
200 | if (chmod(RUN_BIN_DIR, 0755) < 0) | |
201 | errExit("chmod"); | |
202 | ||
207 | ASSERT_PERMS(RUN_BIN_DIR, 0, 0, 0755); | |
203 | 208 | |
204 | 209 | // copy the list of files in the new etc directory |
205 | 210 | // using a new child process without root privileges |
31 | 31 | |
32 | 32 | static void create_char_dev(const char *path, mode_t mode, int major, int minor) { |
33 | 33 | dev_t dev = makedev(major, minor); |
34 | int rv = mknod(path, S_IFCHR | mode, dev); | |
35 | if (rv == -1) | |
36 | goto errexit; | |
37 | ||
38 | ||
34 | if (mknod(path, S_IFCHR | mode, dev) == -1) | |
35 | goto errexit; | |
39 | 36 | if (chmod(path, mode) < 0) |
40 | 37 | goto errexit; |
41 | if (chown(path, 0, 0) < 0) | |
42 | goto errexit; | |
38 | ASSERT_PERMS(path, 0, 0, mode); | |
43 | 39 | |
44 | 40 | return; |
45 | 41 | |
61 | 57 | } |
62 | 58 | |
63 | 59 | void fs_private_dev(void){ |
64 | int rv; | |
65 | 60 | // install a new /dev directory |
66 | 61 | if (arg_debug) |
67 | 62 | printf("Mounting tmpfs on /dev\n"); |
77 | 72 | // create DRI_DIR |
78 | 73 | fs_build_mnt_dir(); |
79 | 74 | if (have_dri) { |
80 | /* coverity[toctou] */ | |
81 | rv = mkdir(RUN_DRI_DIR, 0755); | |
82 | if (rv == -1) | |
83 | errExit("mkdir"); | |
84 | if (chown(RUN_DRI_DIR, 0, 0) < 0) | |
85 | errExit("chown"); | |
86 | if (chmod(RUN_DRI_DIR, 0755) < 0) | |
87 | errExit("chmod"); | |
75 | if (mkdir(RUN_DRI_DIR, 0755) == -1) | |
76 | errExit("mkdir"); | |
77 | ASSERT_PERMS(RUN_DRI_DIR, 0, 0, 0755); | |
88 | 78 | |
89 | 79 | // keep a copy of /dev/dri under DRI_DIR |
90 | 80 | if (mount("/dev/dri", RUN_DRI_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) |
93 | 83 | |
94 | 84 | // create SND_DIR |
95 | 85 | if (have_snd) { |
96 | /* coverity[toctou] */ | |
97 | rv = mkdir(RUN_SND_DIR, 0755); | |
98 | if (rv == -1) | |
99 | errExit("mkdir"); | |
100 | if (chown(RUN_SND_DIR, 0, 0) < 0) | |
101 | errExit("chown"); | |
102 | if (chmod(RUN_SND_DIR, 0755) < 0) | |
103 | errExit("chmod"); | |
86 | if (mkdir(RUN_SND_DIR, 0755) == -1) | |
87 | errExit("mkdir"); | |
88 | ASSERT_PERMS(RUN_SND_DIR, 0, 0, 0755); | |
104 | 89 | |
105 | 90 | // keep a copy of /dev/dri under DRI_DIR |
106 | 91 | if (mount("/dev/snd", RUN_SND_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) |
142 | 127 | // bring back the /dev/snd directory |
143 | 128 | if (have_snd) { |
144 | 129 | /* coverity[toctou] */ |
145 | rv = mkdir("/dev/snd", 0755); | |
146 | if (rv == -1) | |
147 | errExit("mkdir"); | |
148 | if (chown("/dev/snd", 0, 0) < 0) | |
149 | errExit("chown"); | |
150 | if (chmod("/dev/snd",0755) < 0) | |
151 | errExit("chmod"); | |
130 | if (mkdir("/dev/snd", 0755) == -1) | |
131 | errExit("mkdir"); | |
132 | ASSERT_PERMS("/dev/snd", 0, 0, 0755); | |
152 | 133 | if (mount(RUN_SND_DIR, "/dev/snd", NULL, MS_BIND|MS_REC, NULL) < 0) |
153 | 134 | errExit("mounting /dev/snd"); |
154 | 135 | fs_logger("whitelist /dev/snd"); |
156 | 137 | |
157 | 138 | // bring back the /dev/dri directory |
158 | 139 | if (have_dri) { |
159 | /* coverity[toctou] */ | |
160 | rv = mkdir("/dev/dri", 0755); | |
161 | if (rv == -1) | |
162 | errExit("mkdir"); | |
163 | if (chown("/dev/dri", 0, 0) < 0) | |
164 | errExit("chown"); | |
165 | if (chmod("/dev/dri",0755) < 0) | |
166 | errExit("chmod"); | |
140 | if (mkdir("/dev/dri", 0755) == -1) | |
141 | errExit("mkdir"); | |
142 | ASSERT_PERMS("/dev/dri", 0, 0, 0755); | |
167 | 143 | if (mount(RUN_DRI_DIR, "/dev/dri", NULL, MS_BIND|MS_REC, NULL) < 0) |
168 | 144 | errExit("mounting /dev/dri"); |
169 | 145 | fs_logger("whitelist /dev/dri"); |
172 | 148 | // create /dev/shm |
173 | 149 | if (arg_debug) |
174 | 150 | printf("Create /dev/shm directory\n"); |
175 | rv = mkdir("/dev/shm", 01777); | |
176 | if (rv == -1) | |
151 | if (mkdir("/dev/shm", 01777) == -1) | |
177 | 152 | errExit("mkdir"); |
178 | if (chown("/dev/shm", 0, 0) < 0) | |
179 | errExit("chown"); | |
153 | // mkdir sets only the file permission bits | |
180 | 154 | if (chmod("/dev/shm", 01777) < 0) |
181 | 155 | errExit("chmod"); |
156 | ASSERT_PERMS("/dev/shm", 0, 0, 01777); | |
182 | 157 | fs_logger("mkdir /dev/shm"); |
183 | 158 | |
184 | 159 | // create devices |
200 | 175 | #endif |
201 | 176 | |
202 | 177 | // pseudo-terminal |
203 | rv = mkdir("/dev/pts", 0755); | |
204 | if (rv == -1) | |
178 | if (mkdir("/dev/pts", 0755) == -1) | |
205 | 179 | errExit("mkdir"); |
206 | if (chown("/dev/pts", 0, 0) < 0) | |
207 | errExit("chown"); | |
208 | if (chmod("/dev/pts", 0755) < 0) | |
209 | errExit("chmod"); | |
180 | ASSERT_PERMS("/dev/pts", 0, 0, 0755); | |
210 | 181 | fs_logger("mkdir /dev/pts"); |
211 | 182 | create_char_dev("/dev/pts/ptmx", 0666, 5, 2); //"mknod -m 666 /dev/pts/ptmx c 5 2"); |
212 | 183 | fs_logger("mknod /dev/pts/ptmx"); |
257 | 228 | // create directory |
258 | 229 | if (mkdir(lnk, 01777)) |
259 | 230 | errExit("mkdir"); |
260 | if (chown(lnk, 0, 0)) | |
261 | errExit("chown"); | |
231 | // mkdir sets only the file permission bits | |
262 | 232 | if (chmod(lnk, 01777)) |
263 | 233 | errExit("chmod"); |
234 | ASSERT_PERMS(lnk, 0, 0, 01777); | |
264 | 235 | } |
265 | 236 | if (arg_debug) |
266 | 237 | printf("Mounting tmpfs on %s on behalf of /dev/shm\n", lnk); |
27 | 27 | static int check_dir_or_file(const char *name) { |
28 | 28 | assert(name); |
29 | 29 | invalid_filename(name); |
30 | ||
30 | ||
31 | 31 | struct stat s; |
32 | 32 | char *fname; |
33 | 33 | if (asprintf(&fname, "/etc/%s", name) == -1) |
39 | 39 | printf("Warning: file %s not found.\n", fname); |
40 | 40 | return 0; |
41 | 41 | } |
42 | ||
42 | ||
43 | // read access | |
44 | if (access(fname, R_OK) == -1) | |
45 | goto errexit; | |
46 | ||
43 | 47 | // dir or regular file |
44 | 48 | if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { |
45 | 49 | free(fname); |
51 | 55 | return 1; |
52 | 56 | } |
53 | 57 | |
58 | ||
59 | errexit: | |
54 | 60 | fprintf(stderr, "Error: invalid file type, %s.\n", fname); |
55 | 61 | exit(1); |
56 | 62 | } |
87 | 93 | } |
88 | 94 | |
89 | 95 | static void duplicate(char *fname) { |
90 | char *cmd; | |
96 | // copy the file | |
97 | if (arg_debug) | |
98 | printf("running: %s -a --parents /etc/%s %s\n", RUN_CP_COMMAND, fname, RUN_MNT_DIR); | |
91 | 99 | |
92 | // copy the file - this code assumes ETC_DIR is actually MNT_DIR/etc | |
93 | if (asprintf(&cmd, "%s -a --parents /etc/%s %s", RUN_CP_COMMAND, fname, RUN_MNT_DIR) == -1) | |
94 | errExit("asprintf"); | |
95 | if (arg_debug) | |
96 | printf("%s\n", cmd); | |
97 | if (system(cmd)) | |
98 | fprintf(stderr, "Warning (fs_etc): error copying file /etc/%s, skipping...\n", fname); | |
100 | pid_t child = fork(); | |
101 | if (child < 0) | |
102 | errExit("fork"); | |
103 | if (child == 0) { | |
104 | char *f; | |
105 | if (asprintf(&f, "/etc/%s", fname) == -1) | |
106 | errExit("asprintf"); | |
107 | execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", "--parents", f, RUN_MNT_DIR, NULL); | |
108 | } | |
109 | // wait for the child to finish | |
110 | waitpid(child, NULL, 0); | |
99 | 111 | |
100 | free(cmd); | |
101 | ||
102 | 112 | char *name; |
103 | 113 | if (asprintf(&name, "/etc/%s", fname) == -1) |
104 | 114 | errExit("asprintf"); |
119 | 129 | |
120 | 130 | // create /tmp/firejail/mnt/etc directory |
121 | 131 | fs_build_mnt_dir(); |
122 | int rv = mkdir(RUN_ETC_DIR, 0755); | |
123 | if (rv == -1) | |
132 | if (mkdir(RUN_ETC_DIR, 0755) == -1) | |
124 | 133 | errExit("mkdir"); |
125 | if (chown(RUN_ETC_DIR, 0, 0) < 0) | |
126 | errExit("chown"); | |
127 | if (chmod(RUN_ETC_DIR, 0755) < 0) | |
128 | errExit("chmod"); | |
134 | ASSERT_PERMS(RUN_ETC_DIR, 0, 0, 0755); | |
129 | 135 | fs_logger("tmpfs /etc"); |
130 | 136 | |
131 | 137 | fs_logger_print(); // save the current log |
132 | 138 | |
133 | 139 | |
134 | 140 | // copy the list of files in the new etc directory |
135 | // using a new child process without root privileges | |
141 | // using a new child process with root privileges | |
136 | 142 | if (*private_list != '\0') { |
137 | 143 | pid_t child = fork(); |
138 | 144 | if (child < 0) |
27 | 27 | #include <sys/wait.h> |
28 | 28 | #include <unistd.h> |
29 | 29 | #include <grp.h> |
30 | #include <ftw.h> | |
30 | 31 | |
31 | 32 | static void skel(const char *homedir, uid_t u, gid_t g) { |
32 | 33 | char *fname; |
34 | ||
33 | 35 | // zsh |
34 | if (arg_zsh) { | |
36 | if (!arg_shell_none && (strcmp(cfg.shell,"/usr/bin/zsh") == 0 || strcmp(cfg.shell,"/bin/zsh") == 0)) { | |
35 | 37 | // copy skel files |
36 | 38 | if (asprintf(&fname, "%s/.zshrc", homedir) == -1) |
37 | 39 | errExit("asprintf"); |
40 | 42 | if (stat(fname, &s) == 0) |
41 | 43 | return; |
42 | 44 | if (stat("/etc/skel/.zshrc", &s) == 0) { |
43 | if (copy_file("/etc/skel/.zshrc", fname) == 0) { | |
44 | if (chown(fname, u, g) == -1) | |
45 | errExit("chown"); | |
45 | if (copy_file("/etc/skel/.zshrc", fname, u, g, 0644) == 0) { | |
46 | 46 | fs_logger("clone /etc/skel/.zshrc"); |
47 | 47 | } |
48 | 48 | } |
50 | 50 | FILE *fp = fopen(fname, "w"); |
51 | 51 | if (fp) { |
52 | 52 | fprintf(fp, "\n"); |
53 | SET_PERMS_STREAM(fp, u, g, S_IRUSR | S_IWUSR); | |
53 | 54 | fclose(fp); |
54 | if (chown(fname, u, g) == -1) | |
55 | errExit("chown"); | |
56 | if (chmod(fname, S_IRUSR | S_IWUSR) < 0) | |
57 | errExit("chown"); | |
58 | 55 | fs_logger2("touch", fname); |
59 | 56 | } |
60 | 57 | } |
61 | 58 | free(fname); |
62 | 59 | } |
63 | 60 | // csh |
64 | else if (arg_csh) { | |
61 | else if (!arg_shell_none && strcmp(cfg.shell,"/bin/csh") == 0) { | |
65 | 62 | // copy skel files |
66 | 63 | if (asprintf(&fname, "%s/.cshrc", homedir) == -1) |
67 | 64 | errExit("asprintf"); |
70 | 67 | if (stat(fname, &s) == 0) |
71 | 68 | return; |
72 | 69 | if (stat("/etc/skel/.cshrc", &s) == 0) { |
73 | if (copy_file("/etc/skel/.cshrc", fname) == 0) { | |
74 | if (chown(fname, u, g) == -1) | |
75 | errExit("chown"); | |
70 | if (copy_file("/etc/skel/.cshrc", fname, u, g, 0644) == 0) { | |
76 | 71 | fs_logger("clone /etc/skel/.cshrc"); |
77 | 72 | } |
78 | 73 | } |
81 | 76 | FILE *fp = fopen(fname, "w"); |
82 | 77 | if (fp) { |
83 | 78 | fprintf(fp, "\n"); |
79 | SET_PERMS_STREAM(fp, u, g, S_IRUSR | S_IWUSR); | |
84 | 80 | fclose(fp); |
85 | if (chown(fname, u, g) == -1) | |
86 | errExit("chown"); | |
87 | if (chmod(fname, S_IRUSR | S_IWUSR) < 0) | |
88 | errExit("chown"); | |
89 | 81 | fs_logger2("touch", fname); |
90 | 82 | } |
91 | 83 | } |
101 | 93 | if (stat(fname, &s) == 0) |
102 | 94 | return; |
103 | 95 | if (stat("/etc/skel/.bashrc", &s) == 0) { |
104 | if (copy_file("/etc/skel/.bashrc", fname) == 0) { | |
105 | /* coverity[toctou] */ | |
106 | if (chown(fname, u, g) == -1) | |
107 | errExit("chown"); | |
96 | if (copy_file("/etc/skel/.bashrc", fname, u, g, 0644) == 0) { | |
108 | 97 | fs_logger("clone /etc/skel/.bashrc"); |
109 | 98 | } |
110 | 99 | } |
128 | 117 | exit(1); |
129 | 118 | } |
130 | 119 | |
131 | int rv = copy_file(src, dest); | |
120 | int rv = copy_file(src, dest, -1, -1, 0600); | |
132 | 121 | if (rv) { |
133 | 122 | fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); |
134 | 123 | return 0; |
164 | 153 | free(rp); |
165 | 154 | } |
166 | 155 | |
167 | int rv = copy_file(src, dest); | |
156 | int rv = copy_file(src, dest, -1, -1, -0644); | |
168 | 157 | if (rv) { |
169 | 158 | fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); |
170 | 159 | return 0; |
181 | 170 | char *dest; |
182 | 171 | if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) |
183 | 172 | errExit("asprintf"); |
184 | int rv = copy_file(src, dest); | |
173 | // copy, set permissions and ownership | |
174 | int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); | |
185 | 175 | if (rv) |
186 | 176 | fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); |
187 | 177 | else { |
188 | 178 | fs_logger2("clone", dest); |
189 | ||
190 | // set permissions and ownership | |
191 | if (chown(dest, getuid(), getgid()) < 0) | |
192 | errExit("chown"); | |
193 | if (chmod(dest, S_IRUSR | S_IWUSR) < 0) | |
194 | errExit("chmod"); | |
195 | 179 | } |
196 | 180 | |
197 | 181 | // delete the temporary file |
204 | 188 | char *dest; |
205 | 189 | if (asprintf(&dest, "%s/.asoundrc", cfg.homedir) == -1) |
206 | 190 | errExit("asprintf"); |
207 | int rv = copy_file(src, dest); | |
191 | // copy, set permissions and ownership | |
192 | int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); | |
208 | 193 | if (rv) |
209 | 194 | fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); |
210 | 195 | else { |
211 | 196 | fs_logger2("clone", dest); |
212 | ||
213 | // set permissions and ownership | |
214 | if (chown(dest, getuid(), getgid()) < 0) | |
215 | errExit("chown"); | |
216 | if (chmod(dest, S_IRUSR | S_IWUSR) < 0) | |
217 | errExit("chmod"); | |
218 | 197 | } |
219 | 198 | |
220 | 199 | // delete the temporary file |
333 | 312 | |
334 | 313 | } |
335 | 314 | |
315 | int fs_copydir(const char *path, const struct stat *st, int ftype, struct FTW *sftw); | |
316 | ||
317 | ||
318 | int fs_copydir(const char *path, const struct stat *st, int ftype, struct FTW *sftw) | |
319 | { | |
320 | (void) st; | |
321 | (void) sftw; | |
322 | char *homedir = cfg.homedir; | |
323 | char *dest; | |
324 | int srcbaselen = 0; | |
325 | assert(homedir); | |
326 | uid_t u = getuid(); | |
327 | gid_t g = getgid(); | |
328 | srcbaselen = strlen(cfg.private_template); | |
329 | ||
330 | if(ftype == FTW_F || ftype == FTW_D) { | |
331 | if (asprintf(&dest, "%s/%s", homedir, path + srcbaselen) == -1) | |
332 | errExit("asprintf"); | |
333 | struct stat s; | |
334 | // don't copy it if we already have the file | |
335 | if (stat(dest, &s) == 0) | |
336 | return(0); | |
337 | if (stat(path, &s) == 0) { | |
338 | if(ftype == FTW_F) { | |
339 | if (copy_file(path, dest, u, g, 0644) == 0) { | |
340 | if (arg_debug) | |
341 | printf("copy from %s to %s\n", path, dest); | |
342 | fs_logger2("clone", path); | |
343 | } | |
344 | } | |
345 | else if(ftype == FTW_D) { | |
346 | if (mkdir(dest, s.st_mode) == -1) | |
347 | errExit("mkdir"); | |
348 | if (chown(dest, u, g) < 0) | |
349 | errExit("chown"); | |
350 | if (arg_debug) | |
351 | printf("copy from %s to %s\n", path, dest); | |
352 | fs_logger2("clone", path); | |
353 | } | |
354 | } | |
355 | free(dest); | |
356 | } | |
357 | return(0); | |
358 | } | |
359 | ||
360 | void fs_private_template(void) { | |
361 | ||
362 | fs_private(); | |
363 | if(nftw(cfg.private_template, fs_copydir, 1, FTW_PHYS) != 0) { | |
364 | fprintf(stderr, "Error: unable to copy template dir\n"); | |
365 | exit(1); | |
366 | } | |
367 | ||
368 | } | |
336 | 369 | |
337 | 370 | // check new private home directory (--private= option) - exit if it fails |
338 | 371 | void fs_check_private_dir(void) { |
372 | 405 | } |
373 | 406 | } |
374 | 407 | |
408 | // check new template home directoty (--private-template= option) - exit if it fails | |
409 | void fs_check_private_template(void) { | |
410 | EUID_ASSERT(); | |
411 | invalid_filename(cfg.private_template); | |
412 | ||
413 | // Expand the home directory | |
414 | char *tmp = expand_home(cfg.private_template, cfg.homedir); | |
415 | cfg.private_template = realpath(tmp, NULL); | |
416 | free(tmp); | |
417 | ||
418 | if (!cfg.private_template | |
419 | || !is_dir(cfg.private_template) | |
420 | || is_link(cfg.private_template) | |
421 | || strstr(cfg.private_template, "..")) { | |
422 | fprintf(stderr, "Error: invalid private template directory\n"); | |
423 | exit(1); | |
424 | } | |
425 | ||
426 | // check home directory and chroot home directory have the same owner | |
427 | struct stat s2; | |
428 | int rv = stat(cfg.private_template, &s2); | |
429 | if (rv < 0) { | |
430 | fprintf(stderr, "Error: cannot find %s directory\n", cfg.private_template); | |
431 | exit(1); | |
432 | } | |
433 | ||
434 | struct stat s1; | |
435 | rv = stat(cfg.homedir, &s1); | |
436 | if (rv < 0) { | |
437 | fprintf(stderr, "Error: cannot find %s directory, full path name required\n", cfg.homedir); | |
438 | exit(1); | |
439 | } | |
440 | if (s1.st_uid != s2.st_uid) { | |
441 | printf("Error: --private-template directory should be owned by the current user\n"); | |
442 | exit(1); | |
443 | } | |
444 | } | |
445 | ||
446 |
39 | 39 | exit(1); |
40 | 40 | } |
41 | 41 | fprintf(fp, "%s\n", hostname); |
42 | // mode and owner | |
43 | SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH); | |
42 | 44 | fclose(fp); |
43 | ||
44 | // mode and owner | |
45 | if (chown(RUN_HOSTNAME_FILE, 0, 0) < 0) | |
46 | errExit("chown"); | |
47 | if (chmod(RUN_HOSTNAME_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) | |
48 | errExit("chmod"); | |
49 | ||
45 | ||
50 | 46 | // bind-mount the file on top of /etc/hostname |
51 | 47 | if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0) |
52 | 48 | errExit("mount bind /etc/hostname"); |
87 | 83 | fprintf(fp2, "%s\n", buf); |
88 | 84 | } |
89 | 85 | fclose(fp1); |
86 | // mode and owner | |
87 | SET_PERMS_STREAM(fp2, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH); | |
90 | 88 | fclose(fp2); |
91 | ||
92 | // mode and owner | |
93 | if (chown(RUN_HOSTS_FILE, 0, 0) < 0) | |
94 | errExit("chown"); | |
95 | if (chmod(RUN_HOSTS_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) | |
96 | errExit("chmod"); | |
97 | 89 | |
98 | 90 | // bind-mount the file on top of /etc/hostname |
99 | 91 | if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0) |
125 | 117 | fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns2)); |
126 | 118 | if (cfg.dns3) |
127 | 119 | fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns3)); |
120 | ||
121 | // mode and owner | |
122 | SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH); | |
123 | ||
128 | 124 | fclose(fp); |
129 | ||
130 | // mode and owner | |
131 | if (chown(RUN_RESOLVCONF_FILE, 0, 0) < 0) | |
132 | errExit("chown"); | |
133 | if (chmod(RUN_RESOLVCONF_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) | |
134 | errExit("chmod"); | |
135 | 125 | |
136 | 126 | // bind-mount the file on top of /etc/hostname |
137 | 127 | if (mount(RUN_RESOLVCONF_FILE, "/etc/resolv.conf", NULL, MS_BIND|MS_REC, NULL) < 0) |
96 | 96 | perror("fopen"); |
97 | 97 | return; |
98 | 98 | } |
99 | ||
100 | int rv = chown(RUN_FSLOGGER_FILE, getuid(), getgid()); | |
101 | (void) rv; // best effort! | |
102 | rv = chmod(RUN_FSLOGGER_FILE, 0644); | |
103 | (void) rv; // best effort! | |
99 | SET_PERMS_STREAM_NOERR(fp, getuid(), getgid(), 0644); | |
104 | 100 | |
105 | 101 | FsMsg *ptr = head; |
106 | 102 | while (ptr) { |
21 | 21 | #include <sys/stat.h> |
22 | 22 | #include <unistd.h> |
23 | 23 | #include <grp.h> |
24 | #include <sys/wait.h> | |
25 | ||
24 | #include <sys/wait.h> | |
25 | #include <string.h> | |
26 | ||
27 | static void mkdir_recursive(char *path) { | |
28 | char *subdir = NULL; | |
29 | struct stat s; | |
30 | ||
31 | if (chdir("/")) { | |
32 | fprintf(stderr, "Error: can't chdir to /"); | |
33 | return; | |
34 | } | |
35 | ||
36 | subdir = strtok(path, "/"); | |
37 | while(subdir) { | |
38 | if (stat(subdir, &s) == -1) { | |
39 | if (mkdir(subdir, 0700) == -1) { | |
40 | fprintf(stderr, "Warning: cannot create %s directory\n", subdir); | |
41 | return; | |
42 | } | |
43 | } else if (!S_ISDIR(s.st_mode)) { | |
44 | fprintf(stderr, "Warning: '%s' exists, but is no directory\n", subdir); | |
45 | return; | |
46 | } | |
47 | if (chdir(subdir)) { | |
48 | fprintf(stderr, "Error: can't chdir to %s", subdir); | |
49 | return; | |
50 | } | |
51 | ||
52 | subdir = strtok(NULL, "/"); | |
53 | } | |
54 | } | |
55 | ||
26 | 56 | void fs_mkdir(const char *name) { |
27 | 57 | EUID_ASSERT(); |
28 | 58 | |
41 | 71 | } |
42 | 72 | |
43 | 73 | // create directory |
44 | if (mkdir(expanded, 0700) == -1) | |
45 | fprintf(stderr, "Warning: cannot create %s directory\n", expanded); | |
74 | pid_t child = fork(); | |
75 | if (child < 0) | |
76 | errExit("fork"); | |
77 | if (child == 0) { | |
78 | // drop privileges | |
79 | drop_privs(0); | |
80 | ||
81 | // create directory | |
82 | mkdir_recursive(expanded); | |
83 | exit(0); | |
84 | } | |
85 | // wait for the child to finish | |
86 | waitpid(child, NULL, 0); | |
46 | 87 | |
47 | 88 | doexit: |
48 | 89 | free(expanded); |
66 | 107 | } |
67 | 108 | |
68 | 109 | // create file |
69 | FILE *fp = fopen(expanded, "w"); | |
70 | if (!fp) | |
71 | fprintf(stderr, "Warning: cannot create %s file\n", expanded); | |
72 | else { | |
73 | fclose(fp); | |
74 | int rv = chown(expanded, getuid(), getgid()); | |
75 | (void) rv; | |
76 | rv = chmod(expanded, 0600); | |
77 | (void) rv; | |
110 | pid_t child = fork(); | |
111 | if (child < 0) | |
112 | errExit("fork"); | |
113 | if (child == 0) { | |
114 | // drop privileges | |
115 | drop_privs(0); | |
116 | ||
117 | FILE *fp = fopen(expanded, "w"); | |
118 | if (!fp) | |
119 | fprintf(stderr, "Warning: cannot create %s file\n", expanded); | |
120 | else { | |
121 | int fd = fileno(fp); | |
122 | if (fd == -1) | |
123 | errExit("fileno"); | |
124 | int rv = fchmod(fd, 0600); | |
125 | (void) rv; | |
126 | fclose(fp); | |
127 | } | |
128 | exit(0); | |
78 | 129 | } |
130 | // wait for the child to finish | |
131 | waitpid(child, NULL, 0); | |
79 | 132 | |
80 | 133 | doexit: |
81 | 134 | free(expanded); |
82 | }⏎ | |
135 | } |
36 | 36 | FILE *fp = fopen("/etc/ld.so.preload", "w"); |
37 | 37 | if (!fp) |
38 | 38 | errExit("fopen"); |
39 | SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH); | |
39 | 40 | fclose(fp); |
40 | if (chown("/etc/ld.so.preload", 0, 0) < 0) | |
41 | errExit("chown"); | |
42 | if (chmod("/etc/ld.so.preload", S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) | |
43 | errExit("chmod"); | |
44 | 41 | fs_logger("touch /etc/ld.so.preload"); |
45 | 42 | } |
46 | 43 | } |
65 | 62 | } |
66 | 63 | else |
67 | 64 | assert(0); |
68 | ||
65 | ||
66 | SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH); | |
69 | 67 | fclose(fp); |
70 | if (chown(RUN_LDPRELOAD_FILE, 0, 0) < 0) | |
71 | errExit("chown"); | |
72 | if (chmod(RUN_LDPRELOAD_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) | |
73 | errExit("chmod"); | |
74 | 68 | |
75 | 69 | // mount the new preload file |
76 | 70 | if (arg_debug) |
80 | 74 | fs_logger("create /etc/ld.so.preload"); |
81 | 75 | } |
82 | 76 | |
83 | ||
84 | ⏎ |
130 | 130 | // create an empty /var/log/wtmp file |
131 | 131 | /* coverity[toctou] */ |
132 | 132 | FILE *fp = fopen("/var/log/wtmp", "w"); |
133 | SET_PERMS_STREAM(fp, 0, wtmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH); | |
133 | 134 | if (fp) |
134 | 135 | fclose(fp); |
135 | if (chown("/var/log/wtmp", 0, wtmp_group) < 0) | |
136 | errExit("chown"); | |
137 | if (chmod("/var/log/wtmp", S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH ) < 0) | |
138 | errExit("chmod"); | |
139 | 136 | fs_logger("touch /var/log/wtmp"); |
140 | 137 | |
141 | 138 | // create an empty /var/log/btmp file |
142 | 139 | fp = fopen("/var/log/btmp", "w"); |
140 | SET_PERMS_STREAM(fp, 0, wtmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP); | |
143 | 141 | if (fp) |
144 | 142 | fclose(fp); |
145 | if (chown("/var/log/btmp", 0, wtmp_group) < 0) | |
146 | errExit("chown"); | |
147 | if (chmod("/var/log/btmp", S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP) < 0) | |
148 | errExit("chmod"); | |
149 | 143 | fs_logger("touch /var/log/btmp"); |
150 | 144 | } |
151 | 145 | else |
168 | 162 | |
169 | 163 | if (fp) { |
170 | 164 | fprintf(fp, "\n"); |
165 | SET_PERMS_STREAM(fp, 0, 0, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); | |
171 | 166 | fclose(fp); |
172 | if (chown("/var/lib/dhcp/dhcpd.leases", 0, 0) == -1) | |
173 | errExit("chown"); | |
174 | if (chmod("/var/lib/dhcp/dhcpd.leases", S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) | |
175 | errExit("chmod"); | |
176 | 167 | fs_logger("touch /var/lib/dhcp/dhcpd.leases"); |
177 | 168 | } |
178 | 169 | } |
278 | 269 | // create directory |
279 | 270 | if (mkdir(lnk, S_IRWXU|S_IRWXG|S_IRWXO)) |
280 | 271 | errExit("mkdir"); |
281 | if (chown(lnk, 0, 0)) | |
282 | errExit("chown"); | |
283 | 272 | if (chmod(lnk, S_IRWXU|S_IRWXG|S_IRWXO)) |
284 | 273 | errExit("chmod"); |
274 | ASSERT_PERMS(lnk, 0, 0, S_IRWXU|S_IRWXG|S_IRWXO); | |
285 | 275 | } |
286 | 276 | if (arg_debug) |
287 | 277 | printf("Mounting tmpfs on %s on behalf of /var/lock\n", lnk); |
352 | 342 | |
353 | 343 | // save new utmp file |
354 | 344 | fwrite(&u_boot, sizeof(u_boot), 1, fp); |
345 | SET_PERMS_STREAM(fp, 0, utmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH); | |
355 | 346 | fclose(fp); |
356 | if (chown(RUN_UTMP_FILE, 0, utmp_group) < 0) | |
357 | errExit("chown"); | |
358 | if (chmod(RUN_UTMP_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH ) < 0) | |
359 | errExit("chmod"); | |
360 | 347 | |
361 | 348 | // mount the new utmp file |
362 | 349 | if (arg_debug) |
267 | 267 | |
268 | 268 | // process regular file |
269 | 269 | else { |
270 | // create an empty file | |
271 | FILE *fp = fopen(path, "w"); | |
272 | if (!fp) { | |
273 | fprintf(stderr, "Error: cannot create empty file in home directory\n"); | |
274 | exit(1); | |
275 | } | |
276 | fclose(fp); | |
277 | } | |
278 | ||
279 | // set file properties | |
280 | if (chown(path, s.st_uid, s.st_gid) < 0) | |
281 | errExit("chown"); | |
282 | if (chmod(path, s.st_mode) < 0) | |
283 | errExit("chmod"); | |
284 | ||
270 | if (access(path, R_OK)) { | |
271 | // create an empty file | |
272 | FILE *fp = fopen(path, "w"); | |
273 | if (!fp) { | |
274 | fprintf(stderr, "Error: cannot create empty file in home directory\n"); | |
275 | exit(1); | |
276 | } | |
277 | // set file properties | |
278 | SET_PERMS_STREAM(fp, s.st_uid, s.st_gid, s.st_mode); | |
279 | fclose(fp); | |
280 | } | |
281 | else | |
282 | return; // the file is already present | |
283 | } | |
284 | ||
285 | 285 | // mount |
286 | 286 | if (mount(wfile, path, NULL, MS_BIND|MS_REC, NULL) < 0) |
287 | 287 | errExit("mount bind"); |
390 | 390 | |
391 | 391 | entry->home_dir = 1; |
392 | 392 | home_dir = 1; |
393 | if (arg_debug) | |
393 | if (arg_debug || arg_debug_whitelists) | |
394 | 394 | fprintf(stderr, "Debug %d: fname #%s#, cfg.homedir #%s#\n", |
395 | 395 | __LINE__, fname, cfg.homedir); |
396 | 396 | |
397 | 397 | // both path and absolute path are under /home |
398 | // if (strncmp(fname, cfg.homedir, strlen(cfg.homedir)) != 0) { | |
399 | // goto errexit; | |
400 | // } | |
398 | if (strncmp(fname, cfg.homedir, strlen(cfg.homedir)) != 0) { | |
399 | // check if the file is owned by the user | |
400 | struct stat s; | |
401 | if (stat(fname, &s) == 0 && s.st_uid != getuid()) | |
402 | goto errexit; | |
403 | } | |
401 | 404 | } |
402 | 405 | else if (strncmp(new_name, "/tmp/", 5) == 0) { |
403 | 406 | entry->tmp_dir = 1; |
22 | 22 | #include <fcntl.h> |
23 | 23 | #include <unistd.h> |
24 | 24 | #include <sys/prctl.h> |
25 | #include <errno.h> | |
25 | 26 | |
26 | 27 | static int apply_caps = 0; |
27 | 28 | static uint64_t caps = 0; |
47 | 48 | exit(1); |
48 | 49 | } |
49 | 50 | |
50 | ||
51 | int len = 0; | |
52 | int i; | |
53 | // calculate command length | |
54 | for (i = index; i < argc; i++) { | |
55 | len += strlen(argv[i]) + 3; | |
56 | } | |
57 | assert(len > 0); | |
58 | ||
59 | 51 | // build command |
60 | cfg.command_line = malloc(len + 1); | |
61 | *cfg.command_line = '\0'; | |
62 | for (i = index; i < argc; i++) { | |
63 | if (strchr(argv[i], '&')) { | |
64 | strcat(cfg.command_line, "\'"); | |
65 | strcat(cfg.command_line, argv[i]); | |
66 | strcat(cfg.command_line, "\' "); | |
67 | } | |
68 | else { | |
69 | strcat(cfg.command_line, argv[i]); | |
70 | strcat(cfg.command_line, " "); | |
71 | } | |
72 | } | |
52 | build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, index); | |
53 | ||
73 | 54 | if (arg_debug) |
74 | 55 | printf("Extracted command #%s#\n", cfg.command_line); |
75 | 56 | } |
140 | 121 | break; |
141 | 122 | } |
142 | 123 | else if (strncmp(buf, "CapBnd:", 7) == 0) { |
143 | char *ptr = buf + 8; | |
124 | char *ptr = buf + 7; | |
144 | 125 | unsigned long long val; |
145 | 126 | sscanf(ptr, "%llx", &val); |
146 | 127 | apply_caps = 1; |
313 | 294 | // set seccomp filter |
314 | 295 | if (apply_seccomp == 1) // not available for uid 0 |
315 | 296 | seccomp_set(); |
316 | ||
317 | 297 | #endif |
318 | ||
298 | ||
319 | 299 | // fix qt 4.8 |
320 | 300 | if (setenv("QT_X11_NO_MITSHM", "1", 1) < 0) |
321 | 301 | errExit("setenv"); |
332 | 312 | else |
333 | 313 | drop_privs(arg_nogroups); // nogroups not available for uid 0 |
334 | 314 | |
315 | // user namespace resets capabilities | |
316 | // set caps filter | |
317 | if (apply_caps == 1) // not available for uid 0 | |
318 | caps_set(caps); | |
319 | ||
335 | 320 | // set prompt color to green |
336 | //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' | |
337 | if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0) | |
338 | errExit("setenv"); | |
339 | ||
340 | // run cmdline trough /bin/bash | |
321 | char *prompt = getenv("FIREJAIL_PROMPT"); | |
322 | if (prompt && strcmp(prompt, "yes") == 0) { | |
323 | //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' | |
324 | if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0) | |
325 | errExit("setenv"); | |
326 | } | |
327 | ||
328 | // set nice | |
329 | if (arg_nice) { | |
330 | errno = 0; | |
331 | int rv = nice(cfg.nice); | |
332 | (void) rv; | |
333 | if (errno) { | |
334 | fprintf(stderr, "Warning: cannot set nice value\n"); | |
335 | errno = 0; | |
336 | } | |
337 | } | |
338 | ||
339 | // run cmdline trough shell | |
341 | 340 | if (cfg.command_line == NULL) { |
341 | // if the sandbox was started with --shell=none, it is possible we don't have a shell | |
342 | // inside the sandbox | |
343 | if (cfg.shell == NULL) { | |
344 | cfg.shell = guess_shell(); | |
345 | if (!cfg.shell) { | |
346 | fprintf(stderr, "Error: no POSIX shell found, please use --shell command line option\n"); | |
347 | exit(1); | |
348 | } | |
349 | } | |
350 | ||
342 | 351 | struct stat s; |
343 | ||
344 | // replace the process with a shell | |
345 | if (stat("/bin/bash", &s) == 0) | |
346 | execlp("/bin/bash", "/bin/bash", NULL); | |
347 | else if (stat("/usr/bin/zsh", &s) == 0) | |
348 | execlp("/usr/bin/zsh", "/usr/bin/zsh", NULL); | |
349 | else if (stat("/bin/csh", &s) == 0) | |
350 | execlp("/bin/csh", "/bin/csh", NULL); | |
351 | else if (stat("/bin/sh", &s) == 0) | |
352 | execlp("/bin/sh", "/bin/sh", NULL); | |
353 | ||
354 | // no shell found, print an error and exit | |
355 | fprintf(stderr, "Error: no POSIX shell found\n"); | |
356 | sleep(5); | |
357 | exit(1); | |
358 | } | |
359 | else { | |
360 | // run the command supplied by the user | |
361 | int cwd = 0; | |
362 | if (cfg.cwd) { | |
363 | if (chdir(cfg.cwd) == 0) | |
364 | cwd = 1; | |
365 | } | |
366 | ||
367 | if (!cwd) { | |
368 | if (chdir("/") < 0) | |
369 | errExit("chdir"); | |
370 | if (cfg.homedir) { | |
371 | struct stat s; | |
372 | if (stat(cfg.homedir, &s) == 0) { | |
373 | if (chdir(cfg.homedir) < 0) | |
374 | errExit("chdir"); | |
375 | } | |
352 | if (stat(cfg.shell, &s) == -1) { | |
353 | fprintf(stderr, "Error: %s shell not found inside the sandbox\n", cfg.shell); | |
354 | exit(1); | |
355 | } | |
356 | ||
357 | cfg.command_line = cfg.shell; | |
358 | cfg.window_title = cfg.shell; | |
359 | } | |
360 | ||
361 | int cwd = 0; | |
362 | if (cfg.cwd) { | |
363 | if (chdir(cfg.cwd) == 0) | |
364 | cwd = 1; | |
365 | } | |
366 | ||
367 | if (!cwd) { | |
368 | if (chdir("/") < 0) | |
369 | errExit("chdir"); | |
370 | if (cfg.homedir) { | |
371 | struct stat s; | |
372 | if (stat(cfg.homedir, &s) == 0) { | |
373 | /* coverity[toctou] */ | |
374 | if (chdir(cfg.homedir) < 0) | |
375 | errExit("chdir"); | |
376 | 376 | } |
377 | 377 | } |
378 | ||
379 | char *arg[5]; | |
380 | arg[0] = "/bin/bash"; | |
381 | arg[1] = "-c"; | |
382 | if (arg_debug) | |
383 | printf("Starting %s\n", cfg.command_line); | |
384 | if (!arg_doubledash) { | |
385 | arg[2] = cfg.command_line; | |
386 | arg[3] = NULL; | |
387 | } | |
388 | else { | |
389 | arg[2] = "--"; | |
390 | arg[3] = cfg.command_line; | |
391 | arg[4] = NULL; | |
392 | } | |
393 | execvp("/bin/bash", arg); | |
394 | } | |
378 | } | |
379 | ||
380 | start_application(); | |
395 | 381 | |
396 | 382 | // it will never get here!!! |
397 | 383 | } |
373 | 373 | } |
374 | 374 | // copy file |
375 | 375 | EUID_ROOT(); |
376 | copy_file(src_fname, dest_fname); | |
377 | if (chown(dest_fname, getuid(), getgid()) == -1) | |
378 | errExit("chown"); | |
379 | if (chmod(dest_fname, 0644) == -1) | |
380 | errExit("chmod"); | |
376 | copy_file(src_fname, dest_fname, getuid(), getgid(), 0644); | |
381 | 377 | printf("Transfer complete\n"); |
382 | 378 | EUID_USER(); |
383 | 379 | } |
50 | 50 | static char child_stack[STACK_SIZE]; // space for child's stack |
51 | 51 | Config cfg; // configuration |
52 | 52 | int arg_private = 0; // mount private /home and /tmp directoryu |
53 | int arg_private_template = 0; // mount private /home using a template | |
53 | 54 | int arg_debug = 0; // print debug messages |
54 | 55 | int arg_debug_check_filename; // print debug messages for filename checking |
55 | 56 | int arg_debug_blacklists; // print debug messages for blacklists |
57 | 58 | int arg_nonetwork = 0; // --net=none |
58 | 59 | int arg_command = 0; // -c |
59 | 60 | int arg_overlay = 0; // overlay option |
60 | int arg_overlay_keep = 0; // place overlay diff directory in ~/.firejail | |
61 | int arg_zsh = 0; // use zsh as default shell | |
62 | int arg_csh = 0; // use csh as default shell | |
61 | int arg_overlay_keep = 0; // place overlay diff in a known directory | |
62 | int arg_overlay_reuse = 0; // allow the reuse of overlays | |
63 | 63 | |
64 | 64 | int arg_seccomp = 0; // enable default seccomp filter |
65 | 65 | |
100 | 100 | int arg_writable_var = 0; // writable var |
101 | 101 | int arg_appimage = 0; // appimage |
102 | 102 | int arg_audit = 0; // audit |
103 | char *arg_audit_prog; // audit | |
103 | char *arg_audit_prog = NULL; // audit | |
104 | int arg_apparmor = 0; // apparmor | |
105 | int arg_allow_debuggers = 0; // allow debuggers | |
106 | int login_shell = 0; | |
104 | 107 | |
105 | 108 | int parent_to_child_fds[2]; |
106 | 109 | int child_to_parent_fds[2]; |
234 | 237 | stat("/proc/self/gid_map", &s3) == 0) |
235 | 238 | arg_noroot = 1; |
236 | 239 | else { |
237 | fprintf(stderr, "Warning: user namespaces not available in the current kernel.\n"); | |
240 | if (!arg_quiet || arg_debug) | |
241 | fprintf(stderr, "Warning: user namespaces not available in the current kernel.\n"); | |
238 | 242 | arg_noroot = 0; |
239 | 243 | } |
240 | 244 | } |
241 | 245 | #endif |
246 | ||
242 | 247 | |
243 | 248 | // exit commands |
244 | 249 | static void run_cmd_and_exit(int i, int argc, char **argv) { |
254 | 259 | } |
255 | 260 | else if (strcmp(argv[i], "--version") == 0) { |
256 | 261 | printf("firejail version %s\n", VERSION); |
257 | #ifndef HAVE_NETWORK | |
258 | printf("Networking support is disabled.\n"); | |
259 | #endif | |
260 | #ifdef HAVE_NETWORK_RESTRICTED | |
261 | printf("Networking support is allowed only to root user.\n"); | |
262 | #endif | |
263 | #ifndef HAVE_USERNS | |
264 | printf("User namespace support is disabled.\n"); | |
265 | #endif | |
266 | #ifndef HAVE_SECCOMP | |
267 | printf("Seccomp-bpf support is disabled.\n"); | |
268 | #endif | |
269 | #ifndef HAVE_BIND | |
270 | printf("Bind support is disabled.\n"); | |
271 | #endif | |
272 | #ifndef HAVE_CHROOT | |
273 | printf("Chroot support is disabled.\n"); | |
274 | #endif | |
275 | #ifndef HAVE_X11 | |
276 | printf("X11 support is disabled.\n"); | |
277 | #endif | |
278 | #ifndef HAVE_FILE_TRANSFER | |
279 | printf("File transfer support is disabled.\n"); | |
280 | #endif | |
281 | #ifndef HAVE_WHITELIST | |
282 | printf("whitelisting support is disabled.\n"); | |
283 | #endif | |
262 | printf("\n"); | |
263 | print_compiletime_support(); | |
264 | printf("\n"); | |
284 | 265 | exit(0); |
285 | 266 | } |
267 | #ifdef HAVE_OVERLAYFS | |
268 | else if (strcmp(argv[i], "--overlay-clean") == 0) { | |
269 | if (checkcfg(CFG_OVERLAYFS)) { | |
270 | char *path; | |
271 | if (asprintf(&path, "%s/.firejail", cfg.homedir) == -1) | |
272 | errExit("asprintf"); | |
273 | EUID_ROOT(); | |
274 | if (setreuid(0, 0) < 0) | |
275 | errExit("setreuid"); | |
276 | if (setregid(0, 0) < 0) | |
277 | errExit("setregid"); | |
278 | errno = 0; | |
279 | int rv = remove_directory(path); | |
280 | if (rv) { | |
281 | fprintf(stderr, "Error: cannot removed overlays stored in ~/.firejail directory, errno %d\n", errno); | |
282 | exit(1); | |
283 | } | |
284 | } | |
285 | else { | |
286 | fprintf(stderr, "Error: overlayfs feature is disabled in Firejail configuration file\n"); | |
287 | exit(1); | |
288 | } | |
289 | exit(0); | |
290 | } | |
291 | #endif | |
286 | 292 | #ifdef HAVE_X11 |
287 | 293 | else if (strcmp(argv[i], "--x11") == 0) { |
288 | 294 | if (checkcfg(CFG_X11)) { |
568 | 574 | #endif |
569 | 575 | else if (strncmp(argv[i], "--join=", 7) == 0) { |
570 | 576 | logargs(argc, argv); |
571 | ||
577 | ||
578 | if (arg_shell_none) { | |
579 | if (argc <= (i+1)) { | |
580 | fprintf(stderr, "Error: --shell=none set, but no command specified\n"); | |
581 | exit(1); | |
582 | } | |
583 | cfg.original_program_index = i + 1; | |
584 | } | |
585 | ||
586 | if (!cfg.shell && !arg_shell_none) | |
587 | cfg.shell = guess_shell(); | |
588 | ||
572 | 589 | // join sandbox by pid or by name |
573 | 590 | pid_t pid; |
574 | 591 | if (read_pid(argv[i] + 7, &pid) == 0) |
576 | 593 | else |
577 | 594 | join_name(argv[i] + 7, argc, argv, i + 1); |
578 | 595 | exit(0); |
596 | ||
579 | 597 | } |
580 | 598 | #ifdef HAVE_NETWORK |
581 | 599 | else if (strncmp(argv[i], "--join-network=", 15) == 0) { |
644 | 662 | exit(1); |
645 | 663 | } |
646 | 664 | fprintf(fp, "%s\n", cfg.name); |
665 | ||
666 | // mode and ownership | |
667 | SET_PERMS_STREAM(fp, 0, 0, 0644); | |
647 | 668 | fclose(fp); |
648 | ||
649 | // mode and ownership | |
650 | if (chown(fname, 0, 0) == -1) | |
651 | errExit("chown"); | |
652 | if (chmod(fname, 0644) == -1) | |
653 | errExit("chmod"); | |
654 | ||
655 | 669 | } |
656 | 670 | |
657 | 671 | static void delete_name_file(pid_t pid) { |
675 | 689 | exit(1); |
676 | 690 | } |
677 | 691 | fprintf(fp, "%d\n", display); |
692 | ||
693 | // mode and ownership | |
694 | SET_PERMS_STREAM(fp, 0, 0, 0644); | |
678 | 695 | fclose(fp); |
679 | ||
680 | // mode and ownership | |
681 | if (chown(fname, 0, 0) == -1) | |
682 | errExit("chown"); | |
683 | if (chmod(fname, 0644) == -1) | |
684 | errExit("chmod"); | |
685 | ||
686 | 696 | } |
687 | 697 | |
688 | 698 | static void delete_x11_file(pid_t pid) { |
696 | 706 | |
697 | 707 | static void detect_quiet(int argc, char **argv) { |
698 | 708 | int i; |
699 | char *progs[] = { | |
700 | "less", | |
701 | "cpio", | |
702 | "strings", | |
703 | "gzip", | |
704 | "xz", | |
705 | "xzdec", | |
706 | NULL | |
707 | }; | |
708 | 709 | |
709 | 710 | // detect --quiet |
710 | 711 | for (i = 1; i < argc; i++) { |
719 | 720 | if (strncmp(argv[i], "--", 2) != 0) |
720 | 721 | break; |
721 | 722 | } |
722 | ||
723 | // argv[i] is the program name if --quiet was not already detected | |
724 | if (arg_quiet || i == argc) | |
725 | return; | |
726 | ||
727 | // extract the name of the program without the leading path | |
728 | char *ptr = strrchr(argv[i], '/'); | |
729 | char *name = (ptr)? (ptr + 1): argv[i]; | |
730 | if (*name == '\0') | |
731 | return; | |
732 | ||
733 | // look for the program in the list | |
734 | int j = 0; | |
735 | while (progs[j] != NULL) { | |
736 | if (strcmp(name, progs[j]) == 0) { | |
737 | arg_quiet = 1; | |
738 | return; | |
739 | } | |
740 | j++; | |
741 | } | |
723 | } | |
724 | ||
725 | static void detect_allow_debuggers(int argc, char **argv) { | |
726 | int i; | |
727 | ||
728 | // detect --allow-debuggers | |
729 | for (i = 1; i < argc; i++) { | |
730 | if (strcmp(argv[i], "--allow-debuggers") == 0) { | |
731 | arg_allow_debuggers = 1; | |
732 | break; | |
733 | } | |
734 | ||
735 | // detect end of firejail params | |
736 | if (strcmp(argv[i], "--") == 0) | |
737 | break; | |
738 | if (strncmp(argv[i], "--", 2) != 0) | |
739 | break; | |
740 | } | |
741 | } | |
742 | ||
743 | char *guess_shell(void) { | |
744 | char *shell = NULL; | |
745 | // shells in order of preference | |
746 | char *shells[] = {"/bin/bash", "/bin/csh", "/usr/bin/zsh", "/bin/sh", "/bin/ash", NULL }; | |
747 | ||
748 | int i = 0; | |
749 | while (shells[i] != NULL) { | |
750 | struct stat s; | |
751 | // access call checks as real UID/GID, not as effective UID/GID | |
752 | if (stat(shells[i], &s) == 0 && access(shells[i], R_OK) == 0) { | |
753 | shell = shells[i]; | |
754 | break; | |
755 | } | |
756 | i++; | |
757 | } | |
758 | ||
759 | return shell; | |
742 | 760 | } |
743 | 761 | |
744 | 762 | //******************************************* |
758 | 776 | #endif |
759 | 777 | |
760 | 778 | detect_quiet(argc, argv); |
779 | detect_allow_debuggers(argc, argv); | |
761 | 780 | |
762 | 781 | // drop permissions by default and rise them when required |
763 | 782 | EUID_INIT(); |
764 | 783 | EUID_USER(); |
784 | ||
765 | 785 | |
766 | 786 | // check argv[0] symlink wrapper if this is not a login shell |
767 | 787 | if (*argv[0] != '-') |
793 | 813 | strcmp(argv[i], "--debug-protocols") == 0 || |
794 | 814 | strcmp(argv[i], "--help") == 0 || |
795 | 815 | strcmp(argv[i], "--version") == 0 || |
816 | strcmp(argv[i], "--overlay-clean") == 0 || | |
796 | 817 | strncmp(argv[i], "--dns.print=", 12) == 0 || |
797 | 818 | strncmp(argv[i], "--bandwidth=", 12) == 0 || |
798 | 819 | strncmp(argv[i], "--caps.print=", 13) == 0 || |
878 | 899 | if (strcmp(comm, "sshd") == 0) { |
879 | 900 | arg_quiet = 1; |
880 | 901 | parent_sshd = 1; |
902 | ||
903 | #ifdef DEBUG_RESTRICTED_SHELL | |
904 | {EUID_ROOT(); | |
905 | FILE *fp = fopen("/firelog", "w"); | |
906 | if (fp) { | |
907 | int i; | |
908 | fprintf(fp, "argc %d: ", argc); | |
909 | for (i = 0; i < argc; i++) | |
910 | fprintf(fp, "#%s# ", argv[i]); | |
911 | fprintf(fp, "\n"); | |
912 | fclose(fp); | |
913 | } | |
914 | EUID_USER();} | |
915 | #endif | |
916 | // run sftp and scp directly without any sandboxing | |
917 | // regular login has argv[0] == "-firejail" | |
918 | if (*argv[0] != '-') { | |
919 | if (strcmp(argv[1], "-c") == 0 && argc > 2) { | |
920 | if (strcmp(argv[2], "/usr/lib/openssh/sftp-server") == 0 || | |
921 | strncmp(argv[2], "scp ", 4) == 0) { | |
922 | #ifdef DEBUG_RESTRICTED_SHELL | |
923 | {EUID_ROOT(); | |
924 | FILE *fp = fopen("/firelog", "a"); | |
925 | if (fp) { | |
926 | fprintf(fp, "run without a sandbox\n"); | |
927 | fclose(fp); | |
928 | } | |
929 | EUID_USER();} | |
930 | #endif | |
931 | ||
932 | drop_privs(1); | |
933 | int rv = system(argv[2]); | |
934 | exit(rv); | |
935 | } | |
936 | } | |
937 | } | |
881 | 938 | } |
882 | 939 | free(comm); |
883 | 940 | } |
885 | 942 | |
886 | 943 | // is this a login shell, or a command passed by sshd, insert command line options from /etc/firejail/login.users |
887 | 944 | if (*argv[0] == '-' || parent_sshd) { |
945 | if (argc == 1) | |
946 | login_shell = 1; | |
888 | 947 | fullargc = restricted_shell(cfg.username); |
889 | 948 | if (fullargc) { |
949 | ||
950 | #ifdef DEBUG_RESTRICTED_SHELL | |
951 | {EUID_ROOT(); | |
952 | FILE *fp = fopen("/firelog", "a"); | |
953 | if (fp) { | |
954 | fprintf(fp, "fullargc %d: ", fullargc); | |
955 | int i; | |
956 | for (i = 0; i < fullargc; i++) | |
957 | fprintf(fp, "#%s# ", fullargv[i]); | |
958 | fprintf(fp, "\n"); | |
959 | fclose(fp); | |
960 | } | |
961 | EUID_USER();} | |
962 | #endif | |
963 | ||
890 | 964 | int j; |
891 | 965 | for (i = 1, j = fullargc; i < argc && j < MAX_ARGS; i++, j++, fullargc++) |
892 | 966 | fullargv[j] = argv[i]; |
894 | 968 | // replace argc/argv with fullargc/fullargv |
895 | 969 | argv = fullargv; |
896 | 970 | argc = j; |
971 | ||
972 | #ifdef DEBUG_RESTRICTED_SHELL | |
973 | {EUID_ROOT(); | |
974 | FILE *fp = fopen("/firelog", "a"); | |
975 | if (fp) { | |
976 | fprintf(fp, "argc %d: ", argc); | |
977 | int i; | |
978 | for (i = 0; i < argc; i++) | |
979 | fprintf(fp, "#%s# ", argv[i]); | |
980 | fprintf(fp, "\n"); | |
981 | fclose(fp); | |
982 | } | |
983 | EUID_USER();} | |
984 | #endif | |
897 | 985 | } |
898 | 986 | } |
899 | 987 | else { |
905 | 993 | // check for force-nonewprivs in /etc/firejail/firejail.config file |
906 | 994 | if (checkcfg(CFG_FORCE_NONEWPRIVS)) |
907 | 995 | arg_nonewprivs = 1; |
996 | ||
997 | if (arg_allow_debuggers) { | |
998 | char *cmd = strdup("noblacklist ${PATH}/strace"); | |
999 | if (!cmd) | |
1000 | errExit("strdup"); | |
1001 | profile_add(cmd); | |
1002 | } | |
908 | 1003 | |
909 | 1004 | // parse arguments |
910 | 1005 | for (i = 1; i < argc; i++) { |
929 | 1024 | } |
930 | 1025 | else if (strcmp(argv[i], "--force") == 0) |
931 | 1026 | ; |
1027 | else if (strcmp(argv[i], "--allow-debuggers") == 0) { | |
1028 | // already handled | |
1029 | } | |
932 | 1030 | |
933 | 1031 | //************************************* |
934 | 1032 | // filtering |
935 | 1033 | //************************************* |
1034 | #ifdef HAVE_APPARMOR | |
1035 | else if (strcmp(argv[i], "--apparmor") == 0) | |
1036 | arg_apparmor = 1; | |
1037 | #endif | |
936 | 1038 | #ifdef HAVE_SECCOMP |
937 | 1039 | else if (strncmp(argv[i], "--protocol=", 11) == 0) { |
938 | 1040 | if (checkcfg(CFG_SECCOMP)) { |
1207 | 1309 | profile_check_line(line, 0, NULL); // will exit if something wrong |
1208 | 1310 | profile_add(line); |
1209 | 1311 | } |
1312 | #ifdef HAVE_OVERLAYFS | |
1210 | 1313 | else if (strcmp(argv[i], "--overlay") == 0) { |
1211 | if (cfg.chrootdir) { | |
1212 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | |
1213 | exit(1); | |
1214 | } | |
1215 | struct stat s; | |
1216 | if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { | |
1217 | fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n"); | |
1218 | exit(1); | |
1219 | } | |
1220 | arg_overlay = 1; | |
1221 | arg_overlay_keep = 1; | |
1222 | ||
1223 | // create ~/.firejail directory | |
1224 | char *dirname; | |
1225 | if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1) | |
1226 | errExit("asprintf"); | |
1227 | if (stat(dirname, &s) == -1) { | |
1228 | /* coverity[toctou] */ | |
1229 | if (mkdir(dirname, 0700)) | |
1230 | errExit("mkdir"); | |
1231 | if (chown(dirname, getuid(), getgid()) < 0) | |
1232 | errExit("chown"); | |
1233 | if (chmod(dirname, 0700) < 0) | |
1234 | errExit("chmod"); | |
1235 | } | |
1236 | else if (is_link(dirname)) { | |
1237 | fprintf(stderr, "Error: invalid ~/.firejail directory\n"); | |
1238 | exit(1); | |
1239 | } | |
1240 | ||
1241 | free(dirname); | |
1242 | ||
1243 | // check overlay directory | |
1244 | if (asprintf(&dirname, "%s/.firejail/%d", cfg.homedir, getpid()) == -1) | |
1245 | errExit("asprintf"); | |
1246 | if (stat(dirname, &s) == 0) { | |
1247 | fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname); | |
1248 | exit(1); | |
1249 | } | |
1250 | cfg.overlay_dir = dirname; | |
1251 | } | |
1314 | if (checkcfg(CFG_OVERLAYFS)) { | |
1315 | if (cfg.chrootdir) { | |
1316 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | |
1317 | exit(1); | |
1318 | } | |
1319 | struct stat s; | |
1320 | if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { | |
1321 | fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n"); | |
1322 | exit(1); | |
1323 | } | |
1324 | arg_overlay = 1; | |
1325 | arg_overlay_keep = 1; | |
1326 | ||
1327 | char *subdirname; | |
1328 | if (asprintf(&subdirname, "%d", getpid()) == -1) | |
1329 | errExit("asprintf"); | |
1330 | cfg.overlay_dir = fs_check_overlay_dir(subdirname, arg_overlay_reuse); | |
1331 | ||
1332 | free(subdirname); | |
1333 | } | |
1334 | else { | |
1335 | fprintf(stderr, "Error: overlayfs feature is disabled in Firejail configuration file\n"); | |
1336 | exit(1); | |
1337 | } | |
1338 | } | |
1339 | else if (strncmp(argv[i], "--overlay-named=", 16) == 0) { | |
1340 | if (checkcfg(CFG_OVERLAYFS)) { | |
1341 | if (cfg.chrootdir) { | |
1342 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | |
1343 | exit(1); | |
1344 | } | |
1345 | struct stat s; | |
1346 | if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { | |
1347 | fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n"); | |
1348 | exit(1); | |
1349 | } | |
1350 | arg_overlay = 1; | |
1351 | arg_overlay_keep = 1; | |
1352 | arg_overlay_reuse = 1; | |
1353 | ||
1354 | char *subdirname = argv[i] + 16; | |
1355 | if (subdirname == '\0') { | |
1356 | fprintf(stderr, "Error: invalid overlay option\n"); | |
1357 | exit(1); | |
1358 | } | |
1359 | ||
1360 | // check name | |
1361 | invalid_filename(subdirname); | |
1362 | if (strstr(subdirname, "..") || strstr(subdirname, "/")) { | |
1363 | fprintf(stderr, "Error: invalid overlay name\n"); | |
1364 | exit(1); | |
1365 | } | |
1366 | cfg.overlay_dir = fs_check_overlay_dir(subdirname, arg_overlay_reuse); | |
1367 | } | |
1368 | else { | |
1369 | fprintf(stderr, "Error: overlayfs feature is disabled in Firejail configuration file\n"); | |
1370 | exit(1); | |
1371 | } | |
1372 | ||
1373 | } | |
1374 | #if 0 // disabled for now, it could be used to overwrite system directories | |
1375 | else if (strncmp(argv[i], "--overlay-path=", 15) == 0) { | |
1376 | if (checkcfg(CFG_OVERLAYFS)) { | |
1377 | if (cfg.chrootdir) { | |
1378 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | |
1379 | exit(1); | |
1380 | } | |
1381 | struct stat s; | |
1382 | if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { | |
1383 | fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n"); | |
1384 | exit(1); | |
1385 | } | |
1386 | arg_overlay = 1; | |
1387 | arg_overlay_keep = 1; | |
1388 | arg_overlay_reuse = 1; | |
1389 | ||
1390 | char *dirname = argv[i] + 15; | |
1391 | if (dirname == '\0') { | |
1392 | fprintf(stderr, "Error: invalid overlay option\n"); | |
1393 | exit(1); | |
1394 | } | |
1395 | cfg.overlay_dir = expand_home(dirname, cfg.homedir); | |
1396 | } | |
1397 | else { | |
1398 | fprintf(stderr, "Error: overlayfs feature is disabled in Firejail configuration file\n"); | |
1399 | exit(1); | |
1400 | } | |
1401 | } | |
1402 | #endif | |
1252 | 1403 | else if (strcmp(argv[i], "--overlay-tmpfs") == 0) { |
1253 | if (cfg.chrootdir) { | |
1254 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | |
1255 | exit(1); | |
1256 | } | |
1257 | struct stat s; | |
1258 | if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { | |
1259 | fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n"); | |
1260 | exit(1); | |
1261 | } | |
1262 | arg_overlay = 1; | |
1263 | } | |
1404 | if (checkcfg(CFG_OVERLAYFS)) { | |
1405 | if (cfg.chrootdir) { | |
1406 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | |
1407 | exit(1); | |
1408 | } | |
1409 | struct stat s; | |
1410 | if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { | |
1411 | fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n"); | |
1412 | exit(1); | |
1413 | } | |
1414 | arg_overlay = 1; | |
1415 | } | |
1416 | else { | |
1417 | fprintf(stderr, "Error: overlayfs feature is disabled in Firejail configuration file\n"); | |
1418 | exit(1); | |
1419 | } | |
1420 | } | |
1421 | #endif | |
1264 | 1422 | else if (strncmp(argv[i], "--profile=", 10) == 0) { |
1265 | 1423 | if (arg_noprofile) { |
1266 | 1424 | fprintf(stderr, "Error: --noprofile and --profile options are mutually exclusive\n"); |
1381 | 1539 | fprintf(stderr, "Error: --chroot feature is disabled in Firejail configuration file\n"); |
1382 | 1540 | exit(1); |
1383 | 1541 | } |
1384 | ||
1385 | 1542 | } |
1386 | 1543 | #endif |
1387 | 1544 | else if (strcmp(argv[i], "--writable-etc") == 0) { |
1394 | 1551 | else if (strcmp(argv[i], "--writable-var") == 0) { |
1395 | 1552 | arg_writable_var = 1; |
1396 | 1553 | } |
1397 | else if (strcmp(argv[i], "--private") == 0) | |
1554 | else if (strcmp(argv[i], "--private") == 0) { | |
1555 | #if 0 | |
1556 | if (arg_private_template) { | |
1557 | fprintf(stderr, "Error: --private and --private-template are mutually exclusive\n"); | |
1558 | exit(1); | |
1559 | } | |
1560 | #endif | |
1398 | 1561 | arg_private = 1; |
1562 | } | |
1399 | 1563 | else if (strncmp(argv[i], "--private=", 10) == 0) { |
1564 | #if 0 | |
1565 | if (arg_private_template) { | |
1566 | fprintf(stderr, "Error: --private and --private-template are mutually exclusive\n"); | |
1567 | exit(1); | |
1568 | } | |
1569 | #endif | |
1400 | 1570 | // extract private home dirname |
1401 | 1571 | cfg.home_private = argv[i] + 10; |
1402 | 1572 | if (*cfg.home_private == '\0') { |
1406 | 1576 | fs_check_private_dir(); |
1407 | 1577 | arg_private = 1; |
1408 | 1578 | } |
1579 | #if 0 | |
1580 | else if (strncmp(argv[i], "--private-template=", 19) == 0) { | |
1581 | cfg.private_template = argv[i] + 19; | |
1582 | if (arg_private) { | |
1583 | fprintf(stderr, "Error: --private and --private-template are mutually exclusive\n"); | |
1584 | exit(1); | |
1585 | } | |
1586 | if (*cfg.private_template == '\0') { | |
1587 | fprintf(stderr, "Error: invalid private-template option\n"); | |
1588 | exit(1); | |
1589 | } | |
1590 | fs_check_private_template(); | |
1591 | arg_private_template = 1; | |
1592 | } | |
1593 | #endif | |
1409 | 1594 | else if (strcmp(argv[i], "--private-dev") == 0) { |
1410 | 1595 | arg_private_dev = 1; |
1411 | 1596 | } |
1531 | 1716 | errExit("strdup"); |
1532 | 1717 | |
1533 | 1718 | if (net_get_if_addr(intf->dev, &intf->ip, &intf->mask, intf->mac, &intf->mtu)) { |
1534 | fprintf(stderr, "Warning: interface %s is not configured\n", intf->dev); | |
1719 | if (!arg_quiet || arg_debug) | |
1720 | fprintf(stderr, "Warning: interface %s is not configured\n", intf->dev); | |
1535 | 1721 | } |
1536 | 1722 | intf->configured = 1; |
1537 | 1723 | } |
1862 | 2048 | fprintf(stderr, "Error: --shell=none was already specified.\n"); |
1863 | 2049 | return 1; |
1864 | 2050 | } |
1865 | if (arg_zsh || cfg.shell ) { | |
2051 | if (cfg.shell) { | |
1866 | 2052 | fprintf(stderr, "Error: only one default user shell can be specified\n"); |
1867 | 2053 | return 1; |
1868 | 2054 | } |
1869 | arg_csh = 1; | |
2055 | cfg.shell = "/bin/csh"; | |
1870 | 2056 | } |
1871 | 2057 | else if (strcmp(argv[i], "--zsh") == 0) { |
1872 | 2058 | if (arg_shell_none) { |
1873 | 2059 | fprintf(stderr, "Error: --shell=none was already specified.\n"); |
1874 | 2060 | return 1; |
1875 | 2061 | } |
1876 | if (arg_csh || cfg.shell ) { | |
2062 | if (cfg.shell) { | |
1877 | 2063 | fprintf(stderr, "Error: only one default user shell can be specified\n"); |
1878 | 2064 | return 1; |
1879 | 2065 | } |
1880 | arg_zsh = 1; | |
2066 | cfg.shell = "/bin/zsh"; | |
1881 | 2067 | } |
1882 | 2068 | else if (strcmp(argv[i], "--shell=none") == 0) { |
1883 | 2069 | arg_shell_none = 1; |
1884 | if (arg_csh || arg_zsh || cfg.shell) { | |
2070 | if (cfg.shell) { | |
1885 | 2071 | fprintf(stderr, "Error: a shell was already specified\n"); |
1886 | 2072 | return 1; |
1887 | 2073 | } |
1893 | 2079 | } |
1894 | 2080 | invalid_filename(argv[i] + 8); |
1895 | 2081 | |
1896 | if (arg_csh || arg_zsh || cfg.shell) { | |
2082 | if (cfg.shell) { | |
1897 | 2083 | fprintf(stderr, "Error: only one user shell can be specified\n"); |
1898 | 2084 | return 1; |
1899 | 2085 | } |
1903 | 2089 | fprintf(stderr, "Error: invalid shell\n"); |
1904 | 2090 | exit(1); |
1905 | 2091 | } |
1906 | ||
2092 | ||
1907 | 2093 | // access call checks as real UID/GID, not as effective UID/GID |
1908 | if (access(cfg.shell, R_OK)) { | |
2094 | if(cfg.chrootdir) { | |
2095 | char *shellpath; | |
2096 | if (asprintf(&shellpath, "%s%s", cfg.chrootdir, cfg.shell) == -1) | |
2097 | errExit("asprintf"); | |
2098 | if (access(shellpath, R_OK)) { | |
2099 | fprintf(stderr, "Error: cannot access shell file in chroot\n"); | |
2100 | exit(1); | |
2101 | } | |
2102 | free(shellpath); | |
2103 | } else if (access(cfg.shell, R_OK)) { | |
1909 | 2104 | fprintf(stderr, "Error: cannot access shell file\n"); |
1910 | 2105 | exit(1); |
1911 | 2106 | } |
1948 | 2143 | break; |
1949 | 2144 | } |
1950 | 2145 | } |
2146 | ||
2147 | // prog_index could still be -1 if no program was specified | |
2148 | if (prog_index == -1 && arg_shell_none) { | |
2149 | fprintf(stderr, "shell=none configured, but no program specified\n"); | |
2150 | exit(1); | |
2151 | } | |
1951 | 2152 | |
1952 | 2153 | // check trace configuration |
1953 | if (arg_trace && arg_tracelog) | |
1954 | fprintf(stderr, "Warning: --trace and --tracelog are mutually exclusive; --tracelog disabled\n"); | |
2154 | if (arg_trace && arg_tracelog) { | |
2155 | if (!arg_quiet || arg_debug) | |
2156 | fprintf(stderr, "Warning: --trace and --tracelog are mutually exclusive; --tracelog disabled\n"); | |
2157 | } | |
1955 | 2158 | |
1956 | 2159 | // check user namespace (--noroot) options |
1957 | 2160 | if (arg_noroot) { |
1975 | 2178 | free(msg); |
1976 | 2179 | } |
1977 | 2180 | |
2181 | // guess shell if unspecified | |
2182 | if (!arg_shell_none && !cfg.shell) { | |
2183 | cfg.shell = guess_shell(); | |
2184 | if (!cfg.shell) { | |
2185 | fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); | |
2186 | exit(1); | |
2187 | } | |
2188 | if (arg_debug) | |
2189 | printf("Autoselecting %s as shell\n", cfg.shell); | |
2190 | } | |
2191 | ||
1978 | 2192 | // build the sandbox command |
1979 | if (prog_index == -1 && arg_zsh) { | |
1980 | cfg.command_line = "/usr/bin/zsh"; | |
1981 | cfg.window_title = "/usr/bin/zsh"; | |
1982 | cfg.command_name = "zsh"; | |
1983 | } | |
1984 | else if (prog_index == -1 && arg_csh) { | |
1985 | cfg.command_line = "/bin/csh"; | |
1986 | cfg.window_title = "/bin/csh"; | |
1987 | cfg.command_name = "csh"; | |
1988 | } | |
1989 | else if (prog_index == -1 && cfg.shell) { | |
2193 | if (prog_index == -1 && cfg.shell) { | |
1990 | 2194 | cfg.command_line = cfg.shell; |
1991 | 2195 | cfg.window_title = cfg.shell; |
1992 | 2196 | cfg.command_name = cfg.shell; |
1993 | } | |
1994 | else if (prog_index == -1) { | |
1995 | cfg.command_line = "/bin/bash"; | |
1996 | cfg.window_title = "/bin/bash"; | |
1997 | cfg.command_name = "bash"; | |
1998 | 2197 | } |
1999 | 2198 | else if (arg_appimage) { |
2000 | 2199 | if (arg_debug) |
2003 | 2202 | cfg.window_title = "appimage"; |
2004 | 2203 | } |
2005 | 2204 | else { |
2006 | // calculate the length of the command | |
2007 | int i; | |
2008 | int len = 0; | |
2009 | int argcnt = argc - prog_index; | |
2010 | for (i = 0; i < argcnt; i++) | |
2011 | len += strlen(argv[i + prog_index]) + 3; // + ' ' + 2 '"' | |
2012 | ||
2013 | // build the string | |
2014 | cfg.command_line = malloc(len + 1); // + '\0' | |
2015 | if (!cfg.command_line) | |
2016 | errExit("malloc"); | |
2017 | cfg.window_title = malloc(len + 1); // + '\0' | |
2018 | if (!cfg.window_title) | |
2019 | errExit("malloc"); | |
2020 | ||
2021 | char *ptr1 = cfg.command_line; | |
2022 | char *ptr2 = cfg.window_title; | |
2023 | for (i = 0; i < argcnt; i++) { | |
2024 | // detect bash commands | |
2025 | if (strstr(argv[i + prog_index], "&&") || strstr(argv[i + prog_index], "||")) { | |
2026 | sprintf(ptr1, "%s ", argv[i + prog_index]); | |
2027 | } | |
2028 | else if (arg_command){ | |
2029 | sprintf(ptr1, "%s ", argv[i + prog_index]); | |
2030 | } | |
2031 | else { | |
2032 | sprintf(ptr1, "\'%s\' ", argv[i + prog_index]); | |
2033 | } | |
2034 | sprintf(ptr2, "%s ", argv[i + prog_index]); | |
2035 | ||
2036 | ptr1 += strlen(ptr1); | |
2037 | ptr2 += strlen(ptr2); | |
2038 | } | |
2039 | } | |
2205 | build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index); | |
2206 | } | |
2207 | /* else { | |
2208 | fprintf(stderr, "Error: command must be specified when --shell=none used.\n"); | |
2209 | exit(1); | |
2210 | }*/ | |
2040 | 2211 | |
2041 | 2212 | assert(cfg.command_name); |
2042 | 2213 | if (arg_debug) |
2067 | 2238 | |
2068 | 2239 | // use default.profile as the default |
2069 | 2240 | if (!custom_profile && !arg_noprofile) { |
2070 | if (cfg.chrootdir) | |
2071 | fprintf(stderr, "Warning: default profile disabled by --chroot option\n"); | |
2072 | else if (arg_overlay) | |
2073 | fprintf(stderr, "Warning: default profile disabled by --overlay option\n"); | |
2241 | if (cfg.chrootdir) { | |
2242 | if (!arg_quiet || arg_debug) | |
2243 | fprintf(stderr, "Warning: default profile disabled by --chroot option\n"); | |
2244 | } | |
2245 | else if (arg_overlay) { | |
2246 | if (!arg_quiet || arg_debug) | |
2247 | fprintf(stderr, "Warning: default profile disabled by --overlay option\n"); | |
2248 | } | |
2074 | 2249 | else { |
2075 | 2250 | // try to load a default profile |
2076 | 2251 | char *profile_name = DEFAULT_USER_PROFILE; |
2133 | 2308 | errExit("pipe"); |
2134 | 2309 | |
2135 | 2310 | if (arg_noroot && arg_overlay) { |
2136 | fprintf(stderr, "Warning: --overlay and --noroot are mutually exclusive, noroot disabled\n"); | |
2311 | if (!arg_quiet || arg_debug) | |
2312 | fprintf(stderr, "Warning: --overlay and --noroot are mutually exclusive, noroot disabled\n"); | |
2137 | 2313 | arg_noroot = 0; |
2138 | 2314 | } |
2139 | 2315 | else if (arg_noroot && cfg.chrootdir) { |
2140 | fprintf(stderr, "Warning: --chroot and --noroot are mutually exclusive, noroot disabled\n"); | |
2316 | if (!arg_quiet || arg_debug) | |
2317 | fprintf(stderr, "Warning: --chroot and --noroot are mutually exclusive, noroot disabled\n"); | |
2141 | 2318 | arg_noroot = 0; |
2142 | 2319 | } |
2143 | 2320 |
65 | 65 | |
66 | 66 | // custom filter |
67 | 67 | int allocated = 0; |
68 | if (netfilter_default) | |
69 | fname = netfilter_default; | |
68 | 70 | if (fname) { |
69 | 71 | // buffer the filter |
70 | 72 | struct stat s; |
12 | 12 | } |
13 | 13 | |
14 | 14 | net_configure_sandbox_ip(br) { |
15 | if br->ip_snadbox | |
15 | if br->ip_sandbox | |
16 | 16 | check br->ipsandbox inside the bridge network |
17 | 17 | arp_check(br->ipsandbox) // send an arp req to check if anybody else is using this address |
18 | 18 | else |
161 | 161 | void run_no_sandbox(int argc, char **argv) { |
162 | 162 | EUID_ASSERT(); |
163 | 163 | |
164 | // build command | |
165 | char *command = NULL; | |
166 | int allocated = 0; | |
167 | if (argc == 1) | |
168 | command = "/bin/bash"; | |
169 | else { | |
170 | // calculate length | |
171 | int len = 0; | |
172 | int i; | |
173 | for (i = 1; i < argc; i++) { | |
174 | if (*argv[i] == '-') | |
175 | continue; | |
164 | // process limited subset of options | |
165 | int i; | |
166 | for (i = 0; i < argc; i++) { | |
167 | if (strcmp(argv[i], "--csh") == 0) { | |
168 | if (arg_shell_none) { | |
169 | fprintf(stderr, "Error: --shell=none was already specified.\n"); | |
170 | exit(1); | |
171 | } | |
172 | if (cfg.shell) { | |
173 | fprintf(stderr, "Error: only one default user shell can be specified\n"); | |
174 | exit(1); | |
175 | } | |
176 | cfg.shell = "/bin/csh"; | |
177 | } | |
178 | else if (strcmp(argv[i], "--zsh") == 0) { | |
179 | if (arg_shell_none) { | |
180 | fprintf(stderr, "Error: --shell=none was already specified.\n"); | |
181 | exit(1); | |
182 | } | |
183 | if (cfg.shell) { | |
184 | fprintf(stderr, "Error: only one default user shell can be specified\n"); | |
185 | exit(1); | |
186 | } | |
187 | cfg.shell = "/bin/zsh"; | |
188 | } | |
189 | else if (strcmp(argv[i], "--shell=none") == 0) { | |
190 | arg_shell_none = 1; | |
191 | if (cfg.shell) { | |
192 | fprintf(stderr, "Error: a shell was already specified\n"); | |
193 | exit(1); | |
194 | } | |
195 | } | |
196 | else if (strncmp(argv[i], "--shell=", 8) == 0) { | |
197 | if (arg_shell_none) { | |
198 | fprintf(stderr, "Error: --shell=none was already specified.\n"); | |
199 | exit(1); | |
200 | } | |
201 | invalid_filename(argv[i] + 8); | |
202 | ||
203 | if (cfg.shell) { | |
204 | fprintf(stderr, "Error: only one user shell can be specified\n"); | |
205 | exit(1); | |
206 | } | |
207 | cfg.shell = argv[i] + 8; | |
208 | ||
209 | if (is_dir(cfg.shell) || strstr(cfg.shell, "..")) { | |
210 | fprintf(stderr, "Error: invalid shell\n"); | |
211 | exit(1); | |
212 | } | |
213 | ||
214 | // access call checks as real UID/GID, not as effective UID/GID | |
215 | if(cfg.chrootdir) { | |
216 | char *shellpath; | |
217 | if (asprintf(&shellpath, "%s%s", cfg.chrootdir, cfg.shell) == -1) | |
218 | errExit("asprintf"); | |
219 | if (access(shellpath, R_OK)) { | |
220 | fprintf(stderr, "Error: cannot access shell file in chroot\n"); | |
221 | exit(1); | |
222 | } | |
223 | free(shellpath); | |
224 | } else if (access(cfg.shell, R_OK)) { | |
225 | fprintf(stderr, "Error: cannot access shell file\n"); | |
226 | exit(1); | |
227 | } | |
228 | } | |
229 | } | |
230 | ||
231 | // use $SHELL to get shell used in sandbox | |
232 | if (!arg_shell_none && !cfg.shell) { | |
233 | char *shell = getenv("SHELL"); | |
234 | if (access(shell, R_OK) == 0) | |
235 | cfg.shell = shell; | |
236 | } | |
237 | // guess shell otherwise | |
238 | if (!arg_shell_none && !cfg.shell) { | |
239 | cfg.shell = guess_shell(); | |
240 | if (arg_debug) | |
241 | printf("Autoselecting %s as shell\n", cfg.shell); | |
242 | } | |
243 | if (!arg_shell_none && !cfg.shell) { | |
244 | fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); | |
245 | exit(1); | |
246 | } | |
247 | ||
248 | int prog_index = 0; | |
249 | // find first non option arg: | |
250 | // - first argument not starting wiht --, | |
251 | // - whatever follows after -c (example: firejail -c ls) | |
252 | for (i = 1; i < argc; i++) { | |
253 | if (strcmp(argv[i], "-c") == 0) { | |
254 | prog_index = i + 1; | |
255 | if (prog_index == argc) { | |
256 | fprintf(stderr, "Error: option -c requires an argument\n"); | |
257 | exit(1); | |
258 | } | |
176 | 259 | break; |
177 | 260 | } |
178 | int start_index = i; | |
179 | for (i = start_index; i < argc; i++) | |
180 | len += strlen(argv[i]) + 3; | |
181 | ||
182 | // allocate | |
183 | command = malloc(len + 1); | |
184 | if (!command) | |
185 | errExit("malloc"); | |
186 | memset(command, 0, len + 1); | |
187 | allocated = 1; | |
188 | ||
189 | // copy | |
190 | for (i = start_index; i < argc; i++) { | |
191 | if (strchr(argv[i], '&')) { | |
192 | strcat(command, "\""); | |
193 | strcat(command, argv[i]); | |
194 | strcat(command, "\" "); | |
195 | } | |
196 | else { | |
197 | strcat(command, argv[i]); | |
198 | strcat(command, " "); | |
199 | } | |
200 | } | |
201 | } | |
202 | ||
203 | // start the program in /bin/sh | |
204 | fprintf(stderr, "Warning: an existing sandbox was detected. " | |
205 | "%s will run without any additional sandboxing features in a /bin/sh shell\n", command); | |
206 | int rv = system(command); | |
207 | (void) rv; | |
208 | if (allocated) | |
209 | free(command); | |
210 | exit(1); | |
211 | } | |
261 | // check first argument not starting with -- | |
262 | if (strncmp(argv[i],"--",2) != 0) { | |
263 | prog_index = i; | |
264 | break; | |
265 | } | |
266 | } | |
267 | ||
268 | if (!arg_shell_none) { | |
269 | if (prog_index == 0) { | |
270 | cfg.command_line = cfg.shell; | |
271 | cfg.window_title = cfg.shell; | |
272 | } else { | |
273 | build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index); | |
274 | } | |
275 | } | |
276 | ||
277 | cfg.original_argv = argv; | |
278 | cfg.original_program_index = prog_index; | |
279 | ||
280 | char *command; | |
281 | if (prog_index == 0) | |
282 | command = cfg.shell; | |
283 | else | |
284 | command = argv[prog_index]; | |
285 | if (!arg_quiet) | |
286 | fprintf(stderr, "Warning: an existing sandbox was detected. " | |
287 | "%s will run without any additional sandboxing features\n", command); | |
288 | ||
289 | start_application(); | |
290 | } |
445 | 445 | return 0; |
446 | 446 | } |
447 | 447 | |
448 | if (strcmp(ptr, "apparmor") == 0) { | |
449 | #ifdef HAVE_APPARMOR | |
450 | arg_apparmor = 1; | |
451 | #endif | |
452 | return 0; | |
453 | } | |
454 | ||
448 | 455 | if (strncmp(ptr, "protocol ", 9) == 0) { |
449 | 456 | #ifdef HAVE_SECCOMP |
450 | 457 | if (checkcfg(CFG_SECCOMP)) |
605 | 612 | arg_private = 1; |
606 | 613 | return 0; |
607 | 614 | } |
608 | ||
615 | ||
616 | if (strcmp(ptr, "x11") == 0) { | |
617 | #ifdef HAVE_X11 | |
618 | if (checkcfg(CFG_X11)) { | |
619 | char *x11env = getenv("FIREJAIL_X11"); | |
620 | if (x11env && strcmp(x11env, "yes") == 0) | |
621 | return 0; | |
622 | else { | |
623 | // start x11 | |
624 | x11_start(cfg.original_argc, cfg.original_argv); | |
625 | exit(0); | |
626 | } | |
627 | } | |
628 | #endif | |
629 | return 0; | |
630 | } | |
631 | ||
632 | #if 0 | |
633 | if (strncmp(ptr, "private-template ", 17) == 0) { | |
634 | if (arg_private) { | |
635 | fprintf(stderr, "Error: --private and --private-template are mutually exclusive\n"); | |
636 | exit(1); | |
637 | } | |
638 | cfg.private_template = ptr + 17; | |
639 | fs_check_private_template(); | |
640 | arg_private_template = 1; | |
641 | ||
642 | return 0; | |
643 | } | |
644 | #endif | |
609 | 645 | // private /etc list of files and directories |
610 | 646 | if (strncmp(ptr, "private-etc ", 12) == 0) { |
611 | 647 | if (arg_writable_etc) { |
809 | 845 | exit(1); |
810 | 846 | } |
811 | 847 | |
848 | // allow debuggers | |
849 | if (arg_allow_debuggers) { | |
850 | char *tmp = strrchr(fname, '/'); | |
851 | if (tmp && *(tmp + 1) != '\0') { | |
852 | tmp++; | |
853 | if (strcmp(tmp, "disable-devel.inc") == 0) | |
854 | return; | |
855 | } | |
856 | } | |
857 | ||
812 | 858 | // open profile file: |
813 | 859 | FILE *fp = fopen(fname, "r"); |
814 | 860 | if (fp == NULL) { |
816 | 862 | exit(1); |
817 | 863 | } |
818 | 864 | |
819 | if (!arg_quiet) | |
820 | fprintf(stderr, "Reading profile %s\n", fname); | |
865 | int msg_printed = 0; | |
821 | 866 | |
822 | 867 | // read the file line by line |
823 | 868 | char buf[MAX_READ + 1]; |
835 | 880 | continue; |
836 | 881 | } |
837 | 882 | |
883 | // process quiet | |
884 | if (strcmp(ptr, "quiet") == 0) { | |
885 | arg_quiet = 1; | |
886 | continue; | |
887 | } | |
888 | if (!msg_printed) { | |
889 | if (!arg_quiet) | |
890 | fprintf(stderr, "Reading profile %s\n", fname); | |
891 | msg_printed = 1; | |
892 | } | |
893 | ||
838 | 894 | // process include |
839 | 895 | if (strncmp(ptr, "include ", 8) == 0) { |
840 | 896 | include_level++; |
272 | 272 | if (!fp) |
273 | 273 | errExit("fopen"); |
274 | 274 | fprintf(fp, "%s\n", cfg.protocol); |
275 | SET_PERMS_STREAM(fp, 0, 0, 0600); | |
275 | 276 | fclose(fp); |
276 | ||
277 | if (chmod(RUN_PROTOCOL_CFG, 0600) < 0) | |
278 | errExit("chmod"); | |
279 | ||
280 | if (chown(RUN_PROTOCOL_CFG, 0, 0) < 0) | |
281 | errExit("chown"); | |
282 | ||
283 | 277 | } |
284 | 278 | |
285 | 279 | void protocol_filter_load(const char *fname) { |
113 | 113 | char *pulsecfg = NULL; |
114 | 114 | if (asprintf(&pulsecfg, "%s/client.conf", RUN_PULSE_DIR) == -1) |
115 | 115 | errExit("asprintf"); |
116 | if (copy_file("/etc/pulse/client.conf", pulsecfg)) | |
116 | if (copy_file("/etc/pulse/client.conf", pulsecfg, -1, -1, 0644)) | |
117 | 117 | errExit("copy_file"); |
118 | 118 | FILE *fp = fopen(pulsecfg, "a+"); |
119 | 119 | if (!fp) |
120 | 120 | errExit("fopen"); |
121 | 121 | fprintf(fp, "%s", "\nenable-shm = no\n"); |
122 | SET_PERMS_STREAM(fp, getuid(), getgid(), 0644); | |
122 | 123 | fclose(fp); |
123 | if (chmod(pulsecfg, 0644) == -1) | |
124 | errExit("chmod"); | |
125 | if (chown(pulsecfg, getuid(), getgid()) == -1) | |
126 | errExit("chown"); | |
127 | 124 | |
128 | 125 | // create ~/.config/pulse directory if not present |
129 | 126 | char *dir1; |
25 | 25 | #include <dirent.h> |
26 | 26 | #include <fcntl.h> |
27 | 27 | #include <errno.h> |
28 | #include "../../uids.h" | |
28 | 29 | |
29 | 30 | #define MAXBUF 1024 |
30 | 31 | |
117 | 118 | if (stat("/etc/passwd", &s) == -1) |
118 | 119 | return; |
119 | 120 | if (arg_debug) |
120 | printf("Sanitizing /etc/passwd\n"); | |
121 | printf("Sanitizing /etc/passwd, UID_MIN %d\n", UID_MIN); | |
121 | 122 | if (is_link("/etc/passwd")) { |
122 | 123 | fprintf(stderr, "Error: invalid /etc/passwd\n"); |
123 | 124 | exit(1); |
169 | 170 | int rv = sscanf(ptr, "%d:", &uid); |
170 | 171 | if (rv == 0 || uid < 0) |
171 | 172 | goto errout; |
172 | if (uid < 1000) { // todo extract UID_MIN from /etc/login.def | |
173 | if (uid < UID_MIN) { | |
173 | 174 | fprintf(fpout, "%s", buf); |
174 | 175 | continue; |
175 | 176 | } |
185 | 186 | fprintf(fpout, "%s", buf); |
186 | 187 | } |
187 | 188 | fclose(fpin); |
189 | SET_PERMS_STREAM(fpout, 0, 0, 0644); | |
188 | 190 | fclose(fpout); |
189 | if (chown(RUN_PASSWD_FILE, 0, 0) == -1) | |
190 | errExit("chown"); | |
191 | if (chmod(RUN_PASSWD_FILE, 0644) == -1) | |
192 | errExit("chmod"); | |
193 | ||
191 | ||
194 | 192 | // mount-bind tne new password file |
195 | 193 | if (mount(RUN_PASSWD_FILE, "/etc/passwd", "none", MS_BIND, "mode=400,gid=0") < 0) |
196 | 194 | errExit("mount"); |
254 | 252 | if (stat("/etc/group", &s) == -1) |
255 | 253 | return; |
256 | 254 | if (arg_debug) |
257 | printf("Sanitizing /etc/group\n"); | |
255 | printf("Sanitizing /etc/group, GID_MIN %d\n", GID_MIN); | |
258 | 256 | if (is_link("/etc/group")) { |
259 | 257 | fprintf(stderr, "Error: invalid /etc/group\n"); |
260 | 258 | exit(1); |
305 | 303 | int rv = sscanf(ptr, "%d:", &gid); |
306 | 304 | if (rv == 0 || gid < 0) |
307 | 305 | goto errout; |
308 | if (gid < 1000) { // todo extract GID_MIN from /etc/login.def | |
306 | if (gid < GID_MIN) { | |
309 | 307 | if (copy_line(fpout, buf, ptr)) |
310 | 308 | goto errout; |
311 | 309 | continue; |
317 | 315 | goto errout; |
318 | 316 | } |
319 | 317 | fclose(fpin); |
318 | SET_PERMS_STREAM(fpout, 0, 0, 0644); | |
320 | 319 | fclose(fpout); |
321 | if (chown(RUN_GROUP_FILE, 0, 0) == -1) | |
322 | errExit("chown"); | |
323 | if (chmod(RUN_GROUP_FILE, 0644) == -1) | |
324 | errExit("chmod"); | |
325 | ||
320 | ||
326 | 321 | // mount-bind tne new group file |
327 | 322 | if (mount(RUN_GROUP_FILE, "/etc/group", "none", MS_BIND, "mode=400,gid=0") < 0) |
328 | 323 | errExit("mount"); |
39 | 39 | char buf[MAX_READ]; |
40 | 40 | while (fgets(buf, MAX_READ, fp)) { |
41 | 41 | lineno++; |
42 | ||
42 | ||
43 | 43 | // remove empty spaces at the beginning of the line |
44 | 44 | char *ptr = buf; |
45 | 45 | while (*ptr == ' ' || *ptr == '\t') { |
47 | 47 | } |
48 | 48 | if (*ptr == '\n' || *ptr == '#') |
49 | 49 | continue; |
50 | ||
50 | ||
51 | 51 | // parse line |
52 | 52 | char *usr = ptr; |
53 | 53 | char *args = strchr(usr, ':'); |
55 | 55 | fprintf(stderr, "Error: users.conf line %d\n", lineno); |
56 | 56 | exit(1); |
57 | 57 | } |
58 | ||
58 | 59 | *args = '\0'; |
59 | 60 | args++; |
60 | 61 | ptr = strchr(args, '\n'); |
69 | 70 | found = 1; |
70 | 71 | break; |
71 | 72 | } |
73 | ptr2++; | |
72 | 74 | } |
73 | 75 | if (!found) |
74 | 76 | continue; |
75 | 77 | |
76 | 78 | // process user |
77 | 79 | if (strcmp(user, usr) == 0) { |
78 | restricted_user = strdup(user); | |
79 | 80 | // extract program arguments |
80 | 81 | |
81 | 82 | fullargv[0] = "firejail"; |
82 | 83 | int i; |
83 | 84 | ptr = args; |
84 | 85 | for (i = 1; i < MAX_ARGS; i++) { |
86 | // skip blanks | |
87 | while (*ptr == ' ' || *ptr == '\t') | |
88 | ptr++; | |
85 | 89 | fullargv[i] = ptr; |
86 | while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') | |
87 | ptr++; | |
90 | #ifdef DEBUG_RESTRICTED_SHELL | |
91 | {EUID_ROOT(); | |
92 | FILE *fp = fopen("/firelog", "a"); | |
93 | if (fp) { | |
94 | fprintf(fp, "i %d ptr #%s#\n", i, fullargv[i]); | |
95 | fclose(fp); | |
96 | } | |
97 | EUID_USER();} | |
98 | #endif | |
99 | ||
88 | 100 | if (*ptr != '\0') { |
101 | // go to the end of the word | |
102 | while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') | |
103 | ptr++; | |
89 | 104 | *ptr ='\0'; |
90 | 105 | fullargv[i] = strdup(fullargv[i]); |
91 | if (fullargv[i] == NULL) { | |
92 | fprintf(stderr, "Error: cannot allocate memory\n"); | |
93 | exit(1); | |
94 | } | |
106 | if (fullargv[i] == NULL) | |
107 | errExit("strdup"); | |
95 | 108 | ptr++; |
96 | 109 | while (*ptr == ' ' || *ptr == '\t') |
97 | 110 | ptr++; |
107 | 120 | } |
108 | 121 | } |
109 | 122 | fclose(fp); |
110 | ||
123 | ||
111 | 124 | return 0; |
112 | 125 | } |
113 | 126 |
102 | 102 | a[1] = program; |
103 | 103 | int i; |
104 | 104 | for (i = 0; i < (argc - 1); i++) { |
105 | // look for & character | |
106 | if (strchr(argv[i + 1], '&')) { | |
107 | char *str = malloc(strlen(argv[i + 1])); | |
108 | if (str == NULL) | |
109 | errExit("malloc"); | |
110 | sprintf(str, "\"%s\"", argv[i + 1]); | |
111 | a[i + 2] = str; | |
112 | } | |
113 | else | |
114 | a[i + 2] = argv[i + 1]; | |
105 | a[i + 2] = argv[i + 1]; | |
115 | 106 | } |
116 | 107 | a[i + 2] = NULL; |
117 | 108 | execvp(a[0], a); |
38 | 38 | # define PR_SET_NO_NEW_PRIVS 38 |
39 | 39 | #endif |
40 | 40 | |
41 | #ifdef HAVE_APPARMOR | |
42 | #include <sys/apparmor.h> | |
43 | #endif | |
41 | 44 | |
42 | 45 | |
43 | 46 | static int monitored_pid = 0; |
100 | 103 | FILE *fp = fopen(RUN_GROUPS_CFG, "w"); |
101 | 104 | if (fp) { |
102 | 105 | fprintf(fp, "\n"); |
106 | SET_PERMS_STREAM(fp, 0, 0, 0644); // assume mode 0644 | |
103 | 107 | fclose(fp); |
104 | if (chown(RUN_GROUPS_CFG, 0, 0) < 0) | |
105 | errExit("chown"); | |
106 | 108 | } |
107 | 109 | else { |
108 | 110 | fprintf(stderr, "Error: cannot save nogroups state\n"); |
203 | 205 | while(rv != monitored_pid); |
204 | 206 | if (arg_debug) |
205 | 207 | printf("Sandbox monitor: waitpid %u retval %d status %d\n", monitored_pid, rv, status); |
208 | ||
209 | // if /proc is not remounted, we cannot check /proc directory, | |
210 | // for now we just get out of here | |
211 | // todo: find another way of checking child processes! | |
212 | if (!checkcfg(CFG_REMOUNT_PROC_SYS)) | |
213 | break; | |
206 | 214 | |
207 | 215 | DIR *dir; |
208 | 216 | if (!(dir = opendir("/proc"))) { |
280 | 288 | exit(1); |
281 | 289 | } |
282 | 290 | |
283 | static void start_application(void) { | |
291 | void start_application(void) { | |
284 | 292 | //**************************************** |
285 | 293 | // audit |
286 | 294 | //**************************************** |
321 | 329 | // start the program using a shell |
322 | 330 | //**************************************** |
323 | 331 | else { |
324 | // choose the shell requested by the user, or use bash as default | |
325 | char *sh; | |
326 | if (cfg.shell) | |
327 | sh = cfg.shell; | |
328 | else if (arg_zsh) | |
329 | sh = "/usr/bin/zsh"; | |
330 | else if (arg_csh) | |
331 | sh = "/bin/csh"; | |
332 | else | |
333 | sh = "/bin/bash"; | |
334 | ||
332 | assert(cfg.shell); | |
333 | assert(cfg.command_line); | |
334 | ||
335 | 335 | char *arg[5]; |
336 | 336 | int index = 0; |
337 | arg[index++] = sh; | |
338 | arg[index++] = "-c"; | |
339 | assert(cfg.command_line); | |
340 | if (arg_debug) | |
341 | printf("Starting %s\n", cfg.command_line); | |
342 | if (arg_doubledash) | |
343 | arg[index++] = "--"; | |
344 | arg[index++] = cfg.command_line; | |
337 | arg[index++] = cfg.shell; | |
338 | if (login_shell) { | |
339 | arg[index++] = "-l"; | |
340 | if (arg_debug) | |
341 | printf("Starting %s login shell\n", cfg.shell); | |
342 | } else { | |
343 | arg[index++] = "-c"; | |
344 | if (arg_debug) | |
345 | printf("Running %s command through %s\n", cfg.command_line, cfg.shell); | |
346 | if (arg_doubledash) | |
347 | arg[index++] = "--"; | |
348 | arg[index++] = cfg.command_line; | |
349 | } | |
345 | 350 | arg[index] = NULL; |
346 | 351 | assert(index < 5); |
347 | ||
352 | ||
348 | 353 | if (arg_debug) { |
349 | 354 | char *msg; |
350 | 355 | if (asprintf(&msg, "sandbox %d, execvp into %s", sandbox_pid, cfg.command_line) == -1) |
352 | 357 | logmsg(msg); |
353 | 358 | free(msg); |
354 | 359 | } |
355 | ||
360 | ||
356 | 361 | if (arg_debug) { |
357 | 362 | int i; |
358 | 363 | for (i = 0; i < 5; i++) { |
361 | 366 | printf("execvp argument %d: %s\n", i, arg[i]); |
362 | 367 | } |
363 | 368 | } |
364 | ||
369 | ||
365 | 370 | if (!arg_command && !arg_quiet) |
366 | 371 | printf("Child process initialized\n"); |
367 | execvp(sh, arg); | |
368 | } | |
369 | ||
372 | execvp(arg[0], arg); | |
373 | } | |
374 | ||
370 | 375 | perror("execvp"); |
371 | 376 | exit(1); // it should never get here!!! |
372 | 377 | } |
373 | 378 | |
374 | ||
379 | static void enforce_filters(void) { | |
380 | // force default seccomp inside the chroot, no keep or drop list | |
381 | // the list build on top of the default drop list is kept intact | |
382 | arg_seccomp = 1; | |
383 | if (cfg.seccomp_list_drop) { | |
384 | free(cfg.seccomp_list_drop); | |
385 | cfg.seccomp_list_drop = NULL; | |
386 | } | |
387 | if (cfg.seccomp_list_keep) { | |
388 | free(cfg.seccomp_list_keep); | |
389 | cfg.seccomp_list_keep = NULL; | |
390 | } | |
391 | ||
392 | // disable all capabilities | |
393 | if (arg_caps_default_filter || arg_caps_list) | |
394 | fprintf(stderr, "Warning: all capabilities disabled for a regular user in chroot\n"); | |
395 | arg_caps_drop_all = 1; | |
396 | ||
397 | // drop all supplementary groups; /etc/group file inside chroot | |
398 | // is controlled by a regular usr | |
399 | arg_nogroups = 1; | |
400 | if (!arg_quiet) | |
401 | printf("Dropping all Linux capabilities and enforcing default seccomp filter\n"); | |
402 | } | |
375 | 403 | |
376 | 404 | int sandbox(void* sandbox_arg) { |
377 | 405 | // Get rid of unused parameter warning |
390 | 418 | |
391 | 419 | if (arg_debug && child_pid == 1) |
392 | 420 | printf("PID namespace installed\n"); |
421 | ||
393 | 422 | |
394 | 423 | //**************************** |
395 | 424 | // set hostname |
455 | 484 | #ifdef HAVE_CHROOT |
456 | 485 | if (cfg.chrootdir) { |
457 | 486 | fs_chroot(cfg.chrootdir); |
458 | // redo cp command | |
459 | fs_build_cp_command(); | |
460 | 487 | |
461 | 488 | // force caps and seccomp if not started as root |
462 | 489 | if (getuid() != 0) { |
463 | // force default seccomp inside the chroot, no keep or drop list | |
464 | // the list build on top of the default drop list is kept intact | |
465 | arg_seccomp = 1; | |
490 | enforce_filters(); | |
466 | 491 | #ifdef HAVE_SECCOMP |
467 | 492 | enforce_seccomp = 1; |
468 | 493 | #endif |
469 | if (cfg.seccomp_list_drop) { | |
470 | free(cfg.seccomp_list_drop); | |
471 | cfg.seccomp_list_drop = NULL; | |
472 | } | |
473 | if (cfg.seccomp_list_keep) { | |
474 | free(cfg.seccomp_list_keep); | |
475 | cfg.seccomp_list_keep = NULL; | |
476 | } | |
477 | ||
478 | // disable all capabilities | |
479 | if (arg_caps_default_filter || arg_caps_list) | |
480 | fprintf(stderr, "Warning: all capabilities disabled for a regular user during chroot\n"); | |
481 | arg_caps_drop_all = 1; | |
482 | ||
483 | // drop all supplementary groups; /etc/group file inside chroot | |
484 | // is controlled by a regular usr | |
485 | arg_nogroups = 1; | |
486 | if (!arg_quiet) | |
487 | printf("Dropping all Linux capabilities and enforcing default seccomp filter\n"); | |
488 | 494 | } |
489 | 495 | else |
490 | 496 | arg_seccomp = 1; |
497 | 503 | } |
498 | 504 | else |
499 | 505 | #endif |
500 | if (arg_overlay) | |
506 | #ifdef HAVE_OVERLAYFS | |
507 | if (arg_overlay) { | |
501 | 508 | fs_overlayfs(); |
509 | // force caps and seccomp if not started as root | |
510 | if (getuid() != 0) { | |
511 | enforce_filters(); | |
512 | #ifdef HAVE_SECCOMP | |
513 | enforce_seccomp = 1; | |
514 | #endif | |
515 | } | |
516 | else | |
517 | arg_seccomp = 1; | |
518 | } | |
502 | 519 | else |
520 | #endif | |
503 | 521 | fs_basic_fs(); |
504 | 522 | |
505 | ||
506 | 523 | //**************************** |
507 | 524 | // set hostname in /etc/hostname |
508 | 525 | //**************************** |
514 | 531 | // private mode |
515 | 532 | //**************************** |
516 | 533 | if (arg_private) { |
517 | if (cfg.home_private) // --private= | |
518 | fs_private_homedir(); | |
534 | if (cfg.home_private) { // --private= | |
535 | if (cfg.chrootdir) | |
536 | fprintf(stderr, "Warning: private=directory feature is disabled in chroot\n"); | |
537 | else if (arg_overlay) | |
538 | fprintf(stderr, "Warning: private=directory feature is disabled in overlay\n"); | |
539 | else | |
540 | fs_private_homedir(); | |
541 | } | |
519 | 542 | else // --private |
520 | 543 | fs_private(); |
521 | 544 | } |
522 | ||
523 | if (arg_private_dev) | |
524 | fs_private_dev(); | |
545 | ||
546 | #if 0 | |
547 | if (arg_private_template) | |
548 | fs_private_template(); | |
549 | #endif | |
550 | ||
551 | if (arg_private_dev) { | |
552 | if (cfg.chrootdir) | |
553 | fprintf(stderr, "Warning: private-dev feature is disabled in chroot\n"); | |
554 | else if (arg_overlay) | |
555 | fprintf(stderr, "Warning: private-dev feature is disabled in overlay\n"); | |
556 | else | |
557 | fs_private_dev(); | |
558 | } | |
559 | ||
525 | 560 | if (arg_private_etc) { |
526 | fs_private_etc_list(); | |
527 | // create /etc/ld.so.preload file again | |
528 | if (arg_trace || arg_tracelog) | |
529 | fs_trace_preload(); | |
530 | } | |
531 | if (arg_private_bin) | |
532 | fs_private_bin_list(); | |
533 | if (arg_private_tmp) | |
534 | fs_private_tmp(); | |
561 | if (cfg.chrootdir) | |
562 | fprintf(stderr, "Warning: private-etc feature is disabled in chroot\n"); | |
563 | else if (arg_overlay) | |
564 | fprintf(stderr, "Warning: private-etc feature is disabled in overlay\n"); | |
565 | else { | |
566 | fs_private_etc_list(); | |
567 | // create /etc/ld.so.preload file again | |
568 | if (arg_trace || arg_tracelog) | |
569 | fs_trace_preload(); | |
570 | } | |
571 | } | |
572 | ||
573 | if (arg_private_bin) { | |
574 | if (cfg.chrootdir) | |
575 | fprintf(stderr, "Warning: private-bin feature is disabled in chroot\n"); | |
576 | else if (arg_overlay) | |
577 | fprintf(stderr, "Warning: private-bin feature is disabled in overlay\n"); | |
578 | else | |
579 | fs_private_bin_list(); | |
580 | } | |
581 | ||
582 | if (arg_private_tmp) { | |
583 | if (cfg.chrootdir) | |
584 | fprintf(stderr, "Warning: private-tmp feature is disabled in chroot\n"); | |
585 | else if (arg_overlay) | |
586 | fprintf(stderr, "Warning: private-tmp feature is disabled in overlay\n"); | |
587 | else | |
588 | fs_private_tmp(); | |
589 | } | |
590 | ||
591 | //**************************** | |
592 | // update /proc, /sys, /dev, /boot directorymy | |
593 | //**************************** | |
594 | if (checkcfg(CFG_REMOUNT_PROC_SYS)) | |
595 | fs_proc_sys_dev_boot(); | |
535 | 596 | |
536 | 597 | //**************************** |
537 | 598 | // apply the profile file |
538 | 599 | //**************************** |
539 | 600 | if (cfg.profile) { |
540 | 601 | // apply all whitelist commands ... |
541 | fs_whitelist(); | |
602 | if (cfg.chrootdir) | |
603 | fprintf(stderr, "Warning: whitelist feature is disabled in chroot\n"); | |
604 | else if (arg_overlay) | |
605 | fprintf(stderr, "Warning: whitelist feature is disabled in overlay\n"); | |
606 | else | |
607 | fs_whitelist(); | |
542 | 608 | |
543 | 609 | // ... followed by blacklist commands |
544 | 610 | fs_blacklist(); |
550 | 616 | if (arg_trace || arg_tracelog) |
551 | 617 | fs_trace(); |
552 | 618 | |
553 | //**************************** | |
554 | // update /proc, /dev, /boot directorymy | |
555 | //**************************** | |
556 | fs_proc_sys_dev_boot(); | |
557 | ||
558 | 619 | //**************************** |
559 | 620 | // --nosound and fix for pulseaudio 7.0 |
560 | 621 | //**************************** |
797 | 858 | pid_t app_pid = fork(); |
798 | 859 | if (app_pid == -1) |
799 | 860 | errExit("fork"); |
800 | ||
861 | ||
801 | 862 | if (app_pid == 0) { |
863 | #ifdef HAVE_APPARMOR | |
864 | if (arg_apparmor) { | |
865 | errno = 0; | |
866 | if (aa_change_onexec("firejail-default")) { | |
867 | fprintf(stderr, "Error: cannot confine the application using AppArmor.\n"); | |
868 | fprintf(stderr, "Maybe firejail-default AppArmor profile is not loaded into the kernel.\n"); | |
869 | fprintf(stderr, "As root, run \"aa-enforce firejail-default\" to load it.\n"); | |
870 | exit(1); | |
871 | } | |
872 | else if (arg_debug) | |
873 | printf("AppArmor enabled\n"); | |
874 | } | |
875 | #endif | |
802 | 876 | prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died |
803 | 877 | start_application(); // start app |
804 | 878 | } |
100 | 100 | sfilter_alloc_size = SECSIZE; |
101 | 101 | |
102 | 102 | // copy the start entries |
103 | #if defined(__x86_64__) | |
104 | #define X32_SYSCALL_BIT 0x40000000 | |
105 | struct sock_filter filter[] = { | |
106 | VALIDATE_ARCHITECTURE, | |
107 | EXAMINE_SYSCALL, | |
108 | // handle X32 ABI | |
109 | BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0), | |
110 | BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0), | |
111 | RETURN_ERRNO(EPERM) | |
112 | }; | |
113 | #else | |
103 | 114 | struct sock_filter filter[] = { |
104 | 115 | VALIDATE_ARCHITECTURE, |
105 | 116 | EXAMINE_SYSCALL |
106 | 117 | }; |
118 | #endif | |
107 | 119 | sfilter_index = sizeof(filter) / sizeof(struct sock_filter); |
108 | 120 | memcpy(sfilter, filter, sizeof(filter)); |
109 | 121 | } |
277 | 289 | fprintf(stderr, "Error: cannot save seccomp filter\n"); |
278 | 290 | exit(1); |
279 | 291 | } |
292 | SET_PERMS_FD(fd, 0, 0, S_IRUSR | S_IWUSR); | |
280 | 293 | close(fd); |
281 | if (chown(RUN_SECCOMP_CFG, 0, 0) < 0) | |
282 | errExit("chown"); | |
283 | 294 | } |
284 | 295 | |
285 | 296 | // read seccomp filter from /run/firejail/mnt/seccomp |
331 | 342 | EXAMINE_SYSCALL, |
332 | 343 | BLACKLIST(21), // mount |
333 | 344 | BLACKLIST(52), // umount2 |
345 | // todo: implement --allow-debuggers | |
334 | 346 | BLACKLIST(26), // ptrace |
335 | 347 | BLACKLIST(283), // kexec_load |
336 | 348 | BLACKLIST(341), // name_to_handle_at |
403 | 415 | EXAMINE_SYSCALL, |
404 | 416 | BLACKLIST(165), // mount |
405 | 417 | BLACKLIST(166), // umount2 |
418 | // todo: implement --allow-debuggers | |
406 | 419 | BLACKLIST(101), // ptrace |
407 | 420 | BLACKLIST(246), // kexec_load |
408 | 421 | BLACKLIST(304), // open_by_handle_at |
488 | 501 | #ifdef SYS_umount2 |
489 | 502 | filter_add_blacklist(SYS_umount2, 0); |
490 | 503 | #endif |
504 | ||
505 | if (!arg_allow_debuggers) { | |
491 | 506 | #ifdef SYS_ptrace |
492 | filter_add_blacklist(SYS_ptrace, 0); | |
493 | #endif | |
507 | filter_add_blacklist(SYS_ptrace, 0); | |
508 | #endif | |
509 | } | |
510 | ||
494 | 511 | #ifdef SYS_kexec_load |
495 | 512 | filter_add_blacklist(SYS_kexec_load, 0); |
496 | 513 | #endif |
536 | 553 | #ifdef SYS_syslog |
537 | 554 | filter_add_blacklist(SYS_syslog, 0); |
538 | 555 | #endif |
556 | if (!arg_allow_debuggers) { | |
539 | 557 | #ifdef SYS_process_vm_readv |
540 | filter_add_blacklist(SYS_process_vm_readv, 0); | |
541 | #endif | |
558 | filter_add_blacklist(SYS_process_vm_readv, 0); | |
559 | #endif | |
560 | } | |
561 | ||
542 | 562 | #ifdef SYS_process_vm_writev |
543 | 563 | filter_add_blacklist(SYS_process_vm_writev, 0); |
544 | 564 | #endif |
33 | 33 | printf("\n"); |
34 | 34 | printf("Options:\n\n"); |
35 | 35 | printf(" -- - signal the end of options and disables further option processing.\n\n"); |
36 | printf(" --allow-debuggers - allow tools such as strace and gdb inside the sandbox.\n\n"); | |
37 | printf(" --apparmor - enable AppArmor confinement\n\n"); | |
36 | 38 | printf(" --appimage - sandbox an AppImage application\n\n"); |
37 | 39 | printf(" --audit - audit the sandbox, see Audit section for more details\n\n"); |
38 | 40 | printf(" --audit=test-program - audit the sandbox, see Audit section for more details\n\n"); |
174 | 176 | |
175 | 177 | printf(" --overlay - mount a filesystem overlay on top of the current filesystem.\n"); |
176 | 178 | printf("\tThe upper filesystem layer is persistent, and stored in\n"); |
177 | printf("\t$HOME/.firejail directory. (OverlayFS support is required in\n"); | |
178 | printf("\tLinux kernel for this option to work). \n\n"); | |
179 | printf("\t$HOME/.firejail/<PID> directory. (OverlayFS support is required in\n"); | |
180 | printf("\tLinux kernel for this option to work). \n\n"); | |
181 | ||
182 | printf(" --overlay-named=name - mount a filesystem overlay on top of the current\n"); | |
183 | printf("\tfilesystem. The upper filesystem layer is persistent, and stored in\n"); | |
184 | printf("\t$HOME/.firejail/<NAME> directory. (OverlayFS support is required in\n"); | |
185 | printf("\tLinux kernel for this option to work). \n\n"); | |
186 | ||
187 | #if 0 // disabled for now, it could be used to overwrite system directories | |
188 | printf(" --overlay-path=path - mount a filesystem overlay on top of the current\n"); | |
189 | printf("\tfilesystem. The upper filesystem layer is persistent, and stored in\n"); | |
190 | printf("\tthe specified path. (OverlayFS support is required in Linux kernel for\n"); | |
191 | printf("\tthis option to work). \n\n"); | |
192 | ||
193 | .TP | |
194 | \fB\-\-overlay-path=path | |
195 | Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, | |
196 | the system directories are mounted read-write. All filesystem modifications go into the overlay. | |
197 | The overlay is stored in the specified path. The created overlay can be reused between multiple sessions. | |
198 | .br | |
199 | ||
200 | .br | |
201 | OverlayFS support is required in Linux kernel for this option to work. | |
202 | OverlayFS was officially introduced in Linux kernel version 3.18. | |
203 | This option is not available on Grsecurity systems. | |
204 | .br | |
205 | ||
206 | .br | |
207 | Example: | |
208 | .br | |
209 | $ firejail \-\-overlay-path=~/jails/jail1 firefox | |
210 | #endif | |
179 | 211 | |
180 | 212 | printf(" --overlay-tmpfs - mount a filesystem overlay on top of the current\n"); |
181 | 213 | printf("\tfilesystem. The upper layer is stored in a tmpfs filesystem,\n"); |
182 | 214 | printf("\tand it is discarded when the sandbox is closed. (OverlayFS\n"); |
183 | 215 | printf("\tsupport is required in Linux kernel for this option to work).\n\n"); |
216 | ||
217 | printf(" --overlay-clean - clean all overlays stored in $HOME/.firejail directory.\n\n"); | |
184 | 218 | |
185 | 219 | printf(" --private - mount new /root and /home/user directories in temporary\n"); |
186 | 220 | printf("\tfilesystems. All modifications are discarded when the sandbox is\n"); |
187 | 221 | printf("\tclosed.\n\n"); |
188 | 222 | printf(" --private=directory - use directory as user home.\n\n"); |
223 | #if 0 | |
224 | printf(" --private-template=directory - same as --private but copy the\n"); | |
225 | printf("\ttemplatedirectory in the tmpfs mounted user home.\n\n"); | |
226 | ||
227 | .TP | |
228 | \fB\-\-private-template=templatedir | |
229 | Mount new /root and /home/user directories in temporary | |
230 | filesystems, and copy all files in templatedir. All modifications are discarded when the sandbox is | |
231 | closed. | |
232 | .br | |
233 | ||
234 | .br | |
235 | Example: | |
236 | .br | |
237 | $ firejail \-\-private-template=/home/netblue/.config/mozilla firefox | |
238 | #endif | |
239 | ||
240 | ||
189 | 241 | |
190 | 242 | printf(" --private-bin=file,file - build a new /bin in a temporary filesystem,\n"); |
191 | 243 | printf("\tand copy the programs in the list.\n\n"); |
16 | 16 | * with this program; if not, write to the Free Software Foundation, Inc., |
17 | 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | 18 | */ |
19 | #define _XOPEN_SOURCE 500 | |
19 | 20 | #include "firejail.h" |
21 | #include <ftw.h> | |
20 | 22 | #include <sys/stat.h> |
21 | 23 | #include <fcntl.h> |
22 | 24 | #include <syslog.h> |
77 | 79 | |
78 | 80 | int mkpath_as_root(const char* path) { |
79 | 81 | assert(path && *path); |
80 | ||
82 | ||
81 | 83 | // work on a copy of the path |
82 | 84 | char *file_path = strdup(path); |
83 | 85 | if (!file_path) |
100 | 102 | if (chown(file_path, 0, 0) == -1) |
101 | 103 | errExit("chown"); |
102 | 104 | done = 1; |
103 | } | |
105 | } | |
104 | 106 | |
105 | 107 | *p='/'; |
106 | 108 | } |
107 | 109 | if (done) |
108 | 110 | fs_logger2("mkpath", path); |
109 | ||
111 | ||
110 | 112 | free(file_path); |
111 | 113 | return 0; |
112 | 114 | } |
113 | ||
114 | 115 | |
115 | 116 | |
116 | 117 | void logsignal(int s) { |
168 | 169 | |
169 | 170 | |
170 | 171 | // return -1 if error, 0 if no error |
171 | int copy_file(const char *srcname, const char *destname) { | |
172 | int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode) { | |
172 | 173 | assert(srcname); |
173 | 174 | assert(destname); |
174 | 175 | |
205 | 206 | } |
206 | 207 | } |
207 | 208 | |
209 | if (fchown(dst, uid, gid) == -1) | |
210 | errExit("fchown"); | |
211 | if (fchmod(dst, mode) == -1) | |
212 | errExit("fchmod"); | |
213 | ||
208 | 214 | close(src); |
209 | 215 | close(dst); |
210 | 216 | return 0; |
211 | 217 | } |
218 | ||
212 | 219 | |
213 | 220 | // return 1 if the file is a directory |
214 | 221 | int is_dir(const char *fname) { |
215 | 222 | assert(fname); |
216 | 223 | if (*fname == '\0') |
217 | 224 | return 0; |
218 | ||
225 | ||
219 | 226 | // if fname doesn't end in '/', add one |
220 | 227 | int rv; |
221 | 228 | struct stat s; |
226 | 233 | if (asprintf(&tmp, "%s/", fname) == -1) { |
227 | 234 | fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__); |
228 | 235 | errExit("asprintf"); |
229 | } | |
236 | } | |
230 | 237 | rv = stat(tmp, &s); |
231 | 238 | free(tmp); |
232 | 239 | } |
233 | ||
240 | ||
234 | 241 | if (rv == -1) |
235 | 242 | return 0; |
236 | ||
243 | ||
237 | 244 | if (S_ISDIR(s.st_mode)) |
238 | 245 | return 1; |
239 | 246 | |
240 | 247 | return 0; |
241 | 248 | } |
249 | ||
242 | 250 | |
243 | 251 | // return 1 if the file is a link |
244 | 252 | int is_link(const char *fname) { |
324 | 332 | |
325 | 333 | int not_unsigned(const char *str) { |
326 | 334 | EUID_ASSERT(); |
327 | ||
335 | ||
328 | 336 | int rv = 0; |
329 | 337 | const char *ptr = str; |
330 | 338 | while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') { |
346 | 354 | *child = 0; // use it to flag a found child |
347 | 355 | |
348 | 356 | DIR *dir; |
349 | EUID_ROOT(); // grsecurity fix | |
357 | EUID_ROOT(); // grsecurity fix | |
350 | 358 | if (!(dir = opendir("/proc"))) { |
351 | 359 | // sleep 2 seconds and try again |
352 | 360 | sleep(2); |
403 | 411 | } |
404 | 412 | |
405 | 413 | |
406 | ||
407 | 414 | void extract_command_name(int index, char **argv) { |
408 | 415 | EUID_ASSERT(); |
409 | 416 | assert(argv); |
410 | 417 | assert(argv[index]); |
411 | 418 | |
412 | ||
413 | 419 | // configure command index |
414 | 420 | cfg.original_program_index = index; |
415 | 421 | |
418 | 424 | errExit("strdup"); |
419 | 425 | |
420 | 426 | // if we have a symbolic link, use the real path to extract the name |
421 | if (is_link(argv[index])) { | |
422 | char*newname = realpath(argv[index], NULL); | |
423 | if (newname) { | |
424 | free(str); | |
425 | str = newname; | |
426 | } | |
427 | } | |
427 | // if (is_link(argv[index])) { | |
428 | // char*newname = realpath(argv[index], NULL); | |
429 | // if (newname) { | |
430 | // free(str); | |
431 | // str = newname; | |
432 | // } | |
433 | // } | |
428 | 434 | |
429 | 435 | // configure command name |
430 | 436 | cfg.command_name = str; |
445 | 451 | fprintf(stderr, "Error: invalid command name\n"); |
446 | 452 | exit(1); |
447 | 453 | } |
448 | ||
449 | 454 | |
450 | 455 | char *tmp = strdup(ptr); |
451 | 456 | if (!tmp) |
532 | 537 | fclose(stream); |
533 | 538 | } |
534 | 539 | |
540 | ||
535 | 541 | // This function takes a pathname supplied by the user and expands '~' and |
536 | 542 | // '${HOME}' at the start, to refer to a path relative to the user's home |
537 | 543 | // directory (supplied). |
540 | 546 | char *expand_home(const char *path, const char* homedir) { |
541 | 547 | assert(path); |
542 | 548 | assert(homedir); |
543 | ||
549 | ||
544 | 550 | // Replace home macro |
545 | 551 | char *new_name = NULL; |
546 | 552 | if (strncmp(path, "${HOME}", 7) == 0) { |
553 | 559 | errExit("asprintf"); |
554 | 560 | return new_name; |
555 | 561 | } |
556 | ||
562 | ||
557 | 563 | return strdup(path); |
558 | 564 | } |
565 | ||
559 | 566 | |
560 | 567 | // Equivalent to the GNU version of basename, which is incompatible with |
561 | 568 | // the POSIX basename. A few lines of code saves any portability pain. |
567 | 574 | return last_slash+1; |
568 | 575 | } |
569 | 576 | |
577 | ||
570 | 578 | uid_t pid_get_uid(pid_t pid) { |
571 | 579 | EUID_ASSERT(); |
572 | 580 | uid_t rv = 0; |
573 | ||
581 | ||
574 | 582 | // open status file |
575 | 583 | char *file; |
576 | 584 | if (asprintf(&file, "/proc/%u/status", pid) == -1) { |
577 | 585 | perror("asprintf"); |
578 | 586 | exit(1); |
579 | 587 | } |
580 | EUID_ROOT(); // grsecurity fix | |
588 | EUID_ROOT(); // grsecurity fix | |
581 | 589 | FILE *fp = fopen(file, "r"); |
582 | 590 | if (!fp) { |
583 | 591 | free(file); |
596 | 604 | } |
597 | 605 | if (*ptr == '\0') |
598 | 606 | break; |
599 | ||
607 | ||
600 | 608 | rv = atoi(ptr); |
601 | break; // break regardless! | |
609 | break; // break regardless! | |
602 | 610 | } |
603 | 611 | } |
604 | 612 | |
605 | 613 | fclose(fp); |
606 | 614 | free(file); |
607 | EUID_USER(); // grsecurity fix | |
608 | ||
615 | EUID_USER(); // grsecurity fix | |
616 | ||
609 | 617 | if (rv == 0) { |
610 | 618 | fprintf(stderr, "Error: cannot read /proc file\n"); |
611 | 619 | exit(1); |
612 | 620 | } |
613 | 621 | return rv; |
614 | 622 | } |
623 | ||
615 | 624 | |
616 | 625 | void invalid_filename(const char *fname) { |
617 | 626 | EUID_ASSERT(); |
618 | 627 | assert(fname); |
619 | 628 | const char *ptr = fname; |
620 | ||
629 | ||
621 | 630 | if (arg_debug_check_filename) |
622 | 631 | printf("Checking filename %s\n", fname); |
623 | ||
632 | ||
624 | 633 | if (strncmp(ptr, "${HOME}", 7) == 0) |
625 | 634 | ptr = fname + 7; |
626 | 635 | else if (strncmp(ptr, "${PATH}", 7) == 0) |
636 | 645 | } |
637 | 646 | } |
638 | 647 | |
648 | ||
639 | 649 | uid_t get_tty_gid(void) { |
640 | 650 | // find tty group id |
641 | 651 | gid_t ttygid = 0; |
646 | 656 | return ttygid; |
647 | 657 | } |
648 | 658 | |
659 | ||
649 | 660 | uid_t get_audio_gid(void) { |
650 | 661 | // find tty group id |
651 | 662 | gid_t audiogid = 0; |
655 | 666 | |
656 | 667 | return audiogid; |
657 | 668 | } |
669 | ||
670 | ||
671 | static int remove_callback(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { | |
672 | (void) sb; | |
673 | (void) typeflag; | |
674 | (void) ftwbuf; | |
675 | ||
676 | int rv = remove(fpath); | |
677 | if (rv) | |
678 | perror(fpath); | |
679 | ||
680 | return rv; | |
681 | } | |
682 | ||
683 | ||
684 | int remove_directory(const char *path) { | |
685 | // FTW_PHYS - do not follow symbolic links | |
686 | return nftw(path, remove_callback, 64, FTW_DEPTH | FTW_PHYS); | |
687 | } |
19 | 19 | #include "firejail.h" |
20 | 20 | #include <sys/types.h> |
21 | 21 | #include <sys/stat.h> |
22 | #include <fcntl.h> | |
22 | 23 | #include <unistd.h> |
23 | 24 | #include <signal.h> |
24 | 25 | #include <stdlib.h> |
25 | 26 | #include <dirent.h> |
26 | 27 | #include <sys/mount.h> |
28 | #include <sys/wait.h> | |
27 | 29 | |
28 | 30 | #ifdef HAVE_X11 |
29 | 31 | // return 1 if xpra is installed on the system |
129 | 131 | fprintf(stderr, "Error: cannot create empty file in x11 directory\n"); |
130 | 132 | exit(1); |
131 | 133 | } |
134 | // set file properties | |
135 | SET_PERMS_STREAM(fp, s.st_uid, s.st_gid, s.st_mode); | |
132 | 136 | fclose(fp); |
133 | ||
134 | // set file properties | |
135 | if (chown(x11file, s.st_uid, s.st_gid) < 0) | |
136 | errExit("chown"); | |
137 | if (chmod(x11file, s.st_mode) < 0) | |
138 | errExit("chmod"); | |
139 | 137 | |
140 | 138 | // mount |
141 | 139 | char *wx11file; |
163 | 161 | EUID_ASSERT(); |
164 | 162 | int i; |
165 | 163 | struct stat s; |
166 | pid_t client = 0; | |
164 | pid_t jail = 0; | |
167 | 165 | pid_t server = 0; |
168 | 166 | |
169 | ||
170 | 167 | setenv("FIREJAIL_X11", "yes", 1); |
171 | 168 | |
172 | 169 | // unfortunately, xephyr does a number of weird things when started by root user!!! |
185 | 182 | } |
186 | 183 | |
187 | 184 | int display = random_display_number(); |
188 | ||
189 | // start xephyr | |
190 | char *cmd1; | |
185 | char *display_str; | |
186 | if (asprintf(&display_str, ":%d", display) == -1) | |
187 | errExit("asprintf"); | |
188 | ||
189 | assert(xephyr_screen); | |
190 | char *server_argv[256] = { "Xephyr", "-ac", "-br", "-noreset", "-screen", xephyr_screen }; // rest initialyzed to NULL | |
191 | unsigned pos = 0; | |
192 | while (server_argv[pos] != NULL) pos++; | |
191 | 193 | if (checkcfg(CFG_XEPHYR_WINDOW_TITLE)) { |
192 | if (asprintf(&cmd1, "Xephyr -ac -br -title \"firejail x11 sandbox\" %s -noreset -screen %s :%d", xephyr_extra_params, xephyr_screen, display) == -1) | |
193 | errExit("asprintf"); | |
194 | } | |
195 | else { | |
196 | if (asprintf(&cmd1, "Xephyr -ac -br %s -noreset -screen %s :%d", xephyr_extra_params, xephyr_screen, display) == -1) | |
197 | errExit("asprintf"); | |
198 | } | |
199 | ||
200 | int len = 50; // DISPLAY... | |
201 | for (i = 0; i < argc; i++) { | |
202 | len += strlen(argv[i]) + 1; // + ' ' | |
203 | } | |
204 | ||
205 | char *cmd2 = malloc(len + 1); // + '\0' | |
206 | if (!cmd2) | |
207 | errExit("malloc"); | |
208 | ||
209 | sprintf(cmd2, "DISPLAY=:%d ", display); | |
210 | char *ptr = cmd2 + strlen(cmd2); | |
194 | server_argv[pos++] = "-title"; | |
195 | server_argv[pos++] = "firejail x11 sandbox"; | |
196 | } | |
197 | ||
198 | assert(xephyr_extra_params); // should be "" if empty | |
199 | ||
200 | // parse xephyr_extra_params | |
201 | // very basic quoting support | |
202 | char *temp = strdup(xephyr_extra_params); | |
203 | if (*xephyr_extra_params != '\0') { | |
204 | if (!temp) | |
205 | errExit("strdup"); | |
206 | bool dquote = false; | |
207 | bool squote = false; | |
208 | for (i = 0; i < (int) strlen(xephyr_extra_params); i++) { | |
209 | if (temp[i] == '\"') { | |
210 | dquote = !dquote; | |
211 | if (dquote) temp[i] = '\0'; // replace closing quote by \0 | |
212 | } | |
213 | if (temp[i] == '\'') { | |
214 | squote = !squote; | |
215 | if (squote) temp[i] = '\0'; // replace closing quote by \0 | |
216 | } | |
217 | if (!dquote && !squote && temp[i] == ' ') temp[i] = '\0'; | |
218 | if (dquote && squote) { | |
219 | fprintf(stderr, "Error: mixed quoting found while parsing xephyr_extra_params\n"); | |
220 | exit(1); | |
221 | } | |
222 | } | |
223 | if (dquote) { | |
224 | fprintf(stderr, "Error: unclosed quote found while parsing xephyr_extra_params\n"); | |
225 | exit(1); | |
226 | } | |
227 | ||
228 | for (i = 0; i < (int) strlen(xephyr_extra_params)-1; i++) { | |
229 | if (pos >= (sizeof(server_argv)/sizeof(*server_argv))) { | |
230 | fprintf(stderr, "Error: arg count limit exceeded while parsing xephyr_extra_params\n"); | |
231 | exit(1); | |
232 | } | |
233 | if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) server_argv[pos++] = temp + i + 2; | |
234 | else if (temp[i] == '\0' && temp[i+1] != '\0') server_argv[pos++] = temp + i + 1; | |
235 | } | |
236 | } | |
237 | ||
238 | server_argv[pos++] = display_str; | |
239 | server_argv[pos++] = NULL; | |
240 | ||
241 | assert(pos < (sizeof(server_argv)/sizeof(*server_argv))); // no overrun | |
242 | assert(server_argv[pos-1] == NULL); // last element is null | |
243 | ||
244 | if (arg_debug) { | |
245 | size_t i = 0; | |
246 | printf("xephyr server:"); | |
247 | while (server_argv[i]!=NULL) { | |
248 | printf(" \"%s\"", server_argv[i]); | |
249 | i++; | |
250 | } | |
251 | putchar('\n'); | |
252 | } | |
253 | ||
254 | // remove --x11 arg | |
255 | char *jail_argv[argc+2]; | |
256 | int j = 0; | |
211 | 257 | for (i = 0; i < argc; i++) { |
212 | 258 | if (strcmp(argv[i], "--x11") == 0) |
213 | 259 | continue; |
215 | 261 | continue; |
216 | 262 | if (strcmp(argv[i], "--x11=xephyr") == 0) |
217 | 263 | continue; |
218 | ptr += sprintf(ptr, "%s ", argv[i]); | |
219 | } | |
220 | if (arg_debug) | |
221 | printf("xephyr server: %s\n", cmd1); | |
222 | if (arg_debug) | |
223 | printf("xephyr client: %s\n", cmd2); | |
224 | ||
225 | signal(SIGHUP,SIG_IGN); // fix sleep(1) below | |
264 | jail_argv[j] = argv[i]; | |
265 | j++; | |
266 | } | |
267 | jail_argv[j] = NULL; | |
268 | ||
269 | assert(j < argc+2); // no overrun | |
270 | ||
271 | if (arg_debug) { | |
272 | size_t i = 0; | |
273 | printf("xephyr client:"); | |
274 | while (jail_argv[i]!=NULL) { | |
275 | printf(" \"%s\"", jail_argv[i]); | |
276 | i++; | |
277 | } | |
278 | putchar('\n'); | |
279 | } | |
280 | ||
226 | 281 | server = fork(); |
227 | 282 | if (server < 0) |
228 | 283 | errExit("fork"); |
230 | 285 | if (arg_debug) |
231 | 286 | printf("Starting xephyr...\n"); |
232 | 287 | |
233 | char *a[4]; | |
234 | a[0] = "/bin/bash"; | |
235 | a[1] = "-c"; | |
236 | a[2] = cmd1; | |
237 | a[3] = NULL; | |
238 | ||
239 | execvp(a[0], a); | |
288 | execvp(server_argv[0], server_argv); | |
240 | 289 | perror("execvp"); |
241 | 290 | exit(1); |
242 | 291 | } |
292 | ||
293 | if (arg_debug) | |
294 | printf("xephyr server pid %d\n", server); | |
243 | 295 | |
244 | 296 | // check X11 socket |
245 | 297 | char *fname; |
258 | 310 | exit(1); |
259 | 311 | } |
260 | 312 | free(fname); |
261 | sleep(1); | |
262 | 313 | |
263 | 314 | if (arg_debug) { |
264 | 315 | printf("X11 sockets: "); fflush(0); |
266 | 317 | (void) rv; |
267 | 318 | } |
268 | 319 | |
320 | setenv("DISPLAY", display_str, 1); | |
269 | 321 | // run attach command |
270 | client = fork(); | |
271 | if (client < 0) | |
322 | jail = fork(); | |
323 | if (jail < 0) | |
272 | 324 | errExit("fork"); |
273 | if (client == 0) { | |
274 | printf("\n*** Attaching to Xephyr display %d ***\n\n", display); | |
275 | char *a[4]; | |
276 | a[0] = "/bin/bash"; | |
277 | a[1] = "-c"; | |
278 | a[2] = cmd2; | |
279 | a[3] = NULL; | |
280 | ||
281 | execvp(a[0], a); | |
325 | if (jail == 0) { | |
326 | if (!arg_quiet) | |
327 | printf("\n*** Attaching to Xephyr display %d ***\n\n", display); | |
328 | ||
329 | execvp(jail_argv[0], jail_argv); | |
282 | 330 | perror("execvp"); |
283 | 331 | exit(1); |
284 | 332 | } |
285 | sleep(1); | |
286 | ||
287 | if (!arg_quiet) | |
288 | printf("Xephyr server pid %d, client pid %d\n", server, client); | |
333 | ||
334 | // cleanup | |
335 | free(display_str); | |
336 | free(temp); | |
337 | ||
338 | // wait for either server or jail termination | |
339 | pid_t pid = wait(NULL); | |
340 | ||
341 | // see which process terminated and kill other | |
342 | if (pid == server) { | |
343 | kill(jail, SIGTERM); | |
344 | } else if (pid == jail) { | |
345 | kill(server, SIGTERM); | |
346 | } | |
347 | ||
348 | // without this closing Xephyr window may mess your terminal: | |
349 | // "monitoring" process will release terminal before | |
350 | // jail process ends and releases terminal | |
351 | wait(NULL); // fulneral | |
289 | 352 | |
290 | 353 | exit(0); |
291 | 354 | } |
314 | 377 | } |
315 | 378 | |
316 | 379 | int display = random_display_number(); |
380 | char *display_str; | |
381 | if (asprintf(&display_str, ":%d", display) == -1) | |
382 | errExit("asprintf"); | |
317 | 383 | |
318 | 384 | // build the start command |
319 | int len = 50; // xpra start... | |
320 | for (i = 0; i < argc; i++) { | |
321 | len += strlen(argv[i]) + 1; // + ' ' | |
322 | } | |
323 | ||
324 | char *cmd1 = malloc(len + 1); // + '\0' | |
325 | if (!cmd1) | |
326 | errExit("malloc"); | |
327 | ||
328 | sprintf(cmd1, "xpra start :%d --exit-with-children --start-child=\"", display); | |
329 | char *ptr = cmd1 + strlen(cmd1); | |
330 | for (i = 0; i < argc; i++) { | |
331 | if (strcmp(argv[i], "--x11") == 0) | |
332 | continue; | |
333 | if (strcmp(argv[i], "--x11=xpra") == 0) | |
334 | continue; | |
335 | if (strcmp(argv[i], "--x11=xephyr") == 0) | |
336 | continue; | |
337 | ptr += sprintf(ptr, "%s ", argv[i]); | |
338 | } | |
339 | sprintf(ptr, "\""); | |
340 | if (arg_debug) | |
341 | printf("xpra server: %s\n", cmd1); | |
342 | ||
343 | // build the attach command | |
344 | char *cmd2; | |
345 | if (asprintf(&cmd2, "xpra --title=\"firejail x11 sandbox\" attach :%d", display) == -1) | |
346 | errExit("asprintf"); | |
347 | if (arg_debug) | |
348 | printf("xpra client: %s\n", cmd2); | |
349 | ||
350 | signal(SIGHUP,SIG_IGN); // fix sleep(1) below | |
385 | char *server_argv[] = { "xpra", "start", display_str, "--no-daemon", NULL }; | |
386 | ||
387 | int fd_null = -1; | |
388 | if (arg_quiet) { | |
389 | fd_null = open("/dev/null", O_RDWR); | |
390 | if (fd_null == -1) | |
391 | errExit("open"); | |
392 | } | |
393 | ||
394 | // start | |
351 | 395 | server = fork(); |
352 | 396 | if (server < 0) |
353 | 397 | errExit("fork"); |
354 | 398 | if (server == 0) { |
355 | 399 | if (arg_debug) |
356 | 400 | printf("Starting xpra...\n"); |
357 | ||
358 | char *a[4]; | |
359 | a[0] = "/bin/bash"; | |
360 | a[1] = "-c"; | |
361 | a[2] = cmd1; | |
362 | a[3] = NULL; | |
363 | ||
364 | execvp(a[0], a); | |
401 | ||
402 | if (arg_quiet && fd_null != -1) { | |
403 | dup2(fd_null,0); | |
404 | dup2(fd_null,1); | |
405 | dup2(fd_null,2); | |
406 | } | |
407 | ||
408 | execvp(server_argv[0], server_argv); | |
365 | 409 | perror("execvp"); |
366 | 410 | exit(1); |
367 | 411 | } |
376 | 420 | sleep(1); |
377 | 421 | if (stat(fname, &s) == 0) |
378 | 422 | break; |
379 | }; | |
423 | } | |
380 | 424 | |
381 | 425 | if (n == 10) { |
382 | 426 | fprintf(stderr, "Error: failed to start xpra\n"); |
383 | 427 | exit(1); |
384 | 428 | } |
385 | 429 | free(fname); |
386 | sleep(1); | |
387 | 430 | |
388 | 431 | if (arg_debug) { |
389 | 432 | printf("X11 sockets: "); fflush(0); |
391 | 434 | (void) rv; |
392 | 435 | } |
393 | 436 | |
437 | // build attach command | |
438 | char *attach_argv[] = { "xpra", "--title=\"firejail x11 sandbox\"", "attach", display_str }; | |
439 | ||
394 | 440 | // run attach command |
395 | 441 | client = fork(); |
396 | 442 | if (client < 0) |
397 | 443 | errExit("fork"); |
398 | 444 | if (client == 0) { |
399 | printf("\n*** Attaching to xpra display %d ***\n\n", display); | |
400 | char *a[4]; | |
401 | a[0] = "/bin/bash"; | |
402 | a[1] = "-c"; | |
403 | a[2] = cmd2; | |
404 | a[3] = NULL; | |
405 | ||
406 | execvp(a[0], a); | |
445 | if (arg_quiet && fd_null != -1) { | |
446 | dup2(fd_null,0); | |
447 | dup2(fd_null,1); | |
448 | dup2(fd_null,2); | |
449 | } | |
450 | ||
451 | if (!arg_quiet) | |
452 | printf("\n*** Attaching to xpra display %d ***\n\n", display); | |
453 | ||
454 | execvp(attach_argv[0], attach_argv); | |
407 | 455 | perror("execvp"); |
408 | 456 | exit(1); |
409 | 457 | } |
410 | sleep(1); | |
411 | ||
458 | ||
459 | setenv("DISPLAY", display_str, 1); | |
460 | ||
461 | // build jail command | |
462 | char *firejail_argv[argc+2]; | |
463 | int pos = 0; | |
464 | for (i = 0; i < argc; i++) { | |
465 | if (strcmp(argv[i], "--x11") == 0) | |
466 | continue; | |
467 | if (strcmp(argv[i], "--x11=xpra") == 0) | |
468 | continue; | |
469 | if (strcmp(argv[i], "--x11=xephyr") == 0) | |
470 | continue; | |
471 | firejail_argv[pos] = argv[i]; | |
472 | pos++; | |
473 | } | |
474 | firejail_argv[pos] = NULL; | |
475 | ||
476 | assert(pos < (argc+2)); | |
477 | assert(!firejail_argv[pos]); | |
478 | ||
479 | // start jail | |
480 | pid_t jail = fork(); | |
481 | if (jail < 0) | |
482 | errExit("fork"); | |
483 | if (jail == 0) { | |
484 | if (firejail_argv[0]) // shut up llvm scan-build | |
485 | execvp(firejail_argv[0], firejail_argv); | |
486 | perror("execvp"); | |
487 | exit(1); | |
488 | } | |
489 | ||
412 | 490 | if (!arg_quiet) |
413 | printf("Xpra server pid %d, client pid %d\n", server, client); | |
414 | ||
415 | exit(0); | |
491 | printf("Xpra server pid %d, xpra client pid %d, jail %d\n", server, client, jail); | |
492 | ||
493 | sleep(1); // let jail start | |
494 | ||
495 | // wait for jail or server to end | |
496 | while (1) { | |
497 | pid_t pid = wait(NULL); | |
498 | ||
499 | if (pid == jail) { | |
500 | char *stop_argv[] = { "xpra", "stop", display_str, NULL }; | |
501 | pid_t stop = fork(); | |
502 | if (stop < 0) | |
503 | errExit("fork"); | |
504 | if (stop == 0) { | |
505 | if (arg_quiet && fd_null != -1) { | |
506 | dup2(fd_null,0); | |
507 | dup2(fd_null,1); | |
508 | dup2(fd_null,2); | |
509 | } | |
510 | execvp(stop_argv[0], stop_argv); | |
511 | perror("execvp"); | |
512 | exit(1); | |
513 | } | |
514 | ||
515 | // wait for xpra server to stop, 10 seconds limit | |
516 | while (++n < 10) { | |
517 | sleep(1); | |
518 | pid = waitpid(server, NULL, WNOHANG); | |
519 | if (pid == server) | |
520 | break; | |
521 | } | |
522 | ||
523 | if (arg_debug) { | |
524 | if (n == 10) | |
525 | printf("failed to stop xpra server gratefully\n"); | |
526 | else | |
527 | printf("xpra server successfully stoped in %d secs\n", n); | |
528 | } | |
529 | ||
530 | // kill xpra server and xpra client | |
531 | kill(client, SIGTERM); | |
532 | kill(server, SIGTERM); | |
533 | exit(0); | |
534 | } | |
535 | else if (pid == server) { | |
536 | // kill firejail process | |
537 | kill(jail, SIGTERM); | |
538 | // kill xpra client (should die with server, but...) | |
539 | kill(client, SIGTERM); | |
540 | exit(0); | |
541 | } | |
542 | } | |
416 | 543 | } |
417 | 544 | |
418 | 545 | void x11_start(int argc, char **argv) { |
89 | 89 | // list of firejail arguments that don't trigger sandbox creation |
90 | 90 | // the initial -- is not included |
91 | 91 | char *firejail_args = "ls list tree x11 help version top netstats debug-syscalls debug-errnos debug-protocols " |
92 | "protocol.print debug.caps shutdown bandwidth caps.print cpu.print debug-caps fs.print get "; | |
92 | "protocol.print debug.caps shutdown bandwidth caps.print cpu.print debug-caps fs.print get overlay-clean "; | |
93 | 93 | |
94 | 94 | int i; |
95 | 95 | char *start; |
112 | 112 | int name2pid(const char *name, pid_t *pid); |
113 | 113 | char *pid_proc_comm(const pid_t pid); |
114 | 114 | char *pid_proc_cmdline(const pid_t pid); |
115 | int pid_proc_cmdline_x11(const pid_t pid); | |
115 | 116 | #endif |
36 | 36 | static inline void EUID_ROOT(void) { |
37 | 37 | if (seteuid(0) == -1) |
38 | 38 | fprintf(stderr, "Warning: cannot switch euid to root\n"); |
39 | if (setegid(0) == -1) | |
40 | fprintf(stderr, "Warning: cannot switch egid to root\n"); | |
39 | 41 | } |
40 | 42 | |
41 | 43 | static inline void EUID_USER(void) { |
42 | 44 | if (seteuid(firejail_uid) == -1) |
43 | fprintf(stderr, "Warning: cannot switch euid to user\n"); | |
45 | errExit("seteuid"); | |
46 | if (setegid(firejail_uid) == -1) | |
47 | errExit("setegid"); | |
44 | 48 | } |
45 | 49 | |
46 | 50 | static inline void EUID_PRINT(void) { |
198 | 198 | } |
199 | 199 | return rv; |
200 | 200 | } |
201 | ||
202 | // return 1 if firejail --x11 on command line | |
203 | int pid_proc_cmdline_x11(const pid_t pid) { | |
204 | // if comm is not firejail return 0 | |
205 | char *comm = pid_proc_comm(pid); | |
206 | if (strcmp(comm, "firejail") != 0) { | |
207 | free(comm); | |
208 | return 0; | |
209 | } | |
210 | free(comm); | |
211 | ||
212 | // open /proc/pid/cmdline file | |
213 | char *fname; | |
214 | int fd; | |
215 | if (asprintf(&fname, "/proc/%d/cmdline", pid) == -1) | |
216 | return 0; | |
217 | if ((fd = open(fname, O_RDONLY)) < 0) { | |
218 | free(fname); | |
219 | return 0; | |
220 | } | |
221 | free(fname); | |
222 | ||
223 | // read file | |
224 | unsigned char buffer[BUFLEN]; | |
225 | ssize_t len; | |
226 | if ((len = read(fd, buffer, sizeof(buffer) - 1)) <= 0) { | |
227 | close(fd); | |
228 | return 0; | |
229 | } | |
230 | buffer[len] = '\0'; | |
231 | close(fd); | |
232 | ||
233 | // skip the first argument | |
234 | int i; | |
235 | for (i = 0; buffer[i] != '\0'; i++); | |
236 | ||
237 | // parse remaining command line options | |
238 | while (1) { | |
239 | // extract argument | |
240 | i++; | |
241 | if (i >= len) | |
242 | break; | |
243 | char *arg = (char *)buffer + i; | |
244 | ||
245 | // detect the last command line option | |
246 | if (strcmp(arg, "--") == 0) | |
247 | break; | |
248 | if (strncmp(arg, "--", 2) != 0) | |
249 | break; | |
250 | ||
251 | // check x11 | |
252 | if (strncmp(arg, "--x11", 5) == 0) | |
253 | return 1; | |
254 | i += strlen(arg); | |
255 | } | |
256 | return 0; | |
257 | } | |
258 | ||
259 | ||
260 |
339 | 339 | exit(1); |
340 | 340 | } |
341 | 341 | |
342 | if (mon_pid == 0 && strncmp(ptr, "firejail", 8) == 0) { | |
343 | pids[pid].level = 1; | |
344 | } | |
345 | else if (mon_pid == pid && strncmp(ptr, "firejail", 8) == 0) { | |
346 | pids[pid].level = 1; | |
347 | } | |
348 | // else if (mon_pid == 0 && strncmp(ptr, "lxc-execute", 11) == 0) { | |
349 | // pids[pid].level = 1; | |
350 | // } | |
351 | // else if (mon_pid == pid && strncmp(ptr, "lxc-execute", 11) == 0) { | |
352 | // pids[pid].level = 1; | |
353 | // } | |
342 | if ((strncmp(ptr, "firejail", 8) == 0) && (mon_pid == 0 || mon_pid == pid)) { | |
343 | if (pid_proc_cmdline_x11(pid)) | |
344 | pids[pid].level = -1; | |
345 | else | |
346 | pids[pid].level = 1; | |
347 | } | |
354 | 348 | else |
355 | 349 | pids[pid].level = -1; |
356 | 350 | } |
422 | 422 | typedef int (*orig_stat64_t)(const char *pathname, struct stat64 *buf); |
423 | 423 | static orig_stat64_t orig_stat64 = NULL; |
424 | 424 | int stat64(const char *pathname, struct stat64 *buf) { |
425 | if (!orig_stat) | |
425 | if (!orig_stat64) | |
426 | 426 | orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64"); |
427 | 427 | |
428 | 428 | int rv = orig_stat64(pathname, buf); |
429 | printf("%u:%s:stat %s:%d\n", pid(), name(), pathname, rv); | |
429 | printf("%u:%s:stat64 %s:%d\n", pid(), name(), pathname, rv); | |
430 | return rv; | |
431 | } | |
432 | #endif /* __GLIBC__ */ | |
433 | ||
434 | // lstat | |
435 | typedef int (*orig_lstat_t)(const char *pathname, struct stat *buf); | |
436 | static orig_lstat_t orig_lstat = NULL; | |
437 | int lstat(const char *pathname, struct stat *buf) { | |
438 | if (!orig_lstat) | |
439 | orig_lstat = (orig_lstat_t)dlsym(RTLD_NEXT, "lstat"); | |
440 | ||
441 | int rv = orig_lstat(pathname, buf); | |
442 | printf("%u:%s:lstat %s:%d\n", pid(), name(), pathname, rv); | |
443 | return rv; | |
444 | } | |
445 | ||
446 | #ifdef __GLIBC__ | |
447 | typedef int (*orig_lstat64_t)(const char *pathname, struct stat64 *buf); | |
448 | static orig_lstat64_t orig_lstat64 = NULL; | |
449 | int lstat64(const char *pathname, struct stat64 *buf) { | |
450 | if (!orig_lstat64) | |
451 | orig_lstat64 = (orig_lstat64_t)dlsym(RTLD_NEXT, "lstat64"); | |
452 | ||
453 | int rv = orig_lstat64(pathname, buf); | |
454 | printf("%u:%s:lstat64 %s:%d\n", pid(), name(), pathname, rv); | |
430 | 455 | return rv; |
431 | 456 | } |
432 | 457 | #endif /* __GLIBC__ */ |
30 | 30 | #include <sys/stat.h> |
31 | 31 | #include <syslog.h> |
32 | 32 | #include <dirent.h> |
33 | #include <limits.h> | |
33 | 34 | |
34 | 35 | //#define DEBUG |
35 | 36 | |
561 | 562 | #ifdef DEBUG |
562 | 563 | printf("%s %s\n", __FUNCTION__, pathname); |
563 | 564 | #endif |
564 | if (!orig_stat) | |
565 | if (!orig_stat64) | |
565 | 566 | orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64"); |
566 | 567 | if (!blacklist_loaded) |
567 | 568 | load_blacklist(); |
597 | 598 | #ifdef DEBUG |
598 | 599 | printf("%s %s\n", __FUNCTION__, pathname); |
599 | 600 | #endif |
600 | if (!orig_lstat) | |
601 | if (!orig_lstat64) | |
601 | 602 | orig_lstat64 = (orig_lstat64_t)dlsym(RTLD_NEXT, "lstat64"); |
602 | 603 | if (!blacklist_loaded) |
603 | 604 | load_blacklist(); |
15 | 15 | .TP |
16 | 16 | \fB\-\-clean |
17 | 17 | Remove all firejail symbolic links. |
18 | .TP | |
19 | \fB\-\-debug | |
20 | Print debug messages. | |
18 | 21 | .TP |
19 | 22 | \fB\-?\fR, \fB\-\-help\fR |
20 | 23 | Print options end exit. |
92 | 92 | Example: "noblacklist ${HOME}/.mozilla" |
93 | 93 | |
94 | 94 | .TP |
95 | \fBignore command | |
95 | \fBignore | |
96 | 96 | Ignore command. |
97 | 97 | |
98 | 98 | Example: "ignore seccomp" |
99 | ||
100 | .TP | |
101 | \fBquiet | |
102 | Disable Firejail's output. This should be the first uncommented command in the profile file. | |
103 | ||
104 | Example: "quiet" | |
99 | 105 | |
100 | 106 | .SH Filesystem |
101 | 107 | These profile entries define a chroot filesystem built on top of the existing |
135 | 141 | .br |
136 | 142 | Use this command for whitelisted directories you need to preserve |
137 | 143 | when the sandbox is closed. Without it, the application will create the directory, and the directory |
138 | will be deleted when the sandbox is closed. Subdirectories also need to be created using mkdir. Example from | |
144 | will be deleted when the sandbox is closed. Subdirectories are recursively created. Example from | |
139 | 145 | firefox profile: |
140 | 146 | .br |
141 | 147 | |
143 | 149 | mkdir ~/.mozilla |
144 | 150 | .br |
145 | 151 | whitelist ~/.mozilla |
146 | .br | |
147 | mkdir ~/.cache | |
148 | .br | |
149 | mkdir ~/.cache/mozilla | |
150 | 152 | .br |
151 | 153 | mkdir ~/.cache/mozilla/firefox |
152 | 154 | .br |
154 | 156 | .TP |
155 | 157 | \fBmkfile file |
156 | 158 | Similar to mkdir, this command creates a file in user home before the sandbox is started. |
157 | The file is created if it doesn't already exist. | |
159 | The file is created if it doesn't already exist, but it's target directory has to exist. | |
158 | 160 | .TP |
159 | 161 | \fBnoexec file_or_directory |
160 | 162 | Remount the file or the directory noexec, nodev and nosuid. |
195 | 197 | Blacklist violations logged to syslog. |
196 | 198 | .TP |
197 | 199 | \fBwhitelist file_or_directory |
198 | Build a new user home in a temporary filesystem, and mount-bind file_or_directory. | |
199 | The modifications to file_or_directory are persistent, everything else is discarded | |
200 | when the sandbox is closed. | |
200 | Whitelist directory or file. A temporary file system is mounted on the top directory, and the | |
201 | whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent, | |
202 | everything else is discarded when the sandbox is closed. The top directory could be | |
203 | user home, /dev, /media, /opt, /var, and /tmp. | |
204 | .br | |
205 | ||
206 | .br | |
207 | Symbolic link handling: with the exception of user home, both the link and the real file should be in | |
208 | the same top directory. For user home, both the link and the real file should be owned by the user. | |
201 | 209 | .TP |
202 | 210 | \fBwritable-etc |
203 | 211 | Mount /etc directory read-write. |
207 | 215 | .SH Security filters |
208 | 216 | The following security filters are currently implemented: |
209 | 217 | |
218 | .TP | |
219 | \fBapparmor | |
220 | Enable AppArmor confinement. | |
210 | 221 | .TP |
211 | 222 | \fBcaps |
212 | 223 | Enable default Linux capabilities filter. |
246 | 257 | \fBnoroot |
247 | 258 | Use this command to enable an user namespace. The namespace has only one user, the current user. |
248 | 259 | There is no root account (uid 0) defined in the namespace. |
260 | .TP | |
261 | \fBx11 | |
262 | Enable X11 sandboxing. | |
249 | 263 | |
250 | 264 | .SH Resource limits, CPU affinity, Control Groups |
251 | 265 | These profile entries define the limits on system resources (rlimits) for the processes inside the sandbox. |
74 | 74 | \fB\-\- |
75 | 75 | Signal the end of options and disables further option processing. |
76 | 76 | .TP |
77 | \fB\-\-allow-debuggers | |
78 | Allow tools such as strace and gdb inside the sandbox. | |
79 | .br | |
80 | ||
81 | .br | |
82 | Example: | |
83 | .br | |
84 | $ firejail --allow-debuggers --profile=/etc/firejail/firefox.profile strace -f firefox | |
85 | .TP | |
86 | \fB\-\-apparmor | |
87 | Enable AppArmor confinement. Formore information, please see \fBAPPARMOR\fR section below. | |
88 | .TP | |
77 | 89 | \fB\-\-appimage |
78 | 90 | Sandbox an AppImage (http://appimage.org/) application. |
79 | 91 | .br |
861 | 873 | .br |
862 | 874 | |
863 | 875 | .br |
864 | /etc and /var are noexec by default. If there are more than one mount operation | |
876 | /etc and /var are noexec by default if the sandbox was started as a regular user. If there are more than one mount operation | |
865 | 877 | on the path of the file or directory, noexec should be applied to the last one. Always check if the change took effect inside the sandbox. |
866 | 878 | |
867 | 879 | .TP |
946 | 958 | Sets the NO_NEW_PRIVS prctl. This ensures that child processes |
947 | 959 | cannot acquire new privileges using execve(2); in particular, |
948 | 960 | this means that calling a suid binary (or one with file capabilities) |
949 | does not result in an increase of privilege. | |
961 | does not result in an increase of privilege. This option | |
962 | is enabled by default if seccomp filter is activated. | |
950 | 963 | |
951 | 964 | .TP |
952 | 965 | \fB\-\-nosound |
989 | 1002 | \fB\-\-overlay |
990 | 1003 | Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, |
991 | 1004 | the system directories are mounted read-write. All filesystem modifications go into the overlay. |
992 | The overlay is stored in $HOME/.firejail directory. This option is not available on Grsecurity systems. | |
1005 | The overlay is stored in $HOME/.firejail/<PID> directory. | |
993 | 1006 | .br |
994 | 1007 | |
995 | 1008 | .br |
996 | 1009 | OverlayFS support is required in Linux kernel for this option to work. |
997 | OverlayFS was officially introduced in Linux kernel version 3.18 | |
1010 | OverlayFS was officially introduced in Linux kernel version 3.18. | |
1011 | This option is not available on Grsecurity systems. | |
998 | 1012 | .br |
999 | 1013 | |
1000 | 1014 | .br |
1001 | 1015 | Example: |
1002 | 1016 | .br |
1003 | 1017 | $ firejail \-\-overlay firefox |
1018 | ||
1019 | .TP | |
1020 | \fB\-\-overlay-named=name | |
1021 | Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, | |
1022 | the system directories are mounted read-write. All filesystem modifications go into the overlay. | |
1023 | The overlay is stored in $HOME/.firejail/<NAME> directory. The created overlay can be reused between multiple | |
1024 | sessions. | |
1025 | .br | |
1026 | ||
1027 | .br | |
1028 | OverlayFS support is required in Linux kernel for this option to work. | |
1029 | OverlayFS was officially introduced in Linux kernel version 3.18. | |
1030 | This option is not available on Grsecurity systems. | |
1031 | .br | |
1032 | ||
1033 | .br | |
1034 | Example: | |
1035 | .br | |
1036 | $ firejail \-\-overlay-named=jail1 firefox | |
1004 | 1037 | |
1005 | 1038 | .TP |
1006 | 1039 | \fB\-\-overlay-tmpfs |
1007 | 1040 | Mount a filesystem overlay on top of the current filesystem. All filesystem modifications go into the overlay, |
1008 | and are discarded when the sandbox is closed. This option is not available on Grsecurity systems. | |
1041 | and are discarded when the sandbox is closed. | |
1009 | 1042 | .br |
1010 | 1043 | |
1011 | 1044 | .br |
1012 | 1045 | OverlayFS support is required in Linux kernel for this option to work. |
1013 | OverlayFS was officially introduced in Linux kernel version 3.18 | |
1046 | OverlayFS was officially introduced in Linux kernel version 3.18. | |
1047 | This option is not available on Grsecurity systems. | |
1014 | 1048 | .br |
1015 | 1049 | |
1016 | 1050 | .br |
1017 | 1051 | Example: |
1018 | 1052 | .br |
1019 | 1053 | $ firejail \-\-overlay-tmpfs firefox |
1054 | ||
1055 | .TP | |
1056 | \fB\-\-overlay-clean | |
1057 | Clean all overlays stored in $HOME/.firejail directory. Overlays created with --overlay-path=path | |
1058 | outside $HOME/.firejail will not be deleted. | |
1059 | .br | |
1060 | ||
1061 | .br | |
1062 | Example: | |
1063 | .br | |
1064 | $ firejail \-\-overlay-clean | |
1020 | 1065 | |
1021 | 1066 | .TP |
1022 | 1067 | \fB\-\-private |
1520 | 1565 | firejail version 0.9.27 |
1521 | 1566 | .TP |
1522 | 1567 | \fB\-\-whitelist=dirname_or_filename |
1523 | Whitelist directory or file. This feature is implemented only for user home, /dev, /media, /opt, /var, and /tmp directories. | |
1524 | With the exeception of user home, both the link and the real file should be in | |
1525 | the same top directory. | |
1568 | Whitelist directory or file. A temporary file system is mounted on the top directory, and the | |
1569 | whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent, | |
1570 | everything else is discarded when the sandbox is closed. The top directory could be | |
1571 | user home, /dev, /media, /opt, /var, and /tmp. | |
1572 | .br | |
1573 | ||
1574 | .br | |
1575 | Symbolic link handling: with the exception of user home, both the link and the real file should be in | |
1576 | the same top directory. For user home, both the link and the real file should be owned by the user. | |
1526 | 1577 | .br |
1527 | 1578 | |
1528 | 1579 | .br |
1563 | 1614 | A network namespace needs to be instantiated in order to deny access to X11 abstract Unix domain socket. |
1564 | 1615 | .br |
1565 | 1616 | |
1566 | .br | |
1617 | br | |
1567 | 1618 | Firejail will try first Xpra, and if Xpra is not installed on the system, it will try to find Xephyr. |
1568 | 1619 | This feature is not available when running as root. |
1569 | 1620 | .br |
1669 | 1720 | .br |
1670 | 1721 | 1221:netblue:/usr/lib/firefox/firefox |
1671 | 1722 | .RE |
1723 | ||
1724 | .SH APPARMOR | |
1725 | .TP | |
1726 | AppArmor support is disabled by default at compile time. Use --enable-apparmor configuration option to enable it: | |
1727 | .br | |
1728 | ||
1729 | .br | |
1730 | $ ./configure --prefix=/usr --enable-apparmor | |
1731 | .TP | |
1732 | During software install, a generic AppArmor profile file, firejail-default, is placed in /etc/apparmor.d directory. The profile needs to be loaded into the kernel by running the following command as root: | |
1733 | .br | |
1734 | ||
1735 | .br | |
1736 | # aa-enforce firejail-default | |
1737 | .TP | |
1738 | The installed profile tries to replicate some advanced security features inspired by kernel-based Grsecurity: | |
1739 | .br | |
1740 | ||
1741 | .br | |
1742 | - Prevent information leakage in /proc and /sys directories. The resulting filesystem is barely enough for running | |
1743 | commands such as "top" and "ps aux". | |
1744 | .br | |
1745 | ||
1746 | .br | |
1747 | - Allow running programs only from well-known system paths, such as /bin, /sbin, /usr/bin etc. Running | |
1748 | programs and scripts from user home or other directories writable by the user is not allowed. | |
1749 | .br | |
1750 | ||
1751 | .br | |
1752 | - Disable D-Bus. D-Bus has long been a huge security hole, and most programs don't use it anyway. | |
1753 | You should have no problems running Chromium or Firefox. | |
1754 | ||
1755 | .TP | |
1756 | To enable AppArmor confinement on top of your current Firejail security features, pass \fB\-\-apparmor\fR flag to Firejail command line. You can also include \fBapparmor\fR command in a Firejail profile file. Example: | |
1757 | .br | |
1758 | ||
1759 | .br | |
1760 | $ firejail --apparmor firefox | |
1672 | 1761 | |
1673 | 1762 | .SH FILE TRANSFER |
1674 | 1763 | These features allow the user to inspect the filesystem container of an existing sandbox |
8 | 8 | arr[7]="TEST 7: compile X11 disabled" |
9 | 9 | arr[8]="TEST 8: compile network restricted" |
10 | 10 | arr[9]="TEST 9: compile file transfer disabled" |
11 | ||
11 | arr[10]="TEST 10: compile disable whitelist" | |
12 | arr[11]="TEST 11: compile disable global config" | |
13 | arr[12]="TEST 12: compile apparmor" | |
14 | arr[13]="TEST 13: compile busybox" | |
15 | arr[14]="TEST 14: compile overlayfs disabled" | |
12 | 16 | |
13 | 17 | # remove previous reports and output file |
14 | 18 | cleanup() { |
26 | 30 | echo "**************************************************" |
27 | 31 | } |
28 | 32 | |
33 | DIST="$1" | |
29 | 34 | while [ $# -gt 0 ]; do # Until you run out of parameters . . . |
30 | 35 | case "$1" in |
31 | 36 | --clean) |
42 | 47 | |
43 | 48 | cleanup |
44 | 49 | |
50 | ||
45 | 51 | #***************************************************************** |
46 | 52 | # TEST 1 |
47 | 53 | #***************************************************************** |
48 | 54 | # - checkout source code |
49 | # - check compilation | |
50 | # - install | |
51 | 55 | #***************************************************************** |
52 | 56 | print_title "${arr[1]}" |
53 | git clone https://github.com/netblue30/firejail.git | |
57 | echo "$DIST" | |
58 | tar -xJvf ../../$DIST.tar.xz | |
59 | mv $DIST firejail | |
60 | ||
54 | 61 | cd firejail |
55 | 62 | ./configure --prefix=/usr --enable-fatal-warnings 2>&1 | tee ../output-configure |
56 | 63 | make -j4 2>&1 | tee ../output-make |
66 | 73 | # TEST 2 |
67 | 74 | #***************************************************************** |
68 | 75 | # - disable seccomp configuration |
69 | # - check compilation | |
70 | 76 | #***************************************************************** |
71 | 77 | print_title "${arr[2]}" |
72 | 78 | # seccomp |
85 | 91 | # TEST 3 |
86 | 92 | #***************************************************************** |
87 | 93 | # - disable chroot configuration |
88 | # - check compilation | |
89 | 94 | #***************************************************************** |
90 | 95 | print_title "${arr[3]}" |
91 | 96 | # seccomp |
104 | 109 | # TEST 4 |
105 | 110 | #***************************************************************** |
106 | 111 | # - disable bind configuration |
107 | # - check compilation | |
108 | 112 | #***************************************************************** |
109 | 113 | print_title "${arr[4]}" |
110 | 114 | # seccomp |
123 | 127 | # TEST 5 |
124 | 128 | #***************************************************************** |
125 | 129 | # - disable user namespace configuration |
126 | # - check compilation | |
127 | 130 | #***************************************************************** |
128 | 131 | print_title "${arr[5]}" |
129 | 132 | # seccomp |
161 | 164 | # TEST 7 |
162 | 165 | #***************************************************************** |
163 | 166 | # - disable X11 support |
164 | # - check compilation | |
165 | 167 | #***************************************************************** |
166 | 168 | print_title "${arr[7]}" |
167 | 169 | # seccomp |
181 | 183 | # TEST 8 |
182 | 184 | #***************************************************************** |
183 | 185 | # - enable network restricted |
184 | # - check compilation | |
185 | 186 | #***************************************************************** |
186 | 187 | print_title "${arr[8]}" |
187 | 188 | # seccomp |
201 | 202 | # TEST 9 |
202 | 203 | #***************************************************************** |
203 | 204 | # - disable file transfer |
204 | # - check compilation | |
205 | 205 | #***************************************************************** |
206 | 206 | print_title "${arr[9]}" |
207 | 207 | # seccomp |
208 | 208 | cd firejail |
209 | 209 | make distclean |
210 | ./configure --prefix=/usr --enable-network=restricted --enable-fatal-warnings 2>&1 | tee ../output-configure | |
210 | ./configure --prefix=/usr --disable-file-transfer --enable-fatal-warnings 2>&1 | tee ../output-configure | |
211 | 211 | make -j4 2>&1 | tee ../output-make |
212 | 212 | cd .. |
213 | 213 | grep Warning output-configure output-make > ./report-test9 |
214 | 214 | grep Error output-configure output-make >> ./report-test9 |
215 | 215 | cp output-configure oc9 |
216 | 216 | cp output-make om9 |
217 | rm output-configure output-make | |
218 | ||
219 | #***************************************************************** | |
220 | # TEST 10 | |
221 | #***************************************************************** | |
222 | # - disable whitelist | |
223 | #***************************************************************** | |
224 | print_title "${arr[10]}" | |
225 | # seccomp | |
226 | cd firejail | |
227 | make distclean | |
228 | ./configure --prefix=/usr --disable-whitelist --enable-fatal-warnings 2>&1 | tee ../output-configure | |
229 | make -j4 2>&1 | tee ../output-make | |
230 | cd .. | |
231 | grep Warning output-configure output-make > ./report-test10 | |
232 | grep Error output-configure output-make >> ./report-test10 | |
233 | cp output-configure oc10 | |
234 | cp output-make om10 | |
235 | rm output-configure output-make | |
236 | ||
237 | #***************************************************************** | |
238 | # TEST 11 | |
239 | #***************************************************************** | |
240 | # - disable global config | |
241 | #***************************************************************** | |
242 | print_title "${arr[11]}" | |
243 | # seccomp | |
244 | cd firejail | |
245 | make distclean | |
246 | ./configure --prefix=/usr --disable-globalcfg --enable-fatal-warnings 2>&1 | tee ../output-configure | |
247 | make -j4 2>&1 | tee ../output-make | |
248 | cd .. | |
249 | grep Warning output-configure output-make > ./report-test11 | |
250 | grep Error output-configure output-make >> ./report-test11 | |
251 | cp output-configure oc11 | |
252 | cp output-make om11 | |
253 | rm output-configure output-make | |
254 | ||
255 | #***************************************************************** | |
256 | # TEST 12 | |
257 | #***************************************************************** | |
258 | # - enable apparmor | |
259 | #***************************************************************** | |
260 | print_title "${arr[12]}" | |
261 | # seccomp | |
262 | cd firejail | |
263 | make distclean | |
264 | ./configure --prefix=/usr --enable-apparmor --enable-fatal-warnings 2>&1 | tee ../output-configure | |
265 | make -j4 2>&1 | tee ../output-make | |
266 | cd .. | |
267 | grep Warning output-configure output-make > ./report-test12 | |
268 | grep Error output-configure output-make >> ./report-test12 | |
269 | cp output-configure oc12 | |
270 | cp output-make om12 | |
271 | rm output-configure output-make | |
272 | ||
273 | #***************************************************************** | |
274 | # TEST 13 | |
275 | #***************************************************************** | |
276 | # - enable busybox workaround | |
277 | #***************************************************************** | |
278 | print_title "${arr[13]}" | |
279 | # seccomp | |
280 | cd firejail | |
281 | make distclean | |
282 | ./configure --prefix=/usr --enable-busybox-workaround --enable-fatal-warnings 2>&1 | tee ../output-configure | |
283 | make -j4 2>&1 | tee ../output-make | |
284 | cd .. | |
285 | grep Warning output-configure output-make > ./report-test13 | |
286 | grep Error output-configure output-make >> ./report-test13 | |
287 | cp output-configure oc13 | |
288 | cp output-make om13 | |
289 | rm output-configure output-make | |
290 | ||
291 | #***************************************************************** | |
292 | # TEST 14 | |
293 | #***************************************************************** | |
294 | # - disable overlayfs | |
295 | #***************************************************************** | |
296 | print_title "${arr[14]}" | |
297 | # seccomp | |
298 | cd firejail | |
299 | make distclean | |
300 | ./configure --prefix=/usr --disable-overlayfs --enable-fatal-warnings 2>&1 | tee ../output-configure | |
301 | make -j4 2>&1 | tee ../output-make | |
302 | cd .. | |
303 | grep Warning output-configure output-make > ./report-test14 | |
304 | grep Error output-configure output-make >> ./report-test14 | |
305 | cp output-configure oc14 | |
306 | cp output-make om14 | |
217 | 307 | rm output-configure output-make |
218 | 308 | |
219 | 309 | |
240 | 330 | echo ${arr[7]} |
241 | 331 | echo ${arr[8]} |
242 | 332 | echo ${arr[9]} |
333 | echo ${arr[10]} | |
334 | echo ${arr[11]} | |
335 | echo ${arr[12]} | |
336 | echo ${arr[13]} | |
337 | echo ${arr[14]} |
0 | #!/bin/bash | |
1 | ||
2 | arr[1]="TEST 1: standard compilation" | |
3 | arr[2]="TEST 2: compile seccomp disabled" | |
4 | arr[3]="TEST 3: compile chroot disabled" | |
5 | arr[4]="TEST 4: compile bind disabled" | |
6 | arr[5]="TEST 5: compile user namespace disabled" | |
7 | arr[6]="TEST 6: compile network disabled" | |
8 | arr[7]="TEST 7: compile X11 disabled" | |
9 | arr[8]="TEST 8: compile network restricted" | |
10 | arr[9]="TEST 9: compile file transfer disabled" | |
11 | arr[10]="TEST 10: compile disable whitelist" | |
12 | arr[11]="TEST 11: compile disable global config" | |
13 | ||
14 | # remove previous reports and output file | |
15 | cleanup() { | |
16 | rm -f report* | |
17 | rm -fr firejail | |
18 | rm -f oc* om* | |
19 | } | |
20 | ||
21 | print_title() { | |
22 | echo | |
23 | echo | |
24 | echo | |
25 | echo "**************************************************" | |
26 | echo $1 | |
27 | echo "**************************************************" | |
28 | } | |
29 | ||
30 | DIST="$1" | |
31 | while [ $# -gt 0 ]; do # Until you run out of parameters . . . | |
32 | case "$1" in | |
33 | --clean) | |
34 | cleanup | |
35 | exit | |
36 | ;; | |
37 | --help) | |
38 | echo "./compile.sh [--clean|--help]" | |
39 | exit | |
40 | ;; | |
41 | esac | |
42 | shift # Check next set of parameters. | |
43 | done | |
44 | ||
45 | cleanup | |
46 | ||
47 | ||
48 | #***************************************************************** | |
49 | # TEST 1 | |
50 | #***************************************************************** | |
51 | # - checkout source code | |
52 | # - check compilation | |
53 | # - install | |
54 | #***************************************************************** | |
55 | print_title "${arr[1]}" | |
56 | echo "$DIST" | |
57 | tar -xjvf ../../$DIST.tar.bz2 | |
58 | mv $DIST firejail | |
59 | ||
60 | cd firejail | |
61 | ./configure --prefix=/usr --enable-fatal-warnings 2>&1 | tee ../output-configure | |
62 | make -j4 2>&1 | tee ../output-make | |
63 | cd .. | |
64 | grep Warning output-configure output-make > ./report-test1 | |
65 | grep Error output-configure output-make >> ./report-test1 | |
66 | cp output-configure oc1 | |
67 | cp output-make om1 | |
68 | rm output-configure output-make | |
69 | ||
70 | ||
71 | #***************************************************************** | |
72 | # TEST 2 | |
73 | #***************************************************************** | |
74 | # - disable seccomp configuration | |
75 | # - check compilation | |
76 | #***************************************************************** | |
77 | print_title "${arr[2]}" | |
78 | # seccomp | |
79 | cd firejail | |
80 | make distclean | |
81 | ./configure --prefix=/usr --disable-seccomp --enable-fatal-warnings 2>&1 | tee ../output-configure | |
82 | make -j4 2>&1 | tee ../output-make | |
83 | cd .. | |
84 | grep Warning output-configure output-make > ./report-test2 | |
85 | grep Error output-configure output-make >> ./report-test2 | |
86 | cp output-configure oc2 | |
87 | cp output-make om2 | |
88 | rm output-configure output-make | |
89 | ||
90 | #***************************************************************** | |
91 | # TEST 3 | |
92 | #***************************************************************** | |
93 | # - disable chroot configuration | |
94 | # - check compilation | |
95 | #***************************************************************** | |
96 | print_title "${arr[3]}" | |
97 | # seccomp | |
98 | cd firejail | |
99 | make distclean | |
100 | ./configure --prefix=/usr --disable-chroot --enable-fatal-warnings 2>&1 | tee ../output-configure | |
101 | make -j4 2>&1 | tee ../output-make | |
102 | cd .. | |
103 | grep Warning output-configure output-make > ./report-test3 | |
104 | grep Error output-configure output-make >> ./report-test3 | |
105 | cp output-configure oc3 | |
106 | cp output-make om3 | |
107 | rm output-configure output-make | |
108 | ||
109 | #***************************************************************** | |
110 | # TEST 4 | |
111 | #***************************************************************** | |
112 | # - disable bind configuration | |
113 | # - check compilation | |
114 | #***************************************************************** | |
115 | print_title "${arr[4]}" | |
116 | # seccomp | |
117 | cd firejail | |
118 | make distclean | |
119 | ./configure --prefix=/usr --disable-bind --enable-fatal-warnings 2>&1 | tee ../output-configure | |
120 | make -j4 2>&1 | tee ../output-make | |
121 | cd .. | |
122 | grep Warning output-configure output-make > ./report-test4 | |
123 | grep Error output-configure output-make >> ./report-test4 | |
124 | cp output-configure oc4 | |
125 | cp output-make om4 | |
126 | rm output-configure output-make | |
127 | ||
128 | #***************************************************************** | |
129 | # TEST 5 | |
130 | #***************************************************************** | |
131 | # - disable user namespace configuration | |
132 | # - check compilation | |
133 | #***************************************************************** | |
134 | print_title "${arr[5]}" | |
135 | # seccomp | |
136 | cd firejail | |
137 | make distclean | |
138 | ./configure --prefix=/usr --disable-userns --enable-fatal-warnings 2>&1 | tee ../output-configure | |
139 | make -j4 2>&1 | tee ../output-make | |
140 | cd .. | |
141 | grep Warning output-configure output-make > ./report-test5 | |
142 | grep Error output-configure output-make >> ./report-test5 | |
143 | cp output-configure oc5 | |
144 | cp output-make om5 | |
145 | rm output-configure output-make | |
146 | ||
147 | #***************************************************************** | |
148 | # TEST 6 | |
149 | #***************************************************************** | |
150 | # - disable user namespace configuration | |
151 | # - check compilation | |
152 | #***************************************************************** | |
153 | print_title "${arr[6]}" | |
154 | # seccomp | |
155 | cd firejail | |
156 | make distclean | |
157 | ./configure --prefix=/usr --disable-network --enable-fatal-warnings 2>&1 | tee ../output-configure | |
158 | make -j4 2>&1 | tee ../output-make | |
159 | cd .. | |
160 | grep Warning output-configure output-make > ./report-test6 | |
161 | grep Error output-configure output-make >> ./report-test6 | |
162 | cp output-configure oc6 | |
163 | cp output-make om6 | |
164 | rm output-configure output-make | |
165 | ||
166 | #***************************************************************** | |
167 | # TEST 7 | |
168 | #***************************************************************** | |
169 | # - disable X11 support | |
170 | # - check compilation | |
171 | #***************************************************************** | |
172 | print_title "${arr[7]}" | |
173 | # seccomp | |
174 | cd firejail | |
175 | make distclean | |
176 | ./configure --prefix=/usr --disable-x11 --enable-fatal-warnings 2>&1 | tee ../output-configure | |
177 | make -j4 2>&1 | tee ../output-make | |
178 | cd .. | |
179 | grep Warning output-configure output-make > ./report-test7 | |
180 | grep Error output-configure output-make >> ./report-test7 | |
181 | cp output-configure oc7 | |
182 | cp output-make om7 | |
183 | rm output-configure output-make | |
184 | ||
185 | ||
186 | #***************************************************************** | |
187 | # TEST 8 | |
188 | #***************************************************************** | |
189 | # - enable network restricted | |
190 | # - check compilation | |
191 | #***************************************************************** | |
192 | print_title "${arr[8]}" | |
193 | # seccomp | |
194 | cd firejail | |
195 | make distclean | |
196 | ./configure --prefix=/usr --enable-network=restricted --enable-fatal-warnings 2>&1 | tee ../output-configure | |
197 | make -j4 2>&1 | tee ../output-make | |
198 | cd .. | |
199 | grep Warning output-configure output-make > ./report-test8 | |
200 | grep Error output-configure output-make >> ./report-test8 | |
201 | cp output-configure oc8 | |
202 | cp output-make om8 | |
203 | rm output-configure output-make | |
204 | ||
205 | ||
206 | #***************************************************************** | |
207 | # TEST 9 | |
208 | #***************************************************************** | |
209 | # - disable file transfer | |
210 | # - check compilation | |
211 | #***************************************************************** | |
212 | print_title "${arr[9]}" | |
213 | # seccomp | |
214 | cd firejail | |
215 | make distclean | |
216 | ./configure --prefix=/usr --disable-file-transfer --enable-fatal-warnings 2>&1 | tee ../output-configure | |
217 | make -j4 2>&1 | tee ../output-make | |
218 | cd .. | |
219 | grep Warning output-configure output-make > ./report-test9 | |
220 | grep Error output-configure output-make >> ./report-test9 | |
221 | cp output-configure oc9 | |
222 | cp output-make om9 | |
223 | rm output-configure output-make | |
224 | ||
225 | #***************************************************************** | |
226 | # TEST 10 | |
227 | #***************************************************************** | |
228 | # - disable whitelist | |
229 | # - check compilation | |
230 | #***************************************************************** | |
231 | print_title "${arr[10]}" | |
232 | # seccomp | |
233 | cd firejail | |
234 | make distclean | |
235 | ./configure --prefix=/usr --disable-whitelist --enable-fatal-warnings 2>&1 | tee ../output-configure | |
236 | make -j4 2>&1 | tee ../output-make | |
237 | cd .. | |
238 | grep Warning output-configure output-make > ./report-test10 | |
239 | grep Error output-configure output-make >> ./report-test10 | |
240 | cp output-configure oc10 | |
241 | cp output-make om10 | |
242 | rm output-configure output-make | |
243 | ||
244 | #***************************************************************** | |
245 | # TEST 11 | |
246 | #***************************************************************** | |
247 | # - disable global config | |
248 | # - check compilation | |
249 | #***************************************************************** | |
250 | print_title "${arr[11]}" | |
251 | # seccomp | |
252 | cd firejail | |
253 | make distclean | |
254 | ./configure --prefix=/usr --disable-globalcfg --enable-fatal-warnings 2>&1 | tee ../output-configure | |
255 | make -j4 2>&1 | tee ../output-make | |
256 | cd .. | |
257 | grep Warning output-configure output-make > ./report-test11 | |
258 | grep Error output-configure output-make >> ./report-test11 | |
259 | cp output-configure oc11 | |
260 | cp output-make om11 | |
261 | rm output-configure output-make | |
262 | ||
263 | ||
264 | #***************************************************************** | |
265 | # PRINT REPORTS | |
266 | #***************************************************************** | |
267 | echo | |
268 | echo | |
269 | echo | |
270 | echo | |
271 | echo "**********************************************************" | |
272 | echo "TEST RESULTS" | |
273 | echo "**********************************************************" | |
274 | ||
275 | wc -l report-test* | |
276 | echo | |
277 | echo "Legend:" | |
278 | echo ${arr[1]} | |
279 | echo ${arr[2]} | |
280 | echo ${arr[3]} | |
281 | echo ${arr[4]} | |
282 | echo ${arr[5]} | |
283 | echo ${arr[6]} | |
284 | echo ${arr[7]} | |
285 | echo ${arr[8]} | |
286 | echo ${arr[9]} | |
287 | echo ${arr[10]} | |
288 | echo ${arr[11]} |
0 | #!/usr/bin/expect -f | |
1 | ||
2 | set timeout 10 | |
3 | cd /home | |
4 | spawn $env(SHELL) | |
5 | match_max 100000 | |
6 | ||
7 | send -- "firejail --profile=/etc/firejail/firefox.profile --allow-debuggers strace ls\r" | |
8 | expect { | |
9 | timeout {puts "TESTING ERROR 0\n";exit} | |
10 | "Child process initialized" | |
11 | } | |
12 | expect { | |
13 | timeout {puts "TESTING ERROR 1\n";exit} | |
14 | "exited with 0" | |
15 | } | |
16 | after 100 | |
17 | ||
18 | send -- "firejail --allow-debuggers --profile=/etc/firejail/firefox.profile strace ls\r" | |
19 | expect { | |
20 | timeout {puts "TESTING ERROR 2\n";exit} | |
21 | "Child process initialized" | |
22 | } | |
23 | expect { | |
24 | timeout {puts "TESTING ERROR 3\n";exit} | |
25 | "exited with 0" | |
26 | } | |
27 | after 100 | |
28 | ||
29 | ||
30 | puts "\nall done\n" | |
31 |
35 | 35 | sleep 3 |
36 | 36 | |
37 | 37 | spawn $env(SHELL) |
38 | send -- "firejail --list;pwd\r" | |
38 | send -- "firejail --list;ls -d /tmp\r" | |
39 | 39 | expect { |
40 | 40 | timeout {puts "TESTING ERROR 6\n";exit} |
41 | 41 | "name=testing" |
42 | 42 | } |
43 | 43 | expect { |
44 | 44 | timeout {puts "TESTING ERROR 7\n";exit} |
45 | "home" | |
45 | "/tmp" | |
46 | 46 | } |
47 | send -- "firejail --list;pwd\r" | |
47 | send -- "firejail --list;ls -d /tmp\r" | |
48 | 48 | expect { |
49 | 49 | timeout {puts "TESTING ERROR 8 (join)\n";exit} |
50 | 50 | "join=testing" |
51 | 51 | } |
52 | 52 | expect { |
53 | 53 | timeout {puts "TESTING ERROR 9\n";exit} |
54 | "home" | |
54 | "/tmp" | |
55 | 55 | } |
56 | 56 | |
57 | sleep 1 | |
57 | after 100 | |
58 | 58 | |
59 | 59 | puts "\n" |
30 | 30 | "ENV3" |
31 | 31 | } |
32 | 32 | send -- "exit\r" |
33 | sleep 1 | |
33 | after 100 | |
34 | 34 | |
35 | 35 | #*********************************************** |
36 | 36 | send -- "firejail --profile=env.profile\r" |
81 | 81 | echo "TESTING: quiet (test/environment/quiet.exp)" |
82 | 82 | ./quiet.exp |
83 | 83 | |
84 | which strace | |
85 | if [ "$?" -eq 0 ]; | |
86 | then | |
87 | echo "TESTING: --allow-debuggers (test/environment/allow-debuggers.exp)" | |
88 | ./allow-debuggers.exp | |
89 | else | |
90 | echo "TESTING SKIP: strace not found" | |
91 | fi | |
84 | 92 |
18 | 18 | timeout {puts "TESTING ERROR 1\n";exit} |
19 | 19 | "Warning: an existing sandbox was detected" |
20 | 20 | } |
21 | sleep 1 | |
21 | after 100 | |
22 | 22 | |
23 | 23 | puts "\nall done\n" |
18 | 18 | timeout {puts "TESTING ERROR 1\n";exit} |
19 | 19 | "Child process initialized" |
20 | 20 | } |
21 | sleep 1 | |
21 | after 100 | |
22 | 22 | |
23 | 23 | puts "\nall done\n" |
41 | 41 | |
42 | 42 | sleep 1 |
43 | 43 | send -- "exit\r" |
44 | sleep 1 | |
44 | after 100 | |
45 | 45 | |
46 | 46 | send -- "firejail --profile=nice.profile\r" |
47 | 47 | expect { |
14 | 14 | "Child process initialized" {puts "TESTING ERROR 3\n";exit} |
15 | 15 | "done" |
16 | 16 | } |
17 | sleep 1 | |
17 | after 100 | |
18 | 18 | |
19 | 19 | puts "\nall done\n" |
20 | 20 |
28 | 28 | timeout {puts "TESTING ERROR 1.4\n";exit} |
29 | 29 | "Max pending signals 200 200" |
30 | 30 | } |
31 | sleep 1 | |
31 | after 100 | |
32 | 32 | puts "\nall done\n" |
32 | 32 | timeout {puts "TESTING ERROR 1.5\n";exit} |
33 | 33 | "home" |
34 | 34 | } |
35 | sleep 1 | |
35 | after 100 | |
36 | 36 | puts "\n" |
18 | 18 | timeout {puts "TESTING ERROR 1\n";exit} |
19 | 19 | "shell=none configured, but no program specified" |
20 | 20 | } |
21 | sleep 1 | |
21 | after 100 | |
22 | 22 | |
23 | 23 | send -- "firejail --shell=none ls\r" |
24 | 24 | expect { |
29 | 29 | timeout {puts "TESTING ERROR 3\n";exit} |
30 | 30 | "environment.sh" |
31 | 31 | } |
32 | sleep 1 | |
32 | after 100 | |
33 | 33 | |
34 | 34 | send -- "firejail --profile=shell-none.profile ls\r" |
35 | 35 | expect { |
40 | 40 | timeout {puts "TESTING ERROR 5\n";exit} |
41 | 41 | "environment.sh" |
42 | 42 | } |
43 | sleep 1 | |
43 | after 100 | |
44 | 44 | |
45 | 45 | |
46 | 46 | puts "\nall done\n" |
76 | 76 | timeout {puts "TESTING ERROR 25\n";exit} |
77 | 77 | "Parent is shutting down" |
78 | 78 | } |
79 | sleep 2 | |
79 | after 100 | |
80 | 80 | |
81 | 81 | puts "\nall done\n" |
82 | 82 |
29 | 29 | "/usr/bin/zsh" |
30 | 30 | } |
31 | 31 | send -- "exit\r" |
32 | sleep 1 | |
32 | after 100 | |
33 | 33 | |
34 | 34 | puts "\nall done\n" |
35 | 35 |
65 | 65 | "Seccomp:" |
66 | 66 | } |
67 | 67 | send -- "exit\r" |
68 | sleep 1 | |
68 | after 100 | |
69 | 69 | |
70 | 70 | |
71 | 71 | puts "\nall done\n" |
155 | 155 | timeout {puts "TESTING ERROR 24\n";exit} |
156 | 156 | "3" |
157 | 157 | } |
158 | after 100 | |
158 | 159 | puts "\nall done\n" |
179 | 179 | timeout {puts "TESTING ERROR 4.9\n";exit} |
180 | 180 | "after socket" |
181 | 181 | } |
182 | sleep 1 | |
182 | after 100 | |
183 | 183 | |
184 | 184 | puts "\nall done\n" |
35 | 35 | timeout {puts "TESTING ERROR 7\n";exit} |
36 | 36 | "Error: line 1 in seccomp-bad-empty2.profile is invalid" |
37 | 37 | } |
38 | sleep 1 | |
38 | after 100 | |
39 | 39 | puts "\nall done\n" |
40 | 40 |
8 | 8 | |
9 | 9 | send -- "./syscall_test\r" |
10 | 10 | expect { |
11 | timeout {puts "TESTING SKIP: 64-bit support missing\n";exit} | |
11 | timeout {puts "\nTESTING SKIP: 64-bit support missing\n";exit} | |
12 | 12 | "Usage" |
13 | 13 | } |
14 | 14 | |
15 | 15 | send -- "./syscall_test32\r" |
16 | 16 | expect { |
17 | timeout {puts "TESTING SKIP: 32-bit support missing\n";exit} | |
17 | timeout {puts "\nTESTING SKIP: 32-bit support missing\n";exit} | |
18 | 18 | "Usage" |
19 | 19 | } |
20 | 20 | |
50 | 50 | "Parent is shutting down" |
51 | 51 | } |
52 | 52 | |
53 | after 100 | |
53 | 54 | puts "\nall done\n" |
50 | 50 | echo "TESTING: bind as user (test/fs/option_bind_user.exp)" |
51 | 51 | ./option_bind_user.exp |
52 | 52 | |
53 | echo "TESTING: recursive mkdir (test/fs/mkdir.exp)" | |
54 | ./mkdir.exp | |
55 | ||
56 | echo "TESTING: double whitelist (test/fs/whitelist-double.exp)" | |
57 | ./whitelist-double.exp | |
53 | 58 | |
54 | 59 | |
60 | echo "TESTING: whitelist (test/fs/whitelist.exp)" | |
61 | ./whitelist.exp | |
62 | rm -fr ~/fjtest-dir | |
63 | rm -fr ~/fjtest-dir-lnk | |
64 | rm -f ~/fjtest-file | |
65 | rm -f ~/fjtest-file-lnk | |
66 | rm -f /tmp/fjtest-file | |
67 | rm -fr /tmp/fjtest-dir | |
68 | ||
69 | ||
70 |
0 | #!/usr/bin/expect -f | |
1 | # This file is part of Firejail project | |
2 | # Copyright (C) 2016 Firejail Authors | |
3 | # License GPL v2 | |
4 | ||
5 | set timeout 3 | |
6 | spawn $env(SHELL) | |
7 | match_max 100000 | |
8 | ||
9 | send -- "firejail --profile=mkdir.profile find ~/.firejail_test\r" | |
10 | expect { | |
11 | timeout {puts "TESTING ERROR 1.1\n";exit} | |
12 | "Warning: cannot create" { puts "TESTING ERROR 1.2\n";exit} | |
13 | "No such file or directory" { puts "TESTING ERROR 1.3\n";exit} | |
14 | ".firejail_test/a/b/c/d.txt" | |
15 | } | |
16 | send -- "rm -rf ~/.firejail_test\r" | |
17 | after 100 | |
18 | ||
19 | puts "\nall done\n" |
8 | 8 | timeout {puts "TESTING ERROR 0\n";exit} |
9 | 9 | "bind option is available only if running as root" |
10 | 10 | } |
11 | sleep 1 | |
11 | after 100 | |
12 | 12 | |
13 | 13 | puts "\n" |
14 | 14 |
31 | 31 | timeout {puts "TESTING ERROR 4\n";exit} |
32 | 32 | "done" |
33 | 33 | } |
34 | sleep 1 | |
34 | after 100 | |
35 | 35 | |
36 | 36 | puts "\n" |
37 | 37 |
19 | 19 | timeout {puts "TESTING ERROR 2\n";exit} |
20 | 20 | "done" |
21 | 21 | } |
22 | sleep 1 | |
22 | after 100 | |
23 | 23 | |
24 | 24 | puts "\n" |
25 | 25 |
26 | 26 | timeout {puts "TESTING ERROR 2\n";exit} |
27 | 27 | "Permission denied" |
28 | 28 | } |
29 | after 100 | |
29 | 30 | |
30 | 31 | puts "\n" |
31 | 32 |
53 | 53 | timeout {puts "TESTING ERROR 11\n";exit} |
54 | 54 | "done" |
55 | 55 | } |
56 | sleep 1 | |
56 | after 100 | |
57 | 57 | |
58 | 58 | puts "all done\n" |
0 | #!/usr/bin/expect -f | |
1 | # This file is part of Firejail project | |
2 | # Copyright (C) 2014-2016 Firejail Authors | |
3 | # License GPL v2 | |
4 | ||
5 | set timeout 10 | |
6 | spawn $env(SHELL) | |
7 | match_max 100000 | |
8 | ||
9 | send -- "echo 123 > /tmp/firejal-deleteme\r" | |
10 | sleep 1 | |
11 | ||
12 | send -- "firejail --whitelist=/tmp/firejal-deleteme --whitelist=/tmp/firejal-deleteme\r" | |
13 | expect { | |
14 | timeout {puts "TESTING ERROR 0\n";exit} | |
15 | "Child process initialized" | |
16 | } | |
17 | sleep 1 | |
18 | ||
19 | send -- "cat /tmp/firejal-deleteme\r" | |
20 | expect { | |
21 | timeout {puts "TESTING ERROR 1\n";exit} | |
22 | "123" | |
23 | } | |
24 | ||
25 | send -- "exit\r" | |
26 | sleep 1 | |
27 | ||
28 | send -- "cat /tmp/firejal-deleteme\r" | |
29 | expect { | |
30 | timeout {puts "TESTING ERROR 2\n";exit} | |
31 | "123" | |
32 | } | |
33 | ||
34 | send -- "rm /tmp/firejal-deleteme\r" | |
35 | expect { | |
36 | timeout {puts "TESTING ERROR 3\n";exit} | |
37 | "0" | |
38 | } | |
39 | after 100 | |
40 | ||
41 | puts "\nall done\n" |
0 | #!/usr/bin/expect -f | |
1 | # This file is part of Firejail project | |
2 | # Copyright (C) 2014-2016 Firejail Authors | |
3 | # License GPL v2 | |
4 | ||
5 | set timeout 10 | |
6 | spawn $env(SHELL) | |
7 | match_max 100000 | |
8 | ||
9 | # cleanup | |
10 | send -- "rm -fr ~/fjtest-dir\r" | |
11 | after 200 | |
12 | send -- "rm -fr ~/fjtest-dir-lnk\r" | |
13 | after 200 | |
14 | send -- "rm ~/fjtest-file\r" | |
15 | after 200 | |
16 | send -- "rm ~/fjtest-file-lnk\r" | |
17 | after 200 | |
18 | send -- "rm /tmp/fjtest-file\r" | |
19 | after 200 | |
20 | send -- "rm -fr /tmp/fjtest-dir\r" | |
21 | after 200 | |
22 | ||
23 | ||
24 | # simple files and directories | |
25 | send -- "mkdir -p ~/fjtest-dir/fjtest-dir\r" | |
26 | after 200 | |
27 | send -- "echo 123 > ~/fjtest-file\r" | |
28 | after 200 | |
29 | send -- "echo 123 > ~/fjtest-dir/fjtest-file\r" | |
30 | after 200 | |
31 | send -- "echo 123 > ~/fjtest-dir/fjtest-dir/fjtest-file\r" | |
32 | after 200 | |
33 | send -- "ln -s ~/fjtest-file ~/fjtest-file-lnk\r" | |
34 | after 200 | |
35 | send -- "ln -s ~/fjtest-dir ~/fjtest-dir-lnk\r" | |
36 | after 200 | |
37 | ||
38 | send -- "firejail --whitelist=~/fjtest-file --whitelist=~/fjtest-dir\r" | |
39 | expect { | |
40 | timeout {puts "TESTING ERROR 0\n";exit} | |
41 | "Child process initialized" | |
42 | } | |
43 | sleep 1 | |
44 | ||
45 | send -- "ls -l ~/ | grep -v total | wc -l\r" | |
46 | expect { | |
47 | timeout {puts "TESTING ERROR 1\n";exit} | |
48 | "2" | |
49 | } | |
50 | ||
51 | send -- "cat fjtest-file\r" | |
52 | expect { | |
53 | timeout {puts "TESTING ERROR 2\n";exit} | |
54 | "123" | |
55 | } | |
56 | ||
57 | send -- "cat fjtest-dir/fjtest-file\r" | |
58 | expect { | |
59 | timeout {puts "TESTING ERROR 3\n";exit} | |
60 | "123" | |
61 | } | |
62 | ||
63 | send -- "cat fjtest-dir/fjtest-dir/fjtest-file\r" | |
64 | expect { | |
65 | timeout {puts "TESTING ERROR 4\n";exit} | |
66 | "123" | |
67 | } | |
68 | ||
69 | send -- "exit\r" | |
70 | sleep 1 | |
71 | ||
72 | ||
73 | ||
74 | # simple files and directories | |
75 | send -- "firejail --whitelist=~/fjtest-dir/fjtest-dir/fjtest-file\r" | |
76 | expect { | |
77 | timeout {puts "TESTING ERROR 10\n";exit} | |
78 | "Child process initialized" | |
79 | } | |
80 | sleep 1 | |
81 | ||
82 | send -- "ls -l ~/ | grep -v total | wc -l\r" | |
83 | expect { | |
84 | timeout {puts "TESTING ERROR 11\n";exit} | |
85 | "1" | |
86 | } | |
87 | ||
88 | send -- "cat fjtest-dir/fjtest-dir/fjtest-file\r" | |
89 | expect { | |
90 | timeout {puts "TESTING ERROR 12\n";exit} | |
91 | "123" | |
92 | } | |
93 | ||
94 | send -- "exit\r" | |
95 | sleep 1 | |
96 | ||
97 | ||
98 | ||
99 | # symlinks | |
100 | send -- "firejail --whitelist=~/fjtest-file-lnk --whitelist=~/fjtest-dir-lnk\r" | |
101 | expect { | |
102 | timeout {puts "TESTING ERROR 20\n";exit} | |
103 | "Child process initialized" | |
104 | } | |
105 | sleep 1 | |
106 | ||
107 | send -- "ls -l ~/ | grep -v total | wc -l\r" | |
108 | expect { | |
109 | timeout {puts "TESTING ERROR 21\n";exit} | |
110 | "4" | |
111 | } | |
112 | ||
113 | send -- "cat fjtest-file\r" | |
114 | expect { | |
115 | timeout {puts "TESTING ERROR 22\n";exit} | |
116 | "123" | |
117 | } | |
118 | ||
119 | send -- "cat fjtest-dir/fjtest-file\r" | |
120 | expect { | |
121 | timeout {puts "TESTING ERROR 23\n";exit} | |
122 | "123" | |
123 | } | |
124 | ||
125 | send -- "cat fjtest-dir/fjtest-dir/fjtest-file\r" | |
126 | expect { | |
127 | timeout {puts "TESTING ERROR 24\n";exit} | |
128 | "123" | |
129 | } | |
130 | ||
131 | send -- "cat fjtest-file-lnk\r" | |
132 | expect { | |
133 | timeout {puts "TESTING ERROR 25\n";exit} | |
134 | "123" | |
135 | } | |
136 | ||
137 | send -- "cat fjtest-dir-lnk/fjtest-file\r" | |
138 | expect { | |
139 | timeout {puts "TESTING ERROR 26\n";exit} | |
140 | "123" | |
141 | } | |
142 | ||
143 | send -- "cat fjtest-dir-lnk/fjtest-dir/fjtest-file\r" | |
144 | expect { | |
145 | timeout {puts "TESTING ERROR 27\n";exit} | |
146 | "123" | |
147 | } | |
148 | send -- "exit\r" | |
149 | sleep 1 | |
150 | ||
151 | # symlinks outside home to a file we don't own | |
152 | send -- "rm ~/fjtest-file-lnk\r" | |
153 | after 200 | |
154 | send -- "ln -s /etc/passwd ~/fjtest-file-lnk\r" | |
155 | after 200 | |
156 | send -- "firejail --whitelist=~/fjtest-file-lnk --whitelist=~/fjtest-dir-lnk\r" | |
157 | expect { | |
158 | timeout {puts "TESTING ERROR 30\n";exit} | |
159 | "invalid whitelist path" | |
160 | } | |
161 | expect { | |
162 | timeout {puts "TESTING ERROR 31\n";exit} | |
163 | "exiting" | |
164 | } | |
165 | sleep 1 | |
166 | ||
167 | # symlinks outside home to a file we own | |
168 | send -- "rm -fr ~/fjtest-dir-lnk\r" | |
169 | after 200 | |
170 | send -- "rm ~/fjtest-file-lnk\r" | |
171 | after 200 | |
172 | send -- "echo 123 > /tmp/fjtest-file\r" | |
173 | after 200 | |
174 | send -- "mkdir /tmp/fjtest-dir\r" | |
175 | after 200 | |
176 | send -- "echo 123 > /tmp/fjtest-dir/fjtest-file\r" | |
177 | after 200 | |
178 | send -- "ln -s /tmp/fjtest-file ~/fjtest-file-lnk\r" | |
179 | after 200 | |
180 | send -- "ln -s /tmp/fjtest-dir ~/fjtest-dir-lnk\r" | |
181 | after 200 | |
182 | send -- "firejail --whitelist=~/fjtest-file-lnk --whitelist=~/fjtest-dir-lnk\r" | |
183 | expect { | |
184 | timeout {puts "TESTING ERROR 40\n";exit} | |
185 | "Child process initialized" | |
186 | } | |
187 | sleep 1 | |
188 | ||
189 | send -- "ls -l ~/ | grep -v total | wc -l\r" | |
190 | expect { | |
191 | timeout {puts "TESTING ERROR 41\n";exit} | |
192 | "2" | |
193 | } | |
194 | ||
195 | send -- "cat fjtest-file-lnk\r" | |
196 | expect { | |
197 | timeout {puts "TESTING ERROR 42\n";exit} | |
198 | "123" | |
199 | } | |
200 | ||
201 | send -- "cat fjtest-dir-lnk/fjtest-file\r" | |
202 | expect { | |
203 | timeout {puts "TESTING ERROR 43\n";exit} | |
204 | "123" | |
205 | } | |
206 | send -- "exit\r" | |
207 | sleep 1 | |
208 | ||
209 | # cleanup | |
210 | send -- "rm -fr ~/fjtest-dir\r" | |
211 | after 200 | |
212 | send -- "rm -fr ~/fjtest-dir-lnk\r" | |
213 | after 200 | |
214 | send -- "rm ~/fjtest-file\r" | |
215 | after 200 | |
216 | send -- "rm ~/fjtest-file-lnk\r" | |
217 | after 200 | |
218 | send -- "rm /tmp/fjtest-file\r" | |
219 | after 200 | |
220 | send -- "rm -fr /tmp/fjtest-dir\r" | |
221 | after 200 | |
222 | ||
223 | ||
224 | puts "\nall done\n" | |
225 |
166 | 166 | timeout {puts "TESTING ERROR 10.2\n";exit} |
167 | 167 | "10.10.50.0/24 dev eth3 proto kernel scope link" |
168 | 168 | } |
169 | sleep 1 | |
169 | send -- "exit\r" | |
170 | after 100 | |
170 | 171 | |
171 | 172 | puts "\nall done\n" |
172 | 173 |
170 | 170 | "10.10.50.0/24 dev eth3 proto kernel scope link" |
171 | 171 | } |
172 | 172 | |
173 | sleep 1 | |
173 | send -- "exit\r" | |
174 | after 100 | |
174 | 175 | |
175 | 176 | puts "\nall done\n" |
176 | 177 |
17 | 17 | send -- "firejail --bandwidth=test status\r" |
18 | 18 | expect { |
19 | 19 | timeout {puts "TESTING ERROR 1\n";exit} |
20 | "qdisc pfifo_fast 0: dev eth0" | |
20 | "qdisc * 0: dev eth0" | |
21 | 21 | } |
22 | 22 | sleep 1 |
23 | 23 | |
59 | 59 | "rate 80Kbit burst 10Kb" {puts "TESTING ERROR 9\n";exit} |
60 | 60 | "done" |
61 | 61 | } |
62 | sleep 1 | |
62 | after 100 | |
63 | 63 | |
64 | 64 | puts "\nall done\n" |
22 | 22 | timeout {puts "TESTING ERROR 3\n";exit} |
23 | 23 | "done" |
24 | 24 | } |
25 | sleep 1 | |
25 | send -- "exit\r" | |
26 | after 100 | |
26 | 27 | |
27 | 28 | puts "all done\n" |
41 | 41 | "scopeid 0x0<global>" { puts "Arch\n"} |
42 | 42 | } |
43 | 43 | |
44 | send -- "exit\r" | |
45 | after 100 | |
44 | 46 | |
45 | 47 | puts "\nall done\n" |
46 | 48 |
68 | 68 | "sleep 20" |
69 | 69 | } |
70 | 70 | |
71 | # wait for snadboxes to be shutdown | |
71 | # wait for sandboxes to be shutdown | |
72 | 72 | sleep 30 |
73 | 73 | puts "\n" |
12 | 12 | timeout {puts "TESTING ERROR 0.0\n";exit} |
13 | 13 | "the IP address is not" |
14 | 14 | } |
15 | sleep 1 | |
15 | after 100 | |
16 | 16 | |
17 | 17 | puts "\n" |
18 | 18 |
42 | 42 | timeout {puts "TESTING ERROR 10.2\n";exit} |
43 | 43 | "10.10.20.0/29 dev eth0 proto kernel scope link" |
44 | 44 | } |
45 | sleep 1 | |
45 | send -- "exit\r" | |
46 | after 100 | |
46 | 47 | |
47 | 48 | puts "\nall done\n" |
48 | 49 |
36 | 36 | timeout {puts "TESTING ERROR 10.3\n";exit} |
37 | 37 | "10.10.30.0/24 dev eth1 proto kernel scope link" |
38 | 38 | } |
39 | sleep 1 | |
39 | send -- "exit\r" | |
40 | after 100 | |
40 | 41 | |
41 | 42 | puts "\nall done\n" |
42 | 43 |
13 | 13 | "default gateway 10.10.95.89 is not in the range of any network" |
14 | 14 | } |
15 | 15 | |
16 | sleep 1 | |
16 | after 100 | |
17 | ||
17 | 18 | |
18 | 19 | puts "\n" |
19 | 20 |
85 | 85 | timeout {puts "TESTING ERROR 5.1\n";exit} |
86 | 86 | "UP" |
87 | 87 | } |
88 | send -- "exit\r" | |
89 | after 100 | |
88 | 90 | |
89 | 91 | puts "all done\n" |
90 | 92 |
68 | 68 | timeout {puts "TESTING ERROR 10\n";exit} |
69 | 69 | "10.10.20.0/29 dev eth0 proto kernel scope link" |
70 | 70 | } |
71 | sleep 1 | |
71 | send -- "exit\r" | |
72 | after 100 | |
72 | 73 | |
73 | 74 | puts "\n" |
74 | 75 |
42 | 42 | timeout {puts "TESTING ERROR 7\n";exit} |
43 | 43 | "255.0.0.0" |
44 | 44 | } |
45 | send -- "exit\r" | |
46 | after 100 | |
45 | 47 | |
46 | 48 | puts "all done\n" |
47 | 49 |
32 | 32 | timeout {puts "TESTING ERROR 4\n";exit} |
33 | 33 | "Child process initialized" |
34 | 34 | } |
35 | sleep 1 | |
35 | send -- "exit\r" | |
36 | after 100 | |
36 | 37 | |
37 | 38 | puts "\nall done\n" |
38 | 39 |
27 | 27 | timeout {puts "TESTING ERROR 4\n";exit} |
28 | 28 | "state UP" |
29 | 29 | } |
30 | send -- "exit\r" | |
31 | after 100 | |
30 | 32 | |
31 | 33 | puts "\nall done\n" |
32 | 34 |
37 | 37 | timeout {puts "TESTING ERROR 6\n";exit} |
38 | 38 | "done" |
39 | 39 | } |
40 | send -- "exit\r" | |
40 | 41 | after 100 |
41 | 42 | |
42 | 43 | puts "all done\n" |
37 | 37 | timeout {puts "TESTING ERROR 6\n";exit} |
38 | 38 | "done" |
39 | 39 | } |
40 | send -- "exit\r" | |
40 | 41 | after 100 |
41 | 42 | |
42 | 43 | puts "all done\n" |
65 | 65 | "eth0" {puts "TESTING ERROR 5.1\n";exit} |
66 | 66 | "done" |
67 | 67 | } |
68 | sleep 1 | |
68 | send -- "exit\r" | |
69 | after 100 | |
69 | 70 | |
70 | 71 | puts "\nall done\n" |
69 | 69 | "state UP" |
70 | 70 | } |
71 | 71 | |
72 | sleep 1 | |
72 | send -- "exit\r" | |
73 | after 100 | |
73 | 74 | |
74 | 75 | puts "\nall done\n" |
75 | 76 |
30 | 30 | sleep 1 |
31 | 31 | |
32 | 32 | send -- "exit\r" |
33 | after 100 | |
33 | 34 | send -- "rm -fr /tmp/firejailtest*\r" |
34 | sleep 1 | |
35 | after 100 | |
35 | 36 | |
36 | 37 | puts "\nall done\n" |
8 | 8 | timeout {puts "TESTING ERROR 0\n";exit} |
9 | 9 | "cannot access profile" |
10 | 10 | } |
11 | sleep 1 | |
11 | after 100 | |
12 | 12 | puts "\nall done\n" |
27 | 27 | "Read-only file system" |
28 | 28 | } |
29 | 29 | send -- "exit\r" |
30 | sleep 1 | |
30 | after 100 | |
31 | 31 | |
32 | 32 | send -- "rm -fr /tmp/firejailtest*\r" |
33 | sleep 1 | |
33 | after 100 | |
34 | 34 | |
35 | 35 | puts "\nall done\n" |
44 | 44 | timeout {puts "TESTING ERROR 8\n";exit} |
45 | 45 | "Child process initialized" |
46 | 46 | } |
47 | ||
48 | sleep 1 | |
47 | send -- "exit\r" | |
48 | after 100 | |
49 | 49 | puts "\nall done\n" |
12 | 12 | exit |
13 | 13 | } |
14 | 14 | |
15 | send -- "firejail --profile=$argv /bin/bash\r" | |
15 | send -- "firejail --profile=$argv echo done\r" | |
16 | 16 | expect { |
17 | 17 | timeout {puts "TESTING ERROR 0\n";exit} |
18 | "Child process initialized" | |
18 | "done" | |
19 | 19 | } |
20 | 20 | send -- "exit\r" |
21 | 21 | after 100 |
0 | #!/usr/bin/expect -f | |
1 | # This file is part of Firejail project | |
2 | # Copyright (C) 2014-2016 Firejail Authors | |
3 | # License GPL v2 | |
4 | ||
5 | set timeout 10 | |
6 | spawn $env(SHELL) | |
7 | match_max 100000 | |
8 | ||
9 | send -- "find /usr/share/doc/firejail | /bin/cpio -ov > firejail_t1\r" | |
10 | sleep 1 | |
11 | ||
12 | send -- "find /usr/share/doc/firejail | firejail /bin/cpio -ov > firejail_t2\r" | |
13 | sleep 1 | |
14 | ||
15 | send -- "diff -s firejail_t1 firejail_t2\r" | |
16 | expect { | |
17 | timeout {puts "TESTING ERROR 1\n";exit} | |
18 | "firejail_t1 and firejail_t2 are identical" | |
19 | } | |
20 | ||
21 | send -- "rm firejail_t*\r" | |
22 | sleep 1 | |
23 | ||
24 | ||
25 | puts "\nall done\n" |
0 | #!/usr/bin/expect -f | |
1 | # This file is part of Firejail project | |
2 | # Copyright (C) 2014-2016 Firejail Authors | |
3 | # License GPL v2 | |
4 | ||
5 | set timeout 10 | |
6 | spawn $env(SHELL) | |
7 | match_max 100000 | |
8 | ||
9 | send -- "echo 'test string for firejail test' > /tmp/firejail_test.txt; firejail file /tmp/firejail_test.txt\r" | |
10 | expect { | |
11 | timeout {puts "TESTING ERROR 1\n";exit} | |
12 | "ASCII text" | |
13 | } | |
14 | send -- "rm /tmp/firejail_test.txt\r" | |
15 | sleep 1 | |
16 | ||
17 | puts "\nall done\n" |
0 | #!/usr/bin/expect -f | |
1 | # This file is part of Firejail project | |
2 | # Copyright (C) 2014-2016 Firejail Authors | |
3 | # License GPL v2 | |
4 | ||
5 | set timeout 10 | |
6 | spawn $env(SHELL) | |
7 | match_max 100000 | |
8 | ||
9 | send -- "/bin/gzip -c /usr/bin/firejail > firejail_t1\r" | |
10 | sleep 1 | |
11 | ||
12 | send -- "firejail /bin/gzip -c /usr/bin/firejail > firejail_t2\r" | |
13 | sleep 1 | |
14 | ||
15 | send -- "diff -s firejail_t1 firejail_t2\r" | |
16 | expect { | |
17 | timeout {puts "TESTING ERROR 1\n";exit} | |
18 | "firejail_t1 and firejail_t2 are identical" | |
19 | } | |
20 | ||
21 | send -- "rm firejail_t*\r" | |
22 | sleep 1 | |
23 | ||
24 | ||
25 | puts "\nall done\n" |
0 | #!/usr/bin/expect -f | |
1 | # This file is part of Firejail project | |
2 | # Copyright (C) 2014-2016 Firejail Authors | |
3 | # License GPL v2 | |
4 | ||
5 | set timeout 10 | |
6 | spawn $env(SHELL) | |
7 | match_max 100000 | |
8 | ||
9 | send -- "firejail less ../../Makefile.in\r" | |
10 | expect { | |
11 | timeout {puts "TESTING ERROR 1\n";exit} | |
12 | "MYLIBS" | |
13 | } | |
14 | expect { | |
15 | timeout {puts "TESTING ERROR 2\n";exit} | |
16 | "APPS" | |
17 | } | |
18 | ||
19 | puts "\nall done\n" |
0 | #!/usr/bin/expect -f | |
1 | # This file is part of Firejail project | |
2 | # Copyright (C) 2014-2016 Firejail Authors | |
3 | # License GPL v2 | |
4 | ||
5 | set timeout 10 | |
6 | spawn $env(SHELL) | |
7 | match_max 100000 | |
8 | ||
9 | send -- "/usr/bin/strings /usr/bin/firejail > firejail_t1\r" | |
10 | sleep 1 | |
11 | ||
12 | send -- "firejail /usr/bin/strings /usr/bin/firejail > firejail_t2\r" | |
13 | sleep 1 | |
14 | ||
15 | send -- "diff -s firejail_t1 firejail_t2\r" | |
16 | expect { | |
17 | timeout {puts "TESTING ERROR 1\n";exit} | |
18 | "firejail_t1 and firejail_t2 are identical" | |
19 | } | |
20 | ||
21 | send -- "rm firejail_t*\r" | |
22 | sleep 1 | |
23 | ||
24 | ||
25 | puts "\nall done\n" |
0 | #!/bin/bash | |
1 | # This file is part of Firejail project | |
2 | # Copyright (C) 2014-2016 Firejail Authors | |
3 | # License GPL v2 | |
4 | ||
5 | export MALLOC_CHECK_=3 | |
6 | export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) | |
7 | ||
8 | which cpio | |
9 | if [ "$?" -eq 0 ]; | |
10 | then | |
11 | echo "TESTING: cpio" | |
12 | ./cpio.exp | |
13 | else | |
14 | echo "TESTING SKIP: cpio not found" | |
15 | fi | |
16 | ||
17 | #which strings | |
18 | #if [ "$?" -eq 0 ]; | |
19 | #then | |
20 | # echo "TESTING: strings" | |
21 | # ./strings.exp | |
22 | #else | |
23 | # echo "TESTING SKIP: strings not found" | |
24 | #fi | |
25 | ||
26 | which gzip | |
27 | if [ "$?" -eq 0 ]; | |
28 | then | |
29 | echo "TESTING: gzip" | |
30 | ./gzip.exp | |
31 | else | |
32 | echo "TESTING SKIP: gzip not found" | |
33 | fi | |
34 | ||
35 | which xzdec | |
36 | if [ "$?" -eq 0 ]; | |
37 | then | |
38 | echo "TESTING: xzdec" | |
39 | ./xzdec.exp | |
40 | else | |
41 | echo "TESTING SKIP: xzdec not found" | |
42 | fi | |
43 | ||
44 | which xz | |
45 | if [ "$?" -eq 0 ]; | |
46 | then | |
47 | echo "TESTING: xz" | |
48 | ./xz.exp | |
49 | else | |
50 | echo "TESTING SKIP: xz not found" | |
51 | fi | |
52 | ||
53 | which less | |
54 | if [ "$?" -eq 0 ]; | |
55 | then | |
56 | echo "TESTING: less" | |
57 | ./less.exp | |
58 | else | |
59 | echo "TESTING SKIP: less not found" | |
60 | fi | |
61 | ||
62 | which file | |
63 | if [ "$?" -eq 0 ]; | |
64 | then | |
65 | echo "TESTING: file" | |
66 | ./file.exp | |
67 | else | |
68 | echo "TESTING SKIP: file not found" | |
69 | fi | |
70 | ||
71 | which tar | |
72 | if [ "$?" -eq 0 ]; | |
73 | then | |
74 | echo "TESTING: tar" | |
75 | ./tar.exp | |
76 | else | |
77 | echo "TESTING SKIP: tar not found" | |
78 | fi | |
79 |
0 | #!/usr/bin/expect -f | |
1 | # This file is part of Firejail project | |
2 | # Copyright (C) 2014-2016 Firejail Authors | |
3 | # License GPL v2 | |
4 | ||
5 | set timeout 10 | |
6 | spawn $env(SHELL) | |
7 | match_max 100000 | |
8 | ||
9 | send -- "firejail /bin/tar -cjvf firejail_t2 /usr/share/doc/firejail\r" | |
10 | expect { | |
11 | timeout {puts "TESTING ERROR 1.1\n";exit} | |
12 | "Error" {puts "TESTING ERROR 1.2\n";exit} | |
13 | "/usr/share/doc/firejail/README" | |
14 | } | |
15 | after 100 | |
16 | ||
17 | send -- "stat -c '|%s|' firejail_t2; uname -s\r" | |
18 | expect { | |
19 | timeout {puts "TESTING ERROR 2.1\n";exit} | |
20 | "|0|" {puts "TESTING ERROR 2.2\n";exit} | |
21 | "Linux" | |
22 | } | |
23 | sleep 1 | |
24 | ||
25 | send -- "firejail /bin/tar --compare --file=firejail_t2 -C / | wc\r" | |
26 | expect { | |
27 | timeout {puts "TESTING ERROR 3.1\n";exit} | |
28 | "This does not look like a tar archive" {puts "TESTING ERROR 3.2\n"; exit} | |
29 | " 0 0 0" | |
30 | } | |
31 | sleep 1 | |
32 | send -- "/bin/tar --compare --file=firejail_t2 -C / | wc\r" | |
33 | expect { | |
34 | timeout {puts "TESTING ERROR 4.1\n";exit} | |
35 | "This does not look like a tar archive" {puts "TESTING ERROR 4.2\n"; exit} | |
36 | " 0 0 0" | |
37 | } | |
38 | sleep 1 | |
39 | ||
40 | ||
41 | send -- "rm firejail_t*\r" | |
42 | sleep 1 | |
43 | ||
44 | ||
45 | puts "\nall done\n" |
0 | #!/usr/bin/expect -f | |
1 | # This file is part of Firejail project | |
2 | # Copyright (C) 2014-2016 Firejail Authors | |
3 | # License GPL v2 | |
4 | ||
5 | set timeout 10 | |
6 | spawn $env(SHELL) | |
7 | match_max 100000 | |
8 | ||
9 | send -- "/usr/bin/xz -c /usr/bin/firejail > firejail_t1\r" | |
10 | sleep 1 | |
11 | ||
12 | send -- "firejail /usr/bin/xz -c /usr/bin/firejail > firejail_t2\r" | |
13 | sleep 1 | |
14 | ||
15 | send -- "diff -s firejail_t1 firejail_t2\r" | |
16 | expect { | |
17 | timeout {puts "TESTING ERROR 1\n";exit} | |
18 | "firejail_t1 and firejail_t2 are identical" | |
19 | } | |
20 | ||
21 | send -- "rm firejail_t*\r" | |
22 | sleep 1 | |
23 | ||
24 | ||
25 | puts "\nall done\n" |
0 | #!/usr/bin/expect -f | |
1 | # This file is part of Firejail project | |
2 | # Copyright (C) 2014-2016 Firejail Authors | |
3 | # License GPL v2 | |
4 | ||
5 | set timeout 10 | |
6 | spawn $env(SHELL) | |
7 | match_max 100000 | |
8 | ||
9 | send -- "/usr/bin/xz -c /usr/bin/firejail > firejail_t3\r" | |
10 | sleep 1 | |
11 | ||
12 | send -- "/usr/bin/xzdec -c firejail_t3 > firejail_t1\r" | |
13 | sleep 1 | |
14 | ||
15 | send -- "firejail /usr/bin/xzdec -c firejail_t3 > firejail_t2\r" | |
16 | sleep 1 | |
17 | ||
18 | send -- "diff -s firejail_t1 firejail_t2\r" | |
19 | expect { | |
20 | timeout {puts "TESTING ERROR 1\n";exit} | |
21 | "firejail_t1 and firejail_t2 are identical" | |
22 | } | |
23 | ||
24 | send -- "rm firejail_t*\r" | |
25 | sleep 1 | |
26 | ||
27 | ||
28 | puts "\nall done\n" |
27 | 27 | timeout {puts "TESTING ERROR 3\n";exit} |
28 | 28 | "net_raw - disabled" |
29 | 29 | } |
30 | sleep 1 | |
30 | after 100 | |
31 | 31 | puts "\nall done\n" |
19 | 19 | timeout {puts "TESTING ERROR 1\n";exit} |
20 | 20 | "Cpus_allowed_list: 1-2" |
21 | 21 | } |
22 | sleep 1 | |
22 | after 100 | |
23 | 23 | puts "\nall done\n" |
19 | 19 | timeout {puts "TESTING ERROR 1\n";exit} |
20 | 20 | "nameserver 1.2.3.4" |
21 | 21 | } |
22 | sleep 1 | |
22 | after 100 | |
23 | 23 | puts "\nall done\n" |
27 | 27 | timeout {puts "TESTING ERROR 3\n";exit} |
28 | 28 | "blacklist /proc/kmsg" |
29 | 29 | } |
30 | sleep 1 | |
30 | after 100 | |
31 | 31 | puts "\nall done\n" |
19 | 19 | timeout {puts "TESTING ERROR 1\n";exit} |
20 | 20 | "unix,inet,inet6" |
21 | 21 | } |
22 | sleep 1 | |
22 | after 100 | |
23 | 23 | puts "\nall done\n" |
31 | 31 | timeout {puts "TESTING ERROR 4\n";exit} |
32 | 32 | "RETURN_ALLOW" |
33 | 33 | } |
34 | sleep 1 | |
34 | after 100 | |
35 | 35 | puts "\nall done\n" |
39 | 39 | timeout {puts "TESTING ERROR 5\n";exit} |
40 | 40 | "5" |
41 | 41 | } |
42 | sleep 1 | |
42 | after 100 | |
43 | 43 | |
44 | 44 | puts "\nalldone\n" |
59 | 59 | timeout {puts "TESTING ERROR 10\n";exit} |
60 | 60 | "5" |
61 | 61 | } |
62 | sleep 1 | |
62 | after 100 | |
63 | 63 | |
64 | 64 | puts "\nalldone\n" |