diff options
author | netblue30 <netblue30@yahoo.com> | 2015-08-08 19:12:30 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2015-08-08 19:12:30 -0400 |
commit | 1379851360349d6617ad32944a25ee5e2bb74fc2 (patch) | |
tree | f69b48e90708bfa3c2723d5a27ed3e024c827b43 | |
parent | delete files (diff) | |
download | firejail-137985136.tar.gz firejail-137985136.tar.zst firejail-137985136.zip |
Baseline firejail 0.9.28
246 files changed, 33999 insertions, 0 deletions
diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..b6e1c33e0 --- /dev/null +++ b/COPYING | |||
@@ -0,0 +1,280 @@ | |||
1 | GNU GENERAL PUBLIC LICENSE | ||
2 | Version 2, June 1991 | ||
3 | |||
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. | ||
5 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
6 | Everyone is permitted to copy and distribute verbatim copies | ||
7 | of this license document, but changing it is not allowed. | ||
8 | |||
9 | Preamble | ||
10 | |||
11 | The licenses for most software are designed to take away your | ||
12 | freedom to share and change it. By contrast, the GNU General Public | ||
13 | License is intended to guarantee your freedom to share and change free | ||
14 | software--to make sure the software is free for all its users. This | ||
15 | General Public License applies to most of the Free Software | ||
16 | Foundation's software and to any other program whose authors commit to | ||
17 | using it. (Some other Free Software Foundation software is covered by | ||
18 | the GNU Library General Public License instead.) You can apply it to | ||
19 | your programs, too. | ||
20 | |||
21 | When we speak of free software, we are referring to freedom, not | ||
22 | price. Our General Public Licenses are designed to make sure that you | ||
23 | have the freedom to distribute copies of free software (and charge for | ||
24 | this service if you wish), that you receive source code or can get it | ||
25 | if you want it, that you can change the software or use pieces of it | ||
26 | in new free programs; and that you know you can do these things. | ||
27 | |||
28 | To protect your rights, we need to make restrictions that forbid | ||
29 | anyone to deny you these rights or to ask you to surrender the rights. | ||
30 | These restrictions translate to certain responsibilities for you if you | ||
31 | distribute copies of the software, or if you modify it. | ||
32 | |||
33 | For example, if you distribute copies of such a program, whether | ||
34 | gratis or for a fee, you must give the recipients all the rights that | ||
35 | you have. You must make sure that they, too, receive or can get the | ||
36 | source code. And you must show them these terms so they know their | ||
37 | rights. | ||
38 | |||
39 | We protect your rights with two steps: (1) copyright the software, and | ||
40 | (2) offer you this license which gives you legal permission to copy, | ||
41 | distribute and/or modify the software. | ||
42 | |||
43 | Also, for each author's protection and ours, we want to make certain | ||
44 | that everyone understands that there is no warranty for this free | ||
45 | software. If the software is modified by someone else and passed on, we | ||
46 | want its recipients to know that what they have is not the original, so | ||
47 | that any problems introduced by others will not reflect on the original | ||
48 | authors' reputations. | ||
49 | |||
50 | Finally, any free program is threatened constantly by software | ||
51 | patents. We wish to avoid the danger that redistributors of a free | ||
52 | program will individually obtain patent licenses, in effect making the | ||
53 | program proprietary. To prevent this, we have made it clear that any | ||
54 | patent must be licensed for everyone's free use or not licensed at all. | ||
55 | |||
56 | The precise terms and conditions for copying, distribution and | ||
57 | modification follow. | ||
58 | |||
59 | GNU GENERAL PUBLIC LICENSE | ||
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | ||
61 | |||
62 | 0. This License applies to any program or other work which contains | ||
63 | a notice placed by the copyright holder saying it may be distributed | ||
64 | under the terms of this General Public License. The "Program", below, | ||
65 | refers to any such program or work, and a "work based on the Program" | ||
66 | means either the Program or any derivative work under copyright law: | ||
67 | that is to say, a work containing the Program or a portion of it, | ||
68 | either verbatim or with modifications and/or translated into another | ||
69 | language. (Hereinafter, translation is included without limitation in | ||
70 | the term "modification".) Each licensee is addressed as "you". | ||
71 | |||
72 | Activities other than copying, distribution and modification are not | ||
73 | covered by this License; they are outside its scope. The act of | ||
74 | running the Program is not restricted, and the output from the Program | ||
75 | is covered only if its contents constitute a work based on the | ||
76 | Program (independent of having been made by running the Program). | ||
77 | Whether that is true depends on what the Program does. | ||
78 | |||
79 | 1. You may copy and distribute verbatim copies of the Program's | ||
80 | source code as you receive it, in any medium, provided that you | ||
81 | conspicuously and appropriately publish on each copy an appropriate | ||
82 | copyright notice and disclaimer of warranty; keep intact all the | ||
83 | notices that refer to this License and to the absence of any warranty; | ||
84 | and give any other recipients of the Program a copy of this License | ||
85 | along with the Program. | ||
86 | |||
87 | You may charge a fee for the physical act of transferring a copy, and | ||
88 | you may at your option offer warranty protection in exchange for a fee. | ||
89 | |||
90 | 2. You may modify your copy or copies of the Program or any portion | ||
91 | of it, thus forming a work based on the Program, and copy and | ||
92 | distribute such modifications or work under the terms of Section 1 | ||
93 | above, provided that you also meet all of these conditions: | ||
94 | |||
95 | a) You must cause the modified files to carry prominent notices | ||
96 | stating that you changed the files and the date of any change. | ||
97 | |||
98 | b) You must cause any work that you distribute or publish, that in | ||
99 | whole or in part contains or is derived from the Program or any | ||
100 | part thereof, to be licensed as a whole at no charge to all third | ||
101 | parties under the terms of this License. | ||
102 | |||
103 | c) If the modified program normally reads commands interactively | ||
104 | when run, you must cause it, when started running for such | ||
105 | interactive use in the most ordinary way, to print or display an | ||
106 | announcement including an appropriate copyright notice and a | ||
107 | notice that there is no warranty (or else, saying that you provide | ||
108 | a warranty) and that users may redistribute the program under | ||
109 | these conditions, and telling the user how to view a copy of this | ||
110 | License. (Exception: if the Program itself is interactive but | ||
111 | does not normally print such an announcement, your work based on | ||
112 | the Program is not required to print an announcement.) | ||
113 | |||
114 | These requirements apply to the modified work as a whole. If | ||
115 | identifiable sections of that work are not derived from the Program, | ||
116 | and can be reasonably considered independent and separate works in | ||
117 | themselves, then this License, and its terms, do not apply to those | ||
118 | sections when you distribute them as separate works. But when you | ||
119 | distribute the same sections as part of a whole which is a work based | ||
120 | on the Program, the distribution of the whole must be on the terms of | ||
121 | this License, whose permissions for other licensees extend to the | ||
122 | entire whole, and thus to each and every part regardless of who wrote it. | ||
123 | |||
124 | Thus, it is not the intent of this section to claim rights or contest | ||
125 | your rights to work written entirely by you; rather, the intent is to | ||
126 | exercise the right to control the distribution of derivative or | ||
127 | collective works based on the Program. | ||
128 | |||
129 | In addition, mere aggregation of another work not based on the Program | ||
130 | with the Program (or with a work based on the Program) on a volume of | ||
131 | a storage or distribution medium does not bring the other work under | ||
132 | the scope of this License. | ||
133 | |||
134 | 3. You may copy and distribute the Program (or a work based on it, | ||
135 | under Section 2) in object code or executable form under the terms of | ||
136 | Sections 1 and 2 above provided that you also do one of the following: | ||
137 | |||
138 | a) Accompany it with the complete corresponding machine-readable | ||
139 | source code, which must be distributed under the terms of Sections | ||
140 | 1 and 2 above on a medium customarily used for software interchange; or, | ||
141 | |||
142 | b) Accompany it with a written offer, valid for at least three | ||
143 | years, to give any third party, for a charge no more than your | ||
144 | cost of physically performing source distribution, a complete | ||
145 | machine-readable copy of the corresponding source code, to be | ||
146 | distributed under the terms of Sections 1 and 2 above on a medium | ||
147 | customarily used for software interchange; or, | ||
148 | |||
149 | c) Accompany it with the information you received as to the offer | ||
150 | to distribute corresponding source code. (This alternative is | ||
151 | allowed only for noncommercial distribution and only if you | ||
152 | received the program in object code or executable form with such | ||
153 | an offer, in accord with Subsection b above.) | ||
154 | |||
155 | The source code for a work means the preferred form of the work for | ||
156 | making modifications to it. For an executable work, complete source | ||
157 | code means all the source code for all modules it contains, plus any | ||
158 | associated interface definition files, plus the scripts used to | ||
159 | control compilation and installation of the executable. However, as a | ||
160 | special exception, the source code distributed need not include | ||
161 | anything that is normally distributed (in either source or binary | ||
162 | form) with the major components (compiler, kernel, and so on) of the | ||
163 | operating system on which the executable runs, unless that component | ||
164 | itself accompanies the executable. | ||
165 | |||
166 | If distribution of executable or object code is made by offering | ||
167 | access to copy from a designated place, then offering equivalent | ||
168 | access to copy the source code from the same place counts as | ||
169 | distribution of the source code, even though third parties are not | ||
170 | compelled to copy the source along with the object code. | ||
171 | |||
172 | 4. You may not copy, modify, sublicense, or distribute the Program | ||
173 | except as expressly provided under this License. Any attempt | ||
174 | otherwise to copy, modify, sublicense or distribute the Program is | ||
175 | void, and will automatically terminate your rights under this License. | ||
176 | However, parties who have received copies, or rights, from you under | ||
177 | this License will not have their licenses terminated so long as such | ||
178 | parties remain in full compliance. | ||
179 | |||
180 | 5. You are not required to accept this License, since you have not | ||
181 | signed it. However, nothing else grants you permission to modify or | ||
182 | distribute the Program or its derivative works. These actions are | ||
183 | prohibited by law if you do not accept this License. Therefore, by | ||
184 | modifying or distributing the Program (or any work based on the | ||
185 | Program), you indicate your acceptance of this License to do so, and | ||
186 | all its terms and conditions for copying, distributing or modifying | ||
187 | the Program or works based on it. | ||
188 | |||
189 | 6. Each time you redistribute the Program (or any work based on the | ||
190 | Program), the recipient automatically receives a license from the | ||
191 | original licensor to copy, distribute or modify the Program subject to | ||
192 | these terms and conditions. You may not impose any further | ||
193 | restrictions on the recipients' exercise of the rights granted herein. | ||
194 | You are not responsible for enforcing compliance by third parties to | ||
195 | this License. | ||
196 | |||
197 | 7. If, as a consequence of a court judgment or allegation of patent | ||
198 | infringement or for any other reason (not limited to patent issues), | ||
199 | conditions are imposed on you (whether by court order, agreement or | ||
200 | otherwise) that contradict the conditions of this License, they do not | ||
201 | excuse you from the conditions of this License. If you cannot | ||
202 | distribute so as to satisfy simultaneously your obligations under this | ||
203 | License and any other pertinent obligations, then as a consequence you | ||
204 | may not distribute the Program at all. For example, if a patent | ||
205 | license would not permit royalty-free redistribution of the Program by | ||
206 | all those who receive copies directly or indirectly through you, then | ||
207 | the only way you could satisfy both it and this License would be to | ||
208 | refrain entirely from distribution of the Program. | ||
209 | |||
210 | If any portion of this section is held invalid or unenforceable under | ||
211 | any particular circumstance, the balance of the section is intended to | ||
212 | apply and the section as a whole is intended to apply in other | ||
213 | circumstances. | ||
214 | |||
215 | It is not the purpose of this section to induce you to infringe any | ||
216 | patents or other property right claims or to contest validity of any | ||
217 | such claims; this section has the sole purpose of protecting the | ||
218 | integrity of the free software distribution system, which is | ||
219 | implemented by public license practices. Many people have made | ||
220 | generous contributions to the wide range of software distributed | ||
221 | through that system in reliance on consistent application of that | ||
222 | system; it is up to the author/donor to decide if he or she is willing | ||
223 | to distribute software through any other system and a licensee cannot | ||
224 | impose that choice. | ||
225 | |||
226 | This section is intended to make thoroughly clear what is believed to | ||
227 | be a consequence of the rest of this License. | ||
228 | |||
229 | 8. If the distribution and/or use of the Program is restricted in | ||
230 | certain countries either by patents or by copyrighted interfaces, the | ||
231 | original copyright holder who places the Program under this License | ||
232 | may add an explicit geographical distribution limitation excluding | ||
233 | those countries, so that distribution is permitted only in or among | ||
234 | countries not thus excluded. In such case, this License incorporates | ||
235 | the limitation as if written in the body of this License. | ||
236 | |||
237 | 9. The Free Software Foundation may publish revised and/or new versions | ||
238 | of the General Public License from time to time. Such new versions will | ||
239 | be similar in spirit to the present version, but may differ in detail to | ||
240 | address new problems or concerns. | ||
241 | |||
242 | Each version is given a distinguishing version number. If the Program | ||
243 | specifies a version number of this License which applies to it and "any | ||
244 | later version", you have the option of following the terms and conditions | ||
245 | either of that version or of any later version published by the Free | ||
246 | Software Foundation. If the Program does not specify a version number of | ||
247 | this License, you may choose any version ever published by the Free Software | ||
248 | Foundation. | ||
249 | |||
250 | 10. If you wish to incorporate parts of the Program into other free | ||
251 | programs whose distribution conditions are different, write to the author | ||
252 | to ask for permission. For software which is copyrighted by the Free | ||
253 | Software Foundation, write to the Free Software Foundation; we sometimes | ||
254 | make exceptions for this. Our decision will be guided by the two goals | ||
255 | of preserving the free status of all derivatives of our free software and | ||
256 | of promoting the sharing and reuse of software generally. | ||
257 | |||
258 | NO WARRANTY | ||
259 | |||
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | ||
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | ||
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | ||
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | ||
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | ||
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | ||
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | ||
268 | REPAIR OR CORRECTION. | ||
269 | |||
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | ||
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | ||
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | ||
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | ||
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | ||
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | ||
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | ||
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | ||
278 | POSSIBILITY OF SUCH DAMAGES. | ||
279 | |||
280 | END OF TERMS AND CONDITIONS | ||
diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 000000000..6b9739524 --- /dev/null +++ b/Makefile.in | |||
@@ -0,0 +1,156 @@ | |||
1 | all: apps firejail.1 firemon.1 firejail-profile.5 firejail-login.5 | ||
2 | MYLIBS = src/lib | ||
3 | APPS = src/firejail src/firemon src/libtrace src/ftee | ||
4 | |||
5 | datarootdir=@datarootdir@ | ||
6 | PREFIX=@prefix@ | ||
7 | prefix=@prefix@ | ||
8 | VERSION=@PACKAGE_VERSION@ | ||
9 | NAME=@PACKAGE_NAME@ | ||
10 | PACKAGE_TARNAME=@PACKAGE_TARNAME@ | ||
11 | DOCDIR=@docdir@ | ||
12 | |||
13 | |||
14 | .PHONY: mylibs $(MYLIBS) | ||
15 | mylibs: $(MYLIBS) | ||
16 | $(MYLIBS): | ||
17 | $(MAKE) -C $@ | ||
18 | |||
19 | .PHONY: apps $(APPS) | ||
20 | apps: $(APPS) | ||
21 | $(APPS): $(MYLIBS) | ||
22 | $(MAKE) -C $@ | ||
23 | |||
24 | firemon.1: src/man/firemon.txt | ||
25 | ./mkman.sh $(VERSION) src/man/firemon.txt firemon.1 | ||
26 | firejail.1: src/man/firejail.txt | ||
27 | ./mkman.sh $(VERSION) src/man/firejail.txt firejail.1 | ||
28 | firejail-profile.5: src/man/firejail-profile.txt | ||
29 | ./mkman.sh $(VERSION) src/man/firejail-profile.txt firejail-profile.5 | ||
30 | firejail-login.5: src/man/firejail-login.txt | ||
31 | ./mkman.sh $(VERSION) src/man/firejail-login.txt firejail-login.5 | ||
32 | |||
33 | clean:; | ||
34 | for dir in $(APPS); do \ | ||
35 | $(MAKE) -C $$dir clean; \ | ||
36 | done | ||
37 | for dir in $(MYLIBS); do \ | ||
38 | $(MAKE) -C $$dir clean; \ | ||
39 | done | ||
40 | rm -f firejail.1 firejail.1.gz firemon.1 firemon.1.gz firejail-profile.5 firejail-profile.5.gz firejail-login.5 firejail-login.5.gz | ||
41 | |||
42 | distclean: clean | ||
43 | for dir in $(APPS); do \ | ||
44 | $(MAKE) -C $$dir distclean; \ | ||
45 | done | ||
46 | for dir in $(MYLIBS); do \ | ||
47 | $(MAKE) -C $$dir distclean; \ | ||
48 | done | ||
49 | rm -fr Makefile autom4te.cache config.log config.status config.h | ||
50 | |||
51 | install: all | ||
52 | # firejail executable | ||
53 | strip src/firejail/firejail | ||
54 | mkdir -p $(DESTDIR)/$(PREFIX)/bin | ||
55 | install -c -m 0755 src/firejail/firejail $(DESTDIR)/$(PREFIX)/bin/. | ||
56 | chmod u+s $(DESTDIR)/$(PREFIX)/bin/firejail | ||
57 | # firemon executable | ||
58 | strip src/firemon/firemon | ||
59 | install -c -m 0755 src/firemon/firemon $(DESTDIR)/$(PREFIX)/bin/. | ||
60 | # libraries and plugins | ||
61 | strip src/libtrace/libtrace.so | ||
62 | mkdir -p $(DESTDIR)/$(PREFIX)/lib/firejail | ||
63 | install -c -m 0644 src/libtrace/libtrace.so $(DESTDIR)/$(PREFIX)/lib/firejail/. | ||
64 | strip src/ftee/ftee | ||
65 | install -c -m 0755 src/ftee/ftee $(DESTDIR)/$(PREFIX)/lib/firejail/. | ||
66 | install -c -m 0755 src/fshaper/fshaper.sh $(DESTDIR)/$(PREFIX)/lib/firejail/. | ||
67 | # documents | ||
68 | mkdir -p $(DESTDIR)/$(DOCDIR) | ||
69 | install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/. | ||
70 | install -c -m 0644 README $(DESTDIR)/$(DOCDIR)/. | ||
71 | install -c -m 0644 RELNOTES $(DESTDIR)/$(DOCDIR)/. | ||
72 | # etc files | ||
73 | mkdir -p $(DESTDIR)/etc/firejail | ||
74 | install -c -m 0644 etc/audacious.profile $(DESTDIR)/etc/firejail/. | ||
75 | install -c -m 0644 etc/clementine.profile $(DESTDIR)/etc/firejail/. | ||
76 | install -c -m 0644 etc/gnome-mplayer.profile $(DESTDIR)/etc/firejail/. | ||
77 | install -c -m 0644 etc/rhythmbox.profile $(DESTDIR)/etc/firejail/. | ||
78 | install -c -m 0644 etc/totem.profile $(DESTDIR)/etc/firejail/. | ||
79 | install -c -m 0644 etc/firefox.profile $(DESTDIR)/etc/firejail/. | ||
80 | install -c -m 0644 etc/icedove.profile $(DESTDIR)/etc/firejail/. | ||
81 | install -c -m 0644 etc/iceweasel.profile $(DESTDIR)/etc/firejail/. | ||
82 | install -c -m 0644 etc/midori.profile $(DESTDIR)/etc/firejail/. | ||
83 | install -c -m 0644 etc/evince.profile $(DESTDIR)/etc/firejail/. | ||
84 | install -c -m 0644 etc/chromium-browser.profile $(DESTDIR)/etc/firejail/. | ||
85 | install -c -m 0644 etc/chromium.profile $(DESTDIR)/etc/firejail/. | ||
86 | install -c -m 0644 etc/disable-mgmt.inc $(DESTDIR)/etc/firejail/. | ||
87 | install -c -m 0644 etc/disable-secret.inc $(DESTDIR)/etc/firejail/. | ||
88 | install -c -m 0644 etc/disable-common.inc $(DESTDIR)/etc/firejail/. | ||
89 | install -c -m 0644 etc/dropbox.profile $(DESTDIR)/etc/firejail/. | ||
90 | install -c -m 0644 etc/opera.profile $(DESTDIR)/etc/firejail/. | ||
91 | install -c -m 0644 etc/thunderbird.profile $(DESTDIR)/etc/firejail/. | ||
92 | install -c -m 0644 etc/transmission-gtk.profile $(DESTDIR)/etc/firejail/. | ||
93 | install -c -m 0644 etc/transmission-qt.profile $(DESTDIR)/etc/firejail/. | ||
94 | install -c -m 0644 etc/vlc.profile $(DESTDIR)/etc/firejail/. | ||
95 | install -c -m 0644 etc/deluge.profile $(DESTDIR)/etc/firejail/. | ||
96 | install -c -m 0644 etc/qbittorrent.profile $(DESTDIR)/etc/firejail/. | ||
97 | install -c -m 0644 etc/generic.profile $(DESTDIR)/etc/firejail/. | ||
98 | install -c -m 0644 etc/pidgin.profile $(DESTDIR)/etc/firejail/. | ||
99 | install -c -m 0644 etc/xchat.profile $(DESTDIR)/etc/firejail/. | ||
100 | install -c -m 0644 etc/empathy.profile $(DESTDIR)/etc/firejail/. | ||
101 | install -c -m 0644 etc/server.profile $(DESTDIR)/etc/firejail/. | ||
102 | install -c -m 0644 etc/icecat.profile $(DESTDIR)/etc/firejail/. | ||
103 | install -c -m 0644 etc/quassel.profile $(DESTDIR)/etc/firejail/. | ||
104 | install -c -m 0644 etc/deadbeef.profile $(DESTDIR)/etc/firejail/. | ||
105 | install -c -m 0644 etc/filezilla.profile $(DESTDIR)/etc/firejail/. | ||
106 | bash -c "if [ ! -f /etc/firejail/login.users ]; then install -c -m 0644 etc/login.users $(DESTDIR)/etc/firejail/.; fi;" | ||
107 | # man pages | ||
108 | rm -f firejail.1.gz | ||
109 | gzip -9n firejail.1 | ||
110 | rm -f firemon.1.gz | ||
111 | gzip -9n firemon.1 | ||
112 | rm -f firejail-profile.5.gz | ||
113 | gzip -9n firejail-profile.5 | ||
114 | rm -f firejail-login.5.gz | ||
115 | gzip -9n firejail-login.5 | ||
116 | mkdir -p $(DESTDIR)/$(PREFIX)/share/man/man1 | ||
117 | install -c -m 0644 firejail.1.gz $(DESTDIR)/$(PREFIX)/share/man/man1/. | ||
118 | install -c -m 0644 firemon.1.gz $(DESTDIR)/$(PREFIX)/share/man/man1/. | ||
119 | mkdir -p $(DESTDIR)/$(PREFIX)/share/man/man5 | ||
120 | install -c -m 0644 firejail-profile.5.gz $(DESTDIR)/$(PREFIX)/share/man/man5/. | ||
121 | install -c -m 0644 firejail-login.5.gz $(DESTDIR)/$(PREFIX)/share/man/man5/. | ||
122 | rm -f firejail.1.gz firemon.1.gz firejail-profile.5.gz firejail-login.5.gz | ||
123 | # bash completion | ||
124 | mkdir -p $(DESTDIR)/$(PREFIX)/share/bash-completion/completions | ||
125 | install -c -m 0644 etc/firejail.bash_completion $(DESTDIR)/$(PREFIX)/share/bash-completion/completions/firejail | ||
126 | install -c -m 0644 etc/firemon.bash_completion $(DESTDIR)/$(PREFIX)/share/bash-completion/completions/firemon | ||
127 | |||
128 | uninstall:; | ||
129 | rm -f $(DESTDIR)/$(PREFIX)/bin/firejail | ||
130 | rm -f $(DESTDIR)/$(PREFIX)/bin/firemon | ||
131 | rm -fr $(DESTDIR)/$(PREFIX)/lib/firejail | ||
132 | rm -fr $(DESTDIR)/$(PREFIX)/share/doc/firejail | ||
133 | rm -f $(DESTDIR)/$(PREFIX)/share/man/man1/firejail.1* | ||
134 | rm -f $(DESTDIR)/$(PREFIX)/share/man/man1/firemon.1* | ||
135 | rm -f $(DESTDIR)/$(PREFIX)/share/man/man5/firejail-profile.5* | ||
136 | rm -f $(DESTDIR)/$(PREFIX)/share/man/man5/firejail-login.5* | ||
137 | rm -f $(DESTDIR)/$(PREFIX)/share/bash-completion/completions/firejail | ||
138 | rm -f $(DESTDIR)/$(PREFIX)/share/bash-completion/completions/firemon | ||
139 | |||
140 | dist: | ||
141 | make distclean | ||
142 | rm -fr $(NAME)-$(VERSION) $(NAME)-$(VERSION).tar.bz2 | ||
143 | mkdir $(NAME)-$(VERSION) | ||
144 | cd $(NAME)-$(VERSION); cp -a ../src .; cp -a ../etc .; cp -a ../platform .; cp -a ../test .; rm -f src/tools/rvtest; rm -fr src/art; cd .. | ||
145 | cd $(NAME)-$(VERSION); cp -a ../configure .; cp -a ../configure.ac .; cp -a ../Makefile.in .; cp -a ../install.sh .; cp -a ../mkman.sh .; cp -a ../mkdeb.sh .;cd .. | ||
146 | cd $(NAME)-$(VERSION); cp -a ../COPYING .; cp -a ../README .; cp -a ../RELNOTES .; cd .. | ||
147 | cd $(NAME)-$(VERSION); rm -fr `find . -name .svn`; rm -fr $(NAME)-$(VERSION); cd .. | ||
148 | tar -cjvf $(NAME)-$(VERSION).tar.bz2 $(NAME)-$(VERSION) | ||
149 | rm -fr $(NAME)-$(VERSION) | ||
150 | |||
151 | deb: dist | ||
152 | ./mkdeb.sh $(NAME) $(VERSION) | ||
153 | |||
154 | extras: all | ||
155 | $(MAKE) -C extras/firetools | ||
156 | \ No newline at end of file | ||
@@ -0,0 +1,28 @@ | |||
1 | Firejail is a SUID sandbox program that reduces the risk of security | ||
2 | breaches by restricting the running environment of untrusted applications | ||
3 | using Linux namespaces and seccomp-bpf. It includes sandbox profiles for | ||
4 | Iceweasel/Mozilla Firefox, Chromium, Midori, Opera, Evince, Transmission, | ||
5 | VLC, Audoacious, Clementine, Rhythmbox, Totem, Deluge and qBittorrent. | ||
6 | |||
7 | Firejail also expands the restricted shell facility found in bash by adding | ||
8 | Linux namespace support. It supports sandboxing specific users upon login. | ||
9 | |||
10 | Download: http://sourceforge.net/projects/firejail/files/ | ||
11 | Build and install: ./configure && make && sudo make install | ||
12 | Documentation and support: http://firejail.sourceforge.net | ||
13 | License: GPL v2 | ||
14 | |||
15 | Firejail Authors: | ||
16 | |||
17 | netblue30 (netblue30@yahoo.com) | ||
18 | Patrick Toomey (http://sourceforge.net/u/ptoomey/profile/) | ||
19 | - user namespace implementation, ticket 10 | ||
20 | Reiner Herrmann - a number of build patches, man page fixes (tickets 11, 12, 13, 19) | ||
21 | sshirokov (http://sourceforge.net/u/yshirokov/profile/) | ||
22 | - Patch to output "Reading profile" to stderr instead of stdout (ticket 15) | ||
23 | Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> | ||
24 | - src/lib/libnetlink.c extracted from iproute2 software package | ||
25 | G4JC (http://sourceforge.net/u/gaming4jc/profile/) | ||
26 | - ARM support (ticket 17) | ||
27 | |||
28 | Copyright (C) 2014, 2015 Firejail Authors | ||
diff --git a/RELNOTES b/RELNOTES new file mode 100644 index 000000000..379c8f1c3 --- /dev/null +++ b/RELNOTES | |||
@@ -0,0 +1,215 @@ | |||
1 | firejail (0.9.28) baseline; urgency=low | ||
2 | * network scanning, --scan option | ||
3 | * interface MAC address support, --mac option | ||
4 | * IP address range, --iprange option | ||
5 | * traffic shaping, --bandwidth option | ||
6 | * reworked printing of network status at startup | ||
7 | * man pages rework | ||
8 | * added firejail-login man page | ||
9 | * added GNU Icecat, FileZilla, Pidgin, XChat, Empathy, DeaDBeeF default | ||
10 | profiles | ||
11 | * added an /etc/firejail/disable-common.inc file to hold common directory | ||
12 | blacklists | ||
13 | * blacklist Opera and Chrome/Chromium config directories in profile files | ||
14 | * support noroot option for profile files | ||
15 | * enabled noroot in default profile files | ||
16 | * bugfixes | ||
17 | -- netblue30 <netblue30@yahoo.com> Sat, 1 Aug 2015 08:00:00 -0500 | ||
18 | |||
19 | firejail (0.9.26) baseline; urgency=low | ||
20 | * private dev directory | ||
21 | * private.keep option for whitelisting home files in a new private directory | ||
22 | * user namespaces support, noroot option | ||
23 | * added Deluge and qBittorent profiles | ||
24 | * bugfixes | ||
25 | -- netblue30 <netblue30@yahoo.com> Thu, 30 Apr 2015 08:00:00 -0500 | ||
26 | |||
27 | |||
28 | firejail (0.9.24) baseline; urgency=low | ||
29 | * whitelist and blacklist seccomp filters | ||
30 | * doubledash option | ||
31 | * --shell=none support | ||
32 | * netfilter file support in profile files | ||
33 | * dns server support in profile files | ||
34 | * added --dns.print option | ||
35 | * added default profiles for Audacious, Clementine, Gnome-MPlayer, Rhythmbox and Totem. | ||
36 | * added --caps.drop=all in default profiles | ||
37 | * new syscalls in default seccomp filter: sysfs, sysctl, adjtimex, kcmp | ||
38 | * clock_adjtime, lookup_dcookie, perf_event_open, fanotify_init | ||
39 | * Bugfix: using /proc/sys/kernel/pid_max for the max number of pids | ||
40 | * two build patches from Reiner Herman (tickets 11, 12) | ||
41 | * man page patch from Reiner Herman (ticket 13) | ||
42 | * output patch (ticket 15) from sshirokov | ||
43 | |||
44 | -- netblue30 <netblue30@yahoo.com> Sun, 5 Apr 2015 08:00:00 -0500 | ||
45 | |||
46 | firejail (0.9.22) baseline; urgency=low | ||
47 | * Replaced --noip option with --ip=none | ||
48 | * Container stdout logging and log rotation | ||
49 | * Added process_vm_readv, process_vm_writev and mknod to | ||
50 | * default seccomp blacklist | ||
51 | * Added CAP_MKNOD to default caps blacklist | ||
52 | * Blacklist and whitelist custom Linux capabilities filters | ||
53 | * macvlan device driver support for --net option | ||
54 | * DNS server support, --dns option | ||
55 | * Netfilter support | ||
56 | * Monitor network statistics, --netstats option | ||
57 | * Added profile for Mozilla Thunderbird/Icedove | ||
58 | * - --overlay support for Linux kernels 3.18+ | ||
59 | * Bugfix: preserve .Xauthority file in private mode (test with ssh -X) | ||
60 | * Bugfix: check uid/gid for cgroup | ||
61 | |||
62 | -- netblue30 <netblue30@yahoo.com> Mon, 9 Mar 2015 09:00:00 -0500 | ||
63 | |||
64 | firejail (0.9.20) baseline; urgency=low | ||
65 | * utmp, btmp and wtmp enhancements | ||
66 | * create empty /var/log/wtmp and /var/log/btmp files in sandbox | ||
67 | * generate a new /var/run/utmp file in sandbox | ||
68 | * CPU affinity, --cpu option | ||
69 | * Linux control groups support, --cgroup option | ||
70 | * Opera web browser support | ||
71 | * VLC support | ||
72 | * Added "empty" attribute to seccomp command to remove the default | ||
73 | * syscall list form seccomp blacklist | ||
74 | * Added --nogroups option to disable supplementary groups for regular | ||
75 | * users. root user always runs without supplementary groups. | ||
76 | * firemon enhancements | ||
77 | * display the command that started the sandbox | ||
78 | * added --caps option to display capabilities for all sandboxes | ||
79 | * added --cgroup option to display the control groups for all sandboxes | ||
80 | * added --cpu option to display CPU affinity for all sandboxes | ||
81 | * added --seccomp option to display seccomp setting for all sandboxes | ||
82 | * New compile time options: --disable-chroot, --disable-bind | ||
83 | * bugfixes | ||
84 | |||
85 | -- netblue30 <netblue30@yahoo.com> Mon, 02 Feb 2015 08:00:00 -0500 | ||
86 | |||
87 | firejail (0.9.18) baseline; urgency=low | ||
88 | * Support for tracing system, setuid, setgid, setfsuid, setfsgid syscalls | ||
89 | * Support for tracing setreuid, setregid, setresuid, setresguid syscalls | ||
90 | * Added profiles for transmission-gtk and transmission-qt | ||
91 | * bugfixes | ||
92 | |||
93 | -- netblue30 <netblue30@yahoo.com> Fri, 25 Dec 2014 10:00:00 -0500 | ||
94 | |||
95 | firejail (0.9.16) baseline; urgency=low | ||
96 | * Configurable private home directory | ||
97 | * Configurable default user shell | ||
98 | * Software configuration support for --docdir and DESTDIR | ||
99 | * Profile file support for include, caps, seccomp and private keywords | ||
100 | * Dropbox profile file | ||
101 | * Linux capabilities and seccomp filters enabled by default for Firefox, | ||
102 | Midori, Evince and Dropbox | ||
103 | * bugfixes | ||
104 | |||
105 | -- netblue30 <netblue30@yahoo.com> Tue, 4 Nov 2014 10:00:00 -0500 | ||
106 | |||
107 | firejail (0.9.14) baseline; urgency=low | ||
108 | * Linux capabilities and seccomp filters are automatically enabled in | ||
109 | chroot mode (--chroot option) if the sandbox is started as regular user | ||
110 | * Added support for user defined seccomp blacklists | ||
111 | * Added syscall trace support | ||
112 | * Added --tmpfs option | ||
113 | * Added --balcklist option | ||
114 | * Added --read-only option | ||
115 | * Added --bind option | ||
116 | * Logging enhancements | ||
117 | * --overlay option was reactivated | ||
118 | * Added firemon support to print the ARP table for each sandbox | ||
119 | * Added firemon support to print the route table for each sandbox | ||
120 | * Added firemon support to print interface information for each sandbox | ||
121 | * bugfixes | ||
122 | |||
123 | -- netblue30 <netblue30@yahoo.com> Tue, 15 Oct 2014 10:00:00 -0500 | ||
124 | |||
125 | firejail (0.9.12.2) baseline; urgency=low | ||
126 | * Fix for pulseaudio problems | ||
127 | * --overlay option was temporarily disabled in this build | ||
128 | |||
129 | -- netblue30 <netblue30@yahoo.com> Mon, 29 Sept 2014 07:00:00 -0500 | ||
130 | |||
131 | firejail (0.9.12.1) baseline; urgency=low | ||
132 | * Fix for pulseaudio problems | ||
133 | * --overlay option was temporarily disabled in this build | ||
134 | |||
135 | -- netblue30 <netblue30@yahoo.com> Mon, 22 Sept 2014 09:00:00 -0500 | ||
136 | |||
137 | firejail (0.9.12) baseline; urgency=low | ||
138 | * Added capabilities support | ||
139 | * Added support for CentOS 7 | ||
140 | * bugfixes | ||
141 | |||
142 | -- netblue30 <netblue30@yahoo.com> Mon, 15 Sept 2014 10:00:00 -0500 | ||
143 | |||
144 | firejail (0.9.10) baseline; urgency=low | ||
145 | * Disable /proc/kcore, /proc/kallsyms, /dev/port, /boot | ||
146 | * Fixed --top option CPU utilization calculation | ||
147 | * Implemented --tree option in firejail and firemon | ||
148 | * Implemented --join=name option | ||
149 | * Implemented --shutdown option | ||
150 | * Preserve the current working directory if possible | ||
151 | * Cppcheck and clang errors cleanup | ||
152 | * Added a Chromium web browser profile | ||
153 | |||
154 | -- netblue30 <netblue30@yahoo.com> Thu, 28 Aug 2014 07:00:00 -0500 | ||
155 | |||
156 | firejail (0.9.8.1) baseline; urgency=low | ||
157 | * FIxed a number of bugs introduced in 0.9.8 | ||
158 | |||
159 | -- netblue30 <netblue30@yahoo.com> Fri, 25 Jul 2014 07:25:00 -0500 | ||
160 | |||
161 | firejail (0.9.8) baseline; urgency=low | ||
162 | * Implemented nowrap mode for firejail --list command option | ||
163 | * Added --top option in both firejail and firemon | ||
164 | * seccomp filter support | ||
165 | * Added pid support for firemon | ||
166 | * bugfixes | ||
167 | |||
168 | -- netblue30 <netblue30@yahoo.com> Tue, 24 Jul 2014 08:51:00 -0500 | ||
169 | |||
170 | firejail (0.9.6) baseline; urgency=low | ||
171 | |||
172 | * Mounting tmpfs on top of /var/log, required by several server programs | ||
173 | * Server fixes for /var/lib and /var/cache | ||
174 | * Private mode fixes | ||
175 | * csh and zsh default shell support | ||
176 | * Chroot mode fixes | ||
177 | * Added support for lighttpd, isc-dhcp-server, apache2, nginx, snmpd, | ||
178 | |||
179 | -- netblue30 <netblue30@yahoo.com> Sat, 7 Jun 2014 09:00:00 -0500 | ||
180 | |||
181 | firejail (0.9.4) baseline; urgency=low | ||
182 | |||
183 | * Fixed resolv.conf on Ubuntu systems using DHCP | ||
184 | * Fixed resolv.conf on Debian systems using resolvconf package | ||
185 | * Fixed /var/lock directory | ||
186 | * Fixed /var/tmp directory | ||
187 | * Fixed symbolic links in profile files | ||
188 | * Added profiles for evince, midori | ||
189 | |||
190 | -- netblue30 <netblue30@yahoo.com> Sun, 4 May 2014 08:00:00 -0500 | ||
191 | |||
192 | firejail (0.9.2) baseline; urgency=low | ||
193 | |||
194 | * Checking IP address passed with --ip option using ARP; exit if the address | ||
195 | is already present | ||
196 | * Using a lock file during ARP address assignment in order to removed a race | ||
197 | condition. | ||
198 | * Several fixes to --private option; it also mounts a tmpfs filesystem on top | ||
199 | of /tmp | ||
200 | * Added user access check for profile file | ||
201 | * Added --defaultgw option | ||
202 | * Added support of --noip option; it is necessary for DHCP setups | ||
203 | * Added syslog support | ||
204 | * Added support for "tmpfs" and "read-only" profile commands | ||
205 | * Added an expect-based testing framework for the project | ||
206 | * Added bash completion support | ||
207 | * Added support for multiple networks | ||
208 | |||
209 | -- netblue30 <netblue30@yahoo.com> Fri, 25 Apr 2014 08:00:00 -0500 | ||
210 | |||
211 | firejail (0.9) baseline; urgency=low | ||
212 | |||
213 | * First beta version | ||
214 | |||
215 | -- netblue30 <netblue30@yahoo.com> Sat, 12 Apr 2014 09:00:00 -0500 | ||
diff --git a/configure b/configure new file mode 100755 index 000000000..50abe97c2 --- /dev/null +++ b/configure | |||
@@ -0,0 +1,4723 @@ | |||
1 | #! /bin/sh | ||
2 | # Guess values for system-dependent variables and create Makefiles. | ||
3 | # Generated by GNU Autoconf 2.69 for firejail 0.9.28. | ||
4 | # | ||
5 | # Report bugs to <netblue30@yahoo.com>. | ||
6 | # | ||
7 | # | ||
8 | # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. | ||
9 | # | ||
10 | # | ||
11 | # This configure script is free software; the Free Software Foundation | ||
12 | # gives unlimited permission to copy, distribute and modify it. | ||
13 | ## -------------------- ## | ||
14 | ## M4sh Initialization. ## | ||
15 | ## -------------------- ## | ||
16 | |||
17 | # Be more Bourne compatible | ||
18 | DUALCASE=1; export DUALCASE # for MKS sh | ||
19 | if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : | ||
20 | emulate sh | ||
21 | NULLCMD=: | ||
22 | # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which | ||
23 | # is contrary to our usage. Disable this feature. | ||
24 | alias -g '${1+"$@"}'='"$@"' | ||
25 | setopt NO_GLOB_SUBST | ||
26 | else | ||
27 | case `(set -o) 2>/dev/null` in #( | ||
28 | *posix*) : | ||
29 | set -o posix ;; #( | ||
30 | *) : | ||
31 | ;; | ||
32 | esac | ||
33 | fi | ||
34 | |||
35 | |||
36 | as_nl=' | ||
37 | ' | ||
38 | export as_nl | ||
39 | # Printing a long string crashes Solaris 7 /usr/bin/printf. | ||
40 | as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' | ||
41 | as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo | ||
42 | as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo | ||
43 | # Prefer a ksh shell builtin over an external printf program on Solaris, | ||
44 | # but without wasting forks for bash or zsh. | ||
45 | if test -z "$BASH_VERSION$ZSH_VERSION" \ | ||
46 | && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then | ||
47 | as_echo='print -r --' | ||
48 | as_echo_n='print -rn --' | ||
49 | elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then | ||
50 | as_echo='printf %s\n' | ||
51 | as_echo_n='printf %s' | ||
52 | else | ||
53 | if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then | ||
54 | as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' | ||
55 | as_echo_n='/usr/ucb/echo -n' | ||
56 | else | ||
57 | as_echo_body='eval expr "X$1" : "X\\(.*\\)"' | ||
58 | as_echo_n_body='eval | ||
59 | arg=$1; | ||
60 | case $arg in #( | ||
61 | *"$as_nl"*) | ||
62 | expr "X$arg" : "X\\(.*\\)$as_nl"; | ||
63 | arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; | ||
64 | esac; | ||
65 | expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" | ||
66 | ' | ||
67 | export as_echo_n_body | ||
68 | as_echo_n='sh -c $as_echo_n_body as_echo' | ||
69 | fi | ||
70 | export as_echo_body | ||
71 | as_echo='sh -c $as_echo_body as_echo' | ||
72 | fi | ||
73 | |||
74 | # The user is always right. | ||
75 | if test "${PATH_SEPARATOR+set}" != set; then | ||
76 | PATH_SEPARATOR=: | ||
77 | (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { | ||
78 | (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || | ||
79 | PATH_SEPARATOR=';' | ||
80 | } | ||
81 | fi | ||
82 | |||
83 | |||
84 | # IFS | ||
85 | # We need space, tab and new line, in precisely that order. Quoting is | ||
86 | # there to prevent editors from complaining about space-tab. | ||
87 | # (If _AS_PATH_WALK were called with IFS unset, it would disable word | ||
88 | # splitting by setting IFS to empty value.) | ||
89 | IFS=" "" $as_nl" | ||
90 | |||
91 | # Find who we are. Look in the path if we contain no directory separator. | ||
92 | as_myself= | ||
93 | case $0 in #(( | ||
94 | *[\\/]* ) as_myself=$0 ;; | ||
95 | *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
96 | for as_dir in $PATH | ||
97 | do | ||
98 | IFS=$as_save_IFS | ||
99 | test -z "$as_dir" && as_dir=. | ||
100 | test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break | ||
101 | done | ||
102 | IFS=$as_save_IFS | ||
103 | |||
104 | ;; | ||
105 | esac | ||
106 | # We did not find ourselves, most probably we were run as `sh COMMAND' | ||
107 | # in which case we are not to be found in the path. | ||
108 | if test "x$as_myself" = x; then | ||
109 | as_myself=$0 | ||
110 | fi | ||
111 | if test ! -f "$as_myself"; then | ||
112 | $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 | ||
113 | exit 1 | ||
114 | fi | ||
115 | |||
116 | # Unset variables that we do not need and which cause bugs (e.g. in | ||
117 | # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" | ||
118 | # suppresses any "Segmentation fault" message there. '((' could | ||
119 | # trigger a bug in pdksh 5.2.14. | ||
120 | for as_var in BASH_ENV ENV MAIL MAILPATH | ||
121 | do eval test x\${$as_var+set} = xset \ | ||
122 | && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : | ||
123 | done | ||
124 | PS1='$ ' | ||
125 | PS2='> ' | ||
126 | PS4='+ ' | ||
127 | |||
128 | # NLS nuisances. | ||
129 | LC_ALL=C | ||
130 | export LC_ALL | ||
131 | LANGUAGE=C | ||
132 | export LANGUAGE | ||
133 | |||
134 | # CDPATH. | ||
135 | (unset CDPATH) >/dev/null 2>&1 && unset CDPATH | ||
136 | |||
137 | # Use a proper internal environment variable to ensure we don't fall | ||
138 | # into an infinite loop, continuously re-executing ourselves. | ||
139 | if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then | ||
140 | _as_can_reexec=no; export _as_can_reexec; | ||
141 | # We cannot yet assume a decent shell, so we have to provide a | ||
142 | # neutralization value for shells without unset; and this also | ||
143 | # works around shells that cannot unset nonexistent variables. | ||
144 | # Preserve -v and -x to the replacement shell. | ||
145 | BASH_ENV=/dev/null | ||
146 | ENV=/dev/null | ||
147 | (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV | ||
148 | case $- in # (((( | ||
149 | *v*x* | *x*v* ) as_opts=-vx ;; | ||
150 | *v* ) as_opts=-v ;; | ||
151 | *x* ) as_opts=-x ;; | ||
152 | * ) as_opts= ;; | ||
153 | esac | ||
154 | exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} | ||
155 | # Admittedly, this is quite paranoid, since all the known shells bail | ||
156 | # out after a failed `exec'. | ||
157 | $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 | ||
158 | as_fn_exit 255 | ||
159 | fi | ||
160 | # We don't want this to propagate to other subprocesses. | ||
161 | { _as_can_reexec=; unset _as_can_reexec;} | ||
162 | if test "x$CONFIG_SHELL" = x; then | ||
163 | as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : | ||
164 | emulate sh | ||
165 | NULLCMD=: | ||
166 | # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which | ||
167 | # is contrary to our usage. Disable this feature. | ||
168 | alias -g '\${1+\"\$@\"}'='\"\$@\"' | ||
169 | setopt NO_GLOB_SUBST | ||
170 | else | ||
171 | case \`(set -o) 2>/dev/null\` in #( | ||
172 | *posix*) : | ||
173 | set -o posix ;; #( | ||
174 | *) : | ||
175 | ;; | ||
176 | esac | ||
177 | fi | ||
178 | " | ||
179 | as_required="as_fn_return () { (exit \$1); } | ||
180 | as_fn_success () { as_fn_return 0; } | ||
181 | as_fn_failure () { as_fn_return 1; } | ||
182 | as_fn_ret_success () { return 0; } | ||
183 | as_fn_ret_failure () { return 1; } | ||
184 | |||
185 | exitcode=0 | ||
186 | as_fn_success || { exitcode=1; echo as_fn_success failed.; } | ||
187 | as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } | ||
188 | as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } | ||
189 | as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } | ||
190 | if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : | ||
191 | |||
192 | else | ||
193 | exitcode=1; echo positional parameters were not saved. | ||
194 | fi | ||
195 | test x\$exitcode = x0 || exit 1 | ||
196 | test -x / || exit 1" | ||
197 | as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO | ||
198 | as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO | ||
199 | eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && | ||
200 | test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 | ||
201 | test \$(( 1 + 1 )) = 2 || exit 1" | ||
202 | if (eval "$as_required") 2>/dev/null; then : | ||
203 | as_have_required=yes | ||
204 | else | ||
205 | as_have_required=no | ||
206 | fi | ||
207 | if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : | ||
208 | |||
209 | else | ||
210 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
211 | as_found=false | ||
212 | for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH | ||
213 | do | ||
214 | IFS=$as_save_IFS | ||
215 | test -z "$as_dir" && as_dir=. | ||
216 | as_found=: | ||
217 | case $as_dir in #( | ||
218 | /*) | ||
219 | for as_base in sh bash ksh sh5; do | ||
220 | # Try only shells that exist, to save several forks. | ||
221 | as_shell=$as_dir/$as_base | ||
222 | if { test -f "$as_shell" || test -f "$as_shell.exe"; } && | ||
223 | { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : | ||
224 | CONFIG_SHELL=$as_shell as_have_required=yes | ||
225 | if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : | ||
226 | break 2 | ||
227 | fi | ||
228 | fi | ||
229 | done;; | ||
230 | esac | ||
231 | as_found=false | ||
232 | done | ||
233 | $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && | ||
234 | { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : | ||
235 | CONFIG_SHELL=$SHELL as_have_required=yes | ||
236 | fi; } | ||
237 | IFS=$as_save_IFS | ||
238 | |||
239 | |||
240 | if test "x$CONFIG_SHELL" != x; then : | ||
241 | export CONFIG_SHELL | ||
242 | # We cannot yet assume a decent shell, so we have to provide a | ||
243 | # neutralization value for shells without unset; and this also | ||
244 | # works around shells that cannot unset nonexistent variables. | ||
245 | # Preserve -v and -x to the replacement shell. | ||
246 | BASH_ENV=/dev/null | ||
247 | ENV=/dev/null | ||
248 | (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV | ||
249 | case $- in # (((( | ||
250 | *v*x* | *x*v* ) as_opts=-vx ;; | ||
251 | *v* ) as_opts=-v ;; | ||
252 | *x* ) as_opts=-x ;; | ||
253 | * ) as_opts= ;; | ||
254 | esac | ||
255 | exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} | ||
256 | # Admittedly, this is quite paranoid, since all the known shells bail | ||
257 | # out after a failed `exec'. | ||
258 | $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 | ||
259 | exit 255 | ||
260 | fi | ||
261 | |||
262 | if test x$as_have_required = xno; then : | ||
263 | $as_echo "$0: This script requires a shell more modern than all" | ||
264 | $as_echo "$0: the shells that I found on your system." | ||
265 | if test x${ZSH_VERSION+set} = xset ; then | ||
266 | $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" | ||
267 | $as_echo "$0: be upgraded to zsh 4.3.4 or later." | ||
268 | else | ||
269 | $as_echo "$0: Please tell bug-autoconf@gnu.org and | ||
270 | $0: netblue30@yahoo.com about your system, including any | ||
271 | $0: error possibly output before this message. Then install | ||
272 | $0: a modern shell, or manually run the script under such a | ||
273 | $0: shell if you do have one." | ||
274 | fi | ||
275 | exit 1 | ||
276 | fi | ||
277 | fi | ||
278 | fi | ||
279 | SHELL=${CONFIG_SHELL-/bin/sh} | ||
280 | export SHELL | ||
281 | # Unset more variables known to interfere with behavior of common tools. | ||
282 | CLICOLOR_FORCE= GREP_OPTIONS= | ||
283 | unset CLICOLOR_FORCE GREP_OPTIONS | ||
284 | |||
285 | ## --------------------- ## | ||
286 | ## M4sh Shell Functions. ## | ||
287 | ## --------------------- ## | ||
288 | # as_fn_unset VAR | ||
289 | # --------------- | ||
290 | # Portably unset VAR. | ||
291 | as_fn_unset () | ||
292 | { | ||
293 | { eval $1=; unset $1;} | ||
294 | } | ||
295 | as_unset=as_fn_unset | ||
296 | |||
297 | # as_fn_set_status STATUS | ||
298 | # ----------------------- | ||
299 | # Set $? to STATUS, without forking. | ||
300 | as_fn_set_status () | ||
301 | { | ||
302 | return $1 | ||
303 | } # as_fn_set_status | ||
304 | |||
305 | # as_fn_exit STATUS | ||
306 | # ----------------- | ||
307 | # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. | ||
308 | as_fn_exit () | ||
309 | { | ||
310 | set +e | ||
311 | as_fn_set_status $1 | ||
312 | exit $1 | ||
313 | } # as_fn_exit | ||
314 | |||
315 | # as_fn_mkdir_p | ||
316 | # ------------- | ||
317 | # Create "$as_dir" as a directory, including parents if necessary. | ||
318 | as_fn_mkdir_p () | ||
319 | { | ||
320 | |||
321 | case $as_dir in #( | ||
322 | -*) as_dir=./$as_dir;; | ||
323 | esac | ||
324 | test -d "$as_dir" || eval $as_mkdir_p || { | ||
325 | as_dirs= | ||
326 | while :; do | ||
327 | case $as_dir in #( | ||
328 | *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( | ||
329 | *) as_qdir=$as_dir;; | ||
330 | esac | ||
331 | as_dirs="'$as_qdir' $as_dirs" | ||
332 | as_dir=`$as_dirname -- "$as_dir" || | ||
333 | $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ | ||
334 | X"$as_dir" : 'X\(//\)[^/]' \| \ | ||
335 | X"$as_dir" : 'X\(//\)$' \| \ | ||
336 | X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || | ||
337 | $as_echo X"$as_dir" | | ||
338 | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ | ||
339 | s//\1/ | ||
340 | q | ||
341 | } | ||
342 | /^X\(\/\/\)[^/].*/{ | ||
343 | s//\1/ | ||
344 | q | ||
345 | } | ||
346 | /^X\(\/\/\)$/{ | ||
347 | s//\1/ | ||
348 | q | ||
349 | } | ||
350 | /^X\(\/\).*/{ | ||
351 | s//\1/ | ||
352 | q | ||
353 | } | ||
354 | s/.*/./; q'` | ||
355 | test -d "$as_dir" && break | ||
356 | done | ||
357 | test -z "$as_dirs" || eval "mkdir $as_dirs" | ||
358 | } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" | ||
359 | |||
360 | |||
361 | } # as_fn_mkdir_p | ||
362 | |||
363 | # as_fn_executable_p FILE | ||
364 | # ----------------------- | ||
365 | # Test if FILE is an executable regular file. | ||
366 | as_fn_executable_p () | ||
367 | { | ||
368 | test -f "$1" && test -x "$1" | ||
369 | } # as_fn_executable_p | ||
370 | # as_fn_append VAR VALUE | ||
371 | # ---------------------- | ||
372 | # Append the text in VALUE to the end of the definition contained in VAR. Take | ||
373 | # advantage of any shell optimizations that allow amortized linear growth over | ||
374 | # repeated appends, instead of the typical quadratic growth present in naive | ||
375 | # implementations. | ||
376 | if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : | ||
377 | eval 'as_fn_append () | ||
378 | { | ||
379 | eval $1+=\$2 | ||
380 | }' | ||
381 | else | ||
382 | as_fn_append () | ||
383 | { | ||
384 | eval $1=\$$1\$2 | ||
385 | } | ||
386 | fi # as_fn_append | ||
387 | |||
388 | # as_fn_arith ARG... | ||
389 | # ------------------ | ||
390 | # Perform arithmetic evaluation on the ARGs, and store the result in the | ||
391 | # global $as_val. Take advantage of shells that can avoid forks. The arguments | ||
392 | # must be portable across $(()) and expr. | ||
393 | if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : | ||
394 | eval 'as_fn_arith () | ||
395 | { | ||
396 | as_val=$(( $* )) | ||
397 | }' | ||
398 | else | ||
399 | as_fn_arith () | ||
400 | { | ||
401 | as_val=`expr "$@" || test $? -eq 1` | ||
402 | } | ||
403 | fi # as_fn_arith | ||
404 | |||
405 | |||
406 | # as_fn_error STATUS ERROR [LINENO LOG_FD] | ||
407 | # ---------------------------------------- | ||
408 | # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are | ||
409 | # provided, also output the error to LOG_FD, referencing LINENO. Then exit the | ||
410 | # script with STATUS, using 1 if that was 0. | ||
411 | as_fn_error () | ||
412 | { | ||
413 | as_status=$1; test $as_status -eq 0 && as_status=1 | ||
414 | if test "$4"; then | ||
415 | as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | ||
416 | $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 | ||
417 | fi | ||
418 | $as_echo "$as_me: error: $2" >&2 | ||
419 | as_fn_exit $as_status | ||
420 | } # as_fn_error | ||
421 | |||
422 | if expr a : '\(a\)' >/dev/null 2>&1 && | ||
423 | test "X`expr 00001 : '.*\(...\)'`" = X001; then | ||
424 | as_expr=expr | ||
425 | else | ||
426 | as_expr=false | ||
427 | fi | ||
428 | |||
429 | if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then | ||
430 | as_basename=basename | ||
431 | else | ||
432 | as_basename=false | ||
433 | fi | ||
434 | |||
435 | if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then | ||
436 | as_dirname=dirname | ||
437 | else | ||
438 | as_dirname=false | ||
439 | fi | ||
440 | |||
441 | as_me=`$as_basename -- "$0" || | ||
442 | $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ | ||
443 | X"$0" : 'X\(//\)$' \| \ | ||
444 | X"$0" : 'X\(/\)' \| . 2>/dev/null || | ||
445 | $as_echo X/"$0" | | ||
446 | sed '/^.*\/\([^/][^/]*\)\/*$/{ | ||
447 | s//\1/ | ||
448 | q | ||
449 | } | ||
450 | /^X\/\(\/\/\)$/{ | ||
451 | s//\1/ | ||
452 | q | ||
453 | } | ||
454 | /^X\/\(\/\).*/{ | ||
455 | s//\1/ | ||
456 | q | ||
457 | } | ||
458 | s/.*/./; q'` | ||
459 | |||
460 | # Avoid depending upon Character Ranges. | ||
461 | as_cr_letters='abcdefghijklmnopqrstuvwxyz' | ||
462 | as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' | ||
463 | as_cr_Letters=$as_cr_letters$as_cr_LETTERS | ||
464 | as_cr_digits='0123456789' | ||
465 | as_cr_alnum=$as_cr_Letters$as_cr_digits | ||
466 | |||
467 | |||
468 | as_lineno_1=$LINENO as_lineno_1a=$LINENO | ||
469 | as_lineno_2=$LINENO as_lineno_2a=$LINENO | ||
470 | eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && | ||
471 | test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { | ||
472 | # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) | ||
473 | sed -n ' | ||
474 | p | ||
475 | /[$]LINENO/= | ||
476 | ' <$as_myself | | ||
477 | sed ' | ||
478 | s/[$]LINENO.*/&-/ | ||
479 | t lineno | ||
480 | b | ||
481 | :lineno | ||
482 | N | ||
483 | :loop | ||
484 | s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ | ||
485 | t loop | ||
486 | s/-\n.*// | ||
487 | ' >$as_me.lineno && | ||
488 | chmod +x "$as_me.lineno" || | ||
489 | { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } | ||
490 | |||
491 | # If we had to re-execute with $CONFIG_SHELL, we're ensured to have | ||
492 | # already done that, so ensure we don't try to do so again and fall | ||
493 | # in an infinite loop. This has already happened in practice. | ||
494 | _as_can_reexec=no; export _as_can_reexec | ||
495 | # Don't try to exec as it changes $[0], causing all sort of problems | ||
496 | # (the dirname of $[0] is not the place where we might find the | ||
497 | # original and so on. Autoconf is especially sensitive to this). | ||
498 | . "./$as_me.lineno" | ||
499 | # Exit status is that of the last command. | ||
500 | exit | ||
501 | } | ||
502 | |||
503 | ECHO_C= ECHO_N= ECHO_T= | ||
504 | case `echo -n x` in #((((( | ||
505 | -n*) | ||
506 | case `echo 'xy\c'` in | ||
507 | *c*) ECHO_T=' ';; # ECHO_T is single tab character. | ||
508 | xy) ECHO_C='\c';; | ||
509 | *) echo `echo ksh88 bug on AIX 6.1` > /dev/null | ||
510 | ECHO_T=' ';; | ||
511 | esac;; | ||
512 | *) | ||
513 | ECHO_N='-n';; | ||
514 | esac | ||
515 | |||
516 | rm -f conf$$ conf$$.exe conf$$.file | ||
517 | if test -d conf$$.dir; then | ||
518 | rm -f conf$$.dir/conf$$.file | ||
519 | else | ||
520 | rm -f conf$$.dir | ||
521 | mkdir conf$$.dir 2>/dev/null | ||
522 | fi | ||
523 | if (echo >conf$$.file) 2>/dev/null; then | ||
524 | if ln -s conf$$.file conf$$ 2>/dev/null; then | ||
525 | as_ln_s='ln -s' | ||
526 | # ... but there are two gotchas: | ||
527 | # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. | ||
528 | # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. | ||
529 | # In both cases, we have to default to `cp -pR'. | ||
530 | ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || | ||
531 | as_ln_s='cp -pR' | ||
532 | elif ln conf$$.file conf$$ 2>/dev/null; then | ||
533 | as_ln_s=ln | ||
534 | else | ||
535 | as_ln_s='cp -pR' | ||
536 | fi | ||
537 | else | ||
538 | as_ln_s='cp -pR' | ||
539 | fi | ||
540 | rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file | ||
541 | rmdir conf$$.dir 2>/dev/null | ||
542 | |||
543 | if mkdir -p . 2>/dev/null; then | ||
544 | as_mkdir_p='mkdir -p "$as_dir"' | ||
545 | else | ||
546 | test -d ./-p && rmdir ./-p | ||
547 | as_mkdir_p=false | ||
548 | fi | ||
549 | |||
550 | as_test_x='test -x' | ||
551 | as_executable_p=as_fn_executable_p | ||
552 | |||
553 | # Sed expression to map a string onto a valid CPP name. | ||
554 | as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" | ||
555 | |||
556 | # Sed expression to map a string onto a valid variable name. | ||
557 | as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" | ||
558 | |||
559 | |||
560 | test -n "$DJDIR" || exec 7<&0 </dev/null | ||
561 | exec 6>&1 | ||
562 | |||
563 | # Name of the host. | ||
564 | # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, | ||
565 | # so uname gets run too. | ||
566 | ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` | ||
567 | |||
568 | # | ||
569 | # Initializations. | ||
570 | # | ||
571 | ac_default_prefix=/usr/local | ||
572 | ac_clean_files= | ||
573 | ac_config_libobj_dir=. | ||
574 | LIBOBJS= | ||
575 | cross_compiling=no | ||
576 | subdirs= | ||
577 | MFLAGS= | ||
578 | MAKEFLAGS= | ||
579 | |||
580 | # Identity of this package. | ||
581 | PACKAGE_NAME='firejail' | ||
582 | PACKAGE_TARNAME='firejail' | ||
583 | PACKAGE_VERSION='0.9.28' | ||
584 | PACKAGE_STRING='firejail 0.9.28' | ||
585 | PACKAGE_BUGREPORT='netblue30@yahoo.com' | ||
586 | PACKAGE_URL='http://firejail.sourceforge.net' | ||
587 | |||
588 | ac_unique_file="src/firejail/main.c" | ||
589 | # Factoring default headers for most tests. | ||
590 | ac_includes_default="\ | ||
591 | #include <stdio.h> | ||
592 | #ifdef HAVE_SYS_TYPES_H | ||
593 | # include <sys/types.h> | ||
594 | #endif | ||
595 | #ifdef HAVE_SYS_STAT_H | ||
596 | # include <sys/stat.h> | ||
597 | #endif | ||
598 | #ifdef STDC_HEADERS | ||
599 | # include <stdlib.h> | ||
600 | # include <stddef.h> | ||
601 | #else | ||
602 | # ifdef HAVE_STDLIB_H | ||
603 | # include <stdlib.h> | ||
604 | # endif | ||
605 | #endif | ||
606 | #ifdef HAVE_STRING_H | ||
607 | # if !defined STDC_HEADERS && defined HAVE_MEMORY_H | ||
608 | # include <memory.h> | ||
609 | # endif | ||
610 | # include <string.h> | ||
611 | #endif | ||
612 | #ifdef HAVE_STRINGS_H | ||
613 | # include <strings.h> | ||
614 | #endif | ||
615 | #ifdef HAVE_INTTYPES_H | ||
616 | # include <inttypes.h> | ||
617 | #endif | ||
618 | #ifdef HAVE_STDINT_H | ||
619 | # include <stdint.h> | ||
620 | #endif | ||
621 | #ifdef HAVE_UNISTD_H | ||
622 | # include <unistd.h> | ||
623 | #endif" | ||
624 | |||
625 | ac_subst_vars='LTLIBOBJS | ||
626 | LIBOBJS | ||
627 | HAVE_SECCOMP_H | ||
628 | EGREP | ||
629 | GREP | ||
630 | CPP | ||
631 | HAVE_BIND | ||
632 | HAVE_CHROOT | ||
633 | HAVE_SECCOMP | ||
634 | RANLIB | ||
635 | INSTALL_DATA | ||
636 | INSTALL_SCRIPT | ||
637 | INSTALL_PROGRAM | ||
638 | OBJEXT | ||
639 | EXEEXT | ||
640 | ac_ct_CC | ||
641 | CPPFLAGS | ||
642 | LDFLAGS | ||
643 | CFLAGS | ||
644 | CC | ||
645 | target_alias | ||
646 | host_alias | ||
647 | build_alias | ||
648 | LIBS | ||
649 | ECHO_T | ||
650 | ECHO_N | ||
651 | ECHO_C | ||
652 | DEFS | ||
653 | mandir | ||
654 | localedir | ||
655 | libdir | ||
656 | psdir | ||
657 | pdfdir | ||
658 | dvidir | ||
659 | htmldir | ||
660 | infodir | ||
661 | docdir | ||
662 | oldincludedir | ||
663 | includedir | ||
664 | localstatedir | ||
665 | sharedstatedir | ||
666 | sysconfdir | ||
667 | datadir | ||
668 | datarootdir | ||
669 | libexecdir | ||
670 | sbindir | ||
671 | bindir | ||
672 | program_transform_name | ||
673 | prefix | ||
674 | exec_prefix | ||
675 | PACKAGE_URL | ||
676 | PACKAGE_BUGREPORT | ||
677 | PACKAGE_STRING | ||
678 | PACKAGE_VERSION | ||
679 | PACKAGE_TARNAME | ||
680 | PACKAGE_NAME | ||
681 | PATH_SEPARATOR | ||
682 | SHELL' | ||
683 | ac_subst_files='' | ||
684 | ac_user_opts=' | ||
685 | enable_option_checking | ||
686 | enable_seccomp | ||
687 | enable_chroot | ||
688 | enable_bind | ||
689 | ' | ||
690 | ac_precious_vars='build_alias | ||
691 | host_alias | ||
692 | target_alias | ||
693 | CC | ||
694 | CFLAGS | ||
695 | LDFLAGS | ||
696 | LIBS | ||
697 | CPPFLAGS | ||
698 | CPP' | ||
699 | |||
700 | |||
701 | # Initialize some variables set by options. | ||
702 | ac_init_help= | ||
703 | ac_init_version=false | ||
704 | ac_unrecognized_opts= | ||
705 | ac_unrecognized_sep= | ||
706 | # The variables have the same names as the options, with | ||
707 | # dashes changed to underlines. | ||
708 | cache_file=/dev/null | ||
709 | exec_prefix=NONE | ||
710 | no_create= | ||
711 | no_recursion= | ||
712 | prefix=NONE | ||
713 | program_prefix=NONE | ||
714 | program_suffix=NONE | ||
715 | program_transform_name=s,x,x, | ||
716 | silent= | ||
717 | site= | ||
718 | srcdir= | ||
719 | verbose= | ||
720 | x_includes=NONE | ||
721 | x_libraries=NONE | ||
722 | |||
723 | # Installation directory options. | ||
724 | # These are left unexpanded so users can "make install exec_prefix=/foo" | ||
725 | # and all the variables that are supposed to be based on exec_prefix | ||
726 | # by default will actually change. | ||
727 | # Use braces instead of parens because sh, perl, etc. also accept them. | ||
728 | # (The list follows the same order as the GNU Coding Standards.) | ||
729 | bindir='${exec_prefix}/bin' | ||
730 | sbindir='${exec_prefix}/sbin' | ||
731 | libexecdir='${exec_prefix}/libexec' | ||
732 | datarootdir='${prefix}/share' | ||
733 | datadir='${datarootdir}' | ||
734 | sysconfdir='${prefix}/etc' | ||
735 | sharedstatedir='${prefix}/com' | ||
736 | localstatedir='${prefix}/var' | ||
737 | includedir='${prefix}/include' | ||
738 | oldincludedir='/usr/include' | ||
739 | docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' | ||
740 | infodir='${datarootdir}/info' | ||
741 | htmldir='${docdir}' | ||
742 | dvidir='${docdir}' | ||
743 | pdfdir='${docdir}' | ||
744 | psdir='${docdir}' | ||
745 | libdir='${exec_prefix}/lib' | ||
746 | localedir='${datarootdir}/locale' | ||
747 | mandir='${datarootdir}/man' | ||
748 | |||
749 | ac_prev= | ||
750 | ac_dashdash= | ||
751 | for ac_option | ||
752 | do | ||
753 | # If the previous option needs an argument, assign it. | ||
754 | if test -n "$ac_prev"; then | ||
755 | eval $ac_prev=\$ac_option | ||
756 | ac_prev= | ||
757 | continue | ||
758 | fi | ||
759 | |||
760 | case $ac_option in | ||
761 | *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; | ||
762 | *=) ac_optarg= ;; | ||
763 | *) ac_optarg=yes ;; | ||
764 | esac | ||
765 | |||
766 | # Accept the important Cygnus configure options, so we can diagnose typos. | ||
767 | |||
768 | case $ac_dashdash$ac_option in | ||
769 | --) | ||
770 | ac_dashdash=yes ;; | ||
771 | |||
772 | -bindir | --bindir | --bindi | --bind | --bin | --bi) | ||
773 | ac_prev=bindir ;; | ||
774 | -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) | ||
775 | bindir=$ac_optarg ;; | ||
776 | |||
777 | -build | --build | --buil | --bui | --bu) | ||
778 | ac_prev=build_alias ;; | ||
779 | -build=* | --build=* | --buil=* | --bui=* | --bu=*) | ||
780 | build_alias=$ac_optarg ;; | ||
781 | |||
782 | -cache-file | --cache-file | --cache-fil | --cache-fi \ | ||
783 | | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) | ||
784 | ac_prev=cache_file ;; | ||
785 | -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | ||
786 | | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) | ||
787 | cache_file=$ac_optarg ;; | ||
788 | |||
789 | --config-cache | -C) | ||
790 | cache_file=config.cache ;; | ||
791 | |||
792 | -datadir | --datadir | --datadi | --datad) | ||
793 | ac_prev=datadir ;; | ||
794 | -datadir=* | --datadir=* | --datadi=* | --datad=*) | ||
795 | datadir=$ac_optarg ;; | ||
796 | |||
797 | -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | ||
798 | | --dataroo | --dataro | --datar) | ||
799 | ac_prev=datarootdir ;; | ||
800 | -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | ||
801 | | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) | ||
802 | datarootdir=$ac_optarg ;; | ||
803 | |||
804 | -disable-* | --disable-*) | ||
805 | ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` | ||
806 | # Reject names that are not valid shell variable names. | ||
807 | expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && | ||
808 | as_fn_error $? "invalid feature name: $ac_useropt" | ||
809 | ac_useropt_orig=$ac_useropt | ||
810 | ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` | ||
811 | case $ac_user_opts in | ||
812 | *" | ||
813 | "enable_$ac_useropt" | ||
814 | "*) ;; | ||
815 | *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" | ||
816 | ac_unrecognized_sep=', ';; | ||
817 | esac | ||
818 | eval enable_$ac_useropt=no ;; | ||
819 | |||
820 | -docdir | --docdir | --docdi | --doc | --do) | ||
821 | ac_prev=docdir ;; | ||
822 | -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) | ||
823 | docdir=$ac_optarg ;; | ||
824 | |||
825 | -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) | ||
826 | ac_prev=dvidir ;; | ||
827 | -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) | ||
828 | dvidir=$ac_optarg ;; | ||
829 | |||
830 | -enable-* | --enable-*) | ||
831 | ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` | ||
832 | # Reject names that are not valid shell variable names. | ||
833 | expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && | ||
834 | as_fn_error $? "invalid feature name: $ac_useropt" | ||
835 | ac_useropt_orig=$ac_useropt | ||
836 | ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` | ||
837 | case $ac_user_opts in | ||
838 | *" | ||
839 | "enable_$ac_useropt" | ||
840 | "*) ;; | ||
841 | *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" | ||
842 | ac_unrecognized_sep=', ';; | ||
843 | esac | ||
844 | eval enable_$ac_useropt=\$ac_optarg ;; | ||
845 | |||
846 | -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | ||
847 | | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | ||
848 | | --exec | --exe | --ex) | ||
849 | ac_prev=exec_prefix ;; | ||
850 | -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | ||
851 | | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | ||
852 | | --exec=* | --exe=* | --ex=*) | ||
853 | exec_prefix=$ac_optarg ;; | ||
854 | |||
855 | -gas | --gas | --ga | --g) | ||
856 | # Obsolete; use --with-gas. | ||
857 | with_gas=yes ;; | ||
858 | |||
859 | -help | --help | --hel | --he | -h) | ||
860 | ac_init_help=long ;; | ||
861 | -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) | ||
862 | ac_init_help=recursive ;; | ||
863 | -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) | ||
864 | ac_init_help=short ;; | ||
865 | |||
866 | -host | --host | --hos | --ho) | ||
867 | ac_prev=host_alias ;; | ||
868 | -host=* | --host=* | --hos=* | --ho=*) | ||
869 | host_alias=$ac_optarg ;; | ||
870 | |||
871 | -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) | ||
872 | ac_prev=htmldir ;; | ||
873 | -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | ||
874 | | --ht=*) | ||
875 | htmldir=$ac_optarg ;; | ||
876 | |||
877 | -includedir | --includedir | --includedi | --included | --include \ | ||
878 | | --includ | --inclu | --incl | --inc) | ||
879 | ac_prev=includedir ;; | ||
880 | -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | ||
881 | | --includ=* | --inclu=* | --incl=* | --inc=*) | ||
882 | includedir=$ac_optarg ;; | ||
883 | |||
884 | -infodir | --infodir | --infodi | --infod | --info | --inf) | ||
885 | ac_prev=infodir ;; | ||
886 | -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) | ||
887 | infodir=$ac_optarg ;; | ||
888 | |||
889 | -libdir | --libdir | --libdi | --libd) | ||
890 | ac_prev=libdir ;; | ||
891 | -libdir=* | --libdir=* | --libdi=* | --libd=*) | ||
892 | libdir=$ac_optarg ;; | ||
893 | |||
894 | -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | ||
895 | | --libexe | --libex | --libe) | ||
896 | ac_prev=libexecdir ;; | ||
897 | -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | ||
898 | | --libexe=* | --libex=* | --libe=*) | ||
899 | libexecdir=$ac_optarg ;; | ||
900 | |||
901 | -localedir | --localedir | --localedi | --localed | --locale) | ||
902 | ac_prev=localedir ;; | ||
903 | -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) | ||
904 | localedir=$ac_optarg ;; | ||
905 | |||
906 | -localstatedir | --localstatedir | --localstatedi | --localstated \ | ||
907 | | --localstate | --localstat | --localsta | --localst | --locals) | ||
908 | ac_prev=localstatedir ;; | ||
909 | -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | ||
910 | | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) | ||
911 | localstatedir=$ac_optarg ;; | ||
912 | |||
913 | -mandir | --mandir | --mandi | --mand | --man | --ma | --m) | ||
914 | ac_prev=mandir ;; | ||
915 | -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) | ||
916 | mandir=$ac_optarg ;; | ||
917 | |||
918 | -nfp | --nfp | --nf) | ||
919 | # Obsolete; use --without-fp. | ||
920 | with_fp=no ;; | ||
921 | |||
922 | -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | ||
923 | | --no-cr | --no-c | -n) | ||
924 | no_create=yes ;; | ||
925 | |||
926 | -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | ||
927 | | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) | ||
928 | no_recursion=yes ;; | ||
929 | |||
930 | -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | ||
931 | | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | ||
932 | | --oldin | --oldi | --old | --ol | --o) | ||
933 | ac_prev=oldincludedir ;; | ||
934 | -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | ||
935 | | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | ||
936 | | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) | ||
937 | oldincludedir=$ac_optarg ;; | ||
938 | |||
939 | -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) | ||
940 | ac_prev=prefix ;; | ||
941 | -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) | ||
942 | prefix=$ac_optarg ;; | ||
943 | |||
944 | -program-prefix | --program-prefix | --program-prefi | --program-pref \ | ||
945 | | --program-pre | --program-pr | --program-p) | ||
946 | ac_prev=program_prefix ;; | ||
947 | -program-prefix=* | --program-prefix=* | --program-prefi=* \ | ||
948 | | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) | ||
949 | program_prefix=$ac_optarg ;; | ||
950 | |||
951 | -program-suffix | --program-suffix | --program-suffi | --program-suff \ | ||
952 | | --program-suf | --program-su | --program-s) | ||
953 | ac_prev=program_suffix ;; | ||
954 | -program-suffix=* | --program-suffix=* | --program-suffi=* \ | ||
955 | | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) | ||
956 | program_suffix=$ac_optarg ;; | ||
957 | |||
958 | -program-transform-name | --program-transform-name \ | ||
959 | | --program-transform-nam | --program-transform-na \ | ||
960 | | --program-transform-n | --program-transform- \ | ||
961 | | --program-transform | --program-transfor \ | ||
962 | | --program-transfo | --program-transf \ | ||
963 | | --program-trans | --program-tran \ | ||
964 | | --progr-tra | --program-tr | --program-t) | ||
965 | ac_prev=program_transform_name ;; | ||
966 | -program-transform-name=* | --program-transform-name=* \ | ||
967 | | --program-transform-nam=* | --program-transform-na=* \ | ||
968 | | --program-transform-n=* | --program-transform-=* \ | ||
969 | | --program-transform=* | --program-transfor=* \ | ||
970 | | --program-transfo=* | --program-transf=* \ | ||
971 | | --program-trans=* | --program-tran=* \ | ||
972 | | --progr-tra=* | --program-tr=* | --program-t=*) | ||
973 | program_transform_name=$ac_optarg ;; | ||
974 | |||
975 | -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) | ||
976 | ac_prev=pdfdir ;; | ||
977 | -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) | ||
978 | pdfdir=$ac_optarg ;; | ||
979 | |||
980 | -psdir | --psdir | --psdi | --psd | --ps) | ||
981 | ac_prev=psdir ;; | ||
982 | -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) | ||
983 | psdir=$ac_optarg ;; | ||
984 | |||
985 | -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | ||
986 | | -silent | --silent | --silen | --sile | --sil) | ||
987 | silent=yes ;; | ||
988 | |||
989 | -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) | ||
990 | ac_prev=sbindir ;; | ||
991 | -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | ||
992 | | --sbi=* | --sb=*) | ||
993 | sbindir=$ac_optarg ;; | ||
994 | |||
995 | -sharedstatedir | --sharedstatedir | --sharedstatedi \ | ||
996 | | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | ||
997 | | --sharedst | --shareds | --shared | --share | --shar \ | ||
998 | | --sha | --sh) | ||
999 | ac_prev=sharedstatedir ;; | ||
1000 | -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | ||
1001 | | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | ||
1002 | | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | ||
1003 | | --sha=* | --sh=*) | ||
1004 | sharedstatedir=$ac_optarg ;; | ||
1005 | |||
1006 | -site | --site | --sit) | ||
1007 | ac_prev=site ;; | ||
1008 | -site=* | --site=* | --sit=*) | ||
1009 | site=$ac_optarg ;; | ||
1010 | |||
1011 | -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) | ||
1012 | ac_prev=srcdir ;; | ||
1013 | -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) | ||
1014 | srcdir=$ac_optarg ;; | ||
1015 | |||
1016 | -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | ||
1017 | | --syscon | --sysco | --sysc | --sys | --sy) | ||
1018 | ac_prev=sysconfdir ;; | ||
1019 | -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | ||
1020 | | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) | ||
1021 | sysconfdir=$ac_optarg ;; | ||
1022 | |||
1023 | -target | --target | --targe | --targ | --tar | --ta | --t) | ||
1024 | ac_prev=target_alias ;; | ||
1025 | -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) | ||
1026 | target_alias=$ac_optarg ;; | ||
1027 | |||
1028 | -v | -verbose | --verbose | --verbos | --verbo | --verb) | ||
1029 | verbose=yes ;; | ||
1030 | |||
1031 | -version | --version | --versio | --versi | --vers | -V) | ||
1032 | ac_init_version=: ;; | ||
1033 | |||
1034 | -with-* | --with-*) | ||
1035 | ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` | ||
1036 | # Reject names that are not valid shell variable names. | ||
1037 | expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && | ||
1038 | as_fn_error $? "invalid package name: $ac_useropt" | ||
1039 | ac_useropt_orig=$ac_useropt | ||
1040 | ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` | ||
1041 | case $ac_user_opts in | ||
1042 | *" | ||
1043 | "with_$ac_useropt" | ||
1044 | "*) ;; | ||
1045 | *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" | ||
1046 | ac_unrecognized_sep=', ';; | ||
1047 | esac | ||
1048 | eval with_$ac_useropt=\$ac_optarg ;; | ||
1049 | |||
1050 | -without-* | --without-*) | ||
1051 | ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` | ||
1052 | # Reject names that are not valid shell variable names. | ||
1053 | expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && | ||
1054 | as_fn_error $? "invalid package name: $ac_useropt" | ||
1055 | ac_useropt_orig=$ac_useropt | ||
1056 | ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` | ||
1057 | case $ac_user_opts in | ||
1058 | *" | ||
1059 | "with_$ac_useropt" | ||
1060 | "*) ;; | ||
1061 | *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" | ||
1062 | ac_unrecognized_sep=', ';; | ||
1063 | esac | ||
1064 | eval with_$ac_useropt=no ;; | ||
1065 | |||
1066 | --x) | ||
1067 | # Obsolete; use --with-x. | ||
1068 | with_x=yes ;; | ||
1069 | |||
1070 | -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | ||
1071 | | --x-incl | --x-inc | --x-in | --x-i) | ||
1072 | ac_prev=x_includes ;; | ||
1073 | -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | ||
1074 | | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) | ||
1075 | x_includes=$ac_optarg ;; | ||
1076 | |||
1077 | -x-libraries | --x-libraries | --x-librarie | --x-librari \ | ||
1078 | | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) | ||
1079 | ac_prev=x_libraries ;; | ||
1080 | -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | ||
1081 | | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) | ||
1082 | x_libraries=$ac_optarg ;; | ||
1083 | |||
1084 | -*) as_fn_error $? "unrecognized option: \`$ac_option' | ||
1085 | Try \`$0 --help' for more information" | ||
1086 | ;; | ||
1087 | |||
1088 | *=*) | ||
1089 | ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` | ||
1090 | # Reject names that are not valid shell variable names. | ||
1091 | case $ac_envvar in #( | ||
1092 | '' | [0-9]* | *[!_$as_cr_alnum]* ) | ||
1093 | as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; | ||
1094 | esac | ||
1095 | eval $ac_envvar=\$ac_optarg | ||
1096 | export $ac_envvar ;; | ||
1097 | |||
1098 | *) | ||
1099 | # FIXME: should be removed in autoconf 3.0. | ||
1100 | $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 | ||
1101 | expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && | ||
1102 | $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 | ||
1103 | : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" | ||
1104 | ;; | ||
1105 | |||
1106 | esac | ||
1107 | done | ||
1108 | |||
1109 | if test -n "$ac_prev"; then | ||
1110 | ac_option=--`echo $ac_prev | sed 's/_/-/g'` | ||
1111 | as_fn_error $? "missing argument to $ac_option" | ||
1112 | fi | ||
1113 | |||
1114 | if test -n "$ac_unrecognized_opts"; then | ||
1115 | case $enable_option_checking in | ||
1116 | no) ;; | ||
1117 | fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; | ||
1118 | *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; | ||
1119 | esac | ||
1120 | fi | ||
1121 | |||
1122 | # Check all directory arguments for consistency. | ||
1123 | for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ | ||
1124 | datadir sysconfdir sharedstatedir localstatedir includedir \ | ||
1125 | oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ | ||
1126 | libdir localedir mandir | ||
1127 | do | ||
1128 | eval ac_val=\$$ac_var | ||
1129 | # Remove trailing slashes. | ||
1130 | case $ac_val in | ||
1131 | */ ) | ||
1132 | ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` | ||
1133 | eval $ac_var=\$ac_val;; | ||
1134 | esac | ||
1135 | # Be sure to have absolute directory names. | ||
1136 | case $ac_val in | ||
1137 | [\\/$]* | ?:[\\/]* ) continue;; | ||
1138 | NONE | '' ) case $ac_var in *prefix ) continue;; esac;; | ||
1139 | esac | ||
1140 | as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" | ||
1141 | done | ||
1142 | |||
1143 | # There might be people who depend on the old broken behavior: `$host' | ||
1144 | # used to hold the argument of --host etc. | ||
1145 | # FIXME: To remove some day. | ||
1146 | build=$build_alias | ||
1147 | host=$host_alias | ||
1148 | target=$target_alias | ||
1149 | |||
1150 | # FIXME: To remove some day. | ||
1151 | if test "x$host_alias" != x; then | ||
1152 | if test "x$build_alias" = x; then | ||
1153 | cross_compiling=maybe | ||
1154 | elif test "x$build_alias" != "x$host_alias"; then | ||
1155 | cross_compiling=yes | ||
1156 | fi | ||
1157 | fi | ||
1158 | |||
1159 | ac_tool_prefix= | ||
1160 | test -n "$host_alias" && ac_tool_prefix=$host_alias- | ||
1161 | |||
1162 | test "$silent" = yes && exec 6>/dev/null | ||
1163 | |||
1164 | |||
1165 | ac_pwd=`pwd` && test -n "$ac_pwd" && | ||
1166 | ac_ls_di=`ls -di .` && | ||
1167 | ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || | ||
1168 | as_fn_error $? "working directory cannot be determined" | ||
1169 | test "X$ac_ls_di" = "X$ac_pwd_ls_di" || | ||
1170 | as_fn_error $? "pwd does not report name of working directory" | ||
1171 | |||
1172 | |||
1173 | # Find the source files, if location was not specified. | ||
1174 | if test -z "$srcdir"; then | ||
1175 | ac_srcdir_defaulted=yes | ||
1176 | # Try the directory containing this script, then the parent directory. | ||
1177 | ac_confdir=`$as_dirname -- "$as_myself" || | ||
1178 | $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ | ||
1179 | X"$as_myself" : 'X\(//\)[^/]' \| \ | ||
1180 | X"$as_myself" : 'X\(//\)$' \| \ | ||
1181 | X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || | ||
1182 | $as_echo X"$as_myself" | | ||
1183 | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ | ||
1184 | s//\1/ | ||
1185 | q | ||
1186 | } | ||
1187 | /^X\(\/\/\)[^/].*/{ | ||
1188 | s//\1/ | ||
1189 | q | ||
1190 | } | ||
1191 | /^X\(\/\/\)$/{ | ||
1192 | s//\1/ | ||
1193 | q | ||
1194 | } | ||
1195 | /^X\(\/\).*/{ | ||
1196 | s//\1/ | ||
1197 | q | ||
1198 | } | ||
1199 | s/.*/./; q'` | ||
1200 | srcdir=$ac_confdir | ||
1201 | if test ! -r "$srcdir/$ac_unique_file"; then | ||
1202 | srcdir=.. | ||
1203 | fi | ||
1204 | else | ||
1205 | ac_srcdir_defaulted=no | ||
1206 | fi | ||
1207 | if test ! -r "$srcdir/$ac_unique_file"; then | ||
1208 | test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." | ||
1209 | as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" | ||
1210 | fi | ||
1211 | ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" | ||
1212 | ac_abs_confdir=`( | ||
1213 | cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" | ||
1214 | pwd)` | ||
1215 | # When building in place, set srcdir=. | ||
1216 | if test "$ac_abs_confdir" = "$ac_pwd"; then | ||
1217 | srcdir=. | ||
1218 | fi | ||
1219 | # Remove unnecessary trailing slashes from srcdir. | ||
1220 | # Double slashes in file names in object file debugging info | ||
1221 | # mess up M-x gdb in Emacs. | ||
1222 | case $srcdir in | ||
1223 | */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; | ||
1224 | esac | ||
1225 | for ac_var in $ac_precious_vars; do | ||
1226 | eval ac_env_${ac_var}_set=\${${ac_var}+set} | ||
1227 | eval ac_env_${ac_var}_value=\$${ac_var} | ||
1228 | eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} | ||
1229 | eval ac_cv_env_${ac_var}_value=\$${ac_var} | ||
1230 | done | ||
1231 | |||
1232 | # | ||
1233 | # Report the --help message. | ||
1234 | # | ||
1235 | if test "$ac_init_help" = "long"; then | ||
1236 | # Omit some internal or obsolete options to make the list less imposing. | ||
1237 | # This message is too long to be a string in the A/UX 3.1 sh. | ||
1238 | cat <<_ACEOF | ||
1239 | \`configure' configures firejail 0.9.28 to adapt to many kinds of systems. | ||
1240 | |||
1241 | Usage: $0 [OPTION]... [VAR=VALUE]... | ||
1242 | |||
1243 | To assign environment variables (e.g., CC, CFLAGS...), specify them as | ||
1244 | VAR=VALUE. See below for descriptions of some of the useful variables. | ||
1245 | |||
1246 | Defaults for the options are specified in brackets. | ||
1247 | |||
1248 | Configuration: | ||
1249 | -h, --help display this help and exit | ||
1250 | --help=short display options specific to this package | ||
1251 | --help=recursive display the short help of all the included packages | ||
1252 | -V, --version display version information and exit | ||
1253 | -q, --quiet, --silent do not print \`checking ...' messages | ||
1254 | --cache-file=FILE cache test results in FILE [disabled] | ||
1255 | -C, --config-cache alias for \`--cache-file=config.cache' | ||
1256 | -n, --no-create do not create output files | ||
1257 | --srcdir=DIR find the sources in DIR [configure dir or \`..'] | ||
1258 | |||
1259 | Installation directories: | ||
1260 | --prefix=PREFIX install architecture-independent files in PREFIX | ||
1261 | [$ac_default_prefix] | ||
1262 | --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX | ||
1263 | [PREFIX] | ||
1264 | |||
1265 | By default, \`make install' will install all the files in | ||
1266 | \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify | ||
1267 | an installation prefix other than \`$ac_default_prefix' using \`--prefix', | ||
1268 | for instance \`--prefix=\$HOME'. | ||
1269 | |||
1270 | For better control, use the options below. | ||
1271 | |||
1272 | Fine tuning of the installation directories: | ||
1273 | --bindir=DIR user executables [EPREFIX/bin] | ||
1274 | --sbindir=DIR system admin executables [EPREFIX/sbin] | ||
1275 | --libexecdir=DIR program executables [EPREFIX/libexec] | ||
1276 | --sysconfdir=DIR read-only single-machine data [PREFIX/etc] | ||
1277 | --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] | ||
1278 | --localstatedir=DIR modifiable single-machine data [PREFIX/var] | ||
1279 | --libdir=DIR object code libraries [EPREFIX/lib] | ||
1280 | --includedir=DIR C header files [PREFIX/include] | ||
1281 | --oldincludedir=DIR C header files for non-gcc [/usr/include] | ||
1282 | --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] | ||
1283 | --datadir=DIR read-only architecture-independent data [DATAROOTDIR] | ||
1284 | --infodir=DIR info documentation [DATAROOTDIR/info] | ||
1285 | --localedir=DIR locale-dependent data [DATAROOTDIR/locale] | ||
1286 | --mandir=DIR man documentation [DATAROOTDIR/man] | ||
1287 | --docdir=DIR documentation root [DATAROOTDIR/doc/firejail] | ||
1288 | --htmldir=DIR html documentation [DOCDIR] | ||
1289 | --dvidir=DIR dvi documentation [DOCDIR] | ||
1290 | --pdfdir=DIR pdf documentation [DOCDIR] | ||
1291 | --psdir=DIR ps documentation [DOCDIR] | ||
1292 | _ACEOF | ||
1293 | |||
1294 | cat <<\_ACEOF | ||
1295 | _ACEOF | ||
1296 | fi | ||
1297 | |||
1298 | if test -n "$ac_init_help"; then | ||
1299 | case $ac_init_help in | ||
1300 | short | recursive ) echo "Configuration of firejail 0.9.28:";; | ||
1301 | esac | ||
1302 | cat <<\_ACEOF | ||
1303 | |||
1304 | Optional Features: | ||
1305 | --disable-option-checking ignore unrecognized --enable/--with options | ||
1306 | --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) | ||
1307 | --enable-FEATURE[=ARG] include FEATURE [ARG=yes] | ||
1308 | --disable-seccomp Disable seccomp | ||
1309 | --disable-chroot Disable chroot | ||
1310 | --disable-bind Disable bind | ||
1311 | |||
1312 | Some influential environment variables: | ||
1313 | CC C compiler command | ||
1314 | CFLAGS C compiler flags | ||
1315 | LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a | ||
1316 | nonstandard directory <lib dir> | ||
1317 | LIBS libraries to pass to the linker, e.g. -l<library> | ||
1318 | CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if | ||
1319 | you have headers in a nonstandard directory <include dir> | ||
1320 | CPP C preprocessor | ||
1321 | |||
1322 | Use these variables to override the choices made by `configure' or to help | ||
1323 | it to find libraries and programs with nonstandard names/locations. | ||
1324 | |||
1325 | Report bugs to <netblue30@yahoo.com>. | ||
1326 | firejail home page: <http://firejail.sourceforge.net>. | ||
1327 | _ACEOF | ||
1328 | ac_status=$? | ||
1329 | fi | ||
1330 | |||
1331 | if test "$ac_init_help" = "recursive"; then | ||
1332 | # If there are subdirs, report their specific --help. | ||
1333 | for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue | ||
1334 | test -d "$ac_dir" || | ||
1335 | { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || | ||
1336 | continue | ||
1337 | ac_builddir=. | ||
1338 | |||
1339 | case "$ac_dir" in | ||
1340 | .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; | ||
1341 | *) | ||
1342 | ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` | ||
1343 | # A ".." for each directory in $ac_dir_suffix. | ||
1344 | ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` | ||
1345 | case $ac_top_builddir_sub in | ||
1346 | "") ac_top_builddir_sub=. ac_top_build_prefix= ;; | ||
1347 | *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; | ||
1348 | esac ;; | ||
1349 | esac | ||
1350 | ac_abs_top_builddir=$ac_pwd | ||
1351 | ac_abs_builddir=$ac_pwd$ac_dir_suffix | ||
1352 | # for backward compatibility: | ||
1353 | ac_top_builddir=$ac_top_build_prefix | ||
1354 | |||
1355 | case $srcdir in | ||
1356 | .) # We are building in place. | ||
1357 | ac_srcdir=. | ||
1358 | ac_top_srcdir=$ac_top_builddir_sub | ||
1359 | ac_abs_top_srcdir=$ac_pwd ;; | ||
1360 | [\\/]* | ?:[\\/]* ) # Absolute name. | ||
1361 | ac_srcdir=$srcdir$ac_dir_suffix; | ||
1362 | ac_top_srcdir=$srcdir | ||
1363 | ac_abs_top_srcdir=$srcdir ;; | ||
1364 | *) # Relative name. | ||
1365 | ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix | ||
1366 | ac_top_srcdir=$ac_top_build_prefix$srcdir | ||
1367 | ac_abs_top_srcdir=$ac_pwd/$srcdir ;; | ||
1368 | esac | ||
1369 | ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix | ||
1370 | |||
1371 | cd "$ac_dir" || { ac_status=$?; continue; } | ||
1372 | # Check for guested configure. | ||
1373 | if test -f "$ac_srcdir/configure.gnu"; then | ||
1374 | echo && | ||
1375 | $SHELL "$ac_srcdir/configure.gnu" --help=recursive | ||
1376 | elif test -f "$ac_srcdir/configure"; then | ||
1377 | echo && | ||
1378 | $SHELL "$ac_srcdir/configure" --help=recursive | ||
1379 | else | ||
1380 | $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 | ||
1381 | fi || ac_status=$? | ||
1382 | cd "$ac_pwd" || { ac_status=$?; break; } | ||
1383 | done | ||
1384 | fi | ||
1385 | |||
1386 | test -n "$ac_init_help" && exit $ac_status | ||
1387 | if $ac_init_version; then | ||
1388 | cat <<\_ACEOF | ||
1389 | firejail configure 0.9.28 | ||
1390 | generated by GNU Autoconf 2.69 | ||
1391 | |||
1392 | Copyright (C) 2012 Free Software Foundation, Inc. | ||
1393 | This configure script is free software; the Free Software Foundation | ||
1394 | gives unlimited permission to copy, distribute and modify it. | ||
1395 | _ACEOF | ||
1396 | exit | ||
1397 | fi | ||
1398 | |||
1399 | ## ------------------------ ## | ||
1400 | ## Autoconf initialization. ## | ||
1401 | ## ------------------------ ## | ||
1402 | |||
1403 | # ac_fn_c_try_compile LINENO | ||
1404 | # -------------------------- | ||
1405 | # Try to compile conftest.$ac_ext, and return whether this succeeded. | ||
1406 | ac_fn_c_try_compile () | ||
1407 | { | ||
1408 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | ||
1409 | rm -f conftest.$ac_objext | ||
1410 | if { { ac_try="$ac_compile" | ||
1411 | case "(($ac_try" in | ||
1412 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | ||
1413 | *) ac_try_echo=$ac_try;; | ||
1414 | esac | ||
1415 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | ||
1416 | $as_echo "$ac_try_echo"; } >&5 | ||
1417 | (eval "$ac_compile") 2>conftest.err | ||
1418 | ac_status=$? | ||
1419 | if test -s conftest.err; then | ||
1420 | grep -v '^ *+' conftest.err >conftest.er1 | ||
1421 | cat conftest.er1 >&5 | ||
1422 | mv -f conftest.er1 conftest.err | ||
1423 | fi | ||
1424 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | ||
1425 | test $ac_status = 0; } && { | ||
1426 | test -z "$ac_c_werror_flag" || | ||
1427 | test ! -s conftest.err | ||
1428 | } && test -s conftest.$ac_objext; then : | ||
1429 | ac_retval=0 | ||
1430 | else | ||
1431 | $as_echo "$as_me: failed program was:" >&5 | ||
1432 | sed 's/^/| /' conftest.$ac_ext >&5 | ||
1433 | |||
1434 | ac_retval=1 | ||
1435 | fi | ||
1436 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | ||
1437 | as_fn_set_status $ac_retval | ||
1438 | |||
1439 | } # ac_fn_c_try_compile | ||
1440 | |||
1441 | # ac_fn_c_try_link LINENO | ||
1442 | # ----------------------- | ||
1443 | # Try to link conftest.$ac_ext, and return whether this succeeded. | ||
1444 | ac_fn_c_try_link () | ||
1445 | { | ||
1446 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | ||
1447 | rm -f conftest.$ac_objext conftest$ac_exeext | ||
1448 | if { { ac_try="$ac_link" | ||
1449 | case "(($ac_try" in | ||
1450 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | ||
1451 | *) ac_try_echo=$ac_try;; | ||
1452 | esac | ||
1453 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | ||
1454 | $as_echo "$ac_try_echo"; } >&5 | ||
1455 | (eval "$ac_link") 2>conftest.err | ||
1456 | ac_status=$? | ||
1457 | if test -s conftest.err; then | ||
1458 | grep -v '^ *+' conftest.err >conftest.er1 | ||
1459 | cat conftest.er1 >&5 | ||
1460 | mv -f conftest.er1 conftest.err | ||
1461 | fi | ||
1462 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | ||
1463 | test $ac_status = 0; } && { | ||
1464 | test -z "$ac_c_werror_flag" || | ||
1465 | test ! -s conftest.err | ||
1466 | } && test -s conftest$ac_exeext && { | ||
1467 | test "$cross_compiling" = yes || | ||
1468 | test -x conftest$ac_exeext | ||
1469 | }; then : | ||
1470 | ac_retval=0 | ||
1471 | else | ||
1472 | $as_echo "$as_me: failed program was:" >&5 | ||
1473 | sed 's/^/| /' conftest.$ac_ext >&5 | ||
1474 | |||
1475 | ac_retval=1 | ||
1476 | fi | ||
1477 | # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information | ||
1478 | # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would | ||
1479 | # interfere with the next link command; also delete a directory that is | ||
1480 | # left behind by Apple's compiler. We do this before executing the actions. | ||
1481 | rm -rf conftest.dSYM conftest_ipa8_conftest.oo | ||
1482 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | ||
1483 | as_fn_set_status $ac_retval | ||
1484 | |||
1485 | } # ac_fn_c_try_link | ||
1486 | |||
1487 | # ac_fn_c_try_cpp LINENO | ||
1488 | # ---------------------- | ||
1489 | # Try to preprocess conftest.$ac_ext, and return whether this succeeded. | ||
1490 | ac_fn_c_try_cpp () | ||
1491 | { | ||
1492 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | ||
1493 | if { { ac_try="$ac_cpp conftest.$ac_ext" | ||
1494 | case "(($ac_try" in | ||
1495 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | ||
1496 | *) ac_try_echo=$ac_try;; | ||
1497 | esac | ||
1498 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | ||
1499 | $as_echo "$ac_try_echo"; } >&5 | ||
1500 | (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err | ||
1501 | ac_status=$? | ||
1502 | if test -s conftest.err; then | ||
1503 | grep -v '^ *+' conftest.err >conftest.er1 | ||
1504 | cat conftest.er1 >&5 | ||
1505 | mv -f conftest.er1 conftest.err | ||
1506 | fi | ||
1507 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | ||
1508 | test $ac_status = 0; } > conftest.i && { | ||
1509 | test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || | ||
1510 | test ! -s conftest.err | ||
1511 | }; then : | ||
1512 | ac_retval=0 | ||
1513 | else | ||
1514 | $as_echo "$as_me: failed program was:" >&5 | ||
1515 | sed 's/^/| /' conftest.$ac_ext >&5 | ||
1516 | |||
1517 | ac_retval=1 | ||
1518 | fi | ||
1519 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | ||
1520 | as_fn_set_status $ac_retval | ||
1521 | |||
1522 | } # ac_fn_c_try_cpp | ||
1523 | |||
1524 | # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES | ||
1525 | # ------------------------------------------------------- | ||
1526 | # Tests whether HEADER exists, giving a warning if it cannot be compiled using | ||
1527 | # the include files in INCLUDES and setting the cache variable VAR | ||
1528 | # accordingly. | ||
1529 | ac_fn_c_check_header_mongrel () | ||
1530 | { | ||
1531 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | ||
1532 | if eval \${$3+:} false; then : | ||
1533 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 | ||
1534 | $as_echo_n "checking for $2... " >&6; } | ||
1535 | if eval \${$3+:} false; then : | ||
1536 | $as_echo_n "(cached) " >&6 | ||
1537 | fi | ||
1538 | eval ac_res=\$$3 | ||
1539 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 | ||
1540 | $as_echo "$ac_res" >&6; } | ||
1541 | else | ||
1542 | # Is the header compilable? | ||
1543 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 | ||
1544 | $as_echo_n "checking $2 usability... " >&6; } | ||
1545 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
1546 | /* end confdefs.h. */ | ||
1547 | $4 | ||
1548 | #include <$2> | ||
1549 | _ACEOF | ||
1550 | if ac_fn_c_try_compile "$LINENO"; then : | ||
1551 | ac_header_compiler=yes | ||
1552 | else | ||
1553 | ac_header_compiler=no | ||
1554 | fi | ||
1555 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | ||
1556 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 | ||
1557 | $as_echo "$ac_header_compiler" >&6; } | ||
1558 | |||
1559 | # Is the header present? | ||
1560 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 | ||
1561 | $as_echo_n "checking $2 presence... " >&6; } | ||
1562 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
1563 | /* end confdefs.h. */ | ||
1564 | #include <$2> | ||
1565 | _ACEOF | ||
1566 | if ac_fn_c_try_cpp "$LINENO"; then : | ||
1567 | ac_header_preproc=yes | ||
1568 | else | ||
1569 | ac_header_preproc=no | ||
1570 | fi | ||
1571 | rm -f conftest.err conftest.i conftest.$ac_ext | ||
1572 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 | ||
1573 | $as_echo "$ac_header_preproc" >&6; } | ||
1574 | |||
1575 | # So? What about this header? | ||
1576 | case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( | ||
1577 | yes:no: ) | ||
1578 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 | ||
1579 | $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&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 | ;; | ||
1583 | no:yes:* ) | ||
1584 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 | ||
1585 | $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} | ||
1586 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 | ||
1587 | $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} | ||
1588 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 | ||
1589 | $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} | ||
1590 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 | ||
1591 | $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} | ||
1592 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 | ||
1593 | $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} | ||
1594 | ( $as_echo "## ---------------------------------- ## | ||
1595 | ## Report this to netblue30@yahoo.com ## | ||
1596 | ## ---------------------------------- ##" | ||
1597 | ) | sed "s/^/$as_me: WARNING: /" >&2 | ||
1598 | ;; | ||
1599 | esac | ||
1600 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 | ||
1601 | $as_echo_n "checking for $2... " >&6; } | ||
1602 | if eval \${$3+:} false; then : | ||
1603 | $as_echo_n "(cached) " >&6 | ||
1604 | else | ||
1605 | eval "$3=\$ac_header_compiler" | ||
1606 | fi | ||
1607 | eval ac_res=\$$3 | ||
1608 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 | ||
1609 | $as_echo "$ac_res" >&6; } | ||
1610 | fi | ||
1611 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | ||
1612 | |||
1613 | } # ac_fn_c_check_header_mongrel | ||
1614 | |||
1615 | # ac_fn_c_try_run LINENO | ||
1616 | # ---------------------- | ||
1617 | # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes | ||
1618 | # that executables *can* be run. | ||
1619 | ac_fn_c_try_run () | ||
1620 | { | ||
1621 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | ||
1622 | if { { ac_try="$ac_link" | ||
1623 | case "(($ac_try" in | ||
1624 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | ||
1625 | *) ac_try_echo=$ac_try;; | ||
1626 | esac | ||
1627 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | ||
1628 | $as_echo "$ac_try_echo"; } >&5 | ||
1629 | (eval "$ac_link") 2>&5 | ||
1630 | ac_status=$? | ||
1631 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | ||
1632 | test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' | ||
1633 | { { case "(($ac_try" in | ||
1634 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | ||
1635 | *) ac_try_echo=$ac_try;; | ||
1636 | esac | ||
1637 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | ||
1638 | $as_echo "$ac_try_echo"; } >&5 | ||
1639 | (eval "$ac_try") 2>&5 | ||
1640 | ac_status=$? | ||
1641 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | ||
1642 | test $ac_status = 0; }; }; then : | ||
1643 | ac_retval=0 | ||
1644 | else | ||
1645 | $as_echo "$as_me: program exited with status $ac_status" >&5 | ||
1646 | $as_echo "$as_me: failed program was:" >&5 | ||
1647 | sed 's/^/| /' conftest.$ac_ext >&5 | ||
1648 | |||
1649 | ac_retval=$ac_status | ||
1650 | fi | ||
1651 | rm -rf conftest.dSYM conftest_ipa8_conftest.oo | ||
1652 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | ||
1653 | as_fn_set_status $ac_retval | ||
1654 | |||
1655 | } # ac_fn_c_try_run | ||
1656 | |||
1657 | # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES | ||
1658 | # ------------------------------------------------------- | ||
1659 | # Tests whether HEADER exists and can be compiled using the include files in | ||
1660 | # INCLUDES, setting the cache variable VAR accordingly. | ||
1661 | ac_fn_c_check_header_compile () | ||
1662 | { | ||
1663 | as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | ||
1664 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 | ||
1665 | $as_echo_n "checking for $2... " >&6; } | ||
1666 | if eval \${$3+:} false; then : | ||
1667 | $as_echo_n "(cached) " >&6 | ||
1668 | else | ||
1669 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
1670 | /* end confdefs.h. */ | ||
1671 | $4 | ||
1672 | #include <$2> | ||
1673 | _ACEOF | ||
1674 | if ac_fn_c_try_compile "$LINENO"; then : | ||
1675 | eval "$3=yes" | ||
1676 | else | ||
1677 | eval "$3=no" | ||
1678 | fi | ||
1679 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | ||
1680 | fi | ||
1681 | eval ac_res=\$$3 | ||
1682 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 | ||
1683 | $as_echo "$ac_res" >&6; } | ||
1684 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno | ||
1685 | |||
1686 | } # ac_fn_c_check_header_compile | ||
1687 | cat >config.log <<_ACEOF | ||
1688 | This file contains any messages produced by compilers while | ||
1689 | running configure, to aid debugging if configure makes a mistake. | ||
1690 | |||
1691 | It was created by firejail $as_me 0.9.28, which was | ||
1692 | generated by GNU Autoconf 2.69. Invocation command line was | ||
1693 | |||
1694 | $ $0 $@ | ||
1695 | |||
1696 | _ACEOF | ||
1697 | exec 5>>config.log | ||
1698 | { | ||
1699 | cat <<_ASUNAME | ||
1700 | ## --------- ## | ||
1701 | ## Platform. ## | ||
1702 | ## --------- ## | ||
1703 | |||
1704 | hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` | ||
1705 | uname -m = `(uname -m) 2>/dev/null || echo unknown` | ||
1706 | uname -r = `(uname -r) 2>/dev/null || echo unknown` | ||
1707 | uname -s = `(uname -s) 2>/dev/null || echo unknown` | ||
1708 | uname -v = `(uname -v) 2>/dev/null || echo unknown` | ||
1709 | |||
1710 | /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` | ||
1711 | /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` | ||
1712 | |||
1713 | /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` | ||
1714 | /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` | ||
1715 | /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` | ||
1716 | /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` | ||
1717 | /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` | ||
1718 | /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` | ||
1719 | /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` | ||
1720 | |||
1721 | _ASUNAME | ||
1722 | |||
1723 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
1724 | for as_dir in $PATH | ||
1725 | do | ||
1726 | IFS=$as_save_IFS | ||
1727 | test -z "$as_dir" && as_dir=. | ||
1728 | $as_echo "PATH: $as_dir" | ||
1729 | done | ||
1730 | IFS=$as_save_IFS | ||
1731 | |||
1732 | } >&5 | ||
1733 | |||
1734 | cat >&5 <<_ACEOF | ||
1735 | |||
1736 | |||
1737 | ## ----------- ## | ||
1738 | ## Core tests. ## | ||
1739 | ## ----------- ## | ||
1740 | |||
1741 | _ACEOF | ||
1742 | |||
1743 | |||
1744 | # Keep a trace of the command line. | ||
1745 | # Strip out --no-create and --no-recursion so they do not pile up. | ||
1746 | # Strip out --silent because we don't want to record it for future runs. | ||
1747 | # Also quote any args containing shell meta-characters. | ||
1748 | # Make two passes to allow for proper duplicate-argument suppression. | ||
1749 | ac_configure_args= | ||
1750 | ac_configure_args0= | ||
1751 | ac_configure_args1= | ||
1752 | ac_must_keep_next=false | ||
1753 | for ac_pass in 1 2 | ||
1754 | do | ||
1755 | for ac_arg | ||
1756 | do | ||
1757 | case $ac_arg in | ||
1758 | -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; | ||
1759 | -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | ||
1760 | | -silent | --silent | --silen | --sile | --sil) | ||
1761 | continue ;; | ||
1762 | *\'*) | ||
1763 | ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; | ||
1764 | esac | ||
1765 | case $ac_pass in | ||
1766 | 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; | ||
1767 | 2) | ||
1768 | as_fn_append ac_configure_args1 " '$ac_arg'" | ||
1769 | if test $ac_must_keep_next = true; then | ||
1770 | ac_must_keep_next=false # Got value, back to normal. | ||
1771 | else | ||
1772 | case $ac_arg in | ||
1773 | *=* | --config-cache | -C | -disable-* | --disable-* \ | ||
1774 | | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | ||
1775 | | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | ||
1776 | | -with-* | --with-* | -without-* | --without-* | --x) | ||
1777 | case "$ac_configure_args0 " in | ||
1778 | "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; | ||
1779 | esac | ||
1780 | ;; | ||
1781 | -* ) ac_must_keep_next=true ;; | ||
1782 | esac | ||
1783 | fi | ||
1784 | as_fn_append ac_configure_args " '$ac_arg'" | ||
1785 | ;; | ||
1786 | esac | ||
1787 | done | ||
1788 | done | ||
1789 | { ac_configure_args0=; unset ac_configure_args0;} | ||
1790 | { ac_configure_args1=; unset ac_configure_args1;} | ||
1791 | |||
1792 | # When interrupted or exit'd, cleanup temporary files, and complete | ||
1793 | # config.log. We remove comments because anyway the quotes in there | ||
1794 | # would cause problems or look ugly. | ||
1795 | # WARNING: Use '\'' to represent an apostrophe within the trap. | ||
1796 | # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. | ||
1797 | trap 'exit_status=$? | ||
1798 | # Save into config.log some information that might help in debugging. | ||
1799 | { | ||
1800 | echo | ||
1801 | |||
1802 | $as_echo "## ---------------- ## | ||
1803 | ## Cache variables. ## | ||
1804 | ## ---------------- ##" | ||
1805 | echo | ||
1806 | # The following way of writing the cache mishandles newlines in values, | ||
1807 | ( | ||
1808 | for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do | ||
1809 | eval ac_val=\$$ac_var | ||
1810 | case $ac_val in #( | ||
1811 | *${as_nl}*) | ||
1812 | case $ac_var in #( | ||
1813 | *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 | ||
1814 | $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; | ||
1815 | esac | ||
1816 | case $ac_var in #( | ||
1817 | _ | IFS | as_nl) ;; #( | ||
1818 | BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( | ||
1819 | *) { eval $ac_var=; unset $ac_var;} ;; | ||
1820 | esac ;; | ||
1821 | esac | ||
1822 | done | ||
1823 | (set) 2>&1 | | ||
1824 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( | ||
1825 | *${as_nl}ac_space=\ *) | ||
1826 | sed -n \ | ||
1827 | "s/'\''/'\''\\\\'\'''\''/g; | ||
1828 | s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" | ||
1829 | ;; #( | ||
1830 | *) | ||
1831 | sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" | ||
1832 | ;; | ||
1833 | esac | | ||
1834 | sort | ||
1835 | ) | ||
1836 | echo | ||
1837 | |||
1838 | $as_echo "## ----------------- ## | ||
1839 | ## Output variables. ## | ||
1840 | ## ----------------- ##" | ||
1841 | echo | ||
1842 | for ac_var in $ac_subst_vars | ||
1843 | do | ||
1844 | eval ac_val=\$$ac_var | ||
1845 | case $ac_val in | ||
1846 | *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; | ||
1847 | esac | ||
1848 | $as_echo "$ac_var='\''$ac_val'\''" | ||
1849 | done | sort | ||
1850 | echo | ||
1851 | |||
1852 | if test -n "$ac_subst_files"; then | ||
1853 | $as_echo "## ------------------- ## | ||
1854 | ## File substitutions. ## | ||
1855 | ## ------------------- ##" | ||
1856 | echo | ||
1857 | for ac_var in $ac_subst_files | ||
1858 | do | ||
1859 | eval ac_val=\$$ac_var | ||
1860 | case $ac_val in | ||
1861 | *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; | ||
1862 | esac | ||
1863 | $as_echo "$ac_var='\''$ac_val'\''" | ||
1864 | done | sort | ||
1865 | echo | ||
1866 | fi | ||
1867 | |||
1868 | if test -s confdefs.h; then | ||
1869 | $as_echo "## ----------- ## | ||
1870 | ## confdefs.h. ## | ||
1871 | ## ----------- ##" | ||
1872 | echo | ||
1873 | cat confdefs.h | ||
1874 | echo | ||
1875 | fi | ||
1876 | test "$ac_signal" != 0 && | ||
1877 | $as_echo "$as_me: caught signal $ac_signal" | ||
1878 | $as_echo "$as_me: exit $exit_status" | ||
1879 | } >&5 | ||
1880 | rm -f core *.core core.conftest.* && | ||
1881 | rm -f -r conftest* confdefs* conf$$* $ac_clean_files && | ||
1882 | exit $exit_status | ||
1883 | ' 0 | ||
1884 | for ac_signal in 1 2 13 15; do | ||
1885 | trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal | ||
1886 | done | ||
1887 | ac_signal=0 | ||
1888 | |||
1889 | # confdefs.h avoids OS command line length limits that DEFS can exceed. | ||
1890 | rm -f -r conftest* confdefs.h | ||
1891 | |||
1892 | $as_echo "/* confdefs.h */" > confdefs.h | ||
1893 | |||
1894 | # Predefined preprocessor variables. | ||
1895 | |||
1896 | cat >>confdefs.h <<_ACEOF | ||
1897 | #define PACKAGE_NAME "$PACKAGE_NAME" | ||
1898 | _ACEOF | ||
1899 | |||
1900 | cat >>confdefs.h <<_ACEOF | ||
1901 | #define PACKAGE_TARNAME "$PACKAGE_TARNAME" | ||
1902 | _ACEOF | ||
1903 | |||
1904 | cat >>confdefs.h <<_ACEOF | ||
1905 | #define PACKAGE_VERSION "$PACKAGE_VERSION" | ||
1906 | _ACEOF | ||
1907 | |||
1908 | cat >>confdefs.h <<_ACEOF | ||
1909 | #define PACKAGE_STRING "$PACKAGE_STRING" | ||
1910 | _ACEOF | ||
1911 | |||
1912 | cat >>confdefs.h <<_ACEOF | ||
1913 | #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" | ||
1914 | _ACEOF | ||
1915 | |||
1916 | cat >>confdefs.h <<_ACEOF | ||
1917 | #define PACKAGE_URL "$PACKAGE_URL" | ||
1918 | _ACEOF | ||
1919 | |||
1920 | |||
1921 | # Let the site file select an alternate cache file if it wants to. | ||
1922 | # Prefer an explicitly selected file to automatically selected ones. | ||
1923 | ac_site_file1=NONE | ||
1924 | ac_site_file2=NONE | ||
1925 | if test -n "$CONFIG_SITE"; then | ||
1926 | # We do not want a PATH search for config.site. | ||
1927 | case $CONFIG_SITE in #(( | ||
1928 | -*) ac_site_file1=./$CONFIG_SITE;; | ||
1929 | */*) ac_site_file1=$CONFIG_SITE;; | ||
1930 | *) ac_site_file1=./$CONFIG_SITE;; | ||
1931 | esac | ||
1932 | elif test "x$prefix" != xNONE; then | ||
1933 | ac_site_file1=$prefix/share/config.site | ||
1934 | ac_site_file2=$prefix/etc/config.site | ||
1935 | else | ||
1936 | ac_site_file1=$ac_default_prefix/share/config.site | ||
1937 | ac_site_file2=$ac_default_prefix/etc/config.site | ||
1938 | fi | ||
1939 | for ac_site_file in "$ac_site_file1" "$ac_site_file2" | ||
1940 | do | ||
1941 | test "x$ac_site_file" = xNONE && continue | ||
1942 | if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then | ||
1943 | { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 | ||
1944 | $as_echo "$as_me: loading site script $ac_site_file" >&6;} | ||
1945 | sed 's/^/| /' "$ac_site_file" >&5 | ||
1946 | . "$ac_site_file" \ | ||
1947 | || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 | ||
1948 | $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} | ||
1949 | as_fn_error $? "failed to load site script $ac_site_file | ||
1950 | See \`config.log' for more details" "$LINENO" 5; } | ||
1951 | fi | ||
1952 | done | ||
1953 | |||
1954 | if test -r "$cache_file"; then | ||
1955 | # Some versions of bash will fail to source /dev/null (special files | ||
1956 | # actually), so we avoid doing that. DJGPP emulates it as a regular file. | ||
1957 | if test /dev/null != "$cache_file" && test -f "$cache_file"; then | ||
1958 | { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 | ||
1959 | $as_echo "$as_me: loading cache $cache_file" >&6;} | ||
1960 | case $cache_file in | ||
1961 | [\\/]* | ?:[\\/]* ) . "$cache_file";; | ||
1962 | *) . "./$cache_file";; | ||
1963 | esac | ||
1964 | fi | ||
1965 | else | ||
1966 | { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 | ||
1967 | $as_echo "$as_me: creating cache $cache_file" >&6;} | ||
1968 | >$cache_file | ||
1969 | fi | ||
1970 | |||
1971 | # Check that the precious variables saved in the cache have kept the same | ||
1972 | # value. | ||
1973 | ac_cache_corrupted=false | ||
1974 | for ac_var in $ac_precious_vars; do | ||
1975 | eval ac_old_set=\$ac_cv_env_${ac_var}_set | ||
1976 | eval ac_new_set=\$ac_env_${ac_var}_set | ||
1977 | eval ac_old_val=\$ac_cv_env_${ac_var}_value | ||
1978 | eval ac_new_val=\$ac_env_${ac_var}_value | ||
1979 | case $ac_old_set,$ac_new_set in | ||
1980 | set,) | ||
1981 | { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 | ||
1982 | $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} | ||
1983 | ac_cache_corrupted=: ;; | ||
1984 | ,set) | ||
1985 | { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 | ||
1986 | $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} | ||
1987 | ac_cache_corrupted=: ;; | ||
1988 | ,);; | ||
1989 | *) | ||
1990 | if test "x$ac_old_val" != "x$ac_new_val"; then | ||
1991 | # differences in whitespace do not lead to failure. | ||
1992 | ac_old_val_w=`echo x $ac_old_val` | ||
1993 | ac_new_val_w=`echo x $ac_new_val` | ||
1994 | if test "$ac_old_val_w" != "$ac_new_val_w"; then | ||
1995 | { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 | ||
1996 | $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} | ||
1997 | ac_cache_corrupted=: | ||
1998 | else | ||
1999 | { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 | ||
2000 | $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} | ||
2001 | eval $ac_var=\$ac_old_val | ||
2002 | fi | ||
2003 | { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 | ||
2004 | $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} | ||
2005 | { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 | ||
2006 | $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} | ||
2007 | fi;; | ||
2008 | esac | ||
2009 | # Pass precious variables to config.status. | ||
2010 | if test "$ac_new_set" = set; then | ||
2011 | case $ac_new_val in | ||
2012 | *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; | ||
2013 | *) ac_arg=$ac_var=$ac_new_val ;; | ||
2014 | esac | ||
2015 | case " $ac_configure_args " in | ||
2016 | *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. | ||
2017 | *) as_fn_append ac_configure_args " '$ac_arg'" ;; | ||
2018 | esac | ||
2019 | fi | ||
2020 | done | ||
2021 | if $ac_cache_corrupted; then | ||
2022 | { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 | ||
2023 | $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} | ||
2024 | { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 | ||
2025 | $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} | ||
2026 | as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 | ||
2027 | fi | ||
2028 | ## -------------------- ## | ||
2029 | ## Main body of script. ## | ||
2030 | ## -------------------- ## | ||
2031 | |||
2032 | ac_ext=c | ||
2033 | ac_cpp='$CPP $CPPFLAGS' | ||
2034 | ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' | ||
2035 | ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' | ||
2036 | ac_compiler_gnu=$ac_cv_c_compiler_gnu | ||
2037 | |||
2038 | |||
2039 | |||
2040 | #AC_CONFIG_HEADERS([config.h]) | ||
2041 | |||
2042 | |||
2043 | ac_ext=c | ||
2044 | ac_cpp='$CPP $CPPFLAGS' | ||
2045 | ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' | ||
2046 | ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' | ||
2047 | ac_compiler_gnu=$ac_cv_c_compiler_gnu | ||
2048 | if test -n "$ac_tool_prefix"; then | ||
2049 | # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. | ||
2050 | set dummy ${ac_tool_prefix}gcc; ac_word=$2 | ||
2051 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 | ||
2052 | $as_echo_n "checking for $ac_word... " >&6; } | ||
2053 | if ${ac_cv_prog_CC+:} false; then : | ||
2054 | $as_echo_n "(cached) " >&6 | ||
2055 | else | ||
2056 | if test -n "$CC"; then | ||
2057 | ac_cv_prog_CC="$CC" # Let the user override the test. | ||
2058 | else | ||
2059 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
2060 | for as_dir in $PATH | ||
2061 | do | ||
2062 | IFS=$as_save_IFS | ||
2063 | test -z "$as_dir" && as_dir=. | ||
2064 | for ac_exec_ext in '' $ac_executable_extensions; do | ||
2065 | if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then | ||
2066 | ac_cv_prog_CC="${ac_tool_prefix}gcc" | ||
2067 | $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 | ||
2068 | break 2 | ||
2069 | fi | ||
2070 | done | ||
2071 | done | ||
2072 | IFS=$as_save_IFS | ||
2073 | |||
2074 | fi | ||
2075 | fi | ||
2076 | CC=$ac_cv_prog_CC | ||
2077 | if test -n "$CC"; then | ||
2078 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 | ||
2079 | $as_echo "$CC" >&6; } | ||
2080 | else | ||
2081 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | ||
2082 | $as_echo "no" >&6; } | ||
2083 | fi | ||
2084 | |||
2085 | |||
2086 | fi | ||
2087 | if test -z "$ac_cv_prog_CC"; then | ||
2088 | ac_ct_CC=$CC | ||
2089 | # Extract the first word of "gcc", so it can be a program name with args. | ||
2090 | set dummy gcc; ac_word=$2 | ||
2091 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 | ||
2092 | $as_echo_n "checking for $ac_word... " >&6; } | ||
2093 | if ${ac_cv_prog_ac_ct_CC+:} false; then : | ||
2094 | $as_echo_n "(cached) " >&6 | ||
2095 | else | ||
2096 | if test -n "$ac_ct_CC"; then | ||
2097 | ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. | ||
2098 | else | ||
2099 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
2100 | for as_dir in $PATH | ||
2101 | do | ||
2102 | IFS=$as_save_IFS | ||
2103 | test -z "$as_dir" && as_dir=. | ||
2104 | for ac_exec_ext in '' $ac_executable_extensions; do | ||
2105 | if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then | ||
2106 | ac_cv_prog_ac_ct_CC="gcc" | ||
2107 | $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 | ||
2108 | break 2 | ||
2109 | fi | ||
2110 | done | ||
2111 | done | ||
2112 | IFS=$as_save_IFS | ||
2113 | |||
2114 | fi | ||
2115 | fi | ||
2116 | ac_ct_CC=$ac_cv_prog_ac_ct_CC | ||
2117 | if test -n "$ac_ct_CC"; then | ||
2118 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 | ||
2119 | $as_echo "$ac_ct_CC" >&6; } | ||
2120 | else | ||
2121 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | ||
2122 | $as_echo "no" >&6; } | ||
2123 | fi | ||
2124 | |||
2125 | if test "x$ac_ct_CC" = x; then | ||
2126 | CC="" | ||
2127 | else | ||
2128 | case $cross_compiling:$ac_tool_warned in | ||
2129 | yes:) | ||
2130 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 | ||
2131 | $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} | ||
2132 | ac_tool_warned=yes ;; | ||
2133 | esac | ||
2134 | CC=$ac_ct_CC | ||
2135 | fi | ||
2136 | else | ||
2137 | CC="$ac_cv_prog_CC" | ||
2138 | fi | ||
2139 | |||
2140 | if test -z "$CC"; then | ||
2141 | if test -n "$ac_tool_prefix"; then | ||
2142 | # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. | ||
2143 | set dummy ${ac_tool_prefix}cc; ac_word=$2 | ||
2144 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 | ||
2145 | $as_echo_n "checking for $ac_word... " >&6; } | ||
2146 | if ${ac_cv_prog_CC+:} false; then : | ||
2147 | $as_echo_n "(cached) " >&6 | ||
2148 | else | ||
2149 | if test -n "$CC"; then | ||
2150 | ac_cv_prog_CC="$CC" # Let the user override the test. | ||
2151 | else | ||
2152 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
2153 | for as_dir in $PATH | ||
2154 | do | ||
2155 | IFS=$as_save_IFS | ||
2156 | test -z "$as_dir" && as_dir=. | ||
2157 | for ac_exec_ext in '' $ac_executable_extensions; do | ||
2158 | if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then | ||
2159 | ac_cv_prog_CC="${ac_tool_prefix}cc" | ||
2160 | $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 | ||
2161 | break 2 | ||
2162 | fi | ||
2163 | done | ||
2164 | done | ||
2165 | IFS=$as_save_IFS | ||
2166 | |||
2167 | fi | ||
2168 | fi | ||
2169 | CC=$ac_cv_prog_CC | ||
2170 | if test -n "$CC"; then | ||
2171 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 | ||
2172 | $as_echo "$CC" >&6; } | ||
2173 | else | ||
2174 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | ||
2175 | $as_echo "no" >&6; } | ||
2176 | fi | ||
2177 | |||
2178 | |||
2179 | fi | ||
2180 | fi | ||
2181 | if test -z "$CC"; then | ||
2182 | # Extract the first word of "cc", so it can be a program name with args. | ||
2183 | set dummy cc; ac_word=$2 | ||
2184 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 | ||
2185 | $as_echo_n "checking for $ac_word... " >&6; } | ||
2186 | if ${ac_cv_prog_CC+:} false; then : | ||
2187 | $as_echo_n "(cached) " >&6 | ||
2188 | else | ||
2189 | if test -n "$CC"; then | ||
2190 | ac_cv_prog_CC="$CC" # Let the user override the test. | ||
2191 | else | ||
2192 | ac_prog_rejected=no | ||
2193 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
2194 | for as_dir in $PATH | ||
2195 | do | ||
2196 | IFS=$as_save_IFS | ||
2197 | test -z "$as_dir" && as_dir=. | ||
2198 | for ac_exec_ext in '' $ac_executable_extensions; do | ||
2199 | if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then | ||
2200 | if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then | ||
2201 | ac_prog_rejected=yes | ||
2202 | continue | ||
2203 | fi | ||
2204 | ac_cv_prog_CC="cc" | ||
2205 | $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 | ||
2206 | break 2 | ||
2207 | fi | ||
2208 | done | ||
2209 | done | ||
2210 | IFS=$as_save_IFS | ||
2211 | |||
2212 | if test $ac_prog_rejected = yes; then | ||
2213 | # We found a bogon in the path, so make sure we never use it. | ||
2214 | set dummy $ac_cv_prog_CC | ||
2215 | shift | ||
2216 | if test $# != 0; then | ||
2217 | # We chose a different compiler from the bogus one. | ||
2218 | # However, it has the same basename, so the bogon will be chosen | ||
2219 | # first if we set CC to just the basename; use the full file name. | ||
2220 | shift | ||
2221 | ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" | ||
2222 | fi | ||
2223 | fi | ||
2224 | fi | ||
2225 | fi | ||
2226 | CC=$ac_cv_prog_CC | ||
2227 | if test -n "$CC"; then | ||
2228 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 | ||
2229 | $as_echo "$CC" >&6; } | ||
2230 | else | ||
2231 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | ||
2232 | $as_echo "no" >&6; } | ||
2233 | fi | ||
2234 | |||
2235 | |||
2236 | fi | ||
2237 | if test -z "$CC"; then | ||
2238 | if test -n "$ac_tool_prefix"; then | ||
2239 | for ac_prog in cl.exe | ||
2240 | do | ||
2241 | # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. | ||
2242 | set dummy $ac_tool_prefix$ac_prog; ac_word=$2 | ||
2243 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 | ||
2244 | $as_echo_n "checking for $ac_word... " >&6; } | ||
2245 | if ${ac_cv_prog_CC+:} false; then : | ||
2246 | $as_echo_n "(cached) " >&6 | ||
2247 | else | ||
2248 | if test -n "$CC"; then | ||
2249 | ac_cv_prog_CC="$CC" # Let the user override the test. | ||
2250 | else | ||
2251 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
2252 | for as_dir in $PATH | ||
2253 | do | ||
2254 | IFS=$as_save_IFS | ||
2255 | test -z "$as_dir" && as_dir=. | ||
2256 | for ac_exec_ext in '' $ac_executable_extensions; do | ||
2257 | if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then | ||
2258 | ac_cv_prog_CC="$ac_tool_prefix$ac_prog" | ||
2259 | $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 | ||
2260 | break 2 | ||
2261 | fi | ||
2262 | done | ||
2263 | done | ||
2264 | IFS=$as_save_IFS | ||
2265 | |||
2266 | fi | ||
2267 | fi | ||
2268 | CC=$ac_cv_prog_CC | ||
2269 | if test -n "$CC"; then | ||
2270 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 | ||
2271 | $as_echo "$CC" >&6; } | ||
2272 | else | ||
2273 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | ||
2274 | $as_echo "no" >&6; } | ||
2275 | fi | ||
2276 | |||
2277 | |||
2278 | test -n "$CC" && break | ||
2279 | done | ||
2280 | fi | ||
2281 | if test -z "$CC"; then | ||
2282 | ac_ct_CC=$CC | ||
2283 | for ac_prog in cl.exe | ||
2284 | do | ||
2285 | # Extract the first word of "$ac_prog", so it can be a program name with args. | ||
2286 | set dummy $ac_prog; ac_word=$2 | ||
2287 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 | ||
2288 | $as_echo_n "checking for $ac_word... " >&6; } | ||
2289 | if ${ac_cv_prog_ac_ct_CC+:} false; then : | ||
2290 | $as_echo_n "(cached) " >&6 | ||
2291 | else | ||
2292 | if test -n "$ac_ct_CC"; then | ||
2293 | ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. | ||
2294 | else | ||
2295 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
2296 | for as_dir in $PATH | ||
2297 | do | ||
2298 | IFS=$as_save_IFS | ||
2299 | test -z "$as_dir" && as_dir=. | ||
2300 | for ac_exec_ext in '' $ac_executable_extensions; do | ||
2301 | if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then | ||
2302 | ac_cv_prog_ac_ct_CC="$ac_prog" | ||
2303 | $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 | ||
2304 | break 2 | ||
2305 | fi | ||
2306 | done | ||
2307 | done | ||
2308 | IFS=$as_save_IFS | ||
2309 | |||
2310 | fi | ||
2311 | fi | ||
2312 | ac_ct_CC=$ac_cv_prog_ac_ct_CC | ||
2313 | if test -n "$ac_ct_CC"; then | ||
2314 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 | ||
2315 | $as_echo "$ac_ct_CC" >&6; } | ||
2316 | else | ||
2317 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | ||
2318 | $as_echo "no" >&6; } | ||
2319 | fi | ||
2320 | |||
2321 | |||
2322 | test -n "$ac_ct_CC" && break | ||
2323 | done | ||
2324 | |||
2325 | if test "x$ac_ct_CC" = x; then | ||
2326 | CC="" | ||
2327 | else | ||
2328 | case $cross_compiling:$ac_tool_warned in | ||
2329 | yes:) | ||
2330 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 | ||
2331 | $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} | ||
2332 | ac_tool_warned=yes ;; | ||
2333 | esac | ||
2334 | CC=$ac_ct_CC | ||
2335 | fi | ||
2336 | fi | ||
2337 | |||
2338 | fi | ||
2339 | |||
2340 | |||
2341 | test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 | ||
2342 | $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} | ||
2343 | as_fn_error $? "no acceptable C compiler found in \$PATH | ||
2344 | See \`config.log' for more details" "$LINENO" 5; } | ||
2345 | |||
2346 | # Provide some information about the compiler. | ||
2347 | $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 | ||
2348 | set X $ac_compile | ||
2349 | ac_compiler=$2 | ||
2350 | for ac_option in --version -v -V -qversion; do | ||
2351 | { { ac_try="$ac_compiler $ac_option >&5" | ||
2352 | case "(($ac_try" in | ||
2353 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | ||
2354 | *) ac_try_echo=$ac_try;; | ||
2355 | esac | ||
2356 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | ||
2357 | $as_echo "$ac_try_echo"; } >&5 | ||
2358 | (eval "$ac_compiler $ac_option >&5") 2>conftest.err | ||
2359 | ac_status=$? | ||
2360 | if test -s conftest.err; then | ||
2361 | sed '10a\ | ||
2362 | ... rest of stderr output deleted ... | ||
2363 | 10q' conftest.err >conftest.er1 | ||
2364 | cat conftest.er1 >&5 | ||
2365 | fi | ||
2366 | rm -f conftest.er1 conftest.err | ||
2367 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | ||
2368 | test $ac_status = 0; } | ||
2369 | done | ||
2370 | |||
2371 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
2372 | /* end confdefs.h. */ | ||
2373 | |||
2374 | int | ||
2375 | main () | ||
2376 | { | ||
2377 | |||
2378 | ; | ||
2379 | return 0; | ||
2380 | } | ||
2381 | _ACEOF | ||
2382 | ac_clean_files_save=$ac_clean_files | ||
2383 | ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" | ||
2384 | # Try to create an executable without -o first, disregard a.out. | ||
2385 | # It will help us diagnose broken compilers, and finding out an intuition | ||
2386 | # of exeext. | ||
2387 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 | ||
2388 | $as_echo_n "checking whether the C compiler works... " >&6; } | ||
2389 | ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` | ||
2390 | |||
2391 | # The possible output files: | ||
2392 | ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" | ||
2393 | |||
2394 | ac_rmfiles= | ||
2395 | for ac_file in $ac_files | ||
2396 | do | ||
2397 | case $ac_file in | ||
2398 | *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; | ||
2399 | * ) ac_rmfiles="$ac_rmfiles $ac_file";; | ||
2400 | esac | ||
2401 | done | ||
2402 | rm -f $ac_rmfiles | ||
2403 | |||
2404 | if { { ac_try="$ac_link_default" | ||
2405 | case "(($ac_try" in | ||
2406 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | ||
2407 | *) ac_try_echo=$ac_try;; | ||
2408 | esac | ||
2409 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | ||
2410 | $as_echo "$ac_try_echo"; } >&5 | ||
2411 | (eval "$ac_link_default") 2>&5 | ||
2412 | ac_status=$? | ||
2413 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | ||
2414 | test $ac_status = 0; }; then : | ||
2415 | # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. | ||
2416 | # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' | ||
2417 | # in a Makefile. We should not override ac_cv_exeext if it was cached, | ||
2418 | # so that the user can short-circuit this test for compilers unknown to | ||
2419 | # Autoconf. | ||
2420 | for ac_file in $ac_files '' | ||
2421 | do | ||
2422 | test -f "$ac_file" || continue | ||
2423 | case $ac_file in | ||
2424 | *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) | ||
2425 | ;; | ||
2426 | [ab].out ) | ||
2427 | # We found the default executable, but exeext='' is most | ||
2428 | # certainly right. | ||
2429 | break;; | ||
2430 | *.* ) | ||
2431 | if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; | ||
2432 | then :; else | ||
2433 | ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` | ||
2434 | fi | ||
2435 | # We set ac_cv_exeext here because the later test for it is not | ||
2436 | # safe: cross compilers may not add the suffix if given an `-o' | ||
2437 | # argument, so we may need to know it at that point already. | ||
2438 | # Even if this section looks crufty: it has the advantage of | ||
2439 | # actually working. | ||
2440 | break;; | ||
2441 | * ) | ||
2442 | break;; | ||
2443 | esac | ||
2444 | done | ||
2445 | test "$ac_cv_exeext" = no && ac_cv_exeext= | ||
2446 | |||
2447 | else | ||
2448 | ac_file='' | ||
2449 | fi | ||
2450 | if test -z "$ac_file"; then : | ||
2451 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | ||
2452 | $as_echo "no" >&6; } | ||
2453 | $as_echo "$as_me: failed program was:" >&5 | ||
2454 | sed 's/^/| /' conftest.$ac_ext >&5 | ||
2455 | |||
2456 | { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 | ||
2457 | $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} | ||
2458 | as_fn_error 77 "C compiler cannot create executables | ||
2459 | See \`config.log' for more details" "$LINENO" 5; } | ||
2460 | else | ||
2461 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 | ||
2462 | $as_echo "yes" >&6; } | ||
2463 | fi | ||
2464 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 | ||
2465 | $as_echo_n "checking for C compiler default output file name... " >&6; } | ||
2466 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 | ||
2467 | $as_echo "$ac_file" >&6; } | ||
2468 | ac_exeext=$ac_cv_exeext | ||
2469 | |||
2470 | rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out | ||
2471 | ac_clean_files=$ac_clean_files_save | ||
2472 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 | ||
2473 | $as_echo_n "checking for suffix of executables... " >&6; } | ||
2474 | if { { ac_try="$ac_link" | ||
2475 | case "(($ac_try" in | ||
2476 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | ||
2477 | *) ac_try_echo=$ac_try;; | ||
2478 | esac | ||
2479 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | ||
2480 | $as_echo "$ac_try_echo"; } >&5 | ||
2481 | (eval "$ac_link") 2>&5 | ||
2482 | ac_status=$? | ||
2483 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | ||
2484 | test $ac_status = 0; }; then : | ||
2485 | # If both `conftest.exe' and `conftest' are `present' (well, observable) | ||
2486 | # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will | ||
2487 | # work properly (i.e., refer to `conftest.exe'), while it won't with | ||
2488 | # `rm'. | ||
2489 | for ac_file in conftest.exe conftest conftest.*; do | ||
2490 | test -f "$ac_file" || continue | ||
2491 | case $ac_file in | ||
2492 | *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; | ||
2493 | *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` | ||
2494 | break;; | ||
2495 | * ) break;; | ||
2496 | esac | ||
2497 | done | ||
2498 | else | ||
2499 | { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 | ||
2500 | $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} | ||
2501 | as_fn_error $? "cannot compute suffix of executables: cannot compile and link | ||
2502 | See \`config.log' for more details" "$LINENO" 5; } | ||
2503 | fi | ||
2504 | rm -f conftest conftest$ac_cv_exeext | ||
2505 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 | ||
2506 | $as_echo "$ac_cv_exeext" >&6; } | ||
2507 | |||
2508 | rm -f conftest.$ac_ext | ||
2509 | EXEEXT=$ac_cv_exeext | ||
2510 | ac_exeext=$EXEEXT | ||
2511 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
2512 | /* end confdefs.h. */ | ||
2513 | #include <stdio.h> | ||
2514 | int | ||
2515 | main () | ||
2516 | { | ||
2517 | FILE *f = fopen ("conftest.out", "w"); | ||
2518 | return ferror (f) || fclose (f) != 0; | ||
2519 | |||
2520 | ; | ||
2521 | return 0; | ||
2522 | } | ||
2523 | _ACEOF | ||
2524 | ac_clean_files="$ac_clean_files conftest.out" | ||
2525 | # Check that the compiler produces executables we can run. If not, either | ||
2526 | # the compiler is broken, or we cross compile. | ||
2527 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 | ||
2528 | $as_echo_n "checking whether we are cross compiling... " >&6; } | ||
2529 | if test "$cross_compiling" != yes; then | ||
2530 | { { ac_try="$ac_link" | ||
2531 | case "(($ac_try" in | ||
2532 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | ||
2533 | *) ac_try_echo=$ac_try;; | ||
2534 | esac | ||
2535 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | ||
2536 | $as_echo "$ac_try_echo"; } >&5 | ||
2537 | (eval "$ac_link") 2>&5 | ||
2538 | ac_status=$? | ||
2539 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | ||
2540 | test $ac_status = 0; } | ||
2541 | if { ac_try='./conftest$ac_cv_exeext' | ||
2542 | { { case "(($ac_try" in | ||
2543 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | ||
2544 | *) ac_try_echo=$ac_try;; | ||
2545 | esac | ||
2546 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | ||
2547 | $as_echo "$ac_try_echo"; } >&5 | ||
2548 | (eval "$ac_try") 2>&5 | ||
2549 | ac_status=$? | ||
2550 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | ||
2551 | test $ac_status = 0; }; }; then | ||
2552 | cross_compiling=no | ||
2553 | else | ||
2554 | if test "$cross_compiling" = maybe; then | ||
2555 | cross_compiling=yes | ||
2556 | else | ||
2557 | { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 | ||
2558 | $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} | ||
2559 | as_fn_error $? "cannot run C compiled programs. | ||
2560 | If you meant to cross compile, use \`--host'. | ||
2561 | See \`config.log' for more details" "$LINENO" 5; } | ||
2562 | fi | ||
2563 | fi | ||
2564 | fi | ||
2565 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 | ||
2566 | $as_echo "$cross_compiling" >&6; } | ||
2567 | |||
2568 | rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out | ||
2569 | ac_clean_files=$ac_clean_files_save | ||
2570 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 | ||
2571 | $as_echo_n "checking for suffix of object files... " >&6; } | ||
2572 | if ${ac_cv_objext+:} false; then : | ||
2573 | $as_echo_n "(cached) " >&6 | ||
2574 | else | ||
2575 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
2576 | /* end confdefs.h. */ | ||
2577 | |||
2578 | int | ||
2579 | main () | ||
2580 | { | ||
2581 | |||
2582 | ; | ||
2583 | return 0; | ||
2584 | } | ||
2585 | _ACEOF | ||
2586 | rm -f conftest.o conftest.obj | ||
2587 | if { { ac_try="$ac_compile" | ||
2588 | case "(($ac_try" in | ||
2589 | *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; | ||
2590 | *) ac_try_echo=$ac_try;; | ||
2591 | esac | ||
2592 | eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" | ||
2593 | $as_echo "$ac_try_echo"; } >&5 | ||
2594 | (eval "$ac_compile") 2>&5 | ||
2595 | ac_status=$? | ||
2596 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | ||
2597 | test $ac_status = 0; }; then : | ||
2598 | for ac_file in conftest.o conftest.obj conftest.*; do | ||
2599 | test -f "$ac_file" || continue; | ||
2600 | case $ac_file in | ||
2601 | *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; | ||
2602 | *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` | ||
2603 | break;; | ||
2604 | esac | ||
2605 | done | ||
2606 | else | ||
2607 | $as_echo "$as_me: failed program was:" >&5 | ||
2608 | sed 's/^/| /' conftest.$ac_ext >&5 | ||
2609 | |||
2610 | { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 | ||
2611 | $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} | ||
2612 | as_fn_error $? "cannot compute suffix of object files: cannot compile | ||
2613 | See \`config.log' for more details" "$LINENO" 5; } | ||
2614 | fi | ||
2615 | rm -f conftest.$ac_cv_objext conftest.$ac_ext | ||
2616 | fi | ||
2617 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 | ||
2618 | $as_echo "$ac_cv_objext" >&6; } | ||
2619 | OBJEXT=$ac_cv_objext | ||
2620 | ac_objext=$OBJEXT | ||
2621 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 | ||
2622 | $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } | ||
2623 | if ${ac_cv_c_compiler_gnu+:} false; then : | ||
2624 | $as_echo_n "(cached) " >&6 | ||
2625 | else | ||
2626 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
2627 | /* end confdefs.h. */ | ||
2628 | |||
2629 | int | ||
2630 | main () | ||
2631 | { | ||
2632 | #ifndef __GNUC__ | ||
2633 | choke me | ||
2634 | #endif | ||
2635 | |||
2636 | ; | ||
2637 | return 0; | ||
2638 | } | ||
2639 | _ACEOF | ||
2640 | if ac_fn_c_try_compile "$LINENO"; then : | ||
2641 | ac_compiler_gnu=yes | ||
2642 | else | ||
2643 | ac_compiler_gnu=no | ||
2644 | fi | ||
2645 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | ||
2646 | ac_cv_c_compiler_gnu=$ac_compiler_gnu | ||
2647 | |||
2648 | fi | ||
2649 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 | ||
2650 | $as_echo "$ac_cv_c_compiler_gnu" >&6; } | ||
2651 | if test $ac_compiler_gnu = yes; then | ||
2652 | GCC=yes | ||
2653 | else | ||
2654 | GCC= | ||
2655 | fi | ||
2656 | ac_test_CFLAGS=${CFLAGS+set} | ||
2657 | ac_save_CFLAGS=$CFLAGS | ||
2658 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 | ||
2659 | $as_echo_n "checking whether $CC accepts -g... " >&6; } | ||
2660 | if ${ac_cv_prog_cc_g+:} false; then : | ||
2661 | $as_echo_n "(cached) " >&6 | ||
2662 | else | ||
2663 | ac_save_c_werror_flag=$ac_c_werror_flag | ||
2664 | ac_c_werror_flag=yes | ||
2665 | ac_cv_prog_cc_g=no | ||
2666 | CFLAGS="-g" | ||
2667 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
2668 | /* end confdefs.h. */ | ||
2669 | |||
2670 | int | ||
2671 | main () | ||
2672 | { | ||
2673 | |||
2674 | ; | ||
2675 | return 0; | ||
2676 | } | ||
2677 | _ACEOF | ||
2678 | if ac_fn_c_try_compile "$LINENO"; then : | ||
2679 | ac_cv_prog_cc_g=yes | ||
2680 | else | ||
2681 | CFLAGS="" | ||
2682 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
2683 | /* end confdefs.h. */ | ||
2684 | |||
2685 | int | ||
2686 | main () | ||
2687 | { | ||
2688 | |||
2689 | ; | ||
2690 | return 0; | ||
2691 | } | ||
2692 | _ACEOF | ||
2693 | if ac_fn_c_try_compile "$LINENO"; then : | ||
2694 | |||
2695 | else | ||
2696 | ac_c_werror_flag=$ac_save_c_werror_flag | ||
2697 | CFLAGS="-g" | ||
2698 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
2699 | /* end confdefs.h. */ | ||
2700 | |||
2701 | int | ||
2702 | main () | ||
2703 | { | ||
2704 | |||
2705 | ; | ||
2706 | return 0; | ||
2707 | } | ||
2708 | _ACEOF | ||
2709 | if ac_fn_c_try_compile "$LINENO"; then : | ||
2710 | ac_cv_prog_cc_g=yes | ||
2711 | fi | ||
2712 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | ||
2713 | fi | ||
2714 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | ||
2715 | fi | ||
2716 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | ||
2717 | ac_c_werror_flag=$ac_save_c_werror_flag | ||
2718 | fi | ||
2719 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 | ||
2720 | $as_echo "$ac_cv_prog_cc_g" >&6; } | ||
2721 | if test "$ac_test_CFLAGS" = set; then | ||
2722 | CFLAGS=$ac_save_CFLAGS | ||
2723 | elif test $ac_cv_prog_cc_g = yes; then | ||
2724 | if test "$GCC" = yes; then | ||
2725 | CFLAGS="-g -O2" | ||
2726 | else | ||
2727 | CFLAGS="-g" | ||
2728 | fi | ||
2729 | else | ||
2730 | if test "$GCC" = yes; then | ||
2731 | CFLAGS="-O2" | ||
2732 | else | ||
2733 | CFLAGS= | ||
2734 | fi | ||
2735 | fi | ||
2736 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 | ||
2737 | $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } | ||
2738 | if ${ac_cv_prog_cc_c89+:} false; then : | ||
2739 | $as_echo_n "(cached) " >&6 | ||
2740 | else | ||
2741 | ac_cv_prog_cc_c89=no | ||
2742 | ac_save_CC=$CC | ||
2743 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
2744 | /* end confdefs.h. */ | ||
2745 | #include <stdarg.h> | ||
2746 | #include <stdio.h> | ||
2747 | struct stat; | ||
2748 | /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ | ||
2749 | struct buf { int x; }; | ||
2750 | FILE * (*rcsopen) (struct buf *, struct stat *, int); | ||
2751 | static char *e (p, i) | ||
2752 | char **p; | ||
2753 | int i; | ||
2754 | { | ||
2755 | return p[i]; | ||
2756 | } | ||
2757 | static char *f (char * (*g) (char **, int), char **p, ...) | ||
2758 | { | ||
2759 | char *s; | ||
2760 | va_list v; | ||
2761 | va_start (v,p); | ||
2762 | s = g (p, va_arg (v,int)); | ||
2763 | va_end (v); | ||
2764 | return s; | ||
2765 | } | ||
2766 | |||
2767 | /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has | ||
2768 | function prototypes and stuff, but not '\xHH' hex character constants. | ||
2769 | These don't provoke an error unfortunately, instead are silently treated | ||
2770 | as 'x'. The following induces an error, until -std is added to get | ||
2771 | proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an | ||
2772 | array size at least. It's necessary to write '\x00'==0 to get something | ||
2773 | that's true only with -std. */ | ||
2774 | int osf4_cc_array ['\x00' == 0 ? 1 : -1]; | ||
2775 | |||
2776 | /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters | ||
2777 | inside strings and character constants. */ | ||
2778 | #define FOO(x) 'x' | ||
2779 | int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; | ||
2780 | |||
2781 | int test (int i, double x); | ||
2782 | struct s1 {int (*f) (int a);}; | ||
2783 | struct s2 {int (*f) (double a);}; | ||
2784 | int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); | ||
2785 | int argc; | ||
2786 | char **argv; | ||
2787 | int | ||
2788 | main () | ||
2789 | { | ||
2790 | return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; | ||
2791 | ; | ||
2792 | return 0; | ||
2793 | } | ||
2794 | _ACEOF | ||
2795 | for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ | ||
2796 | -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" | ||
2797 | do | ||
2798 | CC="$ac_save_CC $ac_arg" | ||
2799 | if ac_fn_c_try_compile "$LINENO"; then : | ||
2800 | ac_cv_prog_cc_c89=$ac_arg | ||
2801 | fi | ||
2802 | rm -f core conftest.err conftest.$ac_objext | ||
2803 | test "x$ac_cv_prog_cc_c89" != "xno" && break | ||
2804 | done | ||
2805 | rm -f conftest.$ac_ext | ||
2806 | CC=$ac_save_CC | ||
2807 | |||
2808 | fi | ||
2809 | # AC_CACHE_VAL | ||
2810 | case "x$ac_cv_prog_cc_c89" in | ||
2811 | x) | ||
2812 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 | ||
2813 | $as_echo "none needed" >&6; } ;; | ||
2814 | xno) | ||
2815 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 | ||
2816 | $as_echo "unsupported" >&6; } ;; | ||
2817 | *) | ||
2818 | CC="$CC $ac_cv_prog_cc_c89" | ||
2819 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 | ||
2820 | $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; | ||
2821 | esac | ||
2822 | if test "x$ac_cv_prog_cc_c89" != xno; then : | ||
2823 | |||
2824 | fi | ||
2825 | |||
2826 | ac_ext=c | ||
2827 | ac_cpp='$CPP $CPPFLAGS' | ||
2828 | ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' | ||
2829 | ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' | ||
2830 | ac_compiler_gnu=$ac_cv_c_compiler_gnu | ||
2831 | |||
2832 | #AC_PROG_CXX | ||
2833 | ac_aux_dir= | ||
2834 | for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do | ||
2835 | if test -f "$ac_dir/install-sh"; then | ||
2836 | ac_aux_dir=$ac_dir | ||
2837 | ac_install_sh="$ac_aux_dir/install-sh -c" | ||
2838 | break | ||
2839 | elif test -f "$ac_dir/install.sh"; then | ||
2840 | ac_aux_dir=$ac_dir | ||
2841 | ac_install_sh="$ac_aux_dir/install.sh -c" | ||
2842 | break | ||
2843 | elif test -f "$ac_dir/shtool"; then | ||
2844 | ac_aux_dir=$ac_dir | ||
2845 | ac_install_sh="$ac_aux_dir/shtool install -c" | ||
2846 | break | ||
2847 | fi | ||
2848 | done | ||
2849 | if test -z "$ac_aux_dir"; then | ||
2850 | as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 | ||
2851 | fi | ||
2852 | |||
2853 | # These three variables are undocumented and unsupported, | ||
2854 | # and are intended to be withdrawn in a future Autoconf release. | ||
2855 | # They can cause serious problems if a builder's source tree is in a directory | ||
2856 | # whose full name contains unusual characters. | ||
2857 | ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. | ||
2858 | ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. | ||
2859 | ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. | ||
2860 | |||
2861 | |||
2862 | # Find a good install program. We prefer a C program (faster), | ||
2863 | # so one script is as good as another. But avoid the broken or | ||
2864 | # incompatible versions: | ||
2865 | # SysV /etc/install, /usr/sbin/install | ||
2866 | # SunOS /usr/etc/install | ||
2867 | # IRIX /sbin/install | ||
2868 | # AIX /bin/install | ||
2869 | # AmigaOS /C/install, which installs bootblocks on floppy discs | ||
2870 | # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag | ||
2871 | # AFS /usr/afsws/bin/install, which mishandles nonexistent args | ||
2872 | # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" | ||
2873 | # OS/2's system install, which has a completely different semantic | ||
2874 | # ./install, which can be erroneously created by make from ./install.sh. | ||
2875 | # Reject install programs that cannot install multiple files. | ||
2876 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 | ||
2877 | $as_echo_n "checking for a BSD-compatible install... " >&6; } | ||
2878 | if test -z "$INSTALL"; then | ||
2879 | if ${ac_cv_path_install+:} false; then : | ||
2880 | $as_echo_n "(cached) " >&6 | ||
2881 | else | ||
2882 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
2883 | for as_dir in $PATH | ||
2884 | do | ||
2885 | IFS=$as_save_IFS | ||
2886 | test -z "$as_dir" && as_dir=. | ||
2887 | # Account for people who put trailing slashes in PATH elements. | ||
2888 | case $as_dir/ in #(( | ||
2889 | ./ | .// | /[cC]/* | \ | ||
2890 | /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ | ||
2891 | ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ | ||
2892 | /usr/ucb/* ) ;; | ||
2893 | *) | ||
2894 | # OSF1 and SCO ODT 3.0 have their own names for install. | ||
2895 | # Don't use installbsd from OSF since it installs stuff as root | ||
2896 | # by default. | ||
2897 | for ac_prog in ginstall scoinst install; do | ||
2898 | for ac_exec_ext in '' $ac_executable_extensions; do | ||
2899 | if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then | ||
2900 | if test $ac_prog = install && | ||
2901 | grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then | ||
2902 | # AIX install. It has an incompatible calling convention. | ||
2903 | : | ||
2904 | elif test $ac_prog = install && | ||
2905 | grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then | ||
2906 | # program-specific install script used by HP pwplus--don't use. | ||
2907 | : | ||
2908 | else | ||
2909 | rm -rf conftest.one conftest.two conftest.dir | ||
2910 | echo one > conftest.one | ||
2911 | echo two > conftest.two | ||
2912 | mkdir conftest.dir | ||
2913 | if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && | ||
2914 | test -s conftest.one && test -s conftest.two && | ||
2915 | test -s conftest.dir/conftest.one && | ||
2916 | test -s conftest.dir/conftest.two | ||
2917 | then | ||
2918 | ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" | ||
2919 | break 3 | ||
2920 | fi | ||
2921 | fi | ||
2922 | fi | ||
2923 | done | ||
2924 | done | ||
2925 | ;; | ||
2926 | esac | ||
2927 | |||
2928 | done | ||
2929 | IFS=$as_save_IFS | ||
2930 | |||
2931 | rm -rf conftest.one conftest.two conftest.dir | ||
2932 | |||
2933 | fi | ||
2934 | if test "${ac_cv_path_install+set}" = set; then | ||
2935 | INSTALL=$ac_cv_path_install | ||
2936 | else | ||
2937 | # As a last resort, use the slow shell script. Don't cache a | ||
2938 | # value for INSTALL within a source directory, because that will | ||
2939 | # break other packages using the cache if that directory is | ||
2940 | # removed, or if the value is a relative name. | ||
2941 | INSTALL=$ac_install_sh | ||
2942 | fi | ||
2943 | fi | ||
2944 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 | ||
2945 | $as_echo "$INSTALL" >&6; } | ||
2946 | |||
2947 | # Use test -z because SunOS4 sh mishandles braces in ${var-val}. | ||
2948 | # It thinks the first close brace ends the variable substitution. | ||
2949 | test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' | ||
2950 | |||
2951 | test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' | ||
2952 | |||
2953 | test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' | ||
2954 | |||
2955 | if test -n "$ac_tool_prefix"; then | ||
2956 | # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. | ||
2957 | set dummy ${ac_tool_prefix}ranlib; ac_word=$2 | ||
2958 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 | ||
2959 | $as_echo_n "checking for $ac_word... " >&6; } | ||
2960 | if ${ac_cv_prog_RANLIB+:} false; then : | ||
2961 | $as_echo_n "(cached) " >&6 | ||
2962 | else | ||
2963 | if test -n "$RANLIB"; then | ||
2964 | ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. | ||
2965 | else | ||
2966 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
2967 | for as_dir in $PATH | ||
2968 | do | ||
2969 | IFS=$as_save_IFS | ||
2970 | test -z "$as_dir" && as_dir=. | ||
2971 | for ac_exec_ext in '' $ac_executable_extensions; do | ||
2972 | if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then | ||
2973 | ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" | ||
2974 | $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 | ||
2975 | break 2 | ||
2976 | fi | ||
2977 | done | ||
2978 | done | ||
2979 | IFS=$as_save_IFS | ||
2980 | |||
2981 | fi | ||
2982 | fi | ||
2983 | RANLIB=$ac_cv_prog_RANLIB | ||
2984 | if test -n "$RANLIB"; then | ||
2985 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 | ||
2986 | $as_echo "$RANLIB" >&6; } | ||
2987 | else | ||
2988 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | ||
2989 | $as_echo "no" >&6; } | ||
2990 | fi | ||
2991 | |||
2992 | |||
2993 | fi | ||
2994 | if test -z "$ac_cv_prog_RANLIB"; then | ||
2995 | ac_ct_RANLIB=$RANLIB | ||
2996 | # Extract the first word of "ranlib", so it can be a program name with args. | ||
2997 | set dummy ranlib; ac_word=$2 | ||
2998 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 | ||
2999 | $as_echo_n "checking for $ac_word... " >&6; } | ||
3000 | if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : | ||
3001 | $as_echo_n "(cached) " >&6 | ||
3002 | else | ||
3003 | if test -n "$ac_ct_RANLIB"; then | ||
3004 | ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. | ||
3005 | else | ||
3006 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
3007 | for as_dir in $PATH | ||
3008 | do | ||
3009 | IFS=$as_save_IFS | ||
3010 | test -z "$as_dir" && as_dir=. | ||
3011 | for ac_exec_ext in '' $ac_executable_extensions; do | ||
3012 | if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then | ||
3013 | ac_cv_prog_ac_ct_RANLIB="ranlib" | ||
3014 | $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 | ||
3015 | break 2 | ||
3016 | fi | ||
3017 | done | ||
3018 | done | ||
3019 | IFS=$as_save_IFS | ||
3020 | |||
3021 | fi | ||
3022 | fi | ||
3023 | ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB | ||
3024 | if test -n "$ac_ct_RANLIB"; then | ||
3025 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 | ||
3026 | $as_echo "$ac_ct_RANLIB" >&6; } | ||
3027 | else | ||
3028 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | ||
3029 | $as_echo "no" >&6; } | ||
3030 | fi | ||
3031 | |||
3032 | if test "x$ac_ct_RANLIB" = x; then | ||
3033 | RANLIB=":" | ||
3034 | else | ||
3035 | case $cross_compiling:$ac_tool_warned in | ||
3036 | yes:) | ||
3037 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 | ||
3038 | $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} | ||
3039 | ac_tool_warned=yes ;; | ||
3040 | esac | ||
3041 | RANLIB=$ac_ct_RANLIB | ||
3042 | fi | ||
3043 | else | ||
3044 | RANLIB="$ac_cv_prog_RANLIB" | ||
3045 | fi | ||
3046 | |||
3047 | |||
3048 | HAVE_SECCOMP="" | ||
3049 | # Check whether --enable-seccomp was given. | ||
3050 | if test "${enable_seccomp+set}" = set; then : | ||
3051 | enableval=$enable_seccomp; | ||
3052 | fi | ||
3053 | |||
3054 | if test "x$enable_seccomp" != "xno"; then : | ||
3055 | |||
3056 | HAVE_SECCOMP="-DHAVE_SECCOMP" | ||
3057 | |||
3058 | |||
3059 | fi | ||
3060 | |||
3061 | HAVE_CHROOT="" | ||
3062 | # Check whether --enable-chroot was given. | ||
3063 | if test "${enable_chroot+set}" = set; then : | ||
3064 | enableval=$enable_chroot; | ||
3065 | fi | ||
3066 | |||
3067 | if test "x$enable_chroot" != "xno"; then : | ||
3068 | |||
3069 | HAVE_CHROOT="-DHAVE_CHROOT" | ||
3070 | |||
3071 | |||
3072 | fi | ||
3073 | |||
3074 | HAVE_BIND="" | ||
3075 | # Check whether --enable-bind was given. | ||
3076 | if test "${enable_bind+set}" = set; then : | ||
3077 | enableval=$enable_bind; | ||
3078 | fi | ||
3079 | |||
3080 | if test "x$enable_bind" != "xno"; then : | ||
3081 | |||
3082 | HAVE_BIND="-DHAVE_BIND" | ||
3083 | |||
3084 | |||
3085 | fi | ||
3086 | |||
3087 | |||
3088 | # checking pthread library | ||
3089 | |||
3090 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5 | ||
3091 | $as_echo_n "checking for main in -lpthread... " >&6; } | ||
3092 | if ${ac_cv_lib_pthread_main+:} false; then : | ||
3093 | $as_echo_n "(cached) " >&6 | ||
3094 | else | ||
3095 | ac_check_lib_save_LIBS=$LIBS | ||
3096 | LIBS="-lpthread $LIBS" | ||
3097 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
3098 | /* end confdefs.h. */ | ||
3099 | |||
3100 | |||
3101 | int | ||
3102 | main () | ||
3103 | { | ||
3104 | return main (); | ||
3105 | ; | ||
3106 | return 0; | ||
3107 | } | ||
3108 | _ACEOF | ||
3109 | if ac_fn_c_try_link "$LINENO"; then : | ||
3110 | ac_cv_lib_pthread_main=yes | ||
3111 | else | ||
3112 | ac_cv_lib_pthread_main=no | ||
3113 | fi | ||
3114 | rm -f core conftest.err conftest.$ac_objext \ | ||
3115 | conftest$ac_exeext conftest.$ac_ext | ||
3116 | LIBS=$ac_check_lib_save_LIBS | ||
3117 | fi | ||
3118 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5 | ||
3119 | $as_echo "$ac_cv_lib_pthread_main" >&6; } | ||
3120 | if test "x$ac_cv_lib_pthread_main" = xyes; then : | ||
3121 | cat >>confdefs.h <<_ACEOF | ||
3122 | #define HAVE_LIBPTHREAD 1 | ||
3123 | _ACEOF | ||
3124 | |||
3125 | LIBS="-lpthread $LIBS" | ||
3126 | |||
3127 | else | ||
3128 | as_fn_error $? "*** POSIX thread support not installed ***" "$LINENO" 5 | ||
3129 | fi | ||
3130 | |||
3131 | ac_ext=c | ||
3132 | ac_cpp='$CPP $CPPFLAGS' | ||
3133 | ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' | ||
3134 | ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' | ||
3135 | ac_compiler_gnu=$ac_cv_c_compiler_gnu | ||
3136 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 | ||
3137 | $as_echo_n "checking how to run the C preprocessor... " >&6; } | ||
3138 | # On Suns, sometimes $CPP names a directory. | ||
3139 | if test -n "$CPP" && test -d "$CPP"; then | ||
3140 | CPP= | ||
3141 | fi | ||
3142 | if test -z "$CPP"; then | ||
3143 | if ${ac_cv_prog_CPP+:} false; then : | ||
3144 | $as_echo_n "(cached) " >&6 | ||
3145 | else | ||
3146 | # Double quotes because CPP needs to be expanded | ||
3147 | for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" | ||
3148 | do | ||
3149 | ac_preproc_ok=false | ||
3150 | for ac_c_preproc_warn_flag in '' yes | ||
3151 | do | ||
3152 | # Use a header file that comes with gcc, so configuring glibc | ||
3153 | # with a fresh cross-compiler works. | ||
3154 | # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since | ||
3155 | # <limits.h> exists even on freestanding compilers. | ||
3156 | # On the NeXT, cc -E runs the code through the compiler's parser, | ||
3157 | # not just through cpp. "Syntax error" is here to catch this case. | ||
3158 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
3159 | /* end confdefs.h. */ | ||
3160 | #ifdef __STDC__ | ||
3161 | # include <limits.h> | ||
3162 | #else | ||
3163 | # include <assert.h> | ||
3164 | #endif | ||
3165 | Syntax error | ||
3166 | _ACEOF | ||
3167 | if ac_fn_c_try_cpp "$LINENO"; then : | ||
3168 | |||
3169 | else | ||
3170 | # Broken: fails on valid input. | ||
3171 | continue | ||
3172 | fi | ||
3173 | rm -f conftest.err conftest.i conftest.$ac_ext | ||
3174 | |||
3175 | # OK, works on sane cases. Now check whether nonexistent headers | ||
3176 | # can be detected and how. | ||
3177 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
3178 | /* end confdefs.h. */ | ||
3179 | #include <ac_nonexistent.h> | ||
3180 | _ACEOF | ||
3181 | if ac_fn_c_try_cpp "$LINENO"; then : | ||
3182 | # Broken: success on invalid input. | ||
3183 | continue | ||
3184 | else | ||
3185 | # Passes both tests. | ||
3186 | ac_preproc_ok=: | ||
3187 | break | ||
3188 | fi | ||
3189 | rm -f conftest.err conftest.i conftest.$ac_ext | ||
3190 | |||
3191 | done | ||
3192 | # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. | ||
3193 | rm -f conftest.i conftest.err conftest.$ac_ext | ||
3194 | if $ac_preproc_ok; then : | ||
3195 | break | ||
3196 | fi | ||
3197 | |||
3198 | done | ||
3199 | ac_cv_prog_CPP=$CPP | ||
3200 | |||
3201 | fi | ||
3202 | CPP=$ac_cv_prog_CPP | ||
3203 | else | ||
3204 | ac_cv_prog_CPP=$CPP | ||
3205 | fi | ||
3206 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 | ||
3207 | $as_echo "$CPP" >&6; } | ||
3208 | ac_preproc_ok=false | ||
3209 | for ac_c_preproc_warn_flag in '' yes | ||
3210 | do | ||
3211 | # Use a header file that comes with gcc, so configuring glibc | ||
3212 | # with a fresh cross-compiler works. | ||
3213 | # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since | ||
3214 | # <limits.h> exists even on freestanding compilers. | ||
3215 | # On the NeXT, cc -E runs the code through the compiler's parser, | ||
3216 | # not just through cpp. "Syntax error" is here to catch this case. | ||
3217 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
3218 | /* end confdefs.h. */ | ||
3219 | #ifdef __STDC__ | ||
3220 | # include <limits.h> | ||
3221 | #else | ||
3222 | # include <assert.h> | ||
3223 | #endif | ||
3224 | Syntax error | ||
3225 | _ACEOF | ||
3226 | if ac_fn_c_try_cpp "$LINENO"; then : | ||
3227 | |||
3228 | else | ||
3229 | # Broken: fails on valid input. | ||
3230 | continue | ||
3231 | fi | ||
3232 | rm -f conftest.err conftest.i conftest.$ac_ext | ||
3233 | |||
3234 | # OK, works on sane cases. Now check whether nonexistent headers | ||
3235 | # can be detected and how. | ||
3236 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
3237 | /* end confdefs.h. */ | ||
3238 | #include <ac_nonexistent.h> | ||
3239 | _ACEOF | ||
3240 | if ac_fn_c_try_cpp "$LINENO"; then : | ||
3241 | # Broken: success on invalid input. | ||
3242 | continue | ||
3243 | else | ||
3244 | # Passes both tests. | ||
3245 | ac_preproc_ok=: | ||
3246 | break | ||
3247 | fi | ||
3248 | rm -f conftest.err conftest.i conftest.$ac_ext | ||
3249 | |||
3250 | done | ||
3251 | # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. | ||
3252 | rm -f conftest.i conftest.err conftest.$ac_ext | ||
3253 | if $ac_preproc_ok; then : | ||
3254 | |||
3255 | else | ||
3256 | { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 | ||
3257 | $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} | ||
3258 | as_fn_error $? "C preprocessor \"$CPP\" fails sanity check | ||
3259 | See \`config.log' for more details" "$LINENO" 5; } | ||
3260 | fi | ||
3261 | |||
3262 | ac_ext=c | ||
3263 | ac_cpp='$CPP $CPPFLAGS' | ||
3264 | ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' | ||
3265 | ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' | ||
3266 | ac_compiler_gnu=$ac_cv_c_compiler_gnu | ||
3267 | |||
3268 | |||
3269 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 | ||
3270 | $as_echo_n "checking for grep that handles long lines and -e... " >&6; } | ||
3271 | if ${ac_cv_path_GREP+:} false; then : | ||
3272 | $as_echo_n "(cached) " >&6 | ||
3273 | else | ||
3274 | if test -z "$GREP"; then | ||
3275 | ac_path_GREP_found=false | ||
3276 | # Loop through the user's path and test for each of PROGNAME-LIST | ||
3277 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
3278 | for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin | ||
3279 | do | ||
3280 | IFS=$as_save_IFS | ||
3281 | test -z "$as_dir" && as_dir=. | ||
3282 | for ac_prog in grep ggrep; do | ||
3283 | for ac_exec_ext in '' $ac_executable_extensions; do | ||
3284 | ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" | ||
3285 | as_fn_executable_p "$ac_path_GREP" || continue | ||
3286 | # Check for GNU ac_path_GREP and select it if it is found. | ||
3287 | # Check for GNU $ac_path_GREP | ||
3288 | case `"$ac_path_GREP" --version 2>&1` in | ||
3289 | *GNU*) | ||
3290 | ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; | ||
3291 | *) | ||
3292 | ac_count=0 | ||
3293 | $as_echo_n 0123456789 >"conftest.in" | ||
3294 | while : | ||
3295 | do | ||
3296 | cat "conftest.in" "conftest.in" >"conftest.tmp" | ||
3297 | mv "conftest.tmp" "conftest.in" | ||
3298 | cp "conftest.in" "conftest.nl" | ||
3299 | $as_echo 'GREP' >> "conftest.nl" | ||
3300 | "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break | ||
3301 | diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break | ||
3302 | as_fn_arith $ac_count + 1 && ac_count=$as_val | ||
3303 | if test $ac_count -gt ${ac_path_GREP_max-0}; then | ||
3304 | # Best one so far, save it but keep looking for a better one | ||
3305 | ac_cv_path_GREP="$ac_path_GREP" | ||
3306 | ac_path_GREP_max=$ac_count | ||
3307 | fi | ||
3308 | # 10*(2^10) chars as input seems more than enough | ||
3309 | test $ac_count -gt 10 && break | ||
3310 | done | ||
3311 | rm -f conftest.in conftest.tmp conftest.nl conftest.out;; | ||
3312 | esac | ||
3313 | |||
3314 | $ac_path_GREP_found && break 3 | ||
3315 | done | ||
3316 | done | ||
3317 | done | ||
3318 | IFS=$as_save_IFS | ||
3319 | if test -z "$ac_cv_path_GREP"; then | ||
3320 | as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 | ||
3321 | fi | ||
3322 | else | ||
3323 | ac_cv_path_GREP=$GREP | ||
3324 | fi | ||
3325 | |||
3326 | fi | ||
3327 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 | ||
3328 | $as_echo "$ac_cv_path_GREP" >&6; } | ||
3329 | GREP="$ac_cv_path_GREP" | ||
3330 | |||
3331 | |||
3332 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 | ||
3333 | $as_echo_n "checking for egrep... " >&6; } | ||
3334 | if ${ac_cv_path_EGREP+:} false; then : | ||
3335 | $as_echo_n "(cached) " >&6 | ||
3336 | else | ||
3337 | if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 | ||
3338 | then ac_cv_path_EGREP="$GREP -E" | ||
3339 | else | ||
3340 | if test -z "$EGREP"; then | ||
3341 | ac_path_EGREP_found=false | ||
3342 | # Loop through the user's path and test for each of PROGNAME-LIST | ||
3343 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
3344 | for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin | ||
3345 | do | ||
3346 | IFS=$as_save_IFS | ||
3347 | test -z "$as_dir" && as_dir=. | ||
3348 | for ac_prog in egrep; do | ||
3349 | for ac_exec_ext in '' $ac_executable_extensions; do | ||
3350 | ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" | ||
3351 | as_fn_executable_p "$ac_path_EGREP" || continue | ||
3352 | # Check for GNU ac_path_EGREP and select it if it is found. | ||
3353 | # Check for GNU $ac_path_EGREP | ||
3354 | case `"$ac_path_EGREP" --version 2>&1` in | ||
3355 | *GNU*) | ||
3356 | ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; | ||
3357 | *) | ||
3358 | ac_count=0 | ||
3359 | $as_echo_n 0123456789 >"conftest.in" | ||
3360 | while : | ||
3361 | do | ||
3362 | cat "conftest.in" "conftest.in" >"conftest.tmp" | ||
3363 | mv "conftest.tmp" "conftest.in" | ||
3364 | cp "conftest.in" "conftest.nl" | ||
3365 | $as_echo 'EGREP' >> "conftest.nl" | ||
3366 | "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break | ||
3367 | diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break | ||
3368 | as_fn_arith $ac_count + 1 && ac_count=$as_val | ||
3369 | if test $ac_count -gt ${ac_path_EGREP_max-0}; then | ||
3370 | # Best one so far, save it but keep looking for a better one | ||
3371 | ac_cv_path_EGREP="$ac_path_EGREP" | ||
3372 | ac_path_EGREP_max=$ac_count | ||
3373 | fi | ||
3374 | # 10*(2^10) chars as input seems more than enough | ||
3375 | test $ac_count -gt 10 && break | ||
3376 | done | ||
3377 | rm -f conftest.in conftest.tmp conftest.nl conftest.out;; | ||
3378 | esac | ||
3379 | |||
3380 | $ac_path_EGREP_found && break 3 | ||
3381 | done | ||
3382 | done | ||
3383 | done | ||
3384 | IFS=$as_save_IFS | ||
3385 | if test -z "$ac_cv_path_EGREP"; then | ||
3386 | as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 | ||
3387 | fi | ||
3388 | else | ||
3389 | ac_cv_path_EGREP=$EGREP | ||
3390 | fi | ||
3391 | |||
3392 | fi | ||
3393 | fi | ||
3394 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 | ||
3395 | $as_echo "$ac_cv_path_EGREP" >&6; } | ||
3396 | EGREP="$ac_cv_path_EGREP" | ||
3397 | |||
3398 | |||
3399 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 | ||
3400 | $as_echo_n "checking for ANSI C header files... " >&6; } | ||
3401 | if ${ac_cv_header_stdc+:} false; then : | ||
3402 | $as_echo_n "(cached) " >&6 | ||
3403 | else | ||
3404 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
3405 | /* end confdefs.h. */ | ||
3406 | #include <stdlib.h> | ||
3407 | #include <stdarg.h> | ||
3408 | #include <string.h> | ||
3409 | #include <float.h> | ||
3410 | |||
3411 | int | ||
3412 | main () | ||
3413 | { | ||
3414 | |||
3415 | ; | ||
3416 | return 0; | ||
3417 | } | ||
3418 | _ACEOF | ||
3419 | if ac_fn_c_try_compile "$LINENO"; then : | ||
3420 | ac_cv_header_stdc=yes | ||
3421 | else | ||
3422 | ac_cv_header_stdc=no | ||
3423 | fi | ||
3424 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | ||
3425 | |||
3426 | if test $ac_cv_header_stdc = yes; then | ||
3427 | # SunOS 4.x string.h does not declare mem*, contrary to ANSI. | ||
3428 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
3429 | /* end confdefs.h. */ | ||
3430 | #include <string.h> | ||
3431 | |||
3432 | _ACEOF | ||
3433 | if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | | ||
3434 | $EGREP "memchr" >/dev/null 2>&1; then : | ||
3435 | |||
3436 | else | ||
3437 | ac_cv_header_stdc=no | ||
3438 | fi | ||
3439 | rm -f conftest* | ||
3440 | |||
3441 | fi | ||
3442 | |||
3443 | if test $ac_cv_header_stdc = yes; then | ||
3444 | # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. | ||
3445 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
3446 | /* end confdefs.h. */ | ||
3447 | #include <stdlib.h> | ||
3448 | |||
3449 | _ACEOF | ||
3450 | if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | | ||
3451 | $EGREP "free" >/dev/null 2>&1; then : | ||
3452 | |||
3453 | else | ||
3454 | ac_cv_header_stdc=no | ||
3455 | fi | ||
3456 | rm -f conftest* | ||
3457 | |||
3458 | fi | ||
3459 | |||
3460 | if test $ac_cv_header_stdc = yes; then | ||
3461 | # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. | ||
3462 | if test "$cross_compiling" = yes; then : | ||
3463 | : | ||
3464 | else | ||
3465 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | ||
3466 | /* end confdefs.h. */ | ||
3467 | #include <ctype.h> | ||
3468 | #include <stdlib.h> | ||
3469 | #if ((' ' & 0x0FF) == 0x020) | ||
3470 | # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') | ||
3471 | # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) | ||
3472 | #else | ||
3473 | # define ISLOWER(c) \ | ||
3474 | (('a' <= (c) && (c) <= 'i') \ | ||
3475 | || ('j' <= (c) && (c) <= 'r') \ | ||
3476 | || ('s' <= (c) && (c) <= 'z')) | ||
3477 | # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) | ||
3478 | #endif | ||
3479 | |||
3480 | #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) | ||
3481 | int | ||
3482 | main () | ||
3483 | { | ||
3484 | int i; | ||
3485 | for (i = 0; i < 256; i++) | ||
3486 | if (XOR (islower (i), ISLOWER (i)) | ||
3487 | || toupper (i) != TOUPPER (i)) | ||
3488 | return 2; | ||
3489 | return 0; | ||
3490 | } | ||
3491 | _ACEOF | ||
3492 | if ac_fn_c_try_run "$LINENO"; then : | ||
3493 | |||
3494 | else | ||
3495 | ac_cv_header_stdc=no | ||
3496 | fi | ||
3497 | rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ | ||
3498 | conftest.$ac_objext conftest.beam conftest.$ac_ext | ||
3499 | fi | ||
3500 | |||
3501 | fi | ||
3502 | fi | ||
3503 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 | ||
3504 | $as_echo "$ac_cv_header_stdc" >&6; } | ||
3505 | if test $ac_cv_header_stdc = yes; then | ||
3506 | |||
3507 | $as_echo "#define STDC_HEADERS 1" >>confdefs.h | ||
3508 | |||
3509 | fi | ||
3510 | |||
3511 | # On IRIX 5.3, sys/types and inttypes.h are conflicting. | ||
3512 | for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ | ||
3513 | inttypes.h stdint.h unistd.h | ||
3514 | do : | ||
3515 | as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` | ||
3516 | ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default | ||
3517 | " | ||
3518 | if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : | ||
3519 | cat >>confdefs.h <<_ACEOF | ||
3520 | #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 | ||
3521 | _ACEOF | ||
3522 | |||
3523 | fi | ||
3524 | |||
3525 | done | ||
3526 | |||
3527 | |||
3528 | ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" | ||
3529 | if test "x$ac_cv_header_pthread_h" = xyes; then : | ||
3530 | |||
3531 | else | ||
3532 | as_fn_error $? "*** POSIX thread support not installed ***" "$LINENO" 5 | ||
3533 | fi | ||
3534 | |||
3535 | |||
3536 | ac_fn_c_check_header_mongrel "$LINENO" "linux/seccomp.h" "ac_cv_header_linux_seccomp_h" "$ac_includes_default" | ||
3537 | if test "x$ac_cv_header_linux_seccomp_h" = xyes; then : | ||
3538 | HAVE_SECCOMP_H="-DHAVE_SECCOMP_H" | ||
3539 | else | ||
3540 | HAVE_SECCOMP_H="" | ||
3541 | fi | ||
3542 | |||
3543 | |||
3544 | |||
3545 | |||
3546 | ac_config_files="$ac_config_files Makefile src/lib/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/ftee/Makefile" | ||
3547 | |||
3548 | cat >confcache <<\_ACEOF | ||
3549 | # This file is a shell script that caches the results of configure | ||
3550 | # tests run on this system so they can be shared between configure | ||
3551 | # scripts and configure runs, see configure's option --config-cache. | ||
3552 | # It is not useful on other systems. If it contains results you don't | ||
3553 | # want to keep, you may remove or edit it. | ||
3554 | # | ||
3555 | # config.status only pays attention to the cache file if you give it | ||
3556 | # the --recheck option to rerun configure. | ||
3557 | # | ||
3558 | # `ac_cv_env_foo' variables (set or unset) will be overridden when | ||
3559 | # loading this file, other *unset* `ac_cv_foo' will be assigned the | ||
3560 | # following values. | ||
3561 | |||
3562 | _ACEOF | ||
3563 | |||
3564 | # The following way of writing the cache mishandles newlines in values, | ||
3565 | # but we know of no workaround that is simple, portable, and efficient. | ||
3566 | # So, we kill variables containing newlines. | ||
3567 | # Ultrix sh set writes to stderr and can't be redirected directly, | ||
3568 | # and sets the high bit in the cache file unless we assign to the vars. | ||
3569 | ( | ||
3570 | for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do | ||
3571 | eval ac_val=\$$ac_var | ||
3572 | case $ac_val in #( | ||
3573 | *${as_nl}*) | ||
3574 | case $ac_var in #( | ||
3575 | *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 | ||
3576 | $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; | ||
3577 | esac | ||
3578 | case $ac_var in #( | ||
3579 | _ | IFS | as_nl) ;; #( | ||
3580 | BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( | ||
3581 | *) { eval $ac_var=; unset $ac_var;} ;; | ||
3582 | esac ;; | ||
3583 | esac | ||
3584 | done | ||
3585 | |||
3586 | (set) 2>&1 | | ||
3587 | case $as_nl`(ac_space=' '; set) 2>&1` in #( | ||
3588 | *${as_nl}ac_space=\ *) | ||
3589 | # `set' does not quote correctly, so add quotes: double-quote | ||
3590 | # substitution turns \\\\ into \\, and sed turns \\ into \. | ||
3591 | sed -n \ | ||
3592 | "s/'/'\\\\''/g; | ||
3593 | s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" | ||
3594 | ;; #( | ||
3595 | *) | ||
3596 | # `set' quotes correctly as required by POSIX, so do not add quotes. | ||
3597 | sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" | ||
3598 | ;; | ||
3599 | esac | | ||
3600 | sort | ||
3601 | ) | | ||
3602 | sed ' | ||
3603 | /^ac_cv_env_/b end | ||
3604 | t clear | ||
3605 | :clear | ||
3606 | s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ | ||
3607 | t end | ||
3608 | s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ | ||
3609 | :end' >>confcache | ||
3610 | if diff "$cache_file" confcache >/dev/null 2>&1; then :; else | ||
3611 | if test -w "$cache_file"; then | ||
3612 | if test "x$cache_file" != "x/dev/null"; then | ||
3613 | { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 | ||
3614 | $as_echo "$as_me: updating cache $cache_file" >&6;} | ||
3615 | if test ! -f "$cache_file" || test -h "$cache_file"; then | ||
3616 | cat confcache >"$cache_file" | ||
3617 | else | ||
3618 | case $cache_file in #( | ||
3619 | */* | ?:*) | ||
3620 | mv -f confcache "$cache_file"$$ && | ||
3621 | mv -f "$cache_file"$$ "$cache_file" ;; #( | ||
3622 | *) | ||
3623 | mv -f confcache "$cache_file" ;; | ||
3624 | esac | ||
3625 | fi | ||
3626 | fi | ||
3627 | else | ||
3628 | { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 | ||
3629 | $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} | ||
3630 | fi | ||
3631 | fi | ||
3632 | rm -f confcache | ||
3633 | |||
3634 | test "x$prefix" = xNONE && prefix=$ac_default_prefix | ||
3635 | # Let make expand exec_prefix. | ||
3636 | test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' | ||
3637 | |||
3638 | # Transform confdefs.h into DEFS. | ||
3639 | # Protect against shell expansion while executing Makefile rules. | ||
3640 | # Protect against Makefile macro expansion. | ||
3641 | # | ||
3642 | # If the first sed substitution is executed (which looks for macros that | ||
3643 | # take arguments), then branch to the quote section. Otherwise, | ||
3644 | # look for a macro that doesn't take arguments. | ||
3645 | ac_script=' | ||
3646 | :mline | ||
3647 | /\\$/{ | ||
3648 | N | ||
3649 | s,\\\n,, | ||
3650 | b mline | ||
3651 | } | ||
3652 | t clear | ||
3653 | :clear | ||
3654 | s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g | ||
3655 | t quote | ||
3656 | s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g | ||
3657 | t quote | ||
3658 | b any | ||
3659 | :quote | ||
3660 | s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g | ||
3661 | s/\[/\\&/g | ||
3662 | s/\]/\\&/g | ||
3663 | s/\$/$$/g | ||
3664 | H | ||
3665 | :any | ||
3666 | ${ | ||
3667 | g | ||
3668 | s/^\n// | ||
3669 | s/\n/ /g | ||
3670 | p | ||
3671 | } | ||
3672 | ' | ||
3673 | DEFS=`sed -n "$ac_script" confdefs.h` | ||
3674 | |||
3675 | |||
3676 | ac_libobjs= | ||
3677 | ac_ltlibobjs= | ||
3678 | U= | ||
3679 | for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue | ||
3680 | # 1. Remove the extension, and $U if already installed. | ||
3681 | ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' | ||
3682 | ac_i=`$as_echo "$ac_i" | sed "$ac_script"` | ||
3683 | # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR | ||
3684 | # will be set to the directory where LIBOBJS objects are built. | ||
3685 | as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" | ||
3686 | as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' | ||
3687 | done | ||
3688 | LIBOBJS=$ac_libobjs | ||
3689 | |||
3690 | LTLIBOBJS=$ac_ltlibobjs | ||
3691 | |||
3692 | |||
3693 | |||
3694 | : "${CONFIG_STATUS=./config.status}" | ||
3695 | ac_write_fail=0 | ||
3696 | ac_clean_files_save=$ac_clean_files | ||
3697 | ac_clean_files="$ac_clean_files $CONFIG_STATUS" | ||
3698 | { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 | ||
3699 | $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} | ||
3700 | as_write_fail=0 | ||
3701 | cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 | ||
3702 | #! $SHELL | ||
3703 | # Generated by $as_me. | ||
3704 | # Run this file to recreate the current configuration. | ||
3705 | # Compiler output produced by configure, useful for debugging | ||
3706 | # configure, is in config.log if it exists. | ||
3707 | |||
3708 | debug=false | ||
3709 | ac_cs_recheck=false | ||
3710 | ac_cs_silent=false | ||
3711 | |||
3712 | SHELL=\${CONFIG_SHELL-$SHELL} | ||
3713 | export SHELL | ||
3714 | _ASEOF | ||
3715 | cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 | ||
3716 | ## -------------------- ## | ||
3717 | ## M4sh Initialization. ## | ||
3718 | ## -------------------- ## | ||
3719 | |||
3720 | # Be more Bourne compatible | ||
3721 | DUALCASE=1; export DUALCASE # for MKS sh | ||
3722 | if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : | ||
3723 | emulate sh | ||
3724 | NULLCMD=: | ||
3725 | # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which | ||
3726 | # is contrary to our usage. Disable this feature. | ||
3727 | alias -g '${1+"$@"}'='"$@"' | ||
3728 | setopt NO_GLOB_SUBST | ||
3729 | else | ||
3730 | case `(set -o) 2>/dev/null` in #( | ||
3731 | *posix*) : | ||
3732 | set -o posix ;; #( | ||
3733 | *) : | ||
3734 | ;; | ||
3735 | esac | ||
3736 | fi | ||
3737 | |||
3738 | |||
3739 | as_nl=' | ||
3740 | ' | ||
3741 | export as_nl | ||
3742 | # Printing a long string crashes Solaris 7 /usr/bin/printf. | ||
3743 | as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' | ||
3744 | as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo | ||
3745 | as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo | ||
3746 | # Prefer a ksh shell builtin over an external printf program on Solaris, | ||
3747 | # but without wasting forks for bash or zsh. | ||
3748 | if test -z "$BASH_VERSION$ZSH_VERSION" \ | ||
3749 | && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then | ||
3750 | as_echo='print -r --' | ||
3751 | as_echo_n='print -rn --' | ||
3752 | elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then | ||
3753 | as_echo='printf %s\n' | ||
3754 | as_echo_n='printf %s' | ||
3755 | else | ||
3756 | if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then | ||
3757 | as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' | ||
3758 | as_echo_n='/usr/ucb/echo -n' | ||
3759 | else | ||
3760 | as_echo_body='eval expr "X$1" : "X\\(.*\\)"' | ||
3761 | as_echo_n_body='eval | ||
3762 | arg=$1; | ||
3763 | case $arg in #( | ||
3764 | *"$as_nl"*) | ||
3765 | expr "X$arg" : "X\\(.*\\)$as_nl"; | ||
3766 | arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; | ||
3767 | esac; | ||
3768 | expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" | ||
3769 | ' | ||
3770 | export as_echo_n_body | ||
3771 | as_echo_n='sh -c $as_echo_n_body as_echo' | ||
3772 | fi | ||
3773 | export as_echo_body | ||
3774 | as_echo='sh -c $as_echo_body as_echo' | ||
3775 | fi | ||
3776 | |||
3777 | # The user is always right. | ||
3778 | if test "${PATH_SEPARATOR+set}" != set; then | ||
3779 | PATH_SEPARATOR=: | ||
3780 | (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { | ||
3781 | (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || | ||
3782 | PATH_SEPARATOR=';' | ||
3783 | } | ||
3784 | fi | ||
3785 | |||
3786 | |||
3787 | # IFS | ||
3788 | # We need space, tab and new line, in precisely that order. Quoting is | ||
3789 | # there to prevent editors from complaining about space-tab. | ||
3790 | # (If _AS_PATH_WALK were called with IFS unset, it would disable word | ||
3791 | # splitting by setting IFS to empty value.) | ||
3792 | IFS=" "" $as_nl" | ||
3793 | |||
3794 | # Find who we are. Look in the path if we contain no directory separator. | ||
3795 | as_myself= | ||
3796 | case $0 in #(( | ||
3797 | *[\\/]* ) as_myself=$0 ;; | ||
3798 | *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
3799 | for as_dir in $PATH | ||
3800 | do | ||
3801 | IFS=$as_save_IFS | ||
3802 | test -z "$as_dir" && as_dir=. | ||
3803 | test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break | ||
3804 | done | ||
3805 | IFS=$as_save_IFS | ||
3806 | |||
3807 | ;; | ||
3808 | esac | ||
3809 | # We did not find ourselves, most probably we were run as `sh COMMAND' | ||
3810 | # in which case we are not to be found in the path. | ||
3811 | if test "x$as_myself" = x; then | ||
3812 | as_myself=$0 | ||
3813 | fi | ||
3814 | if test ! -f "$as_myself"; then | ||
3815 | $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 | ||
3816 | exit 1 | ||
3817 | fi | ||
3818 | |||
3819 | # Unset variables that we do not need and which cause bugs (e.g. in | ||
3820 | # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" | ||
3821 | # suppresses any "Segmentation fault" message there. '((' could | ||
3822 | # trigger a bug in pdksh 5.2.14. | ||
3823 | for as_var in BASH_ENV ENV MAIL MAILPATH | ||
3824 | do eval test x\${$as_var+set} = xset \ | ||
3825 | && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : | ||
3826 | done | ||
3827 | PS1='$ ' | ||
3828 | PS2='> ' | ||
3829 | PS4='+ ' | ||
3830 | |||
3831 | # NLS nuisances. | ||
3832 | LC_ALL=C | ||
3833 | export LC_ALL | ||
3834 | LANGUAGE=C | ||
3835 | export LANGUAGE | ||
3836 | |||
3837 | # CDPATH. | ||
3838 | (unset CDPATH) >/dev/null 2>&1 && unset CDPATH | ||
3839 | |||
3840 | |||
3841 | # as_fn_error STATUS ERROR [LINENO LOG_FD] | ||
3842 | # ---------------------------------------- | ||
3843 | # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are | ||
3844 | # provided, also output the error to LOG_FD, referencing LINENO. Then exit the | ||
3845 | # script with STATUS, using 1 if that was 0. | ||
3846 | as_fn_error () | ||
3847 | { | ||
3848 | as_status=$1; test $as_status -eq 0 && as_status=1 | ||
3849 | if test "$4"; then | ||
3850 | as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack | ||
3851 | $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 | ||
3852 | fi | ||
3853 | $as_echo "$as_me: error: $2" >&2 | ||
3854 | as_fn_exit $as_status | ||
3855 | } # as_fn_error | ||
3856 | |||
3857 | |||
3858 | # as_fn_set_status STATUS | ||
3859 | # ----------------------- | ||
3860 | # Set $? to STATUS, without forking. | ||
3861 | as_fn_set_status () | ||
3862 | { | ||
3863 | return $1 | ||
3864 | } # as_fn_set_status | ||
3865 | |||
3866 | # as_fn_exit STATUS | ||
3867 | # ----------------- | ||
3868 | # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. | ||
3869 | as_fn_exit () | ||
3870 | { | ||
3871 | set +e | ||
3872 | as_fn_set_status $1 | ||
3873 | exit $1 | ||
3874 | } # as_fn_exit | ||
3875 | |||
3876 | # as_fn_unset VAR | ||
3877 | # --------------- | ||
3878 | # Portably unset VAR. | ||
3879 | as_fn_unset () | ||
3880 | { | ||
3881 | { eval $1=; unset $1;} | ||
3882 | } | ||
3883 | as_unset=as_fn_unset | ||
3884 | # as_fn_append VAR VALUE | ||
3885 | # ---------------------- | ||
3886 | # Append the text in VALUE to the end of the definition contained in VAR. Take | ||
3887 | # advantage of any shell optimizations that allow amortized linear growth over | ||
3888 | # repeated appends, instead of the typical quadratic growth present in naive | ||
3889 | # implementations. | ||
3890 | if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : | ||
3891 | eval 'as_fn_append () | ||
3892 | { | ||
3893 | eval $1+=\$2 | ||
3894 | }' | ||
3895 | else | ||
3896 | as_fn_append () | ||
3897 | { | ||
3898 | eval $1=\$$1\$2 | ||
3899 | } | ||
3900 | fi # as_fn_append | ||
3901 | |||
3902 | # as_fn_arith ARG... | ||
3903 | # ------------------ | ||
3904 | # Perform arithmetic evaluation on the ARGs, and store the result in the | ||
3905 | # global $as_val. Take advantage of shells that can avoid forks. The arguments | ||
3906 | # must be portable across $(()) and expr. | ||
3907 | if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : | ||
3908 | eval 'as_fn_arith () | ||
3909 | { | ||
3910 | as_val=$(( $* )) | ||
3911 | }' | ||
3912 | else | ||
3913 | as_fn_arith () | ||
3914 | { | ||
3915 | as_val=`expr "$@" || test $? -eq 1` | ||
3916 | } | ||
3917 | fi # as_fn_arith | ||
3918 | |||
3919 | |||
3920 | if expr a : '\(a\)' >/dev/null 2>&1 && | ||
3921 | test "X`expr 00001 : '.*\(...\)'`" = X001; then | ||
3922 | as_expr=expr | ||
3923 | else | ||
3924 | as_expr=false | ||
3925 | fi | ||
3926 | |||
3927 | if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then | ||
3928 | as_basename=basename | ||
3929 | else | ||
3930 | as_basename=false | ||
3931 | fi | ||
3932 | |||
3933 | if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then | ||
3934 | as_dirname=dirname | ||
3935 | else | ||
3936 | as_dirname=false | ||
3937 | fi | ||
3938 | |||
3939 | as_me=`$as_basename -- "$0" || | ||
3940 | $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ | ||
3941 | X"$0" : 'X\(//\)$' \| \ | ||
3942 | X"$0" : 'X\(/\)' \| . 2>/dev/null || | ||
3943 | $as_echo X/"$0" | | ||
3944 | sed '/^.*\/\([^/][^/]*\)\/*$/{ | ||
3945 | s//\1/ | ||
3946 | q | ||
3947 | } | ||
3948 | /^X\/\(\/\/\)$/{ | ||
3949 | s//\1/ | ||
3950 | q | ||
3951 | } | ||
3952 | /^X\/\(\/\).*/{ | ||
3953 | s//\1/ | ||
3954 | q | ||
3955 | } | ||
3956 | s/.*/./; q'` | ||
3957 | |||
3958 | # Avoid depending upon Character Ranges. | ||
3959 | as_cr_letters='abcdefghijklmnopqrstuvwxyz' | ||
3960 | as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' | ||
3961 | as_cr_Letters=$as_cr_letters$as_cr_LETTERS | ||
3962 | as_cr_digits='0123456789' | ||
3963 | as_cr_alnum=$as_cr_Letters$as_cr_digits | ||
3964 | |||
3965 | ECHO_C= ECHO_N= ECHO_T= | ||
3966 | case `echo -n x` in #((((( | ||
3967 | -n*) | ||
3968 | case `echo 'xy\c'` in | ||
3969 | *c*) ECHO_T=' ';; # ECHO_T is single tab character. | ||
3970 | xy) ECHO_C='\c';; | ||
3971 | *) echo `echo ksh88 bug on AIX 6.1` > /dev/null | ||
3972 | ECHO_T=' ';; | ||
3973 | esac;; | ||
3974 | *) | ||
3975 | ECHO_N='-n';; | ||
3976 | esac | ||
3977 | |||
3978 | rm -f conf$$ conf$$.exe conf$$.file | ||
3979 | if test -d conf$$.dir; then | ||
3980 | rm -f conf$$.dir/conf$$.file | ||
3981 | else | ||
3982 | rm -f conf$$.dir | ||
3983 | mkdir conf$$.dir 2>/dev/null | ||
3984 | fi | ||
3985 | if (echo >conf$$.file) 2>/dev/null; then | ||
3986 | if ln -s conf$$.file conf$$ 2>/dev/null; then | ||
3987 | as_ln_s='ln -s' | ||
3988 | # ... but there are two gotchas: | ||
3989 | # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. | ||
3990 | # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. | ||
3991 | # In both cases, we have to default to `cp -pR'. | ||
3992 | ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || | ||
3993 | as_ln_s='cp -pR' | ||
3994 | elif ln conf$$.file conf$$ 2>/dev/null; then | ||
3995 | as_ln_s=ln | ||
3996 | else | ||
3997 | as_ln_s='cp -pR' | ||
3998 | fi | ||
3999 | else | ||
4000 | as_ln_s='cp -pR' | ||
4001 | fi | ||
4002 | rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file | ||
4003 | rmdir conf$$.dir 2>/dev/null | ||
4004 | |||
4005 | |||
4006 | # as_fn_mkdir_p | ||
4007 | # ------------- | ||
4008 | # Create "$as_dir" as a directory, including parents if necessary. | ||
4009 | as_fn_mkdir_p () | ||
4010 | { | ||
4011 | |||
4012 | case $as_dir in #( | ||
4013 | -*) as_dir=./$as_dir;; | ||
4014 | esac | ||
4015 | test -d "$as_dir" || eval $as_mkdir_p || { | ||
4016 | as_dirs= | ||
4017 | while :; do | ||
4018 | case $as_dir in #( | ||
4019 | *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( | ||
4020 | *) as_qdir=$as_dir;; | ||
4021 | esac | ||
4022 | as_dirs="'$as_qdir' $as_dirs" | ||
4023 | as_dir=`$as_dirname -- "$as_dir" || | ||
4024 | $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ | ||
4025 | X"$as_dir" : 'X\(//\)[^/]' \| \ | ||
4026 | X"$as_dir" : 'X\(//\)$' \| \ | ||
4027 | X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || | ||
4028 | $as_echo X"$as_dir" | | ||
4029 | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ | ||
4030 | s//\1/ | ||
4031 | q | ||
4032 | } | ||
4033 | /^X\(\/\/\)[^/].*/{ | ||
4034 | s//\1/ | ||
4035 | q | ||
4036 | } | ||
4037 | /^X\(\/\/\)$/{ | ||
4038 | s//\1/ | ||
4039 | q | ||
4040 | } | ||
4041 | /^X\(\/\).*/{ | ||
4042 | s//\1/ | ||
4043 | q | ||
4044 | } | ||
4045 | s/.*/./; q'` | ||
4046 | test -d "$as_dir" && break | ||
4047 | done | ||
4048 | test -z "$as_dirs" || eval "mkdir $as_dirs" | ||
4049 | } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" | ||
4050 | |||
4051 | |||
4052 | } # as_fn_mkdir_p | ||
4053 | if mkdir -p . 2>/dev/null; then | ||
4054 | as_mkdir_p='mkdir -p "$as_dir"' | ||
4055 | else | ||
4056 | test -d ./-p && rmdir ./-p | ||
4057 | as_mkdir_p=false | ||
4058 | fi | ||
4059 | |||
4060 | |||
4061 | # as_fn_executable_p FILE | ||
4062 | # ----------------------- | ||
4063 | # Test if FILE is an executable regular file. | ||
4064 | as_fn_executable_p () | ||
4065 | { | ||
4066 | test -f "$1" && test -x "$1" | ||
4067 | } # as_fn_executable_p | ||
4068 | as_test_x='test -x' | ||
4069 | as_executable_p=as_fn_executable_p | ||
4070 | |||
4071 | # Sed expression to map a string onto a valid CPP name. | ||
4072 | as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" | ||
4073 | |||
4074 | # Sed expression to map a string onto a valid variable name. | ||
4075 | as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" | ||
4076 | |||
4077 | |||
4078 | exec 6>&1 | ||
4079 | ## ----------------------------------- ## | ||
4080 | ## Main body of $CONFIG_STATUS script. ## | ||
4081 | ## ----------------------------------- ## | ||
4082 | _ASEOF | ||
4083 | test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 | ||
4084 | |||
4085 | cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 | ||
4086 | # Save the log message, to keep $0 and so on meaningful, and to | ||
4087 | # report actual input values of CONFIG_FILES etc. instead of their | ||
4088 | # values after options handling. | ||
4089 | ac_log=" | ||
4090 | This file was extended by firejail $as_me 0.9.28, which was | ||
4091 | generated by GNU Autoconf 2.69. Invocation command line was | ||
4092 | |||
4093 | CONFIG_FILES = $CONFIG_FILES | ||
4094 | CONFIG_HEADERS = $CONFIG_HEADERS | ||
4095 | CONFIG_LINKS = $CONFIG_LINKS | ||
4096 | CONFIG_COMMANDS = $CONFIG_COMMANDS | ||
4097 | $ $0 $@ | ||
4098 | |||
4099 | on `(hostname || uname -n) 2>/dev/null | sed 1q` | ||
4100 | " | ||
4101 | |||
4102 | _ACEOF | ||
4103 | |||
4104 | case $ac_config_files in *" | ||
4105 | "*) set x $ac_config_files; shift; ac_config_files=$*;; | ||
4106 | esac | ||
4107 | |||
4108 | |||
4109 | |||
4110 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 | ||
4111 | # Files that config.status was made for. | ||
4112 | config_files="$ac_config_files" | ||
4113 | |||
4114 | _ACEOF | ||
4115 | |||
4116 | cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 | ||
4117 | ac_cs_usage="\ | ||
4118 | \`$as_me' instantiates files and other configuration actions | ||
4119 | from templates according to the current configuration. Unless the files | ||
4120 | and actions are specified as TAGs, all are instantiated by default. | ||
4121 | |||
4122 | Usage: $0 [OPTION]... [TAG]... | ||
4123 | |||
4124 | -h, --help print this help, then exit | ||
4125 | -V, --version print version number and configuration settings, then exit | ||
4126 | --config print configuration, then exit | ||
4127 | -q, --quiet, --silent | ||
4128 | do not print progress messages | ||
4129 | -d, --debug don't remove temporary files | ||
4130 | --recheck update $as_me by reconfiguring in the same conditions | ||
4131 | --file=FILE[:TEMPLATE] | ||
4132 | instantiate the configuration file FILE | ||
4133 | |||
4134 | Configuration files: | ||
4135 | $config_files | ||
4136 | |||
4137 | Report bugs to <netblue30@yahoo.com>. | ||
4138 | firejail home page: <http://firejail.sourceforge.net>." | ||
4139 | |||
4140 | _ACEOF | ||
4141 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 | ||
4142 | ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" | ||
4143 | ac_cs_version="\\ | ||
4144 | firejail config.status 0.9.28 | ||
4145 | configured by $0, generated by GNU Autoconf 2.69, | ||
4146 | with options \\"\$ac_cs_config\\" | ||
4147 | |||
4148 | Copyright (C) 2012 Free Software Foundation, Inc. | ||
4149 | This config.status script is free software; the Free Software Foundation | ||
4150 | gives unlimited permission to copy, distribute and modify it." | ||
4151 | |||
4152 | ac_pwd='$ac_pwd' | ||
4153 | srcdir='$srcdir' | ||
4154 | INSTALL='$INSTALL' | ||
4155 | test -n "\$AWK" || AWK=awk | ||
4156 | _ACEOF | ||
4157 | |||
4158 | cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 | ||
4159 | # The default lists apply if the user does not specify any file. | ||
4160 | ac_need_defaults=: | ||
4161 | while test $# != 0 | ||
4162 | do | ||
4163 | case $1 in | ||
4164 | --*=?*) | ||
4165 | ac_option=`expr "X$1" : 'X\([^=]*\)='` | ||
4166 | ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` | ||
4167 | ac_shift=: | ||
4168 | ;; | ||
4169 | --*=) | ||
4170 | ac_option=`expr "X$1" : 'X\([^=]*\)='` | ||
4171 | ac_optarg= | ||
4172 | ac_shift=: | ||
4173 | ;; | ||
4174 | *) | ||
4175 | ac_option=$1 | ||
4176 | ac_optarg=$2 | ||
4177 | ac_shift=shift | ||
4178 | ;; | ||
4179 | esac | ||
4180 | |||
4181 | case $ac_option in | ||
4182 | # Handling of the options. | ||
4183 | -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) | ||
4184 | ac_cs_recheck=: ;; | ||
4185 | --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) | ||
4186 | $as_echo "$ac_cs_version"; exit ;; | ||
4187 | --config | --confi | --conf | --con | --co | --c ) | ||
4188 | $as_echo "$ac_cs_config"; exit ;; | ||
4189 | --debug | --debu | --deb | --de | --d | -d ) | ||
4190 | debug=: ;; | ||
4191 | --file | --fil | --fi | --f ) | ||
4192 | $ac_shift | ||
4193 | case $ac_optarg in | ||
4194 | *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; | ||
4195 | '') as_fn_error $? "missing file argument" ;; | ||
4196 | esac | ||
4197 | as_fn_append CONFIG_FILES " '$ac_optarg'" | ||
4198 | ac_need_defaults=false;; | ||
4199 | --he | --h | --help | --hel | -h ) | ||
4200 | $as_echo "$ac_cs_usage"; exit ;; | ||
4201 | -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | ||
4202 | | -silent | --silent | --silen | --sile | --sil | --si | --s) | ||
4203 | ac_cs_silent=: ;; | ||
4204 | |||
4205 | # This is an error. | ||
4206 | -*) as_fn_error $? "unrecognized option: \`$1' | ||
4207 | Try \`$0 --help' for more information." ;; | ||
4208 | |||
4209 | *) as_fn_append ac_config_targets " $1" | ||
4210 | ac_need_defaults=false ;; | ||
4211 | |||
4212 | esac | ||
4213 | shift | ||
4214 | done | ||
4215 | |||
4216 | ac_configure_extra_args= | ||
4217 | |||
4218 | if $ac_cs_silent; then | ||
4219 | exec 6>/dev/null | ||
4220 | ac_configure_extra_args="$ac_configure_extra_args --silent" | ||
4221 | fi | ||
4222 | |||
4223 | _ACEOF | ||
4224 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 | ||
4225 | if \$ac_cs_recheck; then | ||
4226 | set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion | ||
4227 | shift | ||
4228 | \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 | ||
4229 | CONFIG_SHELL='$SHELL' | ||
4230 | export CONFIG_SHELL | ||
4231 | exec "\$@" | ||
4232 | fi | ||
4233 | |||
4234 | _ACEOF | ||
4235 | cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 | ||
4236 | exec 5>>config.log | ||
4237 | { | ||
4238 | echo | ||
4239 | sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX | ||
4240 | ## Running $as_me. ## | ||
4241 | _ASBOX | ||
4242 | $as_echo "$ac_log" | ||
4243 | } >&5 | ||
4244 | |||
4245 | _ACEOF | ||
4246 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 | ||
4247 | _ACEOF | ||
4248 | |||
4249 | cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 | ||
4250 | |||
4251 | # Handling of arguments. | ||
4252 | for ac_config_target in $ac_config_targets | ||
4253 | do | ||
4254 | case $ac_config_target in | ||
4255 | "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; | ||
4256 | "src/lib/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib/Makefile" ;; | ||
4257 | "src/firejail/Makefile") CONFIG_FILES="$CONFIG_FILES src/firejail/Makefile" ;; | ||
4258 | "src/firemon/Makefile") CONFIG_FILES="$CONFIG_FILES src/firemon/Makefile" ;; | ||
4259 | "src/libtrace/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtrace/Makefile" ;; | ||
4260 | "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;; | ||
4261 | |||
4262 | *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; | ||
4263 | esac | ||
4264 | done | ||
4265 | |||
4266 | |||
4267 | # If the user did not use the arguments to specify the items to instantiate, | ||
4268 | # then the envvar interface is used. Set only those that are not. | ||
4269 | # We use the long form for the default assignment because of an extremely | ||
4270 | # bizarre bug on SunOS 4.1.3. | ||
4271 | if $ac_need_defaults; then | ||
4272 | test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files | ||
4273 | fi | ||
4274 | |||
4275 | # Have a temporary directory for convenience. Make it in the build tree | ||
4276 | # simply because there is no reason against having it here, and in addition, | ||
4277 | # creating and moving files from /tmp can sometimes cause problems. | ||
4278 | # Hook for its removal unless debugging. | ||
4279 | # Note that there is a small window in which the directory will not be cleaned: | ||
4280 | # after its creation but before its name has been assigned to `$tmp'. | ||
4281 | $debug || | ||
4282 | { | ||
4283 | tmp= ac_tmp= | ||
4284 | trap 'exit_status=$? | ||
4285 | : "${ac_tmp:=$tmp}" | ||
4286 | { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status | ||
4287 | ' 0 | ||
4288 | trap 'as_fn_exit 1' 1 2 13 15 | ||
4289 | } | ||
4290 | # Create a (secure) tmp directory for tmp files. | ||
4291 | |||
4292 | { | ||
4293 | tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && | ||
4294 | test -d "$tmp" | ||
4295 | } || | ||
4296 | { | ||
4297 | tmp=./conf$$-$RANDOM | ||
4298 | (umask 077 && mkdir "$tmp") | ||
4299 | } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 | ||
4300 | ac_tmp=$tmp | ||
4301 | |||
4302 | # Set up the scripts for CONFIG_FILES section. | ||
4303 | # No need to generate them if there are no CONFIG_FILES. | ||
4304 | # This happens for instance with `./config.status config.h'. | ||
4305 | if test -n "$CONFIG_FILES"; then | ||
4306 | |||
4307 | |||
4308 | ac_cr=`echo X | tr X '\015'` | ||
4309 | # On cygwin, bash can eat \r inside `` if the user requested igncr. | ||
4310 | # But we know of no other shell where ac_cr would be empty at this | ||
4311 | # point, so we can use a bashism as a fallback. | ||
4312 | if test "x$ac_cr" = x; then | ||
4313 | eval ac_cr=\$\'\\r\' | ||
4314 | fi | ||
4315 | ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` | ||
4316 | if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then | ||
4317 | ac_cs_awk_cr='\\r' | ||
4318 | else | ||
4319 | ac_cs_awk_cr=$ac_cr | ||
4320 | fi | ||
4321 | |||
4322 | echo 'BEGIN {' >"$ac_tmp/subs1.awk" && | ||
4323 | _ACEOF | ||
4324 | |||
4325 | |||
4326 | { | ||
4327 | echo "cat >conf$$subs.awk <<_ACEOF" && | ||
4328 | echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && | ||
4329 | echo "_ACEOF" | ||
4330 | } >conf$$subs.sh || | ||
4331 | as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 | ||
4332 | ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` | ||
4333 | ac_delim='%!_!# ' | ||
4334 | for ac_last_try in false false false false false :; do | ||
4335 | . ./conf$$subs.sh || | ||
4336 | as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 | ||
4337 | |||
4338 | ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` | ||
4339 | if test $ac_delim_n = $ac_delim_num; then | ||
4340 | break | ||
4341 | elif $ac_last_try; then | ||
4342 | as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 | ||
4343 | else | ||
4344 | ac_delim="$ac_delim!$ac_delim _$ac_delim!! " | ||
4345 | fi | ||
4346 | done | ||
4347 | rm -f conf$$subs.sh | ||
4348 | |||
4349 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 | ||
4350 | cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && | ||
4351 | _ACEOF | ||
4352 | sed -n ' | ||
4353 | h | ||
4354 | s/^/S["/; s/!.*/"]=/ | ||
4355 | p | ||
4356 | g | ||
4357 | s/^[^!]*!// | ||
4358 | :repl | ||
4359 | t repl | ||
4360 | s/'"$ac_delim"'$// | ||
4361 | t delim | ||
4362 | :nl | ||
4363 | h | ||
4364 | s/\(.\{148\}\)..*/\1/ | ||
4365 | t more1 | ||
4366 | s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ | ||
4367 | p | ||
4368 | n | ||
4369 | b repl | ||
4370 | :more1 | ||
4371 | s/["\\]/\\&/g; s/^/"/; s/$/"\\/ | ||
4372 | p | ||
4373 | g | ||
4374 | s/.\{148\}// | ||
4375 | t nl | ||
4376 | :delim | ||
4377 | h | ||
4378 | s/\(.\{148\}\)..*/\1/ | ||
4379 | t more2 | ||
4380 | s/["\\]/\\&/g; s/^/"/; s/$/"/ | ||
4381 | p | ||
4382 | b | ||
4383 | :more2 | ||
4384 | s/["\\]/\\&/g; s/^/"/; s/$/"\\/ | ||
4385 | p | ||
4386 | g | ||
4387 | s/.\{148\}// | ||
4388 | t delim | ||
4389 | ' <conf$$subs.awk | sed ' | ||
4390 | /^[^""]/{ | ||
4391 | N | ||
4392 | s/\n// | ||
4393 | } | ||
4394 | ' >>$CONFIG_STATUS || ac_write_fail=1 | ||
4395 | rm -f conf$$subs.awk | ||
4396 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 | ||
4397 | _ACAWK | ||
4398 | cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && | ||
4399 | for (key in S) S_is_set[key] = 1 | ||
4400 | FS = "" | ||
4401 | |||
4402 | } | ||
4403 | { | ||
4404 | line = $ 0 | ||
4405 | nfields = split(line, field, "@") | ||
4406 | substed = 0 | ||
4407 | len = length(field[1]) | ||
4408 | for (i = 2; i < nfields; i++) { | ||
4409 | key = field[i] | ||
4410 | keylen = length(key) | ||
4411 | if (S_is_set[key]) { | ||
4412 | value = S[key] | ||
4413 | line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) | ||
4414 | len += length(value) + length(field[++i]) | ||
4415 | substed = 1 | ||
4416 | } else | ||
4417 | len += 1 + keylen | ||
4418 | } | ||
4419 | |||
4420 | print line | ||
4421 | } | ||
4422 | |||
4423 | _ACAWK | ||
4424 | _ACEOF | ||
4425 | cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 | ||
4426 | if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then | ||
4427 | sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" | ||
4428 | else | ||
4429 | cat | ||
4430 | fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ | ||
4431 | || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 | ||
4432 | _ACEOF | ||
4433 | |||
4434 | # VPATH may cause trouble with some makes, so we remove sole $(srcdir), | ||
4435 | # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and | ||
4436 | # trailing colons and then remove the whole line if VPATH becomes empty | ||
4437 | # (actually we leave an empty line to preserve line numbers). | ||
4438 | if test "x$srcdir" = x.; then | ||
4439 | ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ | ||
4440 | h | ||
4441 | s/// | ||
4442 | s/^/:/ | ||
4443 | s/[ ]*$/:/ | ||
4444 | s/:\$(srcdir):/:/g | ||
4445 | s/:\${srcdir}:/:/g | ||
4446 | s/:@srcdir@:/:/g | ||
4447 | s/^:*// | ||
4448 | s/:*$// | ||
4449 | x | ||
4450 | s/\(=[ ]*\).*/\1/ | ||
4451 | G | ||
4452 | s/\n// | ||
4453 | s/^[^=]*=[ ]*$// | ||
4454 | }' | ||
4455 | fi | ||
4456 | |||
4457 | cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 | ||
4458 | fi # test -n "$CONFIG_FILES" | ||
4459 | |||
4460 | |||
4461 | eval set X " :F $CONFIG_FILES " | ||
4462 | shift | ||
4463 | for ac_tag | ||
4464 | do | ||
4465 | case $ac_tag in | ||
4466 | :[FHLC]) ac_mode=$ac_tag; continue;; | ||
4467 | esac | ||
4468 | case $ac_mode$ac_tag in | ||
4469 | :[FHL]*:*);; | ||
4470 | :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; | ||
4471 | :[FH]-) ac_tag=-:-;; | ||
4472 | :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; | ||
4473 | esac | ||
4474 | ac_save_IFS=$IFS | ||
4475 | IFS=: | ||
4476 | set x $ac_tag | ||
4477 | IFS=$ac_save_IFS | ||
4478 | shift | ||
4479 | ac_file=$1 | ||
4480 | shift | ||
4481 | |||
4482 | case $ac_mode in | ||
4483 | :L) ac_source=$1;; | ||
4484 | :[FH]) | ||
4485 | ac_file_inputs= | ||
4486 | for ac_f | ||
4487 | do | ||
4488 | case $ac_f in | ||
4489 | -) ac_f="$ac_tmp/stdin";; | ||
4490 | *) # Look for the file first in the build tree, then in the source tree | ||
4491 | # (if the path is not absolute). The absolute path cannot be DOS-style, | ||
4492 | # because $ac_f cannot contain `:'. | ||
4493 | test -f "$ac_f" || | ||
4494 | case $ac_f in | ||
4495 | [\\/$]*) false;; | ||
4496 | *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; | ||
4497 | esac || | ||
4498 | as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; | ||
4499 | esac | ||
4500 | case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac | ||
4501 | as_fn_append ac_file_inputs " '$ac_f'" | ||
4502 | done | ||
4503 | |||
4504 | # Let's still pretend it is `configure' which instantiates (i.e., don't | ||
4505 | # use $as_me), people would be surprised to read: | ||
4506 | # /* config.h. Generated by config.status. */ | ||
4507 | configure_input='Generated from '` | ||
4508 | $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' | ||
4509 | `' by configure.' | ||
4510 | if test x"$ac_file" != x-; then | ||
4511 | configure_input="$ac_file. $configure_input" | ||
4512 | { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 | ||
4513 | $as_echo "$as_me: creating $ac_file" >&6;} | ||
4514 | fi | ||
4515 | # Neutralize special characters interpreted by sed in replacement strings. | ||
4516 | case $configure_input in #( | ||
4517 | *\&* | *\|* | *\\* ) | ||
4518 | ac_sed_conf_input=`$as_echo "$configure_input" | | ||
4519 | sed 's/[\\\\&|]/\\\\&/g'`;; #( | ||
4520 | *) ac_sed_conf_input=$configure_input;; | ||
4521 | esac | ||
4522 | |||
4523 | case $ac_tag in | ||
4524 | *:-:* | *:-) cat >"$ac_tmp/stdin" \ | ||
4525 | || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; | ||
4526 | esac | ||
4527 | ;; | ||
4528 | esac | ||
4529 | |||
4530 | ac_dir=`$as_dirname -- "$ac_file" || | ||
4531 | $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ | ||
4532 | X"$ac_file" : 'X\(//\)[^/]' \| \ | ||
4533 | X"$ac_file" : 'X\(//\)$' \| \ | ||
4534 | X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || | ||
4535 | $as_echo X"$ac_file" | | ||
4536 | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ | ||
4537 | s//\1/ | ||
4538 | q | ||
4539 | } | ||
4540 | /^X\(\/\/\)[^/].*/{ | ||
4541 | s//\1/ | ||
4542 | q | ||
4543 | } | ||
4544 | /^X\(\/\/\)$/{ | ||
4545 | s//\1/ | ||
4546 | q | ||
4547 | } | ||
4548 | /^X\(\/\).*/{ | ||
4549 | s//\1/ | ||
4550 | q | ||
4551 | } | ||
4552 | s/.*/./; q'` | ||
4553 | as_dir="$ac_dir"; as_fn_mkdir_p | ||
4554 | ac_builddir=. | ||
4555 | |||
4556 | case "$ac_dir" in | ||
4557 | .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; | ||
4558 | *) | ||
4559 | ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` | ||
4560 | # A ".." for each directory in $ac_dir_suffix. | ||
4561 | ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` | ||
4562 | case $ac_top_builddir_sub in | ||
4563 | "") ac_top_builddir_sub=. ac_top_build_prefix= ;; | ||
4564 | *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; | ||
4565 | esac ;; | ||
4566 | esac | ||
4567 | ac_abs_top_builddir=$ac_pwd | ||
4568 | ac_abs_builddir=$ac_pwd$ac_dir_suffix | ||
4569 | # for backward compatibility: | ||
4570 | ac_top_builddir=$ac_top_build_prefix | ||
4571 | |||
4572 | case $srcdir in | ||
4573 | .) # We are building in place. | ||
4574 | ac_srcdir=. | ||
4575 | ac_top_srcdir=$ac_top_builddir_sub | ||
4576 | ac_abs_top_srcdir=$ac_pwd ;; | ||
4577 | [\\/]* | ?:[\\/]* ) # Absolute name. | ||
4578 | ac_srcdir=$srcdir$ac_dir_suffix; | ||
4579 | ac_top_srcdir=$srcdir | ||
4580 | ac_abs_top_srcdir=$srcdir ;; | ||
4581 | *) # Relative name. | ||
4582 | ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix | ||
4583 | ac_top_srcdir=$ac_top_build_prefix$srcdir | ||
4584 | ac_abs_top_srcdir=$ac_pwd/$srcdir ;; | ||
4585 | esac | ||
4586 | ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix | ||
4587 | |||
4588 | |||
4589 | case $ac_mode in | ||
4590 | :F) | ||
4591 | # | ||
4592 | # CONFIG_FILE | ||
4593 | # | ||
4594 | |||
4595 | case $INSTALL in | ||
4596 | [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; | ||
4597 | *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; | ||
4598 | esac | ||
4599 | _ACEOF | ||
4600 | |||
4601 | cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 | ||
4602 | # If the template does not know about datarootdir, expand it. | ||
4603 | # FIXME: This hack should be removed a few years after 2.60. | ||
4604 | ac_datarootdir_hack=; ac_datarootdir_seen= | ||
4605 | ac_sed_dataroot=' | ||
4606 | /datarootdir/ { | ||
4607 | p | ||
4608 | q | ||
4609 | } | ||
4610 | /@datadir@/p | ||
4611 | /@docdir@/p | ||
4612 | /@infodir@/p | ||
4613 | /@localedir@/p | ||
4614 | /@mandir@/p' | ||
4615 | case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in | ||
4616 | *datarootdir*) ac_datarootdir_seen=yes;; | ||
4617 | *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) | ||
4618 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 | ||
4619 | $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} | ||
4620 | _ACEOF | ||
4621 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 | ||
4622 | ac_datarootdir_hack=' | ||
4623 | s&@datadir@&$datadir&g | ||
4624 | s&@docdir@&$docdir&g | ||
4625 | s&@infodir@&$infodir&g | ||
4626 | s&@localedir@&$localedir&g | ||
4627 | s&@mandir@&$mandir&g | ||
4628 | s&\\\${datarootdir}&$datarootdir&g' ;; | ||
4629 | esac | ||
4630 | _ACEOF | ||
4631 | |||
4632 | # Neutralize VPATH when `$srcdir' = `.'. | ||
4633 | # Shell code in configure.ac might set extrasub. | ||
4634 | # FIXME: do we really want to maintain this feature? | ||
4635 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 | ||
4636 | ac_sed_extra="$ac_vpsub | ||
4637 | $extrasub | ||
4638 | _ACEOF | ||
4639 | cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 | ||
4640 | :t | ||
4641 | /@[a-zA-Z_][a-zA-Z_0-9]*@/!b | ||
4642 | s|@configure_input@|$ac_sed_conf_input|;t t | ||
4643 | s&@top_builddir@&$ac_top_builddir_sub&;t t | ||
4644 | s&@top_build_prefix@&$ac_top_build_prefix&;t t | ||
4645 | s&@srcdir@&$ac_srcdir&;t t | ||
4646 | s&@abs_srcdir@&$ac_abs_srcdir&;t t | ||
4647 | s&@top_srcdir@&$ac_top_srcdir&;t t | ||
4648 | s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t | ||
4649 | s&@builddir@&$ac_builddir&;t t | ||
4650 | s&@abs_builddir@&$ac_abs_builddir&;t t | ||
4651 | s&@abs_top_builddir@&$ac_abs_top_builddir&;t t | ||
4652 | s&@INSTALL@&$ac_INSTALL&;t t | ||
4653 | $ac_datarootdir_hack | ||
4654 | " | ||
4655 | eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ | ||
4656 | >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 | ||
4657 | |||
4658 | test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && | ||
4659 | { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && | ||
4660 | { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ | ||
4661 | "$ac_tmp/out"`; test -z "$ac_out"; } && | ||
4662 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' | ||
4663 | which seems to be undefined. Please make sure it is defined" >&5 | ||
4664 | $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' | ||
4665 | which seems to be undefined. Please make sure it is defined" >&2;} | ||
4666 | |||
4667 | rm -f "$ac_tmp/stdin" | ||
4668 | case $ac_file in | ||
4669 | -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; | ||
4670 | *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; | ||
4671 | esac \ | ||
4672 | || as_fn_error $? "could not create $ac_file" "$LINENO" 5 | ||
4673 | ;; | ||
4674 | |||
4675 | |||
4676 | |||
4677 | esac | ||
4678 | |||
4679 | done # for ac_tag | ||
4680 | |||
4681 | |||
4682 | as_fn_exit 0 | ||
4683 | _ACEOF | ||
4684 | ac_clean_files=$ac_clean_files_save | ||
4685 | |||
4686 | test $ac_write_fail = 0 || | ||
4687 | as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 | ||
4688 | |||
4689 | |||
4690 | # configure is writing to config.log, and then calls config.status. | ||
4691 | # config.status does its own redirection, appending to config.log. | ||
4692 | # Unfortunately, on DOS this fails, as config.log is still kept open | ||
4693 | # by configure, so config.status won't be able to write to it; its | ||
4694 | # output is simply discarded. So we exec the FD to /dev/null, | ||
4695 | # effectively closing config.log, so it can be properly (re)opened and | ||
4696 | # appended to by config.status. When coming back to configure, we | ||
4697 | # need to make the FD available again. | ||
4698 | if test "$no_create" != yes; then | ||
4699 | ac_cs_success=: | ||
4700 | ac_config_status_args= | ||
4701 | test "$silent" = yes && | ||
4702 | ac_config_status_args="$ac_config_status_args --quiet" | ||
4703 | exec 5>/dev/null | ||
4704 | $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false | ||
4705 | exec 5>>config.log | ||
4706 | # Use ||, not &&, to avoid exiting from the if with $? = 1, which | ||
4707 | # would make configure fail if this is the last instruction. | ||
4708 | $ac_cs_success || as_fn_exit 1 | ||
4709 | fi | ||
4710 | if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then | ||
4711 | { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 | ||
4712 | $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} | ||
4713 | fi | ||
4714 | |||
4715 | |||
4716 | echo | ||
4717 | echo "Configuration options:" | ||
4718 | echo " prefix: $prefix" | ||
4719 | echo " seccomp: $HAVE_SECCOMP" | ||
4720 | echo " <linux/seccomp.h>: $HAVE_SECCOMP_H" | ||
4721 | echo " chroot: $HAVE_CHROOT" | ||
4722 | echo " bind: $HAVE_BIND" | ||
4723 | echo | ||
diff --git a/configure.ac b/configure.ac new file mode 100644 index 000000000..9e34aec20 --- /dev/null +++ b/configure.ac | |||
@@ -0,0 +1,52 @@ | |||
1 | AC_PREREQ([2.68]) | ||
2 | AC_INIT(firejail, 0.9.28, netblue30@yahoo.com, , http://firejail.sourceforge.net) | ||
3 | AC_CONFIG_SRCDIR([src/firejail/main.c]) | ||
4 | #AC_CONFIG_HEADERS([config.h]) | ||
5 | |||
6 | |||
7 | AC_PROG_CC | ||
8 | #AC_PROG_CXX | ||
9 | AC_PROG_INSTALL | ||
10 | AC_PROG_RANLIB | ||
11 | |||
12 | HAVE_SECCOMP="" | ||
13 | AC_ARG_ENABLE([seccomp], | ||
14 | AS_HELP_STRING([--disable-seccomp], [Disable seccomp])) | ||
15 | AS_IF([test "x$enable_seccomp" != "xno"], [ | ||
16 | HAVE_SECCOMP="-DHAVE_SECCOMP" | ||
17 | AC_SUBST(HAVE_SECCOMP) | ||
18 | ]) | ||
19 | |||
20 | HAVE_CHROOT="" | ||
21 | AC_ARG_ENABLE([chroot], | ||
22 | AS_HELP_STRING([--disable-chroot], [Disable chroot])) | ||
23 | AS_IF([test "x$enable_chroot" != "xno"], [ | ||
24 | HAVE_CHROOT="-DHAVE_CHROOT" | ||
25 | AC_SUBST(HAVE_CHROOT) | ||
26 | ]) | ||
27 | |||
28 | HAVE_BIND="" | ||
29 | AC_ARG_ENABLE([bind], | ||
30 | AS_HELP_STRING([--disable-bind], [Disable bind])) | ||
31 | AS_IF([test "x$enable_bind" != "xno"], [ | ||
32 | HAVE_BIND="-DHAVE_BIND" | ||
33 | AC_SUBST(HAVE_BIND) | ||
34 | ]) | ||
35 | |||
36 | |||
37 | # checking pthread library | ||
38 | AC_CHECK_LIB([pthread], [main], [], AC_MSG_ERROR([*** POSIX thread support not installed ***])) | ||
39 | AC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR([*** POSIX thread support not installed ***])) | ||
40 | AC_CHECK_HEADER([linux/seccomp.h], HAVE_SECCOMP_H="-DHAVE_SECCOMP_H", HAVE_SECCOMP_H="") | ||
41 | AC_SUBST(HAVE_SECCOMP_H) | ||
42 | |||
43 | AC_OUTPUT(Makefile src/lib/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/ftee/Makefile) | ||
44 | |||
45 | echo | ||
46 | echo "Configuration options:" | ||
47 | echo " prefix: $prefix" | ||
48 | echo " seccomp: $HAVE_SECCOMP" | ||
49 | echo " <linux/seccomp.h>: $HAVE_SECCOMP_H" | ||
50 | echo " chroot: $HAVE_CHROOT" | ||
51 | echo " bind: $HAVE_BIND" | ||
52 | echo | ||
diff --git a/etc/audacious.profile b/etc/audacious.profile new file mode 100644 index 000000000..23f223a29 --- /dev/null +++ b/etc/audacious.profile | |||
@@ -0,0 +1,8 @@ | |||
1 | # Audacious profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | noroot | ||
8 | |||
diff --git a/etc/chromium-browser.profile b/etc/chromium-browser.profile new file mode 100644 index 000000000..4cdc098d1 --- /dev/null +++ b/etc/chromium-browser.profile | |||
@@ -0,0 +1,3 @@ | |||
1 | # Chromium browser profile | ||
2 | include /etc/firejail/chromium.profile | ||
3 | |||
diff --git a/etc/chromium.profile b/etc/chromium.profile new file mode 100644 index 000000000..4f6e7e450 --- /dev/null +++ b/etc/chromium.profile | |||
@@ -0,0 +1,7 @@ | |||
1 | # Chromium browser profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc chromium | ||
5 | netfilter | ||
6 | |||
7 | |||
diff --git a/etc/clementine.profile b/etc/clementine.profile new file mode 100644 index 000000000..dd855cc62 --- /dev/null +++ b/etc/clementine.profile | |||
@@ -0,0 +1,7 @@ | |||
1 | # Clementine profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | noroot | ||
diff --git a/etc/deadbeef.profile b/etc/deadbeef.profile new file mode 100644 index 000000000..e2f5787cc --- /dev/null +++ b/etc/deadbeef.profile | |||
@@ -0,0 +1,8 @@ | |||
1 | # DeaDBeeF profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | noroot | ||
8 | |||
diff --git a/etc/deluge.profile b/etc/deluge.profile new file mode 100644 index 000000000..138d0a133 --- /dev/null +++ b/etc/deluge.profile | |||
@@ -0,0 +1,9 @@ | |||
1 | # deluge profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | netfilter | ||
8 | noroot | ||
9 | |||
diff --git a/etc/disable-common.inc b/etc/disable-common.inc new file mode 100644 index 000000000..926000411 --- /dev/null +++ b/etc/disable-common.inc | |||
@@ -0,0 +1,10 @@ | |||
1 | blacklist ${HOME}/.adobe | ||
2 | blacklist ${HOME}/.macromedia | ||
3 | blacklist ${HOME}/.mozilla | ||
4 | blacklist ${HOME}/.icedove | ||
5 | blacklist ${HOME}/.thunderbird | ||
6 | blacklist ${HOME}/.config/midori | ||
7 | blacklist ${HOME}/.config/opera | ||
8 | blacklist ${HOME}/.config/chromium | ||
9 | blacklist ${HOME}/.config/google-chrome | ||
10 | blacklist ${HOME}/.filezilla | ||
diff --git a/etc/disable-mgmt.inc b/etc/disable-mgmt.inc new file mode 100644 index 000000000..f04619ea0 --- /dev/null +++ b/etc/disable-mgmt.inc | |||
@@ -0,0 +1,12 @@ | |||
1 | # system directories | ||
2 | blacklist /sbin | ||
3 | blacklist /usr/sbin | ||
4 | |||
5 | # system management | ||
6 | blacklist ${PATH}/umount | ||
7 | blacklist ${PATH}/mount | ||
8 | blacklist ${PATH}/fusermount | ||
9 | blacklist ${PATH}/su | ||
10 | blacklist ${PATH}/sudo | ||
11 | blacklist ${PATH}/xinput | ||
12 | blacklist ${PATH}/strace | ||
diff --git a/etc/disable-secret.inc b/etc/disable-secret.inc new file mode 100644 index 000000000..8ac1b3792 --- /dev/null +++ b/etc/disable-secret.inc | |||
@@ -0,0 +1,9 @@ | |||
1 | # HOME directory | ||
2 | blacklist ${HOME}/.ssh | ||
3 | tmpfs ${HOME}/.gnome2_private | ||
4 | blacklist ${HOME}/.gnome2/keyrings | ||
5 | blacklist ${HOME}/kde4/share/apps/kwallet | ||
6 | blacklist ${HOME}/kde/share/apps/kwallet | ||
7 | blacklist ${HOME}/.pki/nssdb | ||
8 | blacklist ${HOME}/.gnupg | ||
9 | blacklist ${HOME}/.local/share/recently-used.xbel | ||
diff --git a/etc/dropbox.profile b/etc/dropbox.profile new file mode 100644 index 000000000..82b54adb1 --- /dev/null +++ b/etc/dropbox.profile | |||
@@ -0,0 +1,7 @@ | |||
1 | # dropbox profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps | ||
6 | seccomp | ||
7 | noroot | ||
diff --git a/etc/empathy.profile b/etc/empathy.profile new file mode 100644 index 000000000..d24cae528 --- /dev/null +++ b/etc/empathy.profile | |||
@@ -0,0 +1,6 @@ | |||
1 | # Empathy profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
diff --git a/etc/evince.profile b/etc/evince.profile new file mode 100644 index 000000000..4d96d5904 --- /dev/null +++ b/etc/evince.profile | |||
@@ -0,0 +1,8 @@ | |||
1 | # evince profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | netfilter | ||
8 | noroot | ||
diff --git a/etc/filezilla.profile b/etc/filezilla.profile new file mode 100644 index 000000000..a54b5a734 --- /dev/null +++ b/etc/filezilla.profile | |||
@@ -0,0 +1,10 @@ | |||
1 | # FileZilla profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc .filezilla | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | noroot | ||
8 | netfilter | ||
9 | |||
10 | |||
diff --git a/etc/firefox.profile b/etc/firefox.profile new file mode 100644 index 000000000..dc3489d35 --- /dev/null +++ b/etc/firefox.profile | |||
@@ -0,0 +1,9 @@ | |||
1 | # Firejail profile for Mozilla Firefox (Iceweasel in Debian) | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc .mozilla | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | netfilter | ||
8 | noroot | ||
9 | |||
diff --git a/etc/firejail.bash_completion b/etc/firejail.bash_completion new file mode 100644 index 000000000..50eccf536 --- /dev/null +++ b/etc/firejail.bash_completion | |||
@@ -0,0 +1,86 @@ | |||
1 | # bash completion for firejail -*- shell-script -*- | ||
2 | #******************************************************************** | ||
3 | # Script based on completions/configure script in bash-completion package in | ||
4 | # Debian. The original package is release under GPL v2 license, the webpage is | ||
5 | # http://bash-completion.alioth.debian.org | ||
6 | #******************************************************************* | ||
7 | |||
8 | __interfaces(){ | ||
9 | cut -f 1 -d ':' /proc/net/dev | tail -n +3 | grep -v lo | xargs | ||
10 | } | ||
11 | |||
12 | |||
13 | _firejail() | ||
14 | { | ||
15 | local cur prev words cword split | ||
16 | _init_completion -s || return | ||
17 | |||
18 | case $prev in | ||
19 | --help|--version|-debug-caps|--debug-syscalls|--list|--tree|--top|--join|--shutdown) | ||
20 | return 0 | ||
21 | ;; | ||
22 | --profile) | ||
23 | _filedir | ||
24 | return 0 | ||
25 | ;; | ||
26 | --chroot) | ||
27 | _filedir -d | ||
28 | return 0 | ||
29 | ;; | ||
30 | --cgroup) | ||
31 | _filedir -d | ||
32 | return 0 | ||
33 | ;; | ||
34 | --tmpfs) | ||
35 | _filedir | ||
36 | return 0 | ||
37 | ;; | ||
38 | --blacklist) | ||
39 | _filedir | ||
40 | return 0 | ||
41 | ;; | ||
42 | --read-only) | ||
43 | _filedir | ||
44 | return 0 | ||
45 | ;; | ||
46 | --bind) | ||
47 | _filedir | ||
48 | return 0 | ||
49 | ;; | ||
50 | --private) | ||
51 | _filedir | ||
52 | return 0 | ||
53 | ;; | ||
54 | --shell) | ||
55 | _filedir | ||
56 | return 0 | ||
57 | ;; | ||
58 | --net) | ||
59 | comps=$(__interfaces) | ||
60 | COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) | ||
61 | return 0 | ||
62 | ;; | ||
63 | esac | ||
64 | |||
65 | $split && return 0 | ||
66 | |||
67 | # if $COMP_CONFIGURE_HINTS is not null, then completions of the form | ||
68 | # --option=SETTING will include 'SETTING' as a contextual hint | ||
69 | [[ "$cur" != -* ]] && _filedir && return 0 | ||
70 | |||
71 | if [[ -n $COMP_CONFIGURE_HINTS ]]; then | ||
72 | COMPREPLY=( $( compgen -W "$( $1 --help 2>&1 | \ | ||
73 | awk '/^ --[A-Za-z]/ { print $1; \ | ||
74 | if ($2 ~ /--[A-Za-z]/) print $2 }' | sed -e 's/[[,].*//g' )" \ | ||
75 | -- "$cur" ) ) | ||
76 | [[ $COMPREPLY == *=* ]] && compopt -o nospace | ||
77 | else | ||
78 | COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) | ||
79 | [[ $COMPREPLY == *= ]] && compopt -o nospace | ||
80 | fi | ||
81 | |||
82 | } && | ||
83 | complete -F _firejail firejail | ||
84 | |||
85 | |||
86 | |||
diff --git a/etc/firemon.bash_completion b/etc/firemon.bash_completion new file mode 100644 index 000000000..befbf2388 --- /dev/null +++ b/etc/firemon.bash_completion | |||
@@ -0,0 +1,39 @@ | |||
1 | # bash completion for firemon -*- shell-script -*- | ||
2 | #******************************************************************** | ||
3 | # Script based on completions/configure script in bash-completion package in | ||
4 | # Debian. The original package is release under GPL v2 license, the webpage is | ||
5 | # http://bash-completion.alioth.debian.org | ||
6 | #******************************************************************* | ||
7 | |||
8 | _firemon() | ||
9 | { | ||
10 | local cur prev words cword split | ||
11 | _init_completion -s || return | ||
12 | |||
13 | case $prev in | ||
14 | --help|--version) | ||
15 | return | ||
16 | ;; | ||
17 | esac | ||
18 | |||
19 | $split && return 0 | ||
20 | |||
21 | # if $COMP_CONFIGURE_HINTS is not null, then completions of the form | ||
22 | # --option=SETTING will include 'SETTING' as a contextual hint | ||
23 | [[ "$cur" != -* ]] && return 0 | ||
24 | |||
25 | if [[ -n $COMP_CONFIGURE_HINTS ]]; then | ||
26 | COMPREPLY=( $( compgen -W "$( $1 --help 2>&1 | \ | ||
27 | awk '/^ --[A-Za-z]/ { print $1; \ | ||
28 | if ($2 ~ /--[A-Za-z]/) print $2 }' | sed -e 's/[[,].*//g' )" \ | ||
29 | -- "$cur" ) ) | ||
30 | [[ $COMPREPLY == *=* ]] && compopt -o nospace | ||
31 | else | ||
32 | COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) | ||
33 | [[ $COMPREPLY == *= ]] && compopt -o nospace | ||
34 | fi | ||
35 | } && | ||
36 | complete -F _firemon firemon | ||
37 | |||
38 | |||
39 | |||
diff --git a/etc/generic.profile b/etc/generic.profile new file mode 100644 index 000000000..83bf59e0a --- /dev/null +++ b/etc/generic.profile | |||
@@ -0,0 +1,41 @@ | |||
1 | ################################ | ||
2 | # Generic profile based on Firefox profile | ||
3 | ################################ | ||
4 | #include /etc/firejail/disable-mgmt.inc | ||
5 | # system directories | ||
6 | blacklist /sbin | ||
7 | blacklist /usr/sbin | ||
8 | # system management | ||
9 | blacklist ${PATH}/umount | ||
10 | blacklist ${PATH}/mount | ||
11 | blacklist ${PATH}/fusermount | ||
12 | blacklist ${PATH}/su | ||
13 | blacklist ${PATH}/sudo | ||
14 | blacklist ${PATH}/xinput | ||
15 | blacklist ${PATH}/strace | ||
16 | |||
17 | #include /etc/firejail/disable-secret.inc | ||
18 | # HOME directory | ||
19 | blacklist ${HOME}/.ssh | ||
20 | tmpfs ${HOME}/.gnome2_private | ||
21 | blacklist ${HOME}/.gnome2/keyrings | ||
22 | blacklist ${HOME}/kde4/share/apps/kwallet | ||
23 | blacklist ${HOME}/kde/share/apps/kwallet | ||
24 | blacklist ${HOME}/.pki/nssdb | ||
25 | blacklist ${HOME}/.gnupg | ||
26 | blacklist ${HOME}/.local/share/recently-used.xbel | ||
27 | |||
28 | blacklist ${HOME}/.adobe | ||
29 | blacklist ${HOME}/.macromedia | ||
30 | blacklist ${HOME}/.mozilla | ||
31 | blacklist ${HOME}/.icedove | ||
32 | blacklist ${HOME}/.thunderbird | ||
33 | blacklist ${HOME}/.config/opera | ||
34 | blacklist ${HOME}/.config/chromium | ||
35 | blacklist ${HOME}/.config/google-chrome | ||
36 | |||
37 | caps.drop all | ||
38 | seccomp | ||
39 | netfilter | ||
40 | noroot | ||
41 | |||
diff --git a/etc/gnome-mplayer.profile b/etc/gnome-mplayer.profile new file mode 100644 index 000000000..b69cf3a57 --- /dev/null +++ b/etc/gnome-mplayer.profile | |||
@@ -0,0 +1,7 @@ | |||
1 | # GNOME MPlayer profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | noroot | ||
diff --git a/etc/icecat.profile b/etc/icecat.profile new file mode 100644 index 000000000..25d426ad2 --- /dev/null +++ b/etc/icecat.profile | |||
@@ -0,0 +1,2 @@ | |||
1 | # Firejail profile for GNU Icecat | ||
2 | include /etc/firejail/firefox.profile | ||
diff --git a/etc/icedove.profile b/etc/icedove.profile new file mode 100644 index 000000000..057e0c9ef --- /dev/null +++ b/etc/icedove.profile | |||
@@ -0,0 +1,3 @@ | |||
1 | # Firejail profile for Mozilla Thunderbird (Icedove in Debian) | ||
2 | include /etc/firejail/thunderbird.profile | ||
3 | |||
diff --git a/etc/iceweasel.profile b/etc/iceweasel.profile new file mode 100644 index 000000000..e9b32846a --- /dev/null +++ b/etc/iceweasel.profile | |||
@@ -0,0 +1,2 @@ | |||
1 | # Firejail profile for Mozilla Firefox (Iceweasel in Debian) | ||
2 | include /etc/firejail/firefox.profile | ||
diff --git a/etc/login.users b/etc/login.users new file mode 100644 index 000000000..5d5969091 --- /dev/null +++ b/etc/login.users | |||
@@ -0,0 +1,14 @@ | |||
1 | # /etc/firejail/login.users - restricted user shell configuration | ||
2 | # | ||
3 | # Each user entry consists of a user name and firejail | ||
4 | # program arguments: | ||
5 | # | ||
6 | # user name: arguments | ||
7 | # | ||
8 | # For example: | ||
9 | # | ||
10 | # netblue:--debug --net=none | ||
11 | # | ||
12 | # The extra arguments are inserted into program command line if firejail | ||
13 | # was started as a login shell. | ||
14 | |||
diff --git a/etc/midori.profile b/etc/midori.profile new file mode 100644 index 000000000..5479ba172 --- /dev/null +++ b/etc/midori.profile | |||
@@ -0,0 +1,9 @@ | |||
1 | # Midory browser profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc midori | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | netfilter | ||
8 | noroot | ||
9 | |||
diff --git a/etc/opera.profile b/etc/opera.profile new file mode 100644 index 000000000..852f10719 --- /dev/null +++ b/etc/opera.profile | |||
@@ -0,0 +1,8 @@ | |||
1 | # Chromium browser profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc opera | ||
5 | netfilter | ||
6 | noroot | ||
7 | |||
8 | |||
diff --git a/etc/pidgin.profile b/etc/pidgin.profile new file mode 100644 index 000000000..6f5594919 --- /dev/null +++ b/etc/pidgin.profile | |||
@@ -0,0 +1,7 @@ | |||
1 | # Pidgin profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | noroot | ||
diff --git a/etc/qbittorrent.profile b/etc/qbittorrent.profile new file mode 100644 index 000000000..f85dfc994 --- /dev/null +++ b/etc/qbittorrent.profile | |||
@@ -0,0 +1,9 @@ | |||
1 | # abittorrent profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | netfilter | ||
8 | noroot | ||
9 | |||
diff --git a/etc/quassel.profile b/etc/quassel.profile new file mode 100644 index 000000000..a2057ad01 --- /dev/null +++ b/etc/quassel.profile | |||
@@ -0,0 +1,7 @@ | |||
1 | # Quassel IRC profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | noroot | ||
diff --git a/etc/rhythmbox.profile b/etc/rhythmbox.profile new file mode 100644 index 000000000..42d4dc0fa --- /dev/null +++ b/etc/rhythmbox.profile | |||
@@ -0,0 +1,7 @@ | |||
1 | # Rhythmbox profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | noroot | ||
diff --git a/etc/server.profile b/etc/server.profile new file mode 100644 index 000000000..bb15774fa --- /dev/null +++ b/etc/server.profile | |||
@@ -0,0 +1,6 @@ | |||
1 | # generic server profile | ||
2 | include /etc/firejail/disable-mgmt.inc sbin | ||
3 | private | ||
4 | private-dev | ||
5 | seccomp | ||
6 | |||
diff --git a/etc/thunderbird.profile b/etc/thunderbird.profile new file mode 100644 index 000000000..8b63a6ec5 --- /dev/null +++ b/etc/thunderbird.profile | |||
@@ -0,0 +1,9 @@ | |||
1 | # Firejail profile for Mozilla Thunderbird (Icedove in Debian) | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc thunderbird icedove | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | netfilter | ||
8 | noroot | ||
9 | |||
diff --git a/etc/totem.profile b/etc/totem.profile new file mode 100644 index 000000000..50115deb5 --- /dev/null +++ b/etc/totem.profile | |||
@@ -0,0 +1,7 @@ | |||
1 | # Totem profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | noroot | ||
diff --git a/etc/transmission-gtk.profile b/etc/transmission-gtk.profile new file mode 100644 index 000000000..9ccece285 --- /dev/null +++ b/etc/transmission-gtk.profile | |||
@@ -0,0 +1,9 @@ | |||
1 | # transmission-gtk profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | netfilter | ||
8 | noroot | ||
9 | |||
diff --git a/etc/transmission-qt.profile b/etc/transmission-qt.profile new file mode 100644 index 000000000..65a045f8e --- /dev/null +++ b/etc/transmission-qt.profile | |||
@@ -0,0 +1,9 @@ | |||
1 | # transmission-qt profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | netfilter | ||
8 | noroot | ||
9 | |||
diff --git a/etc/vlc.profile b/etc/vlc.profile new file mode 100644 index 000000000..76e1395f9 --- /dev/null +++ b/etc/vlc.profile | |||
@@ -0,0 +1,7 @@ | |||
1 | # VLC profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | noroot | ||
diff --git a/etc/xchat.profile b/etc/xchat.profile new file mode 100644 index 000000000..b8d8cb1e2 --- /dev/null +++ b/etc/xchat.profile | |||
@@ -0,0 +1,7 @@ | |||
1 | # XChat profile | ||
2 | include /etc/firejail/disable-mgmt.inc | ||
3 | include /etc/firejail/disable-secret.inc | ||
4 | include /etc/firejail/disable-common.inc | ||
5 | caps.drop all | ||
6 | seccomp | ||
7 | noroot | ||
diff --git a/install.sh b/install.sh new file mode 100755 index 000000000..b3ddf0423 --- /dev/null +++ b/install.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | echo "installing..." | ||
diff --git a/mkdeb.sh b/mkdeb.sh new file mode 100755 index 000000000..159649975 --- /dev/null +++ b/mkdeb.sh | |||
@@ -0,0 +1,96 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | # a code archive should already be available | ||
4 | |||
5 | TOP=`pwd` | ||
6 | CODE_ARCHIVE="$1-$2.tar.bz2" | ||
7 | CODE_DIR="$1-$2" | ||
8 | INSTALL_DIR=$TOP | ||
9 | INSTALL_DIR+="/debian/usr" | ||
10 | DEBIAN_CTRL_DIR=$TOP | ||
11 | DEBIAN_CTRL_DIR+="/debian/DEBIAN" | ||
12 | |||
13 | echo "*****************************************" | ||
14 | echo "code archive: $CODE_ARCHIVE" | ||
15 | echo "code directory: $CODE_DIR" | ||
16 | echo "install directory: $INSTALL_DIR" | ||
17 | echo "debian control directory: $DEBIAN_CTRL_DIR" | ||
18 | echo "*****************************************" | ||
19 | tar -xjvf $CODE_ARCHIVE | ||
20 | mkdir -p $INSTALL_DIR | ||
21 | cd $CODE_DIR | ||
22 | ./configure --prefix=$INSTALL_DIR | ||
23 | make && make install | ||
24 | |||
25 | # second compilation - the path to libtrace.so is hardcoded in firejail executable | ||
26 | # pointing according to --prefix=$INSTALL_DIR. We need it to point to /usr/lib | ||
27 | make distclean | ||
28 | ./configure --prefix=/usr | ||
29 | make | ||
30 | # install firejail executable in $TOP/$INSTALL_DIR | ||
31 | strip src/firejail/firejail | ||
32 | install -c -m 0755 src/firejail/firejail $INSTALL_DIR/bin/. | ||
33 | chmod u+s $INSTALL_DIR/bin/firejail | ||
34 | |||
35 | |||
36 | cd .. | ||
37 | echo "*****************************************" | ||
38 | SIZE=`du -s debian/usr` | ||
39 | echo "install size $SIZE" | ||
40 | echo "*****************************************" | ||
41 | |||
42 | mv $INSTALL_DIR/share/doc/firejail/RELNOTES $INSTALL_DIR/share/doc/firejail/changelog.Debian | ||
43 | gzip -9 $INSTALL_DIR/share/doc/firejail/changelog.Debian | ||
44 | rm $INSTALL_DIR/share/doc/firejail/COPYING | ||
45 | cp platform/debian/copyright $INSTALL_DIR/share/doc/firejail/. | ||
46 | mkdir -p $DEBIAN_CTRL_DIR | ||
47 | sed "s/FIREJAILVER/$2/g" platform/debian/control > $DEBIAN_CTRL_DIR/control | ||
48 | mkdir -p debian/etc/firejail | ||
49 | cp etc/chromium.profile debian/etc/firejail/. | ||
50 | cp etc/chromium-browser.profile debian/etc/firejail/. | ||
51 | cp etc/disable-mgmt.inc debian/etc/firejail/. | ||
52 | cp etc/disable-secret.inc debian/etc/firejail/. | ||
53 | cp etc/dropbox.profile debian/etc/firejail/. | ||
54 | cp etc/evince.profile debian/etc/firejail/. | ||
55 | cp etc/firefox.profile debian/etc/firejail/. | ||
56 | cp etc/iceweasel.profile debian/etc/firejail/. | ||
57 | cp etc/icedove.profile debian/etc/firejail/. | ||
58 | cp etc/login* debian/etc/firejail/. | ||
59 | cp etc/midori.profile debian/etc/firejail/. | ||
60 | cp etc/opera.profile debian/etc/firejail/. | ||
61 | cp etc/thunderbird.profile debian/etc/firejail/. | ||
62 | cp etc/transmission-gtk.profile debian/etc/firejail/. | ||
63 | cp etc/transmission-qt.profile debian/etc/firejail/. | ||
64 | cp etc/vlc.profile debian/etc/firejail/. | ||
65 | cp etc/audacious.profile debian/etc/firejail/. | ||
66 | cp etc/clementine.profile debian/etc/firejail/. | ||
67 | cp etc/gnome-mplayer.profile debian/etc/firejail/. | ||
68 | cp etc/rhythmbox.profile debian/etc/firejail/. | ||
69 | cp etc/totem.profile debian/etc/firejail/. | ||
70 | cp etc/deluge.profile debian/etc/firejail/. | ||
71 | cp etc/qbittorrent.profile debian/etc/firejail/. | ||
72 | cp etc/generic.profile debian/etc/firejail/. | ||
73 | cp etc/xchat.profile debian/etc/firejail/. | ||
74 | cp etc/server.profile debian/etc/firejail/. | ||
75 | cp etc/quassel.profile debian/etc/firejail/. | ||
76 | cp etc/pidgin.profile debian/etc/firejail/. | ||
77 | cp etc/filezilla.profile debian/etc/firejail/. | ||
78 | cp etc/empathy.profile debian/etc/firejail/. | ||
79 | cp etc/disable-common.inc debian/etc/firejail/. | ||
80 | cp etc/deadbeef.profile debian/etc/firejail/. | ||
81 | cp etc/icecat.profile debian/etc/firejail/. | ||
82 | cp platform/debian/conffiles $DEBIAN_CTRL_DIR/. | ||
83 | find ./debian -type d | xargs chmod 755 | ||
84 | dpkg-deb --build debian | ||
85 | lintian debian.deb | ||
86 | mv debian.deb firejail_$2_1_amd64.deb | ||
87 | echo "if building a 32bit package, rename the deb file manually" | ||
88 | rm -fr debian | ||
89 | rm -fr $CODE_DIR | ||
90 | |||
91 | |||
92 | |||
93 | |||
94 | |||
95 | |||
96 | |||
diff --git a/mkman.sh b/mkman.sh new file mode 100755 index 000000000..f2a5ef3c6 --- /dev/null +++ b/mkman.sh | |||
@@ -0,0 +1,7 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | sed "s/VERSION/$1/g" $2 > $3 | ||
4 | MONTH=`date +%b` | ||
5 | sed -i "s/MONTH/$MONTH/g" $3 | ||
6 | YEAR=`date +%Y` | ||
7 | sed -i "s/YEAR/$YEAR/g" $3 | ||
diff --git a/platform/debian/conffiles b/platform/debian/conffiles new file mode 100644 index 000000000..6f55cc021 --- /dev/null +++ b/platform/debian/conffiles | |||
@@ -0,0 +1,33 @@ | |||
1 | /etc/firejail/evince.profile | ||
2 | /etc/firejail/disable-secret.inc | ||
3 | /etc/firejail/chromium.profile | ||
4 | /etc/firejail/midori.profile | ||
5 | /etc/firejail/icedove.profile | ||
6 | /etc/firejail/iceweasel.profile | ||
7 | /etc/firejail/dropbox.profile | ||
8 | /etc/firejail/login.users | ||
9 | /etc/firejail/chromium-browser.profile | ||
10 | /etc/firejail/disable-mgmt.inc | ||
11 | /etc/firejail/firefox.profile | ||
12 | /etc/firejail/opera.profile | ||
13 | /etc/firejail/thunderbird.profile | ||
14 | /etc/firejail/transmission-gtk.profile | ||
15 | /etc/firejail/transmission-qt.profile | ||
16 | /etc/firejail/vlc.profile | ||
17 | /etc/firejail/audacious.profile | ||
18 | /etc/firejail/clementine.profile | ||
19 | /etc/firejail/gnome-mplayer.profile | ||
20 | /etc/firejail/rhythmbox.profile | ||
21 | /etc/firejail/totem.profile | ||
22 | /etc/firejail/deluge.profile | ||
23 | /etc/firejail/qbittorrent.profile | ||
24 | /etc/firejail/generic.profile | ||
25 | /etc/firejail/xchat.profile | ||
26 | /etc/firejail/server.profile | ||
27 | /etc/firejail/quassel.profile | ||
28 | /etc/firejail/pidgin.profile | ||
29 | /etc/firejail/filezilla.profile | ||
30 | /etc/firejail/empathy.profile | ||
31 | /etc/firejail/disable-common.inc | ||
32 | /etc/firejail/deadbeef.profile | ||
33 | /etc/firejail/icecat.profile | ||
diff --git a/platform/debian/control b/platform/debian/control new file mode 100644 index 000000000..18d857c36 --- /dev/null +++ b/platform/debian/control | |||
@@ -0,0 +1,20 @@ | |||
1 | Package: firejail | ||
2 | Version: FIREJAILVER-1 | ||
3 | Architecture: amd64 | ||
4 | Maintainer: netblue30 <netblue30@yahoo.com> | ||
5 | Installed-Size: 272 | ||
6 | Depends: libc6 | ||
7 | Section: admin | ||
8 | Priority: extra | ||
9 | Homepage: http://firejail.sourceforge.net | ||
10 | Description: Linux namepaces sandbox program. | ||
11 | Firejail is a SUID sandbox program that reduces the risk of security | ||
12 | breaches by restricting the running environment of untrusted applications | ||
13 | using Linux namespaces and seccmp-bpf. It includes sandbox profiles for | ||
14 | Iceweasel/Mozilla Firefox, Chromium, Midori, Opera, Evince, Transmission | ||
15 | and VLC. | ||
16 | . | ||
17 | Firejail also expands the restricted shell facility found in bash by | ||
18 | adding Linux namespace support. It also supports sandboxing SSH users | ||
19 | upon login. | ||
20 | |||
diff --git a/platform/debian/copyright b/platform/debian/copyright new file mode 100644 index 000000000..7d8d0a2c7 --- /dev/null +++ b/platform/debian/copyright | |||
@@ -0,0 +1,30 @@ | |||
1 | |||
2 | This is the Debian/Ubuntu prepackaged version of firejail. | ||
3 | |||
4 | Firejail is a sandbox program that reduces the risk of security breaches | ||
5 | by restricting the running environment of untrusted applications using | ||
6 | Linux namespaces. It currently implements hostname, filesystem, PID, IPC | ||
7 | and networking stack isolation, and it runs on any recent Linux system. It | ||
8 | includes a sandbox profile for Mozilla Firefox. | ||
9 | |||
10 | Copyright (C) 2014,2015 Firejail Authors (see README file for more details) | ||
11 | |||
12 | This program is free software; you can redistribute it and/or modify | ||
13 | it under the terms of the GNU General Public License as published by | ||
14 | the Free Software Foundation; either version 2 of the License, or | ||
15 | (at your option) any later version. | ||
16 | |||
17 | This program is distributed in the hope that it will be useful, | ||
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | GNU General Public License for more details. | ||
21 | |||
22 | You should have received a copy of the GNU General Public License along | ||
23 | with this program; if not, write to the Free Software Foundation, Inc., 51 | ||
24 | Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | ||
25 | |||
26 | The complete text of the GNU General Public License can be found | ||
27 | in /usr/share/common-licenses/GPL-2. | ||
28 | |||
29 | Homepage: http://firejail.sourceforge.net. | ||
30 | |||
diff --git a/platform/rpm/mkrpm.sh b/platform/rpm/mkrpm.sh new file mode 100755 index 000000000..adac1de46 --- /dev/null +++ b/platform/rpm/mkrpm.sh | |||
@@ -0,0 +1,256 @@ | |||
1 | #!/bin/bash | ||
2 | VERSION="0.9.26" | ||
3 | rm -fr ~/rpmbuild | ||
4 | rm -f firejail-$VERSION-1.x86_64.rpm | ||
5 | |||
6 | mkdir -p ~/rpmbuild/{RPMS,SRPMS,BUILD,SOURCES,SPECS,tmp} | ||
7 | cat <<EOF >~/.rpmmacros | ||
8 | %_topdir %(echo $HOME)/rpmbuild | ||
9 | %_tmppath %{_topdir}/tmp | ||
10 | EOF | ||
11 | |||
12 | cd ~/rpmbuild | ||
13 | echo "building directory tree" | ||
14 | |||
15 | mkdir -p firejail-$VERSION/usr/bin | ||
16 | install -m 755 /usr/bin/firejail firejail-$VERSION/usr/bin/. | ||
17 | install -m 755 /usr/bin/firemon firejail-$VERSION/usr/bin/. | ||
18 | |||
19 | mkdir -p firejail-$VERSION/usr/lib/firejail | ||
20 | install -m 644 /usr/lib/firejail/libtrace.so firejail-$VERSION/usr/lib/firejail/. | ||
21 | install -m 755 /usr/lib/firejail/ftee firejail-$VERSION/usr/lib/firejail/. | ||
22 | |||
23 | mkdir -p firejail-$VERSION/usr/share/man/man1 | ||
24 | install -m 644 /usr/share/man/man1/firejail.1.gz firejail-$VERSION/usr/share/man/man1/. | ||
25 | install -m 644 /usr/share/man/man1/firemon.1.gz firejail-$VERSION/usr/share/man/man1/. | ||
26 | |||
27 | mkdir -p firejail-$VERSION/usr/share/man/man5 | ||
28 | install -m 644 /usr/share/man/man5/firejail-profile.5.gz firejail-$VERSION/usr/share/man/man5/. | ||
29 | |||
30 | mkdir -p firejail-$VERSION/usr/share/doc/packages/firejail | ||
31 | install -m 644 /usr/share/doc/firejail/COPYING firejail-$VERSION/usr/share/doc/packages/firejail/. | ||
32 | install -m 644 /usr/share/doc/firejail/README firejail-$VERSION/usr/share/doc/packages/firejail/. | ||
33 | install -m 644 /usr/share/doc/firejail/RELNOTES firejail-$VERSION/usr/share/doc/packages/firejail/. | ||
34 | |||
35 | mkdir -p firejail-$VERSION/etc/firejail | ||
36 | install -m 644 /etc/firejail/chromium-browser.profile firejail-$VERSION/etc/firejail/chromium-browser.profile | ||
37 | install -m 644 /etc/firejail/chromium.profile firejail-$VERSION/etc/firejail/chromium.profile | ||
38 | install -m 644 /etc/firejail/dropbox.profile firejail-$VERSION/etc/firejail/dropbox.profile | ||
39 | install -m 644 /etc/firejail/disable-secret.inc firejail-$VERSION/etc/firejail/disable-secret.inc | ||
40 | install -m 644 /etc/firejail/disable-mgmt.inc firejail-$VERSION/etc/firejail/disable-mgmt.inc | ||
41 | install -m 644 /etc/firejail/evince.profile firejail-$VERSION/etc/firejail/evince.profile | ||
42 | install -m 644 /etc/firejail/firefox.profile firejail-$VERSION/etc/firejail/firefox.profile | ||
43 | install -m 644 /etc/firejail/icedove.profile firejail-$VERSION/etc/firejail/icedove.profile | ||
44 | install -m 644 /etc/firejail/iceweasel.profile firejail-$VERSION/etc/firejail/iceweasel.profile | ||
45 | install -m 644 /etc/firejail/midori.profile firejail-$VERSION/etc/firejail/midori.profile | ||
46 | install -m 644 /etc/firejail/thunderbird.profile firejail-$VERSION/etc/firejail/thunderbird.profile | ||
47 | install -m 644 /etc/firejail/opera.profile firejail-$VERSION/etc/firejail/opera.profile | ||
48 | install -m 644 /etc/firejail/transmission-gtk.profile firejail-$VERSION/etc/firejail/transmission-gtk.profile | ||
49 | install -m 644 /etc/firejail/transmission-qt.profile firejail-$VERSION/etc/firejail/transmission-qt.profile | ||
50 | install -m 644 /etc/firejail/vlc.profile firejail-$VERSION/etc/firejail/vlc.profile | ||
51 | install -m 644 /etc/firejail/audacious.profile firejail-$VERSION/etc/firejail/audacious.profile | ||
52 | install -m 644 /etc/firejail/clementine.profile firejail-$VERSION/etc/firejail/clementine.profile | ||
53 | install -m 644 /etc/firejail/gnome-mplayer.profile firejail-$VERSION/etc/firejail/gnome-mplayer.profile | ||
54 | install -m 644 /etc/firejail/rhythmbox.profile firejail-$VERSION/etc/firejail/rhythmbox.profile | ||
55 | install -m 644 /etc/firejail/totem.profile firejail-$VERSION/etc/firejail/totem.profile | ||
56 | install -m 644 /etc/firejail/deluge.profile firejail-$VERSION/etc/firejail/deluge.profile | ||
57 | install -m 644 /etc/firejail/qbittorrent.profile firejail-$VERSION/etc/firejail/qbittorrent.profile | ||
58 | install -m 644 /etc/firejail/generic.profile firejail-$VERSION/etc/firejail/generic.profile | ||
59 | install -m 644 /etc/firejail/login.users firejail-$VERSION/etc/firejail/login.users | ||
60 | |||
61 | mkdir -p firejail-$VERSION/usr/share/bash-completion/completions | ||
62 | install -m 644 /usr/share/bash-completion/completions/firejail firejail-$VERSION/usr/share/bash-completion/completions/. | ||
63 | |||
64 | echo "building tar.gz archive" | ||
65 | tar -czvf firejail-$VERSION.tar.gz firejail-$VERSION | ||
66 | |||
67 | cp firejail-$VERSION.tar.gz SOURCES/. | ||
68 | |||
69 | echo "building config spec" | ||
70 | cat <<EOF > SPECS/firejail.spec | ||
71 | %define __spec_install_post %{nil} | ||
72 | %define debug_package %{nil} | ||
73 | %define __os_install_post %{_dbpath}/brp-compress | ||
74 | |||
75 | Summary: Linux namepaces sandbox program | ||
76 | Name: firejail | ||
77 | Version: $VERSION | ||
78 | Release: 1 | ||
79 | License: GPL+ | ||
80 | Group: Development/Tools | ||
81 | SOURCE0 : %{name}-%{version}.tar.gz | ||
82 | URL: http://firejail.sourceforege.net | ||
83 | |||
84 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root | ||
85 | |||
86 | %description | ||
87 | Firejail is a SUID sandbox program that reduces the risk of security | ||
88 | breaches by restricting the running environment of untrusted applications | ||
89 | using Linux namespaces. It includes a sandbox profile for Mozilla Firefox. | ||
90 | |||
91 | %prep | ||
92 | %setup -q | ||
93 | |||
94 | %build | ||
95 | |||
96 | %install | ||
97 | rm -rf %{buildroot} | ||
98 | mkdir -p %{buildroot} | ||
99 | |||
100 | cp -a * %{buildroot} | ||
101 | |||
102 | |||
103 | %clean | ||
104 | rm -rf %{buildroot} | ||
105 | |||
106 | |||
107 | %files | ||
108 | %defattr(-,root,root,-) | ||
109 | %config(noreplace) %{_sysconfdir}/%{name}/chromium-browser.profile | ||
110 | %config(noreplace) %{_sysconfdir}/%{name}/chromium.profile | ||
111 | %config(noreplace) %{_sysconfdir}/%{name}/disable-mgmt.inc | ||
112 | %config(noreplace) %{_sysconfdir}/%{name}/disable-secret.inc | ||
113 | %config(noreplace) %{_sysconfdir}/%{name}/dropbox.profile | ||
114 | %config(noreplace) %{_sysconfdir}/%{name}/evince.profile | ||
115 | %config(noreplace) %{_sysconfdir}/%{name}/firefox.profile | ||
116 | %config(noreplace) %{_sysconfdir}/%{name}/icedove.profile | ||
117 | %config(noreplace) %{_sysconfdir}/%{name}/iceweasel.profile | ||
118 | %config(noreplace) %{_sysconfdir}/%{name}/login.users | ||
119 | %config(noreplace) %{_sysconfdir}/%{name}/midori.profile | ||
120 | %config(noreplace) %{_sysconfdir}/%{name}/opera.profile | ||
121 | %config(noreplace) %{_sysconfdir}/%{name}/thunderbird.profile | ||
122 | %config(noreplace) %{_sysconfdir}/%{name}/transmission-gtk.profile | ||
123 | %config(noreplace) %{_sysconfdir}/%{name}/transmission-qt.profile | ||
124 | %config(noreplace) %{_sysconfdir}/%{name}/vlc.profile | ||
125 | %config(noreplace) %{_sysconfdir}/%{name}/audacious.profile | ||
126 | %config(noreplace) %{_sysconfdir}/%{name}/clementine.profile | ||
127 | %config(noreplace) %{_sysconfdir}/%{name}/gnome-mplayer.profile | ||
128 | %config(noreplace) %{_sysconfdir}/%{name}/rhythmbox.profile | ||
129 | %config(noreplace) %{_sysconfdir}/%{name}/totem.profile | ||
130 | %config(noreplace) %{_sysconfdir}/%{name}/deluge.profile | ||
131 | %config(noreplace) %{_sysconfdir}/%{name}/qbittorrent.profile | ||
132 | %config(noreplace) %{_sysconfdir}/%{name}/generic.profile | ||
133 | |||
134 | /usr/bin/firejail | ||
135 | /usr/bin/firemon | ||
136 | /usr/lib/firejail/libtrace.so | ||
137 | /usr/lib/firejail/ftee | ||
138 | /usr/share/doc/packages/firejail/COPYING | ||
139 | /usr/share/doc/packages/firejail/README | ||
140 | /usr/share/doc/packages/firejail/RELNOTES | ||
141 | /usr/share/man/man1/firejail.1.gz | ||
142 | /usr/share/man/man1/firemon.1.gz | ||
143 | /usr/share/man/man5/firejail-profile.5.gz | ||
144 | /usr/share/bash-completion/completions/firejail | ||
145 | |||
146 | %post | ||
147 | chmod u+s /usr/bin/firejail | ||
148 | |||
149 | %changelog | ||
150 | * Thu Apr 30 2015 netblue30 <netblue30@yahoo.com> 0.9.26-1 | ||
151 | - private dev directory | ||
152 | - private.keep option for whitelisting home files in a new private directory | ||
153 | - user namespaces support, noroot option | ||
154 | - added Deluge and qBittorent profiles | ||
155 | - bugfixes | ||
156 | |||
157 | * Sun Apr 5 2015 netblue30 <netblue30@yahoo.com> 0.9.24-1 | ||
158 | - whitelist and blacklist seccomp filters | ||
159 | - doubledash option | ||
160 | - --shell=none support | ||
161 | - netfilter file support in profile files | ||
162 | - dns server support in profile files | ||
163 | - added --dns.print option | ||
164 | - added default profiles for Audoacious, Clementine, Rhythmbox and Totem. | ||
165 | - added --caps.drop=all in default profiles | ||
166 | - new syscalls in default seccomp filter: sysfs, sysctl, adjtimex, kcmp | ||
167 | - clock_adjtime, lookup_dcookie, perf_event_open, fanotify_init | ||
168 | - Bugfix: using /proc/sys/kernel/pid_max for the max number of pids | ||
169 | - two build patches from Reiner Herman (tickets 11, 12) | ||
170 | - man page patch from Reiner Herman (ticket 13) | ||
171 | - output patch (ticket 15) from sshirokov | ||
172 | |||
173 | * Mon Mar 9 2015 netblue30 <netblue30@yahoo.com> 0.9.22-1 | ||
174 | - Replaced --noip option with --ip=none | ||
175 | - Container stdout logging and log rotation | ||
176 | - Added process_vm_readv, process_vm_writev and mknod to | ||
177 | default seccomp blacklist | ||
178 | - Added CAP_MKNOD to default caps blacklist | ||
179 | - Blacklist and whitelist custom Linux capabilities filters | ||
180 | - macvlan device driver support for --net option | ||
181 | - DNS server support, --dns option | ||
182 | - Netfilter support | ||
183 | - Monitor network statistics, --netstats option | ||
184 | - Added profile for Mozilla Thunderbird/Icedove | ||
185 | - --overlay support for Linux kernels 3.18+ | ||
186 | - Bugfix: preserve .Xauthority file in private mode (test with ssh -X) | ||
187 | - Bugfix: check uid/gid for cgroup | ||
188 | |||
189 | * Fri Feb 6 2015 netblue30 <netblue30@yahoo.com> 0.9.20-1 | ||
190 | - utmp, btmp and wtmp enhancements | ||
191 | - create empty /var/log/wtmp and /var/log/btmp files in sandbox | ||
192 | - generate a new /var/run/utmp file in sandbox | ||
193 | - CPU affinity, --cpu option | ||
194 | - Linux control groups support, --cgroup option | ||
195 | - Opera web browser support | ||
196 | - VLC support | ||
197 | - Added "empty" attribute to seccomp command to remove the default | ||
198 | - syscall list form seccomp blacklist | ||
199 | - Added --nogroups option to disable supplementary groups for regular | ||
200 | - users. root user always runs without supplementary groups. | ||
201 | - firemon enhancements | ||
202 | - display the command that started the sandbox | ||
203 | - added --caps option to display capabilities for all sandboxes | ||
204 | - added --cgroup option to display the control groups for all sandboxes | ||
205 | - added --cpu option to display CPU affinity for all sandboxes | ||
206 | - added --seccomp option to display seccomp setting for all sandboxes | ||
207 | - New compile time options: --disable-chroot, --disable-bind | ||
208 | - bugfixes | ||
209 | |||
210 | * Sat Dec 27 2014 netblue30 <netblue30@yahoo.com> 0.9.18-1 | ||
211 | - Support for tracing system, setuid, setgid, setfsuid, setfsgid syscalls | ||
212 | - Support for tracing setreuid, setregid, setresuid, setresguid syscalls | ||
213 | - Added profiles for transmission-gtk and transmission-qt | ||
214 | - bugfixes | ||
215 | |||
216 | * Tue Nov 4 2014 netblue30 <netblue30@yahoo.com> 0.9.16-1 | ||
217 | - Configurable private home directory | ||
218 | - Configurable default user shell | ||
219 | - Software configuration support for --docdir and DESTDIR | ||
220 | - Profile file support for include, caps, seccomp and private keywords | ||
221 | - Dropbox profile file | ||
222 | - Linux capabilities and seccomp filters enabled by default for Firefox, | ||
223 | Midori, Evince and Dropbox | ||
224 | - bugfixes | ||
225 | |||
226 | * Wed Oct 8 2014 netblue30 <netblue30@yahoo.com> 0.9.14-1 | ||
227 | - Linux capabilities and seccomp filters are automatically enabled in | ||
228 | chroot mode (--chroot option) if the sandbox is started as regular | ||
229 | user | ||
230 | - Added support for user defined seccomp blacklists | ||
231 | - Added syscall trace support | ||
232 | - Added --tmpfs option | ||
233 | - Added --balcklist option | ||
234 | - Added --read-only option | ||
235 | - Added --bind option | ||
236 | - Logging enhancements | ||
237 | - --overlay option was reactivated | ||
238 | - Added firemon support to print the ARP table for each sandbox | ||
239 | - Added firemon support to print the route table for each sandbox | ||
240 | - Added firemon support to print interface information for each sandbox | ||
241 | - bugfixes | ||
242 | |||
243 | * Tue Sep 16 2014 netblue30 <netblue30@yahoo.com> 0.9.12-1 | ||
244 | - Added capabilities support | ||
245 | - Added support for CentOS 7 | ||
246 | - bugfixes | ||
247 | |||
248 | EOF | ||
249 | |||
250 | echo "building rpm" | ||
251 | rpmbuild -ba SPECS/firejail.spec | ||
252 | rpm -qpl RPMS/x86_64/firejail-$VERSION-1.x86_64.rpm | ||
253 | cd .. | ||
254 | rm -f firejail-$VERSION-1.x86_64.rpm | ||
255 | cp rpmbuild/RPMS/x86_64/firejail-$VERSION-1.x86_64.rpm . | ||
256 | |||
diff --git a/src/firejail/Makefile.in b/src/firejail/Makefile.in new file mode 100644 index 000000000..1f7b563c4 --- /dev/null +++ b/src/firejail/Makefile.in | |||
@@ -0,0 +1,28 @@ | |||
1 | all: firejail | ||
2 | |||
3 | PREFIX=@prefix@ | ||
4 | VERSION=@PACKAGE_VERSION@ | ||
5 | NAME=@PACKAGE_NAME@ | ||
6 | HAVE_SECCOMP_H=@HAVE_SECCOMP_H@ | ||
7 | HAVE_SECCOMP=@HAVE_SECCOMP@ | ||
8 | HAVE_CHROOT=@HAVE_CHROOT@ | ||
9 | HAVE_BIND=@HAVE_BIND@ | ||
10 | |||
11 | H_FILE_LIST = $(wildcard *.[h]) | ||
12 | C_FILE_LIST = $(wildcard *.c) | ||
13 | OBJS = $(C_FILE_LIST:.c=.o) | ||
14 | BINOBJS = $(foreach file, $(OBJS), $file) | ||
15 | CFLAGS += -ggdb -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(PREFIX)"' $(HAVE_SECCOMP) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_BIND) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security | ||
16 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread | ||
17 | |||
18 | %.o : %.c $(H_FILE_LIST) | ||
19 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ | ||
20 | |||
21 | firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o | ||
22 | $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/libnetlink.o ../lib/common.o $(LIBS) | ||
23 | |||
24 | clean:; rm -f *.o firejail firejail.1 firejail.1.gz | ||
25 | |||
26 | distclean: clean | ||
27 | rm -fr Makefile | ||
28 | |||
diff --git a/src/firejail/arg-checking.txt b/src/firejail/arg-checking.txt new file mode 100644 index 000000000..c1ab2cb21 --- /dev/null +++ b/src/firejail/arg-checking.txt | |||
@@ -0,0 +1,85 @@ | |||
1 | arg checking: | ||
2 | |||
3 | 1. --output=filename | ||
4 | - not supported in profiles | ||
5 | - checking no "..", | ||
6 | - checking no link, | ||
7 | - checking no dir, | ||
8 | - checking same permissions, | ||
9 | - checking no hard links | ||
10 | - unit test | ||
11 | |||
12 | 2. --chroot=dirname | ||
13 | - not supported in profiles | ||
14 | - expand "~" | ||
15 | - checking no "..", | ||
16 | - checking is dir, | ||
17 | - checking no link | ||
18 | - checking directory structure | ||
19 | - unit test | ||
20 | |||
21 | 3. --bind=dirname1,dirname2, --bind=filename1,filenam2 | ||
22 | - supported in profiles | ||
23 | - accepted only when running as root | ||
24 | - checking string chars | ||
25 | - checking no ".." | ||
26 | - unit test non root | ||
27 | |||
28 | 4. --tmpfs=dirname | ||
29 | - supported in profiles | ||
30 | - checking string chars | ||
31 | - checking no ".." | ||
32 | - unit test | ||
33 | |||
34 | 5. --blacklist=filename, --blacklist=dirname | ||
35 | - supported in profiles | ||
36 | - checking string chars | ||
37 | - checking no ".." | ||
38 | - unit test | ||
39 | |||
40 | 6. --read-only=filename, --read-only=dirname | ||
41 | - supported in profiles | ||
42 | - checking string chars | ||
43 | - checking no ".." | ||
44 | - unit test | ||
45 | |||
46 | 7. --profile=filename | ||
47 | - check access as real GID/UID | ||
48 | - checking no dir | ||
49 | - checking no link | ||
50 | - checking no ".." | ||
51 | - unit test | ||
52 | |||
53 | 8. --private=dirname | ||
54 | - supported in profiles | ||
55 | - expand "~" | ||
56 | - check is dir | ||
57 | - check no link | ||
58 | - checking no ".." | ||
59 | - check same owner | ||
60 | - unit test | ||
61 | |||
62 | 9. --private.keep=filelist | ||
63 | - supported in profiles | ||
64 | - checking no ".." | ||
65 | - checking file found | ||
66 | - checking same owner | ||
67 | - checking no link | ||
68 | - unit test | ||
69 | |||
70 | 10. --netfilter=filename | ||
71 | - supported in profiles | ||
72 | - check access as real GID/UID | ||
73 | - checking no dir | ||
74 | - checking no link | ||
75 | - checking no ".." | ||
76 | - unit test | ||
77 | |||
78 | 11. --shell=filename | ||
79 | - not supported in profiles | ||
80 | - check access as real GID/UID | ||
81 | - checking no dir | ||
82 | - checking no link | ||
83 | - checking no ".." | ||
84 | - unit test | ||
85 | |||
diff --git a/src/firejail/arp.c b/src/firejail/arp.c new file mode 100644 index 000000000..37f8716e7 --- /dev/null +++ b/src/firejail/arp.c | |||
@@ -0,0 +1,474 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/socket.h> | ||
22 | #include <sys/ioctl.h> | ||
23 | #include <linux/if_ether.h> //TCP/IP Protocol Suite for Linux | ||
24 | #include <net/if.h> | ||
25 | #include <netinet/in.h> | ||
26 | #include <linux/ip.h> | ||
27 | #include <linux/udp.h> | ||
28 | #include <linux/tcp.h> | ||
29 | #include <linux/if_packet.h> | ||
30 | |||
31 | typedef struct arp_hdr_t { | ||
32 | uint16_t htype; | ||
33 | uint16_t ptype; | ||
34 | uint8_t hlen; | ||
35 | uint8_t plen; | ||
36 | uint16_t opcode; | ||
37 | uint8_t sender_mac[6]; | ||
38 | uint8_t sender_ip[4]; | ||
39 | uint8_t target_mac[6]; | ||
40 | uint8_t target_ip[4]; | ||
41 | } ArpHdr; | ||
42 | |||
43 | // returns 0 if the address is not in use, -1 otherwise | ||
44 | int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr) { | ||
45 | if (strlen(dev) > IFNAMSIZ) { | ||
46 | fprintf(stderr, "Error: invalid network device name %s\n", dev); | ||
47 | exit(1); | ||
48 | } | ||
49 | |||
50 | if (arg_debug) | ||
51 | printf("Trying %d.%d.%d.%d ...\n", PRINT_IP(destaddr)); | ||
52 | |||
53 | // find interface address | ||
54 | int sock; | ||
55 | if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) | ||
56 | errExit("socket"); | ||
57 | |||
58 | srcaddr = htonl(srcaddr); | ||
59 | destaddr = htonl(destaddr); | ||
60 | |||
61 | // Find interface MAC address | ||
62 | struct ifreq ifr; | ||
63 | memset(&ifr, 0, sizeof (ifr)); | ||
64 | strncpy(ifr.ifr_name, dev, IFNAMSIZ); | ||
65 | if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) | ||
66 | errExit("ioctl"); | ||
67 | close(sock); | ||
68 | |||
69 | // configure layer2 socket address information | ||
70 | struct sockaddr_ll addr; | ||
71 | memset(&addr, 0, sizeof(addr)); | ||
72 | if ((addr.sll_ifindex = if_nametoindex(dev)) == 0) | ||
73 | errExit("if_nametoindex"); | ||
74 | addr.sll_family = AF_PACKET; | ||
75 | memcpy (addr.sll_addr, ifr.ifr_hwaddr.sa_data, 6); | ||
76 | addr.sll_halen = htons(6); | ||
77 | |||
78 | // build the arp packet header | ||
79 | ArpHdr hdr; | ||
80 | memset(&hdr, 0, sizeof(hdr)); | ||
81 | hdr.htype = htons(1); | ||
82 | hdr.ptype = htons(ETH_P_IP); | ||
83 | hdr.hlen = 6; | ||
84 | hdr.plen = 4; | ||
85 | hdr.opcode = htons(1); //ARPOP_REQUEST | ||
86 | memcpy(hdr.sender_mac, ifr.ifr_hwaddr.sa_data, 6); | ||
87 | memcpy(hdr.sender_ip, (uint8_t *)&srcaddr, 4); | ||
88 | memcpy(hdr.target_ip, (uint8_t *)&destaddr, 4); | ||
89 | |||
90 | // buiild ethernet frame | ||
91 | uint8_t frame[ETH_FRAME_LEN]; // includes eht header, vlan, and crc | ||
92 | memset(frame, 0, sizeof(frame)); | ||
93 | frame[0] = frame[1] = frame[2] = frame[3] = frame[4] = frame[5] = 0xff; | ||
94 | memcpy(frame + 6, ifr.ifr_hwaddr.sa_data, 6); | ||
95 | frame[12] = ETH_P_ARP / 256; | ||
96 | frame[13] = ETH_P_ARP % 256; | ||
97 | memcpy (frame + 14, &hdr, sizeof(hdr)); | ||
98 | |||
99 | // open layer2 socket | ||
100 | if ((sock = socket(PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0) | ||
101 | errExit("socket"); | ||
102 | |||
103 | int len; | ||
104 | if ((len = sendto (sock, frame, 14 + sizeof(ArpHdr), 0, (struct sockaddr *) &addr, sizeof (addr))) <= 0) | ||
105 | errExit("send"); | ||
106 | fflush(0); | ||
107 | |||
108 | // wait not more than one second for an answer | ||
109 | fd_set fds; | ||
110 | FD_ZERO(&fds); | ||
111 | FD_SET(sock, &fds); | ||
112 | int maxfd = sock; | ||
113 | struct timeval ts; | ||
114 | ts.tv_sec = 1; // 1 second wait time | ||
115 | ts.tv_usec = 0; | ||
116 | while (1) { | ||
117 | int nready = select(maxfd + 1, &fds, (fd_set *) 0, (fd_set *) 0, &ts); | ||
118 | if (nready < 0) | ||
119 | errExit("select"); | ||
120 | else if (nready == 0) { // timeout | ||
121 | close(sock); | ||
122 | return 0; | ||
123 | } | ||
124 | else { | ||
125 | // read the incoming packet | ||
126 | int len = recvfrom(sock, frame, ETH_FRAME_LEN, 0, NULL, NULL); | ||
127 | if (len < 0) { | ||
128 | perror("recvfrom"); | ||
129 | close(sock); | ||
130 | return -1; | ||
131 | } | ||
132 | |||
133 | // parse the incomming packet | ||
134 | if (len < 14 + sizeof(ArpHdr)) | ||
135 | continue; | ||
136 | if (frame[12] != (ETH_P_ARP / 256) || frame[13] != (ETH_P_ARP % 256)) | ||
137 | continue; | ||
138 | memcpy(&hdr, frame + 14, sizeof(ArpHdr)); | ||
139 | if (hdr.opcode == htons(1)) | ||
140 | continue; | ||
141 | if (hdr.opcode == htons(2)) { | ||
142 | // check my mac and my address | ||
143 | if (memcmp(ifr.ifr_hwaddr.sa_data, hdr.target_mac, 6) != 0) | ||
144 | continue; | ||
145 | uint32_t ip; | ||
146 | memcpy(&ip, hdr.target_ip, 4); | ||
147 | if (ip != srcaddr) { | ||
148 | continue; | ||
149 | } | ||
150 | close(sock); | ||
151 | return -1; | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | |||
156 | // it will never get here! | ||
157 | close(sock); | ||
158 | return -1; | ||
159 | } | ||
160 | |||
161 | // assign a random IP address and check it | ||
162 | // the address needs to be in the range if it --iprange was specified | ||
163 | static uint32_t arp_random(const char *dev, Bridge *br) { | ||
164 | assert(dev); | ||
165 | assert(br); | ||
166 | uint32_t ifip = br->ip; | ||
167 | uint32_t ifmask = br->mask; | ||
168 | assert(ifip); | ||
169 | assert(ifmask); | ||
170 | |||
171 | if (arg_debug) | ||
172 | printf("ARP-scan %s, %d.%d.%d.%d/%d\n", | ||
173 | dev, PRINT_IP(ifip), mask2bits(ifmask)); | ||
174 | |||
175 | // determine the range based on network address | ||
176 | uint32_t range = ~ifmask + 1; // the number of potential addresses | ||
177 | // this software is not supported for /31 networks | ||
178 | if (range < 4) | ||
179 | return 0; // the user will have to set the IP address manually | ||
180 | range -= 2; // subtract the network address and the broadcast address | ||
181 | uint32_t start = (ifip & ifmask) + 1; | ||
182 | |||
183 | // adjust range based on --iprange params | ||
184 | if (br->iprange_start && br->iprange_end) { | ||
185 | start = br->iprange_start; | ||
186 | range = br->iprange_end - br->iprange_start; | ||
187 | } | ||
188 | |||
189 | if (arg_debug) | ||
190 | printf("IP address range from %d.%d.%d.%d to %d.%d.%d.%d\n", | ||
191 | PRINT_IP(start), PRINT_IP(start + range)); | ||
192 | |||
193 | // generate a random address - 10 tries | ||
194 | uint32_t dest = 0; | ||
195 | int i = 0; | ||
196 | for (i = 0; i < 10; i++) { | ||
197 | dest = start + ((uint32_t) rand()) % range; | ||
198 | if (dest == ifip) // do not allow the interface address | ||
199 | continue; // try again | ||
200 | |||
201 | // if we've made it up to here, we have a valid address | ||
202 | break; | ||
203 | } | ||
204 | if (i == 10) // we failed 10 times | ||
205 | return 0; | ||
206 | |||
207 | // check address | ||
208 | uint32_t rv = arp_check(dev, dest, ifip); | ||
209 | if (!rv) | ||
210 | return dest; | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | // go sequentially trough all IP addresses and assign the first one not in use | ||
215 | static uint32_t arp_sequential(const char *dev, Bridge *br) { | ||
216 | assert(dev); | ||
217 | assert(br); | ||
218 | uint32_t ifip = br->ip; | ||
219 | uint32_t ifmask = br->mask; | ||
220 | assert(ifip); | ||
221 | assert(ifmask); | ||
222 | |||
223 | // range based on network address | ||
224 | uint32_t range = ~ifmask + 1; // the number of potential addresses | ||
225 | // this software is not supported for /31 networks | ||
226 | if (range < 4) | ||
227 | return 0; // the user will have to set the IP address manually | ||
228 | range -= 2; // subtract the network address and the broadcast address | ||
229 | |||
230 | // try all possible ip addresses in ascending order | ||
231 | // start address | ||
232 | uint32_t dest = (ifip & ifmask) + 1; | ||
233 | if (br->iprange_start) | ||
234 | dest = br->iprange_start; | ||
235 | // end address | ||
236 | uint32_t last = dest + range - 1; | ||
237 | if (br->iprange_end) | ||
238 | last = br->iprange_end; | ||
239 | |||
240 | if (arg_debug) | ||
241 | printf("Trying IP address range from %d.%d.%d.%d to %d.%d.%d.%d\n", | ||
242 | PRINT_IP(dest), PRINT_IP(last)); | ||
243 | |||
244 | // loop through addresses and stop as soon as you find an unused one | ||
245 | while (dest <= last) { | ||
246 | if (dest == ifip) { | ||
247 | dest++; | ||
248 | continue; | ||
249 | } | ||
250 | uint32_t rv = arp_check(dev, dest, ifip); | ||
251 | if (!rv) | ||
252 | return dest; | ||
253 | dest++; | ||
254 | } | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | // assign an IP address first trying some random addresses, and if this fails | ||
260 | // by doing an arp scan. | ||
261 | // | ||
262 | // dev is the name of the device to use in scanning, | ||
263 | // br is bridge structure holding the ip address and mask to use in | ||
264 | // arp packets. It also holds values for for the range of addresses | ||
265 | // if --iprange was set by the user | ||
266 | uint32_t arp_assign(const char *dev, Bridge *br) { | ||
267 | assert(br); | ||
268 | uint32_t ip = 0; | ||
269 | |||
270 | // try two random IP addresses | ||
271 | ip = arp_random(dev, br); | ||
272 | if (!ip) | ||
273 | ip = arp_random(dev, br); | ||
274 | |||
275 | // try all possible IP addresses one by one | ||
276 | if (!ip) | ||
277 | ip = arp_sequential(dev, br); | ||
278 | |||
279 | // print result | ||
280 | if (!ip) { | ||
281 | fprintf(stderr, "Error: cannot assign an IP address; it looks like all of them are in use.\n"); | ||
282 | logerr("Cannot assign an IP address; it looks like all of them are in use."); | ||
283 | exit(1); | ||
284 | } | ||
285 | |||
286 | return ip; | ||
287 | } | ||
288 | |||
289 | // scan interface (--scan option) | ||
290 | void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask) { | ||
291 | assert(dev); | ||
292 | assert(ifip); | ||
293 | |||
294 | // printf("Scanning interface %s (%d.%d.%d.%d/%d)\n", | ||
295 | // dev, PRINT_IP(ifip & ifmask), mask2bits(ifmask)); | ||
296 | |||
297 | if (strlen(dev) > IFNAMSIZ) { | ||
298 | fprintf(stderr, "Error: invalid network device name %s\n", dev); | ||
299 | exit(1); | ||
300 | } | ||
301 | |||
302 | // find interface mac address | ||
303 | int sock; | ||
304 | if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) | ||
305 | errExit("socket"); | ||
306 | struct ifreq ifr; | ||
307 | memset(&ifr, 0, sizeof (ifr)); | ||
308 | strncpy(ifr.ifr_name, dev, IFNAMSIZ); | ||
309 | if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) | ||
310 | errExit("ioctl"); | ||
311 | close(sock); | ||
312 | uint8_t mac[6]; | ||
313 | memcpy (mac, ifr.ifr_hwaddr.sa_data, 6); | ||
314 | |||
315 | // open layer2 socket | ||
316 | if ((sock = socket(PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0) | ||
317 | errExit("socket"); | ||
318 | |||
319 | // try all possible ip addresses in ascending order | ||
320 | uint32_t range = ~ifmask + 1; // the number of potential addresses | ||
321 | // this software is not supported for /31 networks | ||
322 | if (range < 4) { | ||
323 | fprintf(stderr, "Warning: this option is not supported for /31 networks\n"); | ||
324 | close(sock); | ||
325 | return; | ||
326 | } | ||
327 | |||
328 | uint32_t dest = (ifip & ifmask) + 1; | ||
329 | uint32_t last = dest + range - 1; | ||
330 | uint32_t src = htonl(ifip); | ||
331 | |||
332 | // wait not more than one second for an answer | ||
333 | int header_printed = 0; | ||
334 | int last_ip = 0; | ||
335 | struct timeval ts; | ||
336 | ts.tv_sec = 2; // 2 seconds receive timeout | ||
337 | ts.tv_usec = 0; | ||
338 | |||
339 | while (1) { | ||
340 | fd_set rfds; | ||
341 | FD_ZERO(&rfds); | ||
342 | FD_SET(sock, &rfds); | ||
343 | fd_set wfds; | ||
344 | FD_ZERO(&wfds); | ||
345 | FD_SET(sock, &wfds); | ||
346 | int maxfd = sock; | ||
347 | |||
348 | uint8_t frame[ETH_FRAME_LEN]; // includes eht header, vlan, and crc | ||
349 | memset(frame, 0, ETH_FRAME_LEN); | ||
350 | |||
351 | int nready; | ||
352 | if (dest < last) | ||
353 | nready = select(maxfd + 1, &rfds, &wfds, (fd_set *) 0, NULL); | ||
354 | else | ||
355 | nready = select(maxfd + 1, &rfds, (fd_set *) 0, (fd_set *) 0, &ts); | ||
356 | |||
357 | if (nready < 0) | ||
358 | errExit("select"); | ||
359 | |||
360 | if (nready == 0) { // timeout | ||
361 | break; | ||
362 | } | ||
363 | |||
364 | if (FD_ISSET(sock, &wfds) && dest < last) { | ||
365 | // configure layer2 socket address information | ||
366 | struct sockaddr_ll addr; | ||
367 | memset(&addr, 0, sizeof(addr)); | ||
368 | if ((addr.sll_ifindex = if_nametoindex(dev)) == 0) | ||
369 | errExit("if_nametoindex"); | ||
370 | addr.sll_family = AF_PACKET; | ||
371 | memcpy (addr.sll_addr, mac, 6); | ||
372 | addr.sll_halen = htons(6); | ||
373 | |||
374 | // build the arp packet header | ||
375 | ArpHdr hdr; | ||
376 | memset(&hdr, 0, sizeof(hdr)); | ||
377 | hdr.htype = htons(1); | ||
378 | hdr.ptype = htons(ETH_P_IP); | ||
379 | hdr.hlen = 6; | ||
380 | hdr.plen = 4; | ||
381 | hdr.opcode = htons(1); //ARPOP_REQUEST | ||
382 | memcpy(hdr.sender_mac, mac, 6); | ||
383 | memcpy(hdr.sender_ip, (uint8_t *)&src, 4); | ||
384 | uint32_t dst = htonl(dest); | ||
385 | memcpy(hdr.target_ip, (uint8_t *)&dst, 4); | ||
386 | |||
387 | // buiild ethernet frame | ||
388 | uint8_t frame[ETH_FRAME_LEN]; // includes eht header, vlan, and crc | ||
389 | memset(frame, 0, sizeof(frame)); | ||
390 | frame[0] = frame[1] = frame[2] = frame[3] = frame[4] = frame[5] = 0xff; | ||
391 | memcpy(frame + 6, mac, 6); | ||
392 | frame[12] = ETH_P_ARP / 256; | ||
393 | frame[13] = ETH_P_ARP % 256; | ||
394 | memcpy (frame + 14, &hdr, sizeof(hdr)); | ||
395 | |||
396 | // send packet | ||
397 | int len; | ||
398 | if ((len = sendto (sock, frame, 14 + sizeof(ArpHdr), 0, (struct sockaddr *) &addr, sizeof (addr))) <= 0) | ||
399 | errExit("send"); | ||
400 | //printf("send %d bytes to %d.%d.%d.%d\n", len, PRINT_IP(dest)); | ||
401 | fflush(0); | ||
402 | dest++; | ||
403 | } | ||
404 | |||
405 | if (FD_ISSET(sock, &rfds)) { | ||
406 | // read the incoming packet | ||
407 | int len = recvfrom(sock, frame, ETH_FRAME_LEN, 0, NULL, NULL); | ||
408 | if (len < 0) { | ||
409 | perror("recvfrom"); | ||
410 | } | ||
411 | |||
412 | // parse the incomming packet | ||
413 | if (len < 14 + sizeof(ArpHdr)) | ||
414 | continue; | ||
415 | |||
416 | // look only at ARP packets | ||
417 | if (frame[12] != (ETH_P_ARP / 256) || frame[13] != (ETH_P_ARP % 256)) | ||
418 | continue; | ||
419 | |||
420 | ArpHdr hdr; | ||
421 | memcpy(&hdr, frame + 14, sizeof(ArpHdr)); | ||
422 | |||
423 | if (hdr.opcode == htons(2)) { | ||
424 | // check my mac and my address | ||
425 | if (memcmp(mac, hdr.target_mac, 6) != 0) | ||
426 | continue; | ||
427 | uint32_t ip; | ||
428 | memcpy(&ip, hdr.target_ip, 4); | ||
429 | if (ip != src) | ||
430 | continue; | ||
431 | memcpy(&ip, hdr.sender_ip, 4); | ||
432 | ip = ntohl(ip); | ||
433 | |||
434 | if (ip == last_ip) // filter duplicates | ||
435 | continue; | ||
436 | last_ip = ip; | ||
437 | |||
438 | // printing | ||
439 | if (header_printed == 0) { | ||
440 | printf(" Network scan:\n"); | ||
441 | |||
442 | // print parent interface | ||
443 | if (cfg.bridge0.configured && cfg.bridge0.ip && cfg.bridge0.macvlan && | ||
444 | (cfg.bridge0.ip & cfg.bridge0.mask) == (ifip & cfg.bridge0.mask)) | ||
445 | printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n", | ||
446 | PRINT_MAC(cfg.bridge0.mac), PRINT_IP(cfg.bridge0.ip)); | ||
447 | |||
448 | if (cfg.bridge1.configured && cfg.bridge1.ip && cfg.bridge1.macvlan && | ||
449 | (cfg.bridge1.ip & cfg.bridge1.mask) == (ifip & cfg.bridge1.mask)) | ||
450 | printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n", | ||
451 | PRINT_MAC(cfg.bridge1.mac), PRINT_IP(cfg.bridge1.ip)); | ||
452 | |||
453 | if (cfg.bridge2.configured && cfg.bridge2.ip && cfg.bridge2.macvlan && | ||
454 | (cfg.bridge2.ip & cfg.bridge2.mask) == (ifip & cfg.bridge2.mask)) | ||
455 | printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n", | ||
456 | PRINT_MAC(cfg.bridge2.mac), PRINT_IP(cfg.bridge2.ip)); | ||
457 | |||
458 | if (cfg.bridge3.configured && cfg.bridge3.ip && cfg.bridge3.macvlan && | ||
459 | (cfg.bridge3.ip & cfg.bridge3.mask) == (ifip & cfg.bridge3.mask)) | ||
460 | printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n", | ||
461 | PRINT_MAC(cfg.bridge3.mac), PRINT_IP(cfg.bridge3.ip)); | ||
462 | |||
463 | header_printed = 1; | ||
464 | } | ||
465 | printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n", | ||
466 | PRINT_MAC(hdr.sender_mac), PRINT_IP(ip)); | ||
467 | } | ||
468 | } | ||
469 | } | ||
470 | |||
471 | close(sock); | ||
472 | } | ||
473 | |||
474 | |||
diff --git a/src/firejail/bandwidth.c b/src/firejail/bandwidth.c new file mode 100644 index 000000000..25dd7a0fb --- /dev/null +++ b/src/firejail/bandwidth.c | |||
@@ -0,0 +1,483 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #define _GNU_SOURCE | ||
21 | #include <stdio.h> | ||
22 | #include <sys/types.h> | ||
23 | #include <sys/stat.h> | ||
24 | #include <unistd.h> | ||
25 | #include <net/if.h> | ||
26 | #include "firejail.h" | ||
27 | |||
28 | //*********************************** | ||
29 | // interface bandwidth linked list | ||
30 | //*********************************** | ||
31 | typedef struct ifbw_t { | ||
32 | struct ifbw_t *next; | ||
33 | char *txt; | ||
34 | } IFBW; | ||
35 | IFBW *ifbw = NULL; | ||
36 | |||
37 | |||
38 | #if 0 | ||
39 | static void ifbw_print(void) { | ||
40 | IFBW *ptr = ifbw; | ||
41 | while (ptr) { | ||
42 | printf("#%s#\n", ptr->txt); | ||
43 | ptr = ptr->next; | ||
44 | } | ||
45 | } | ||
46 | #endif | ||
47 | |||
48 | static void ifbw_add(IFBW *ptr) { | ||
49 | assert(ptr); | ||
50 | |||
51 | if (ifbw != NULL) | ||
52 | ptr->next = ifbw; | ||
53 | ifbw = ptr; | ||
54 | } | ||
55 | |||
56 | |||
57 | IFBW *ifbw_find(const char *dev) { | ||
58 | assert(dev); | ||
59 | int len = strlen(dev); | ||
60 | assert(len); | ||
61 | |||
62 | if (ifbw == NULL) | ||
63 | return NULL; | ||
64 | |||
65 | IFBW *ptr = ifbw; | ||
66 | while (ptr) { | ||
67 | if (strncmp(ptr->txt, dev, len) == 0 && ptr->txt[len] == ':') | ||
68 | return ptr; | ||
69 | ptr = ptr->next; | ||
70 | } | ||
71 | |||
72 | return NULL; | ||
73 | } | ||
74 | |||
75 | void ifbw_remove(IFBW *r) { | ||
76 | if (ifbw == NULL) | ||
77 | return; | ||
78 | |||
79 | // remove the first element | ||
80 | if (ifbw == r) { | ||
81 | ifbw = ifbw->next; | ||
82 | return; | ||
83 | } | ||
84 | |||
85 | // walk the list | ||
86 | IFBW *ptr = ifbw->next; | ||
87 | IFBW *prev = ifbw; | ||
88 | while (ptr) { | ||
89 | if (ptr == r) { | ||
90 | prev->next = ptr->next; | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | prev = ptr; | ||
95 | ptr = ptr->next; | ||
96 | } | ||
97 | |||
98 | return; | ||
99 | } | ||
100 | |||
101 | int fibw_count(viod) { | ||
102 | int rv = 0; | ||
103 | IFBW *ptr = ifbw; | ||
104 | |||
105 | while (ptr) { | ||
106 | rv++; | ||
107 | ptr = ptr->next; | ||
108 | } | ||
109 | |||
110 | return rv; | ||
111 | } | ||
112 | |||
113 | |||
114 | //*********************************** | ||
115 | // shm file handling | ||
116 | //*********************************** | ||
117 | void shm_create_firejail_dir(void) { | ||
118 | struct stat s; | ||
119 | if (stat("/dev/shm/firejail", &s) == -1) { | ||
120 | /* coverity[toctou] */ | ||
121 | if (mkdir("/dev/shm/firejail", 0777) == -1) | ||
122 | errExit("mkdir"); | ||
123 | if (chown("/dev/shm/firejail", 0, 0) == -1) | ||
124 | errExit("chown"); | ||
125 | } | ||
126 | else { // check /dev/shm/firejail directory belongs to root end exit if doesn't! | ||
127 | if (s.st_uid != 0 || s.st_gid != 0) { | ||
128 | fprintf(stderr, "Error: non-root %s directory, exiting...\n", "/dev/shm/firejail"); | ||
129 | exit(1); | ||
130 | } | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static void shm_create_bandwidth_file(pid_t pid) { | ||
135 | char *fname; | ||
136 | if (asprintf(&fname, "/dev/shm/firejail/%d-bandwidth", (int) pid) == -1) | ||
137 | errExit("asprintf"); | ||
138 | |||
139 | // if the file already exists, do nothing | ||
140 | struct stat s; | ||
141 | if (stat(fname, &s) == 0) { | ||
142 | free(fname); | ||
143 | return; | ||
144 | } | ||
145 | |||
146 | // create an empty file and set mod and ownership | ||
147 | /* coverity[toctou] */ | ||
148 | FILE *fp = fopen(fname, "w"); | ||
149 | if (fp) { | ||
150 | fclose(fp); | ||
151 | |||
152 | /* coverity[toctou] */ | ||
153 | if (chmod(fname, 0644) == -1) | ||
154 | errExit("chmod"); | ||
155 | /* coverity[toctou] */ | ||
156 | if (chown(fname, 0, 0) == -1) | ||
157 | errExit("chown"); | ||
158 | } | ||
159 | else { | ||
160 | fprintf(stderr, "Error: cannot create bandwidth file in /dev/shm/firejail directory\n"); | ||
161 | exit(1); | ||
162 | } | ||
163 | |||
164 | free(fname); | ||
165 | } | ||
166 | |||
167 | // delete shm bandwidth file | ||
168 | void bandwidth_shm_del_file(pid_t pid) { | ||
169 | char *fname; | ||
170 | if (asprintf(&fname, "/dev/shm/firejail/%d-bandwidth", (int) pid) == -1) | ||
171 | errExit("asprintf"); | ||
172 | unlink(fname); | ||
173 | free(fname); | ||
174 | } | ||
175 | |||
176 | void network_shm_del_file(pid_t pid) { | ||
177 | char *fname; | ||
178 | if (asprintf(&fname, "/dev/shm/firejail/%d-netmap", (int) pid) == -1) | ||
179 | errExit("asprintf"); | ||
180 | unlink(fname); | ||
181 | free(fname); | ||
182 | } | ||
183 | |||
184 | void network_shm_set_file(pid_t pid) { | ||
185 | char *fname; | ||
186 | if (asprintf(&fname, "/dev/shm/firejail/%d-netmap", (int) pid) == -1) | ||
187 | errExit("asprintf"); | ||
188 | |||
189 | // create an empty file and set mod and ownership | ||
190 | FILE *fp = fopen(fname, "w"); | ||
191 | if (fp) { | ||
192 | if (cfg.bridge0.configured) | ||
193 | fprintf(fp, "%s:%s\n", cfg.bridge0.dev, cfg.bridge0.devsandbox); | ||
194 | if (cfg.bridge1.configured) | ||
195 | fprintf(fp, "%s:%s\n", cfg.bridge1.dev, cfg.bridge1.devsandbox); | ||
196 | if (cfg.bridge2.configured) | ||
197 | fprintf(fp, "%s:%s\n", cfg.bridge2.dev, cfg.bridge2.devsandbox); | ||
198 | if (cfg.bridge3.configured) | ||
199 | fprintf(fp, "%s:%s\n", cfg.bridge3.dev, cfg.bridge3.devsandbox); | ||
200 | fclose(fp); | ||
201 | |||
202 | if (chmod(fname, 0644) == -1) | ||
203 | errExit("chmod"); | ||
204 | if (chown(fname, 0, 0) == -1) | ||
205 | errExit("chown"); | ||
206 | } | ||
207 | else { | ||
208 | fprintf(stderr, "Error: cannot create network map file in /dev/shm/firejail directory\n"); | ||
209 | exit(1); | ||
210 | } | ||
211 | |||
212 | free(fname); | ||
213 | } | ||
214 | |||
215 | |||
216 | void shm_read_bandwidth_file(pid_t pid) { | ||
217 | assert(ifbw == NULL); | ||
218 | |||
219 | char *fname; | ||
220 | if (asprintf(&fname, "/dev/shm/firejail/%d-bandwidth", (int) pid) == -1) | ||
221 | errExit("asprintf"); | ||
222 | |||
223 | FILE *fp = fopen(fname, "r"); | ||
224 | if (fp) { | ||
225 | char buf[1024]; | ||
226 | while (fgets(buf, 1024,fp)) { | ||
227 | // remove '\n' | ||
228 | char *ptr = strchr(buf, '\n'); | ||
229 | if (ptr) | ||
230 | *ptr = '\0'; | ||
231 | if (strlen(buf) == 0) | ||
232 | continue; | ||
233 | |||
234 | // create a new IFBW entry | ||
235 | IFBW *ifbw_new = malloc(sizeof(IFBW)); | ||
236 | if (!ifbw_new) | ||
237 | errExit("malloc"); | ||
238 | memset(ifbw_new, 0, sizeof(IFBW)); | ||
239 | ifbw_new->txt = strdup(buf); | ||
240 | if (!ifbw_new->txt) | ||
241 | errExit("strdup"); | ||
242 | |||
243 | // add it to the linked list | ||
244 | ifbw_add(ifbw_new); | ||
245 | } | ||
246 | |||
247 | fclose(fp); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | void shm_write_bandwidth_file(pid_t pid) { | ||
252 | if (ifbw == NULL) | ||
253 | return; // nothing to do | ||
254 | |||
255 | char *fname; | ||
256 | if (asprintf(&fname, "/dev/shm/firejail/%d-bandwidth", (int) pid) == -1) | ||
257 | errExit("asprintf"); | ||
258 | |||
259 | FILE *fp = fopen(fname, "w"); | ||
260 | if (fp) { | ||
261 | IFBW *ptr = ifbw; | ||
262 | while (ptr) { | ||
263 | fprintf(fp, "%s\n", ptr->txt); | ||
264 | ptr = ptr->next; | ||
265 | } | ||
266 | fclose(fp); | ||
267 | } | ||
268 | else { | ||
269 | fprintf(stderr, "Error: cannot write bandwidht file %s\n", fname); | ||
270 | exit(1); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | //*********************************** | ||
275 | // add or remove interfaces | ||
276 | //*********************************** | ||
277 | |||
278 | // remove interface from shm file | ||
279 | void bandwidth_shm_remove(pid_t pid, const char *dev) { | ||
280 | // create bandwidth directory & file in case they are not in the filesystem yet | ||
281 | shm_create_firejail_dir(); | ||
282 | shm_create_bandwidth_file(pid); | ||
283 | |||
284 | // read bandwidth file | ||
285 | shm_read_bandwidth_file(pid); | ||
286 | |||
287 | // find the element and remove it | ||
288 | IFBW *elem = ifbw_find(dev); | ||
289 | if (elem) { | ||
290 | ifbw_remove(elem); | ||
291 | shm_write_bandwidth_file(pid) ; | ||
292 | } | ||
293 | |||
294 | // remove the file if there are no entries in the list | ||
295 | if (ifbw == NULL) { | ||
296 | bandwidth_shm_del_file(pid); | ||
297 | } | ||
298 | } | ||
299 | |||
300 | // add interface to shm file | ||
301 | void bandwidth_shm_set(pid_t pid, const char *dev, int down, int up) { | ||
302 | // create bandwidth directory & file in case they are not in the filesystem yet | ||
303 | shm_create_firejail_dir(); | ||
304 | shm_create_bandwidth_file(pid); | ||
305 | |||
306 | // create the new text entry | ||
307 | char *txt; | ||
308 | if (asprintf(&txt, "%s: RX %dKB/s, TX %dKB/s", dev, down, up) == -1) | ||
309 | errExit("asprintf"); | ||
310 | |||
311 | // read bandwidth file | ||
312 | shm_read_bandwidth_file(pid); | ||
313 | |||
314 | // look for an existing entry and replace the text | ||
315 | IFBW *ptr = ifbw_find(dev); | ||
316 | if (ptr) { | ||
317 | assert(ptr->txt); | ||
318 | free(ptr->txt); | ||
319 | ptr->txt = txt; | ||
320 | } | ||
321 | // ... or add a new entry | ||
322 | else { | ||
323 | IFBW *ifbw_new = malloc(sizeof(IFBW)); | ||
324 | if (!ifbw_new) | ||
325 | errExit("malloc"); | ||
326 | memset(ifbw_new, 0, sizeof(IFBW)); | ||
327 | ifbw_new->txt = txt; | ||
328 | |||
329 | // add it to the linked list | ||
330 | ifbw_add(ifbw_new); | ||
331 | } | ||
332 | shm_write_bandwidth_file(pid) ; | ||
333 | } | ||
334 | |||
335 | |||
336 | //*********************************** | ||
337 | // command execution | ||
338 | //*********************************** | ||
339 | void bandwidth_name(const char *name, const char *command, const char *dev, int down, int up) { | ||
340 | if (!name || strlen(name) == 0) { | ||
341 | fprintf(stderr, "Error: invalid sandbox name\n"); | ||
342 | exit(1); | ||
343 | } | ||
344 | pid_t pid; | ||
345 | if (name2pid(name, &pid)) { | ||
346 | fprintf(stderr, "Error: cannot find sandbox %s\n", name); | ||
347 | exit(1); | ||
348 | } | ||
349 | |||
350 | bandwidth_pid(pid, command, dev, down, up); | ||
351 | } | ||
352 | |||
353 | void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up) { | ||
354 | //************************ | ||
355 | // verify sandbox | ||
356 | //************************ | ||
357 | char *comm = pid_proc_comm(pid); | ||
358 | if (!comm) { | ||
359 | fprintf(stderr, "Error: cannot find sandbox\n"); | ||
360 | exit(1); | ||
361 | } | ||
362 | |||
363 | // remove \n and check for firejail sandbox | ||
364 | char *ptr = strchr(comm, '\n'); | ||
365 | if (ptr) | ||
366 | *ptr = '\0'; | ||
367 | if (strcmp(comm, "firejail") != 0) { | ||
368 | fprintf(stderr, "Error: cannot find sandbox\n"); | ||
369 | exit(1); | ||
370 | } | ||
371 | free(comm); | ||
372 | |||
373 | // check network namespace | ||
374 | char *cmd = pid_proc_cmdline(pid); | ||
375 | if (!cmd || strstr(cmd, "--net") == NULL) { | ||
376 | fprintf(stderr, "Error: the sandbox doesn't use a new network namespace\n"); | ||
377 | exit(1); | ||
378 | } | ||
379 | free(cmd); | ||
380 | |||
381 | |||
382 | //************************ | ||
383 | // join the network namespace | ||
384 | //************************ | ||
385 | pid_t child; | ||
386 | if (find_child(pid, &child) == -1) { | ||
387 | fprintf(stderr, "Error: cannot join the network namespace\n"); | ||
388 | exit(1); | ||
389 | } | ||
390 | if (join_namespace(child, "net")) { | ||
391 | fprintf(stderr, "Error: cannot join the network namespace\n"); | ||
392 | exit(1); | ||
393 | } | ||
394 | |||
395 | // set shm file | ||
396 | if (strcmp(command, "set") == 0) | ||
397 | bandwidth_shm_set(pid, dev, down, up); | ||
398 | else if (strcmp(command, "clear") == 0) | ||
399 | bandwidth_shm_remove(pid, dev); | ||
400 | |||
401 | //************************ | ||
402 | // build command | ||
403 | //************************ | ||
404 | char *devname = NULL; | ||
405 | if (dev) { | ||
406 | // read shm network map file | ||
407 | char *fname; | ||
408 | if (asprintf(&fname, "/dev/shm/firejail/%d-netmap", (int) pid) == -1) | ||
409 | errExit("asprintf"); | ||
410 | FILE *fp = fopen(fname, "r"); | ||
411 | if (!fp) { | ||
412 | fprintf(stderr, "Error: cannot read netowk map filel %s\n", fname); | ||
413 | exit(1); | ||
414 | } | ||
415 | |||
416 | char buf[1024]; | ||
417 | int len = strlen(dev); | ||
418 | while (fgets(buf, 1024, fp)) { | ||
419 | // remove '\n' | ||
420 | char *ptr = strchr(buf, '\n'); | ||
421 | if (ptr) | ||
422 | *ptr = '\0'; | ||
423 | if (*buf == '\0') | ||
424 | break; | ||
425 | |||
426 | if (strncmp(buf, dev, len) == 0 && buf[len] == ':') { | ||
427 | devname = strdup(buf + len + 1); | ||
428 | if (!devname) | ||
429 | errExit("strdup"); | ||
430 | // check device in namespace | ||
431 | if (if_nametoindex(devname) == 0) { | ||
432 | fprintf(stderr, "Error: cannot find network device %s\n", devname); | ||
433 | exit(1); | ||
434 | } | ||
435 | break; | ||
436 | } | ||
437 | } | ||
438 | free(fname); | ||
439 | fclose(fp); | ||
440 | } | ||
441 | |||
442 | // build fshaper.sh command | ||
443 | cmd = NULL; | ||
444 | if (devname) { | ||
445 | if (strcmp(command, "set") == 0) { | ||
446 | if (asprintf(&cmd, "%s/lib/firejail/fshaper.sh --%s %s %d %d", | ||
447 | PREFIX, command, devname, down, up) == -1) | ||
448 | errExit("asprintf"); | ||
449 | } | ||
450 | else { | ||
451 | if (asprintf(&cmd, "%s/lib/firejail/fshaper.sh --%s %s", | ||
452 | PREFIX, command, devname) == -1) | ||
453 | errExit("asprintf"); | ||
454 | } | ||
455 | } | ||
456 | else { | ||
457 | if (asprintf(&cmd, "%s/lib/firejail/fshaper.sh --%s", PREFIX, command) == -1) | ||
458 | errExit("asprintf"); | ||
459 | } | ||
460 | assert(cmd); | ||
461 | |||
462 | // wipe out environment variables | ||
463 | environ = NULL; | ||
464 | |||
465 | //************************ | ||
466 | // build command | ||
467 | //************************ | ||
468 | // elevate privileges | ||
469 | if (setreuid(0, 0)) | ||
470 | errExit("setreuid"); | ||
471 | if (setregid(0, 0)) | ||
472 | errExit("setregid"); | ||
473 | |||
474 | char *arg[4]; | ||
475 | arg[0] = "/bin/bash"; | ||
476 | arg[1] = "-c"; | ||
477 | arg[2] = cmd; | ||
478 | arg[3] = NULL; | ||
479 | execvp("/bin/bash", arg); | ||
480 | |||
481 | // it will never get here | ||
482 | exit(0); | ||
483 | } | ||
diff --git a/src/firejail/caps.c b/src/firejail/caps.c new file mode 100644 index 000000000..d8777c0db --- /dev/null +++ b/src/firejail/caps.c | |||
@@ -0,0 +1,453 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include "firejail.h" | ||
22 | #include <errno.h> | ||
23 | #include <linux/filter.h> | ||
24 | #include <stddef.h> | ||
25 | #include <linux/capability.h> | ||
26 | #include <linux/audit.h> | ||
27 | #include <sys/prctl.h> | ||
28 | #include <sys/types.h> | ||
29 | #include <sys/stat.h> | ||
30 | #include <unistd.h> | ||
31 | |||
32 | extern int capget(cap_user_header_t hdrp, cap_user_data_t datap); | ||
33 | extern int capset(cap_user_header_t hdrp, const cap_user_data_t datap); | ||
34 | |||
35 | |||
36 | typedef struct { | ||
37 | char *name; | ||
38 | int nr; | ||
39 | } CapsEntry; | ||
40 | |||
41 | static CapsEntry capslist[] = { | ||
42 | // | ||
43 | // code generated using tools/extract-caps | ||
44 | // updated manually based on kernel 3.18/include/linux/capability.h (added block suspend and audit_read | ||
45 | // | ||
46 | #ifdef CAP_CHOWN | ||
47 | {"chown", CAP_CHOWN }, | ||
48 | #endif | ||
49 | #ifdef CAP_DAC_OVERRIDE | ||
50 | {"dac_override", CAP_DAC_OVERRIDE }, | ||
51 | #endif | ||
52 | #ifdef CAP_DAC_READ_SEARCH | ||
53 | {"dac_read_search", CAP_DAC_READ_SEARCH }, | ||
54 | #endif | ||
55 | #ifdef CAP_FOWNER | ||
56 | {"fowner", CAP_FOWNER }, | ||
57 | #endif | ||
58 | #ifdef CAP_FSETID | ||
59 | {"fsetid", CAP_FSETID }, | ||
60 | #endif | ||
61 | #ifdef CAP_KILL | ||
62 | {"kill", CAP_KILL }, | ||
63 | #endif | ||
64 | #ifdef CAP_SETGID | ||
65 | {"setgid", CAP_SETGID }, | ||
66 | #endif | ||
67 | #ifdef CAP_SETUID | ||
68 | {"setuid", CAP_SETUID }, | ||
69 | #endif | ||
70 | #ifdef CAP_SETPCAP | ||
71 | {"setpcap", CAP_SETPCAP }, | ||
72 | #endif | ||
73 | #ifdef CAP_LINUX_IMMUTABLE | ||
74 | {"linux_immutable", CAP_LINUX_IMMUTABLE }, | ||
75 | #endif | ||
76 | #ifdef CAP_NET_BIND_SERVICE | ||
77 | {"net_bind_service", CAP_NET_BIND_SERVICE }, | ||
78 | #endif | ||
79 | #ifdef CAP_NET_BROADCAST | ||
80 | {"net_broadcast", CAP_NET_BROADCAST }, | ||
81 | #endif | ||
82 | #ifdef CAP_NET_ADMIN | ||
83 | {"net_admin", CAP_NET_ADMIN }, | ||
84 | #endif | ||
85 | #ifdef CAP_NET_RAW | ||
86 | {"net_raw", CAP_NET_RAW }, | ||
87 | #endif | ||
88 | #ifdef CAP_IPC_LOCK | ||
89 | {"ipc_lock", CAP_IPC_LOCK }, | ||
90 | #endif | ||
91 | #ifdef CAP_IPC_OWNER | ||
92 | {"ipc_owner", CAP_IPC_OWNER }, | ||
93 | #endif | ||
94 | #ifdef CAP_SYS_MODULE | ||
95 | {"sys_module", CAP_SYS_MODULE }, | ||
96 | #endif | ||
97 | #ifdef CAP_SYS_RAWIO | ||
98 | {"sys_rawio", CAP_SYS_RAWIO }, | ||
99 | #endif | ||
100 | #ifdef CAP_SYS_CHROOT | ||
101 | {"sys_chroot", CAP_SYS_CHROOT }, | ||
102 | #endif | ||
103 | #ifdef CAP_SYS_PTRACE | ||
104 | {"sys_ptrace", CAP_SYS_PTRACE }, | ||
105 | #endif | ||
106 | #ifdef CAP_SYS_PACCT | ||
107 | {"sys_pacct", CAP_SYS_PACCT }, | ||
108 | #endif | ||
109 | #ifdef CAP_SYS_ADMIN | ||
110 | {"sys_admin", CAP_SYS_ADMIN }, | ||
111 | #endif | ||
112 | #ifdef CAP_SYS_BOOT | ||
113 | {"sys_boot", CAP_SYS_BOOT }, | ||
114 | #endif | ||
115 | #ifdef CAP_SYS_NICE | ||
116 | {"sys_nice", CAP_SYS_NICE }, | ||
117 | #endif | ||
118 | #ifdef CAP_SYS_RESOURCE | ||
119 | {"sys_resource", CAP_SYS_RESOURCE }, | ||
120 | #endif | ||
121 | #ifdef CAP_SYS_TIME | ||
122 | {"sys_time", CAP_SYS_TIME }, | ||
123 | #endif | ||
124 | #ifdef CAP_SYS_TTY_CONFIG | ||
125 | {"sys_tty_config", CAP_SYS_TTY_CONFIG }, | ||
126 | #endif | ||
127 | #ifdef CAP_MKNOD | ||
128 | {"mknod", CAP_MKNOD }, | ||
129 | #endif | ||
130 | #ifdef CAP_LEASE | ||
131 | {"lease", CAP_LEASE }, | ||
132 | #endif | ||
133 | #ifdef CAP_AUDIT_WRITE | ||
134 | {"audit_write", CAP_AUDIT_WRITE }, | ||
135 | #endif | ||
136 | #ifdef CAP_AUDIT_CONTROL | ||
137 | {"audit_control", CAP_AUDIT_CONTROL }, | ||
138 | #endif | ||
139 | #ifdef CAP_SETFCAP | ||
140 | {"setfcap", CAP_SETFCAP }, | ||
141 | #endif | ||
142 | #ifdef CAP_MAC_OVERRIDE | ||
143 | {"mac_override", CAP_MAC_OVERRIDE }, | ||
144 | #endif | ||
145 | #ifdef CAP_MAC_ADMIN | ||
146 | {"mac_admin", CAP_MAC_ADMIN }, | ||
147 | #endif | ||
148 | #ifdef CAP_SYSLOG | ||
149 | {"syslog", CAP_SYSLOG }, | ||
150 | #endif | ||
151 | #ifdef CAP_WAKE_ALARM | ||
152 | {"wake_alarm", CAP_WAKE_ALARM }, | ||
153 | #endif | ||
154 | // not in Debian 7 | ||
155 | #ifdef CAP_BLOCK_SUSPEND | ||
156 | {"block_suspend", CAP_BLOCK_SUSPEND }, | ||
157 | #else | ||
158 | {"block_suspend", 36 }, | ||
159 | #endif | ||
160 | #ifdef CAP_AUDIT_READ | ||
161 | {"audit_read", CAP_AUDIT_READ }, | ||
162 | #else | ||
163 | {"audit_read", 37 }, | ||
164 | #endif | ||
165 | |||
166 | // | ||
167 | // end of generated code | ||
168 | // | ||
169 | }; // end of capslist | ||
170 | |||
171 | const char *caps_find_nr(int nr) { | ||
172 | int i; | ||
173 | int elems = sizeof(capslist) / sizeof(capslist[0]); | ||
174 | for (i = 0; i < elems; i++) { | ||
175 | if (nr == capslist[i].nr) | ||
176 | return capslist[i].name; | ||
177 | } | ||
178 | |||
179 | return "unknown"; | ||
180 | } | ||
181 | |||
182 | // return -1 if error, or syscall number | ||
183 | static int caps_find_name(const char *name) { | ||
184 | int i; | ||
185 | int elems = sizeof(capslist) / sizeof(capslist[0]); | ||
186 | for (i = 0; i < elems; i++) { | ||
187 | if (strcmp(name, capslist[i].name) == 0) | ||
188 | return capslist[i].nr; | ||
189 | } | ||
190 | |||
191 | return -1; | ||
192 | } | ||
193 | |||
194 | // return 1 if error, 0 if OK | ||
195 | int caps_check_list(const char *clist, void (*callback)(int)) { | ||
196 | // don't allow empty lists | ||
197 | if (clist == NULL || *clist == '\0') { | ||
198 | fprintf(stderr, "Error: empty capabilities lists are not allowed\n"); | ||
199 | return -1; | ||
200 | } | ||
201 | |||
202 | // work on a copy of the string | ||
203 | char *str = strdup(clist); | ||
204 | if (!str) | ||
205 | errExit("strdup"); | ||
206 | |||
207 | char *ptr = str; | ||
208 | char *start = str; | ||
209 | while (*ptr != '\0') { | ||
210 | if (islower(*ptr) || isdigit(*ptr) || *ptr == '_') | ||
211 | ; | ||
212 | else if (*ptr == ',') { | ||
213 | *ptr = '\0'; | ||
214 | int nr = caps_find_name(start); | ||
215 | if (nr == -1) { | ||
216 | fprintf(stderr, "Error: capability %s not found\n", start); | ||
217 | free(str); | ||
218 | return -1; | ||
219 | } | ||
220 | else if (callback != NULL) | ||
221 | callback(nr); | ||
222 | |||
223 | start = ptr + 1; | ||
224 | } | ||
225 | ptr++; | ||
226 | } | ||
227 | if (*start != '\0') { | ||
228 | int nr = caps_find_name(start); | ||
229 | if (nr == -1) { | ||
230 | fprintf(stderr, "Error: capability %s not found\n", start); | ||
231 | free(str); | ||
232 | return -1; | ||
233 | } | ||
234 | else if (callback != NULL) | ||
235 | callback(nr); | ||
236 | } | ||
237 | |||
238 | free(str); | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | void caps_print(void) { | ||
243 | int i; | ||
244 | int elems = sizeof(capslist) / sizeof(capslist[0]); | ||
245 | |||
246 | // check current caps supported by the kernel | ||
247 | int cnt = 0; | ||
248 | unsigned long cap; | ||
249 | for (cap=0; cap <= 63; cap++) { | ||
250 | int code = prctl(PR_CAPBSET_DROP, cap, 0, 0, 0); | ||
251 | if (code == 0) | ||
252 | cnt++; | ||
253 | } | ||
254 | printf("Your kernel supports %d capabilities.\n", cnt); | ||
255 | |||
256 | for (i = 0; i < elems; i++) { | ||
257 | printf("%d\t- %s\n", capslist[i].nr, capslist[i].name); | ||
258 | } | ||
259 | } | ||
260 | |||
261 | |||
262 | |||
263 | |||
264 | // enabled by default | ||
265 | int caps_default_filter(void) { | ||
266 | // drop capabilities | ||
267 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_MODULE, 0, 0, 0) && arg_debug) | ||
268 | fprintf(stderr, "Warning: cannot drop CAP_SYS_MODULE"); | ||
269 | else if (arg_debug) | ||
270 | printf("Drop CAP_SYS_MODULE\n"); | ||
271 | |||
272 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_RAWIO, 0, 0, 0) && arg_debug) | ||
273 | fprintf(stderr, "Warning: cannot drop CAP_SYS_RAWIO"); | ||
274 | else if (arg_debug) | ||
275 | printf("Drop CAP_SYS_RAWIO\n"); | ||
276 | |||
277 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0) && arg_debug) | ||
278 | fprintf(stderr, "Warning: cannot drop CAP_SYS_BOOT"); | ||
279 | else if (arg_debug) | ||
280 | printf("Drop CAP_SYS_BOOT\n"); | ||
281 | |||
282 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_NICE, 0, 0, 0) && arg_debug) | ||
283 | fprintf(stderr, "Warning: cannot drop CAP_SYS_NICE"); | ||
284 | else if (arg_debug) | ||
285 | printf("Drop CAP_SYS_NICE\n"); | ||
286 | |||
287 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_TTY_CONFIG, 0, 0, 0) && arg_debug) | ||
288 | fprintf(stderr, "Warning: cannot drop CAP_SYS_TTY_CONFIG"); | ||
289 | else if (arg_debug) | ||
290 | printf("Drop CAP_SYS_TTY_CONFIG\n"); | ||
291 | |||
292 | if (prctl(PR_CAPBSET_DROP, CAP_SYSLOG, 0, 0, 0) && arg_debug) | ||
293 | fprintf(stderr, "Warning: cannot drop CAP_SYSLOG"); | ||
294 | else if (arg_debug) | ||
295 | printf("Drop CAP_SYSLOG\n"); | ||
296 | |||
297 | if (prctl(PR_CAPBSET_DROP, CAP_MKNOD, 0, 0, 0) && arg_debug) | ||
298 | fprintf(stderr, "Warning: cannot drop CAP_MKNOD"); | ||
299 | else if (arg_debug) | ||
300 | printf("Drop CAP_MKNOD\n"); | ||
301 | |||
302 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_ADMIN, 0, 0, 0) && arg_debug) | ||
303 | fprintf(stderr, "Warning: cannot drop CAP_SYS_ADMIN"); | ||
304 | else if (arg_debug) | ||
305 | printf("Drop CAP_SYS_ADMIN\n"); | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | void caps_drop_all(void) { | ||
311 | if (arg_debug) | ||
312 | printf("Droping all capabilities\n"); | ||
313 | |||
314 | unsigned long cap; | ||
315 | for (cap=0; cap <= 63; cap++) { | ||
316 | int code = prctl(PR_CAPBSET_DROP, cap, 0, 0, 0); | ||
317 | if (code == -1 && errno != EINVAL) | ||
318 | errExit("PR_CAPBSET_DROP"); | ||
319 | } | ||
320 | } | ||
321 | |||
322 | |||
323 | void caps_set(uint64_t caps) { | ||
324 | if (arg_debug) | ||
325 | printf("Set caps filter %llx\n", (unsigned long long) caps); | ||
326 | |||
327 | unsigned long i; | ||
328 | uint64_t mask = 1LLU; | ||
329 | for (i = 0; i < 64; i++, mask <<= 1) { | ||
330 | if ((mask & caps) == 0) { | ||
331 | int code = prctl(PR_CAPBSET_DROP, i, 0, 0, 0); | ||
332 | if (code == -1 && errno != EINVAL) | ||
333 | errExit("PR_CAPBSET_DROP"); | ||
334 | } | ||
335 | } | ||
336 | } | ||
337 | |||
338 | |||
339 | static uint64_t filter; | ||
340 | |||
341 | static void caps_set_bit(int nr) { | ||
342 | uint64_t mask = 1LLU << nr; | ||
343 | filter |= mask; | ||
344 | } | ||
345 | static void caps_reset_bit(int nr) { | ||
346 | uint64_t mask = 1LLU << nr; | ||
347 | filter &= ~mask; | ||
348 | } | ||
349 | |||
350 | void caps_drop_list(const char *clist) { | ||
351 | filter = 0; | ||
352 | filter--; | ||
353 | caps_check_list(clist, caps_reset_bit); | ||
354 | caps_set(filter); | ||
355 | } | ||
356 | |||
357 | void caps_keep_list(const char *clist) { | ||
358 | filter = 0; | ||
359 | caps_check_list(clist, caps_set_bit); | ||
360 | caps_set(filter); | ||
361 | } | ||
362 | |||
363 | #define MAXBUF 4098 | ||
364 | static uint64_t extract_caps(int pid) { | ||
365 | char *file; | ||
366 | if (asprintf(&file, "/proc/%d/status", pid) == -1) { | ||
367 | errExit("asprintf"); | ||
368 | exit(1); | ||
369 | } | ||
370 | |||
371 | FILE *fp = fopen(file, "r"); | ||
372 | if (!fp) { | ||
373 | printf("Error: cannot open %s\n", file); | ||
374 | free(file); | ||
375 | exit(1); | ||
376 | } | ||
377 | |||
378 | char buf[MAXBUF]; | ||
379 | while (fgets(buf, MAXBUF, fp)) { | ||
380 | if (strncmp(buf, "CapBnd:", 7) == 0) { | ||
381 | char *ptr = buf + 8; | ||
382 | unsigned long long val; | ||
383 | sscanf(ptr, "%llx", &val); | ||
384 | free(file); | ||
385 | fclose(fp); | ||
386 | return val; | ||
387 | } | ||
388 | } | ||
389 | fclose(fp); | ||
390 | free(file); | ||
391 | printf("Error: cannot read caps configuration\n"); | ||
392 | exit(1); | ||
393 | } | ||
394 | |||
395 | |||
396 | void caps_print_filter_name(const char *name) { | ||
397 | if (!name || strlen(name) == 0) { | ||
398 | fprintf(stderr, "Error: invalid sandbox name\n"); | ||
399 | exit(1); | ||
400 | } | ||
401 | pid_t pid; | ||
402 | if (name2pid(name, &pid)) { | ||
403 | fprintf(stderr, "Error: cannot find sandbox %s\n", name); | ||
404 | exit(1); | ||
405 | } | ||
406 | |||
407 | caps_print_filter(pid); | ||
408 | } | ||
409 | |||
410 | void caps_print_filter(pid_t pid) { | ||
411 | // if the pid is that of a firejail process, use the pid of the first child process | ||
412 | char *comm = pid_proc_comm(pid); | ||
413 | if (comm) { | ||
414 | // remove \n | ||
415 | char *ptr = strchr(comm, '\n'); | ||
416 | if (ptr) | ||
417 | *ptr = '\0'; | ||
418 | if (strcmp(comm, "firejail") == 0) { | ||
419 | pid_t child; | ||
420 | if (find_child(pid, &child) == 0) { | ||
421 | pid = child; | ||
422 | } | ||
423 | } | ||
424 | free(comm); | ||
425 | } | ||
426 | |||
427 | // check privileges for non-root users | ||
428 | uid_t uid = getuid(); | ||
429 | if (uid != 0) { | ||
430 | struct stat s; | ||
431 | char *dir; | ||
432 | if (asprintf(&dir, "/proc/%u/ns", pid) == -1) | ||
433 | errExit("asprintf"); | ||
434 | if (stat(dir, &s) < 0) | ||
435 | errExit("stat"); | ||
436 | if (s.st_uid != uid) { | ||
437 | printf("Error: permission denied.\n"); | ||
438 | exit(1); | ||
439 | } | ||
440 | } | ||
441 | |||
442 | uint64_t caps = extract_caps(pid); | ||
443 | drop_privs(1); | ||
444 | |||
445 | int i; | ||
446 | uint64_t mask; | ||
447 | int elems = sizeof(capslist) / sizeof(capslist[0]); | ||
448 | for (i = 0, mask = 1; i < elems; i++, mask <<= 1) { | ||
449 | printf("%-18.18s - %s\n", capslist[i].name, (mask & caps)? "enabled": "disabled"); | ||
450 | } | ||
451 | |||
452 | exit(0); | ||
453 | } | ||
diff --git a/src/firejail/cgroup.c b/src/firejail/cgroup.c new file mode 100644 index 000000000..7366a6699 --- /dev/null +++ b/src/firejail/cgroup.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/stat.h> | ||
22 | |||
23 | #define MAXBUF 4096 | ||
24 | |||
25 | void save_cgroup(void) { | ||
26 | if (cfg.cgroup == NULL) | ||
27 | return; | ||
28 | |||
29 | char *fname; | ||
30 | if (asprintf(&fname, "%s/cgroup", MNT_DIR) == -1) | ||
31 | errExit(fname); | ||
32 | |||
33 | FILE *fp = fopen(fname, "w"); | ||
34 | if (fp) { | ||
35 | fprintf(fp, "%s", cfg.cgroup); | ||
36 | fflush(0); | ||
37 | fclose(fp); | ||
38 | if (chown(fname, 0, 0) < 0) | ||
39 | errExit("chown"); | ||
40 | } | ||
41 | else { | ||
42 | fprintf(stderr, "Error: cannot save cgroup\n"); | ||
43 | free(fname); | ||
44 | exit(1); | ||
45 | } | ||
46 | |||
47 | free(fname); | ||
48 | } | ||
49 | |||
50 | void load_cgroup(const char *fname) { | ||
51 | if (!fname) | ||
52 | return; | ||
53 | |||
54 | FILE *fp = fopen(fname, "r"); | ||
55 | if (fp) { | ||
56 | char buf[MAXBUF]; | ||
57 | if (fgets(buf, MAXBUF, fp)) { | ||
58 | cfg.cgroup = strdup(buf); | ||
59 | if (!cfg.cgroup) | ||
60 | errExit("strdup"); | ||
61 | } | ||
62 | else | ||
63 | goto errout; | ||
64 | |||
65 | fclose(fp); | ||
66 | return; | ||
67 | } | ||
68 | errout: | ||
69 | fprintf(stderr, "Warrning: cannot load control group\n"); | ||
70 | if (fp) | ||
71 | fclose(fp); | ||
72 | } | ||
73 | |||
74 | |||
75 | void set_cgroup(const char *path) { | ||
76 | // path starts with /sys/fs/cgroup | ||
77 | if (strncmp(path, "/sys/fs/cgroup", 14) != 0) | ||
78 | goto errout; | ||
79 | |||
80 | // path ends in tasks | ||
81 | char *ptr = strstr(path, "tasks"); | ||
82 | if (!ptr) | ||
83 | goto errout; | ||
84 | if (*(ptr + 5) != '\0') | ||
85 | goto errout; | ||
86 | |||
87 | // no .. traversal | ||
88 | ptr = strstr(path, ".."); | ||
89 | if (ptr) | ||
90 | goto errout; | ||
91 | |||
92 | // tasks file exists | ||
93 | struct stat s; | ||
94 | if (stat(path, &s) == -1) | ||
95 | goto errout; | ||
96 | |||
97 | // task file belongs to the user running the sandbox | ||
98 | if (s.st_uid != getuid() && s.st_gid != getgid()) | ||
99 | goto errout2; | ||
100 | |||
101 | // add the task to cgroup | ||
102 | /* coverity[toctou] */ | ||
103 | FILE *fp = fopen(path, "a"); | ||
104 | if (!fp) | ||
105 | goto errout; | ||
106 | pid_t pid = getpid(); | ||
107 | int rv = fprintf(fp, "%d\n", pid); | ||
108 | (void) rv; | ||
109 | fclose(fp); | ||
110 | return; | ||
111 | |||
112 | errout: | ||
113 | fprintf(stderr, "Error: invalid cgroup\n"); | ||
114 | exit(1); | ||
115 | errout2: | ||
116 | fprintf(stderr, "Error: you don't have permissions to use this control group\n"); | ||
117 | exit(1); | ||
118 | } | ||
diff --git a/src/firejail/cpu.c b/src/firejail/cpu.c new file mode 100644 index 000000000..633081a3f --- /dev/null +++ b/src/firejail/cpu.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sched.h> | ||
22 | |||
23 | // converts a numeric cpu value in the corresponding bit mask | ||
24 | static void set_cpu(const char *str) { | ||
25 | if (strlen(str) == 0) | ||
26 | return; | ||
27 | |||
28 | int val = atoi(str); | ||
29 | if (val < 0 || val >= 32) { | ||
30 | fprintf(stderr, "Error: invalid cpu number. Accepted values are between 0 and 31.\n"); | ||
31 | exit(1); | ||
32 | } | ||
33 | |||
34 | uint32_t mask = 1; | ||
35 | int i; | ||
36 | for (i = 0; i < val; i++, mask <<= 1); | ||
37 | cfg.cpus |= mask; | ||
38 | } | ||
39 | |||
40 | void read_cpu_list(const char *str) { | ||
41 | char *tmp = strdup(str); | ||
42 | if (tmp == NULL) | ||
43 | errExit("strdup"); | ||
44 | |||
45 | char *ptr = tmp; | ||
46 | while (*ptr != '\0') { | ||
47 | if (*ptr == ',' || isdigit(*ptr)) | ||
48 | ; | ||
49 | else { | ||
50 | fprintf(stderr, "Error: invalid cpu list\n"); | ||
51 | exit(1); | ||
52 | } | ||
53 | ptr++; | ||
54 | } | ||
55 | |||
56 | char *start = tmp; | ||
57 | ptr = tmp; | ||
58 | while (*ptr != '\0') { | ||
59 | if (*ptr == ',') { | ||
60 | *ptr = '\0'; | ||
61 | set_cpu(start); | ||
62 | start = ptr + 1; | ||
63 | } | ||
64 | ptr++; | ||
65 | } | ||
66 | set_cpu(start); | ||
67 | free(tmp); | ||
68 | } | ||
69 | |||
70 | void save_cpu(void) { | ||
71 | if (cfg.cpus == 0) | ||
72 | return; | ||
73 | |||
74 | char *fname; | ||
75 | if (asprintf(&fname, "%s/cpu", MNT_DIR) == -1) | ||
76 | errExit("asprintf"); | ||
77 | FILE *fp = fopen(fname, "w"); | ||
78 | if (fp) { | ||
79 | fprintf(fp, "%x\n", cfg.cpus); | ||
80 | fclose(fp); | ||
81 | if (chown(fname, 0, 0) < 0) | ||
82 | errExit("chown"); | ||
83 | } | ||
84 | else { | ||
85 | fprintf(stderr, "Error: cannot save cpu affinity mask\n"); | ||
86 | free(fname); | ||
87 | exit(1); | ||
88 | } | ||
89 | |||
90 | free(fname); | ||
91 | } | ||
92 | |||
93 | void load_cpu(const char *fname) { | ||
94 | if (!fname) | ||
95 | return; | ||
96 | |||
97 | FILE *fp = fopen(fname, "r"); | ||
98 | if (fp) { | ||
99 | unsigned tmp; | ||
100 | int rv = fscanf(fp, "%x", &tmp); | ||
101 | if (rv) | ||
102 | cfg.cpus = (uint32_t) tmp; | ||
103 | fclose(fp); | ||
104 | } | ||
105 | else | ||
106 | fprintf(stderr, "Warning: cannot load cpu affinity mask\n"); | ||
107 | } | ||
108 | |||
109 | void set_cpu_affinity(void) { | ||
110 | // set cpu affinity | ||
111 | cpu_set_t mask; | ||
112 | CPU_ZERO(&mask); | ||
113 | |||
114 | int i; | ||
115 | uint32_t m = 1; | ||
116 | for (i = 0; i < 32; i++, m <<= 1) { | ||
117 | if (cfg.cpus & m) | ||
118 | CPU_SET(i, &mask); | ||
119 | } | ||
120 | |||
121 | if (sched_setaffinity(0, sizeof(mask), &mask) == -1) { | ||
122 | fprintf(stderr, "Warning: cannot set cpu affinity\n"); | ||
123 | fprintf(stderr, " "); | ||
124 | perror("sched_setaffinity"); | ||
125 | } | ||
126 | |||
127 | // verify cpu affinity | ||
128 | cpu_set_t mask2; | ||
129 | CPU_ZERO(&mask2); | ||
130 | if (sched_getaffinity(0, sizeof(mask2), &mask2) == -1) { | ||
131 | fprintf(stderr, "Warning: cannot verify cpu affinity\n"); | ||
132 | fprintf(stderr, " "); | ||
133 | perror("sched_getaffinity"); | ||
134 | } | ||
135 | else { | ||
136 | if (CPU_EQUAL(&mask, &mask2)) | ||
137 | printf("CPU affinity set\n"); | ||
138 | else | ||
139 | printf("CPU affinity not set\n"); | ||
140 | } | ||
141 | } | ||
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h new file mode 100644 index 000000000..2ec6e54c9 --- /dev/null +++ b/src/firejail/firejail.h | |||
@@ -0,0 +1,354 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #ifndef FIREJAIL_H | ||
21 | #define FIREJAIL_H | ||
22 | #include "../include/common.h" | ||
23 | |||
24 | #define USELOCK | ||
25 | #define FIREJAIL_DIR "/tmp/firejail" | ||
26 | #define RO_DIR "/tmp/firejail/firejail.ro.dir" | ||
27 | #define RO_FILE "/tmp/firejail/firejail.ro.file" | ||
28 | #define MNT_DIR "/tmp/firejail/mnt" | ||
29 | #define OVERLAY_DIR "/tmp/firejail/overlay" | ||
30 | #define HOME_DIR "/tmp/firejail/mnt/home" | ||
31 | #define MAX_INCLUDE_LEVEL 6 | ||
32 | |||
33 | // main.c | ||
34 | typedef struct bridge_t { | ||
35 | // on the host | ||
36 | char *dev; // interface device name: bridge or regular ethernet | ||
37 | uint32_t ip; // interface device IP address | ||
38 | uint32_t mask; // interface device mask | ||
39 | uint8_t mac[6]; // interface mac address | ||
40 | |||
41 | // inside the sandbox | ||
42 | char *devsandbox; // name of the device inside the sandbox | ||
43 | uint32_t ipsandbox; // ip address inside the sandbox | ||
44 | uint8_t macsandbox[6]; // mac address inside the sandbox | ||
45 | uint32_t iprange_start;// iprange arp scan start range | ||
46 | uint32_t iprange_end; // iprange arp scan end range | ||
47 | |||
48 | // flags | ||
49 | uint8_t arg_ip_none; // --ip=none | ||
50 | uint8_t macvlan; // set by --net=eth0 (or eth1, ...); reset by --net=br0 (or br1, ...) | ||
51 | uint8_t configured; | ||
52 | uint8_t scan; // set by --scan | ||
53 | } Bridge; | ||
54 | |||
55 | typedef struct profile_entry_t { | ||
56 | struct profile_entry_t *next; | ||
57 | char *data; | ||
58 | }ProfileEntry; | ||
59 | |||
60 | typedef struct config_t { | ||
61 | // user data | ||
62 | char *username; | ||
63 | char *homedir; | ||
64 | |||
65 | // filesystem | ||
66 | ProfileEntry *profile; | ||
67 | char *chrootdir; // chroot directory | ||
68 | char *home_private; // private home directory | ||
69 | char *home_private_keep; // keep list for private home directory | ||
70 | char *cwd; // current working directory | ||
71 | |||
72 | // networking | ||
73 | char *hostname; | ||
74 | uint32_t defaultgw; // default gateway | ||
75 | Bridge bridge0; | ||
76 | Bridge bridge1; | ||
77 | Bridge bridge2; | ||
78 | Bridge bridge3; | ||
79 | uint32_t dns1; // up to 3 IP addresses for dns servers | ||
80 | uint32_t dns2; | ||
81 | uint32_t dns3; | ||
82 | |||
83 | // rlimits | ||
84 | unsigned rlimit_nofile; | ||
85 | unsigned rlimit_nproc; | ||
86 | unsigned rlimit_fsize; | ||
87 | unsigned rlimit_sigpending; | ||
88 | |||
89 | // cpu affinity and control groups | ||
90 | uint32_t cpus; | ||
91 | char *cgroup; | ||
92 | |||
93 | |||
94 | // command line | ||
95 | char *command_line; | ||
96 | char *command_name; | ||
97 | char *shell; | ||
98 | char **original_argv; | ||
99 | int original_argc; | ||
100 | int original_program_index; | ||
101 | } Config; | ||
102 | extern Config cfg; | ||
103 | |||
104 | static inline int any_bridge_configured(void) { | ||
105 | if (cfg.bridge3.configured || cfg.bridge2.configured || cfg.bridge1.configured || cfg.bridge0.configured) | ||
106 | return 1; | ||
107 | else | ||
108 | return 0; | ||
109 | } | ||
110 | extern int arg_private; // mount private /home and /tmp directory | ||
111 | extern int arg_debug; // print debug messages | ||
112 | extern int arg_nonetwork; // --net=none | ||
113 | extern int arg_command; // -c | ||
114 | extern int arg_overlay; // --overlay | ||
115 | extern int arg_zsh; // use zsh as default shell | ||
116 | extern int arg_csh; // use csh as default shell | ||
117 | |||
118 | extern int arg_seccomp; // enable default seccomp filter | ||
119 | extern char *arg_seccomp_list;// optional seccomp list on top of default filter | ||
120 | extern char *arg_seccomp_list_drop; // seccomp drop list | ||
121 | extern char *arg_seccomp_list_keep; // seccomp keep list | ||
122 | |||
123 | extern int arg_caps_default_filter; // enable default capabilities filter | ||
124 | extern int arg_caps_drop; // drop list | ||
125 | extern int arg_caps_drop_all; // drop all capabilities | ||
126 | extern int arg_caps_keep; // keep list | ||
127 | extern char *arg_caps_list; // optional caps list | ||
128 | |||
129 | extern int arg_trace; // syscall tracing support | ||
130 | extern int arg_rlimit_nofile; // rlimit nofile | ||
131 | extern int arg_rlimit_nproc; // rlimit nproc | ||
132 | extern int arg_rlimit_fsize; // rlimit fsize | ||
133 | extern int arg_rlimit_sigpending;// rlimit sigpending | ||
134 | extern int arg_nox11; // kill the program if x11 unix domain socket is accessed | ||
135 | extern int arg_nodbus; // kill the program if D-Bus is accessed | ||
136 | extern int arg_nogroups; // disable supplementary groups | ||
137 | extern int arg_noroot; // create a new user namespace and disable root user | ||
138 | extern int arg_netfilter; // enable netfilter | ||
139 | extern char *arg_netfilter_file; // netfilter file | ||
140 | extern int arg_doubledash; // double dash | ||
141 | extern int arg_shell_none; // run the program directly without a shell | ||
142 | extern int arg_private_dev; // private dev directory | ||
143 | extern int arg_scan; // arp-scan all interfaces | ||
144 | |||
145 | extern int parent_to_child_fds[2]; | ||
146 | extern int child_to_parent_fds[2]; | ||
147 | extern pid_t sandbox_pid; | ||
148 | |||
149 | |||
150 | |||
151 | #define MAX_ARGS 128 // maximum number of command arguments (argc) | ||
152 | extern char *fullargv[MAX_ARGS]; | ||
153 | extern int fullargc; | ||
154 | |||
155 | // main.c | ||
156 | void check_user_namespace(void); | ||
157 | |||
158 | // sandbox.c | ||
159 | int sandbox(void* sandbox_arg); | ||
160 | |||
161 | // network_main.c | ||
162 | void net_configure_bridge(Bridge *br, char *dev_name); | ||
163 | void net_configure_sandbox_ip(Bridge *br); | ||
164 | void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child); | ||
165 | void net_check_cfg(void); | ||
166 | void net_dns_print_name(const char *name); | ||
167 | void net_dns_print(pid_t pid); | ||
168 | |||
169 | // network.c | ||
170 | void net_if_up(const char *ifname); | ||
171 | void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask); | ||
172 | int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6]); | ||
173 | int net_add_route(uint32_t dest, uint32_t mask, uint32_t gw); | ||
174 | void net_ifprint(void); | ||
175 | void net_bridge_add_interface(const char *bridge, const char *dev); | ||
176 | uint32_t network_get_defaultgw(void); | ||
177 | int net_config_mac(const char *ifname, const unsigned char mac[6]); | ||
178 | int net_get_mac(const char *ifname, unsigned char mac[6]); | ||
179 | |||
180 | // fs.c | ||
181 | // build /tmp/firejail directory | ||
182 | void fs_build_firejail_dir(void); | ||
183 | // build /tmp/firejail/mnt directory | ||
184 | void fs_build_mnt_dir(void); | ||
185 | // blacklist files or directoies by mounting empty files on top of them | ||
186 | void fs_blacklist(const char *homedir); | ||
187 | //void fs_blacklist(char **blacklist, const char *homedir); | ||
188 | // remount a directory read-only | ||
189 | void fs_rdonly(const char *dir); | ||
190 | // mount /proc and /sys directories | ||
191 | void fs_proc_sys_dev_boot(void); | ||
192 | // build a basic read-only filesystem | ||
193 | void fs_basic_fs(void); | ||
194 | // mount overlayfs on top of / directory | ||
195 | void fs_overlayfs(void); | ||
196 | // chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf | ||
197 | void fs_chroot(const char *rootdir); | ||
198 | int fs_check_chroot_dir(const char *rootdir); | ||
199 | |||
200 | // profile.c | ||
201 | // find and read the profile specified by name from dir directory | ||
202 | int profile_find(const char *name, const char *dir); | ||
203 | // read a profile file | ||
204 | void profile_read(const char *fname, const char *skip1, const char *skip2); | ||
205 | // check profile line; if line == 0, this was generated from a command line option | ||
206 | // return 1 if the command is to be added to the linked list of profile commands | ||
207 | // return 0 if the command was already executed inside the function | ||
208 | int profile_check_line(char *ptr, int lineno); | ||
209 | // add a profile entry in cfg.profile list; use str to populate the list | ||
210 | void profile_add(char *str); | ||
211 | |||
212 | // list.c | ||
213 | void list(void); | ||
214 | void tree(void); | ||
215 | void top(void); | ||
216 | void netstats(void); | ||
217 | |||
218 | // usage.c | ||
219 | void usage(void); | ||
220 | |||
221 | // join.c | ||
222 | void join(pid_t pid, const char *homedir, int argc, char **argv, int index); | ||
223 | void join_name(const char *name, const char *homedir, int argc, char **argv, int index); | ||
224 | void shut(pid_t pid); | ||
225 | void shut_name(const char *name); | ||
226 | |||
227 | // restricted_shell.c | ||
228 | extern char *restricted_user; | ||
229 | int restricted_shell(const char *user); | ||
230 | |||
231 | // arp.c | ||
232 | // returns 0 if the address is not in use, -1 otherwise | ||
233 | int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr); | ||
234 | // assign an IP address using arp scanning | ||
235 | uint32_t arp_assign(const char *dev, Bridge *br); | ||
236 | // scan interface (--scan option) | ||
237 | void arp_scan(const char *dev, uint32_t srcaddr, uint32_t srcmask); | ||
238 | |||
239 | // veth.c | ||
240 | int net_create_veth(const char *dev, const char *nsdev, unsigned pid); | ||
241 | int net_create_macvlan(const char *dev, const char *parent, unsigned pid); | ||
242 | |||
243 | // util.c | ||
244 | void drop_privs(int nogroups); | ||
245 | void extract_command_name(const char *str); | ||
246 | void logsignal(int s); | ||
247 | void logmsg(const char *msg); | ||
248 | void logargs(int argc, char **argv) ; | ||
249 | void logerr(const char *msg); | ||
250 | int copy_file(const char *srcname, const char *destname); | ||
251 | char *get_link(const char *fname); | ||
252 | int is_dir(const char *fname); | ||
253 | int is_link(const char *fname); | ||
254 | char *line_remove_spaces(const char *buf); | ||
255 | char *split_comma(char *str); | ||
256 | int not_unsigned(const char *str); | ||
257 | int find_child(pid_t parent, pid_t *child); | ||
258 | void check_private_dir(void); | ||
259 | void update_map(char *mapping, char *map_file); | ||
260 | void wait_for_other(int fd); | ||
261 | void notify_other(int fd); | ||
262 | |||
263 | // fs_var.c | ||
264 | void fs_var_log(void); // mounting /var/log | ||
265 | void fs_var_lib(void); // various other fixes for software in /var directory | ||
266 | void fs_var_cache(void); // various other fixes for software in /var/cache directory | ||
267 | void fs_var_run(void); | ||
268 | void fs_var_lock(void); | ||
269 | void fs_var_tmp(void); | ||
270 | void fs_var_utmp(void); | ||
271 | void dbg_test_dir(const char *dir); | ||
272 | |||
273 | // fs_dev.c | ||
274 | void fs_dev_shm(void); | ||
275 | void fs_private_dev(void); | ||
276 | |||
277 | // fs_home.c | ||
278 | // private mode (--private) | ||
279 | void fs_private(void); | ||
280 | // private mode (--private=homedir) | ||
281 | void fs_private_homedir(void); | ||
282 | // private mode (--private.keep=list) | ||
283 | void fs_private_home_list(void); | ||
284 | // check directory linst specified by user (--private.keep option) - exit if it fails | ||
285 | void fs_check_home_list(void); | ||
286 | // check new private home directory (--private= option) - exit if it fails | ||
287 | void fs_check_private_dir(void); | ||
288 | |||
289 | |||
290 | // seccomp.c | ||
291 | int seccomp_filter_drop(void); | ||
292 | int seccomp_filter_keep(void); | ||
293 | void seccomp_set(void); | ||
294 | void seccomp_print_filter_name(const char *name); | ||
295 | void seccomp_print_filter(pid_t pid); | ||
296 | |||
297 | // caps.c | ||
298 | int caps_default_filter(void); | ||
299 | void caps_print(void); | ||
300 | void caps_drop_all(void); | ||
301 | void caps_set(uint64_t caps); | ||
302 | int caps_check_list(const char *clist, void (*callback)(int)); | ||
303 | void caps_drop_list(const char *clist); | ||
304 | void caps_keep_list(const char *clist); | ||
305 | void caps_print_filter(pid_t pid); | ||
306 | void caps_print_filter_name(const char *name); | ||
307 | |||
308 | // syscall.c | ||
309 | const char *syscall_find_nr(int nr); | ||
310 | // return -1 if error, 0 if no error | ||
311 | int syscall_check_list(const char *slist, void (*callback)(int)); | ||
312 | // print all available syscalls | ||
313 | void syscall_print(void); | ||
314 | |||
315 | // fs_trace.c | ||
316 | void fs_trace_preload(void); | ||
317 | void fs_trace(void); | ||
318 | |||
319 | // fs_hostname.c | ||
320 | void fs_hostname(const char *hostname); | ||
321 | void fs_resolvconf(void); | ||
322 | |||
323 | // rlimit.c | ||
324 | void set_rlimits(void); | ||
325 | |||
326 | // cpu.c | ||
327 | void read_cpu_list(const char *str); | ||
328 | void set_cpu_affinity(void); | ||
329 | void load_cpu(const char *fname); | ||
330 | void save_cpu(void); | ||
331 | |||
332 | // cgroup.c | ||
333 | void save_cgroup(void); | ||
334 | void load_cgroup(const char *fname); | ||
335 | void set_cgroup(const char *path); | ||
336 | |||
337 | // output.c | ||
338 | void check_output(int argc, char **argv); | ||
339 | |||
340 | // netfilter.c | ||
341 | void check_netfilter_file(const char *fname); | ||
342 | void netfilter(const char *fname); | ||
343 | |||
344 | // bandwidth.c | ||
345 | void shm_create_firejail_dir(void); | ||
346 | void bandwidth_shm_del_file(pid_t pid); | ||
347 | void bandwidth_shm_set(pid_t pid, const char *dev, int down, int up); | ||
348 | void bandwidth_name(const char *name, const char *command, const char *dev, int down, int up); | ||
349 | void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up); | ||
350 | void network_shm_del_file(pid_t pid); | ||
351 | void network_shm_set_file(pid_t pid); | ||
352 | |||
353 | |||
354 | #endif \ No newline at end of file | ||
diff --git a/src/firejail/fs.c b/src/firejail/fs.c new file mode 100644 index 000000000..1fc1c0942 --- /dev/null +++ b/src/firejail/fs.c | |||
@@ -0,0 +1,825 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/mount.h> | ||
22 | #include <sys/stat.h> | ||
23 | #include <linux/limits.h> | ||
24 | #include <glob.h> | ||
25 | #include <dirent.h> | ||
26 | #include <fcntl.h> | ||
27 | #include <errno.h> | ||
28 | |||
29 | // build /tmp/firejail directory | ||
30 | void fs_build_firejail_dir(void) { | ||
31 | struct stat s; | ||
32 | |||
33 | if (stat(FIREJAIL_DIR, &s)) { | ||
34 | if (arg_debug) | ||
35 | printf("Creating %s directory\n", FIREJAIL_DIR); | ||
36 | /* coverity[toctou] */ | ||
37 | int rv = mkdir(FIREJAIL_DIR, S_IRWXU | S_IRWXG | S_IRWXO); | ||
38 | if (rv == -1) | ||
39 | errExit("mkdir"); | ||
40 | if (chown(FIREJAIL_DIR, 0, 0) < 0) | ||
41 | errExit("chown"); | ||
42 | if (chmod(FIREJAIL_DIR, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | ||
43 | errExit("chmod"); | ||
44 | } | ||
45 | else { // check /tmp/firejail directory belongs to root end exit if doesn't! | ||
46 | if (s.st_uid != 0 || s.st_gid != 0) { | ||
47 | fprintf(stderr, "Error: non-root %s directory, exiting...\n", FIREJAIL_DIR); | ||
48 | exit(1); | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | |||
53 | |||
54 | // build /tmp/firejail/mnt directory | ||
55 | static int tmpfs_mounted = 0; | ||
56 | void fs_build_mnt_dir(void) { | ||
57 | struct stat s; | ||
58 | fs_build_firejail_dir(); | ||
59 | |||
60 | // create /tmp/firejail directory | ||
61 | if (stat(MNT_DIR, &s)) { | ||
62 | if (arg_debug) | ||
63 | printf("Creating %s directory\n", MNT_DIR); | ||
64 | /* coverity[toctou] */ | ||
65 | int rv = mkdir(MNT_DIR, S_IRWXU | S_IRWXG | S_IRWXO); | ||
66 | if (rv == -1) | ||
67 | errExit("mkdir"); | ||
68 | if (chown(MNT_DIR, 0, 0) < 0) | ||
69 | errExit("chown"); | ||
70 | if (chmod(MNT_DIR, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | ||
71 | errExit("chmod"); | ||
72 | } | ||
73 | |||
74 | // ... and mount tmpfs on top of it | ||
75 | if (!tmpfs_mounted) { | ||
76 | // mount tmpfs on top of /tmp/firejail/mnt | ||
77 | if (arg_debug) | ||
78 | printf("Mounting tmpfs on %s directory\n", MNT_DIR); | ||
79 | if (mount("tmpfs", MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
80 | errExit("mounting /tmp/firejail/mnt"); | ||
81 | tmpfs_mounted = 1; | ||
82 | } | ||
83 | } | ||
84 | |||
85 | // build /tmp/firejail/overlay directory | ||
86 | void fs_build_overlay_dir(void) { | ||
87 | struct stat s; | ||
88 | fs_build_firejail_dir(); | ||
89 | |||
90 | // create /tmp/firejail directory | ||
91 | if (stat(OVERLAY_DIR, &s)) { | ||
92 | if (arg_debug) | ||
93 | printf("Creating %s directory\n", MNT_DIR); | ||
94 | /* coverity[toctou] */ | ||
95 | int rv = mkdir(OVERLAY_DIR, S_IRWXU | S_IRWXG | S_IRWXO); | ||
96 | if (rv == -1) | ||
97 | errExit("mkdir"); | ||
98 | if (chown(OVERLAY_DIR, 0, 0) < 0) | ||
99 | errExit("chown"); | ||
100 | if (chmod(OVERLAY_DIR, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | ||
101 | errExit("chmod"); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | |||
106 | |||
107 | |||
108 | |||
109 | //*********************************************** | ||
110 | // process profile file | ||
111 | //*********************************************** | ||
112 | typedef enum { | ||
113 | BLACKLIST_FILE, | ||
114 | MOUNT_READONLY, | ||
115 | MOUNT_TMPFS, | ||
116 | OPERATION_MAX | ||
117 | } OPERATION; | ||
118 | |||
119 | |||
120 | static char *create_empty_dir(void) { | ||
121 | struct stat s; | ||
122 | fs_build_firejail_dir(); | ||
123 | |||
124 | if (stat(RO_DIR, &s)) { | ||
125 | /* coverity[toctou] */ | ||
126 | int rv = mkdir(RO_DIR, S_IRUSR | S_IXUSR); | ||
127 | if (rv == -1) | ||
128 | errExit("mkdir"); | ||
129 | if (chown(RO_DIR, 0, 0) < 0) | ||
130 | errExit("chown"); | ||
131 | } | ||
132 | |||
133 | return RO_DIR; | ||
134 | } | ||
135 | |||
136 | static char *create_empty_file(void) { | ||
137 | struct stat s; | ||
138 | fs_build_firejail_dir(); | ||
139 | |||
140 | if (stat(RO_FILE, &s)) { | ||
141 | /* coverity[toctou] */ | ||
142 | FILE *fp = fopen(RO_FILE, "w"); | ||
143 | if (!fp) | ||
144 | errExit("fopen"); | ||
145 | fclose(fp); | ||
146 | if (chown(RO_FILE, 0, 0) < 0) | ||
147 | errExit("chown"); | ||
148 | if (chmod(RO_FILE, S_IRUSR) < 0) | ||
149 | errExit("chown"); | ||
150 | } | ||
151 | |||
152 | return RO_FILE; | ||
153 | } | ||
154 | |||
155 | static void disable_file(OPERATION op, const char *fname, const char *emptydir, const char *emptyfile) { | ||
156 | assert(fname); | ||
157 | assert(emptydir); | ||
158 | assert(emptyfile); | ||
159 | assert(op <OPERATION_MAX); | ||
160 | |||
161 | // if the file is a link, follow the link | ||
162 | char *lnk = NULL; | ||
163 | if (is_link(fname)) { | ||
164 | lnk = get_link(fname); | ||
165 | if (lnk) | ||
166 | fname = lnk; | ||
167 | else | ||
168 | fprintf(stderr, "Warning: cannot follow link %s, skipping...\n", fname); | ||
169 | } | ||
170 | |||
171 | // if the file is not present, do nothing | ||
172 | struct stat s; | ||
173 | if (stat(fname, &s) == -1) { | ||
174 | if (lnk) | ||
175 | free(lnk); | ||
176 | return; | ||
177 | } | ||
178 | |||
179 | // modify the file | ||
180 | if (op == BLACKLIST_FILE) { | ||
181 | if (arg_debug) | ||
182 | printf("Disable %s\n", fname); | ||
183 | if (S_ISDIR(s.st_mode)) { | ||
184 | if (mount(emptydir, fname, "none", MS_BIND, "mode=400,gid=0") < 0) | ||
185 | errExit("disable file"); | ||
186 | } | ||
187 | else { | ||
188 | if (mount(emptyfile, fname, "none", MS_BIND, "mode=400,gid=0") < 0) | ||
189 | errExit("disable file"); | ||
190 | } | ||
191 | } | ||
192 | else if (op == MOUNT_READONLY) { | ||
193 | if (arg_debug) | ||
194 | printf("Mounting read-only %s\n", fname); | ||
195 | fs_rdonly(fname); | ||
196 | } | ||
197 | else if (op == MOUNT_TMPFS) { | ||
198 | if (S_ISDIR(s.st_mode)) { | ||
199 | if (arg_debug) | ||
200 | printf("Mounting tmpfs on %s\n", fname); | ||
201 | // preserve owner and mode for the directory | ||
202 | if (mount("tmpfs", fname, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, 0) < 0) | ||
203 | errExit("mounting tmpfs"); | ||
204 | /* coverity[toctou] */ | ||
205 | if (chown(fname, s.st_uid, s.st_gid) == -1) | ||
206 | errExit("mounting tmpfs chmod"); | ||
207 | } | ||
208 | else | ||
209 | printf("Warning: %s is not a directory; cannot mount a tmpfs on top of it.\n", fname); | ||
210 | } | ||
211 | else | ||
212 | assert(0); | ||
213 | |||
214 | if (lnk) | ||
215 | free(lnk); | ||
216 | } | ||
217 | |||
218 | static void globbing(OPERATION op, const char *fname, const char *emptydir, const char *emptyfile) { | ||
219 | assert(fname); | ||
220 | assert(emptydir); | ||
221 | assert(emptyfile); | ||
222 | |||
223 | // filename globbing: expand * macro and continue processing for every single file | ||
224 | if (strchr(fname, '*')) { | ||
225 | glob_t globbuf; | ||
226 | globbuf.gl_offs = 0; | ||
227 | glob(fname, GLOB_DOOFFS, NULL, &globbuf); | ||
228 | int i; | ||
229 | for (i = 0; i < globbuf.gl_pathc; i++) { | ||
230 | assert(globbuf.gl_pathv[i]); | ||
231 | disable_file(op, globbuf.gl_pathv[i], emptydir, emptyfile); | ||
232 | } | ||
233 | } | ||
234 | else | ||
235 | disable_file(op, fname, emptydir, emptyfile); | ||
236 | } | ||
237 | |||
238 | static void expand_path(OPERATION op, const char *path, const char *fname, const char *emptydir, const char *emptyfile) { | ||
239 | assert(path); | ||
240 | assert(fname); | ||
241 | assert(emptydir); | ||
242 | assert(emptyfile); | ||
243 | char newname[strlen(path) + strlen(fname) + 1]; | ||
244 | sprintf(newname, "%s%s", path, fname); | ||
245 | |||
246 | globbing(op, newname, emptydir, emptyfile); | ||
247 | } | ||
248 | |||
249 | // blacklist files or directoies by mounting empty files on top of them | ||
250 | void fs_blacklist(const char *homedir) { | ||
251 | ProfileEntry *entry = cfg.profile; | ||
252 | if (!entry) | ||
253 | return; | ||
254 | |||
255 | char *emptydir = create_empty_dir(); | ||
256 | char *emptyfile = create_empty_file(); | ||
257 | |||
258 | while (entry) { | ||
259 | OPERATION op = OPERATION_MAX; | ||
260 | char *ptr; | ||
261 | |||
262 | // process blacklist command | ||
263 | if (strncmp(entry->data, "bind", 4) == 0) { | ||
264 | char *dname1 = entry->data + 5; | ||
265 | char *dname2 = split_comma(dname1); | ||
266 | if (dname2 == NULL) { | ||
267 | fprintf(stderr, "Error: second directory missing in bind command\n"); | ||
268 | entry = entry->next; | ||
269 | continue; | ||
270 | } | ||
271 | struct stat s; | ||
272 | if (stat(dname1, &s) == -1) { | ||
273 | fprintf(stderr, "Error: cannot find directories for bind command\n"); | ||
274 | entry = entry->next; | ||
275 | continue; | ||
276 | } | ||
277 | if (stat(dname2, &s) == -1) { | ||
278 | fprintf(stderr, "Error: cannot find directories for bind command\n"); | ||
279 | entry = entry->next; | ||
280 | continue; | ||
281 | } | ||
282 | |||
283 | // mount --bind olddir newdir | ||
284 | if (arg_debug) | ||
285 | printf("Mount-bind %s on top of %s\n", dname1, dname2); | ||
286 | // preserve dname2 mode and ownership | ||
287 | if (mount(dname1, dname2, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
288 | errExit("mount bind"); | ||
289 | /* coverity[toctou] */ | ||
290 | if (chown(dname2, s.st_uid, s.st_gid) == -1) | ||
291 | errExit("mount-bind chown"); | ||
292 | /* coverity[toctou] */ | ||
293 | if (chmod(dname2, s.st_mode) == -1) | ||
294 | errExit("mount-bind chmod"); | ||
295 | |||
296 | entry = entry->next; | ||
297 | continue; | ||
298 | } | ||
299 | |||
300 | // process blacklist command | ||
301 | if (strncmp(entry->data, "blacklist", 9) == 0) { | ||
302 | ptr = entry->data + 10; | ||
303 | op = BLACKLIST_FILE; | ||
304 | } | ||
305 | else if (strncmp(entry->data, "read-only", 9) == 0) { | ||
306 | ptr = entry->data + 10; | ||
307 | op = MOUNT_READONLY; | ||
308 | } | ||
309 | else if (strncmp(entry->data, "tmpfs", 5) == 0) { | ||
310 | ptr = entry->data + 6; | ||
311 | op = MOUNT_TMPFS; | ||
312 | } | ||
313 | else { | ||
314 | fprintf(stderr, "Error: invalid profile line %s\n", entry->data); | ||
315 | entry = entry->next; | ||
316 | continue; | ||
317 | } | ||
318 | |||
319 | // replace home macro in blacklist array | ||
320 | char *new_name = NULL; | ||
321 | if (strncmp(ptr, "${HOME}", 7) == 0) { | ||
322 | if (asprintf(&new_name, "%s%s", homedir, ptr + 7) == -1) | ||
323 | errExit("asprintf"); | ||
324 | ptr = new_name; | ||
325 | } | ||
326 | |||
327 | // expand path macro - look for the file in /bin, /usr/bin, /sbin and /usr/sbin directories | ||
328 | if (strncmp(ptr, "${PATH}", 7) == 0) { | ||
329 | expand_path(op, "/bin", ptr + 7, emptydir, emptyfile); | ||
330 | expand_path(op, "/sbin", ptr + 7, emptydir, emptyfile); | ||
331 | expand_path(op, "/usr/bin", ptr + 7, emptydir, emptyfile); | ||
332 | expand_path(op, "/usr/sbin", ptr + 7, emptydir, emptyfile); | ||
333 | } | ||
334 | else | ||
335 | globbing(op, ptr, emptydir, emptyfile); | ||
336 | |||
337 | if (new_name) | ||
338 | free(new_name); | ||
339 | entry = entry->next; | ||
340 | } | ||
341 | } | ||
342 | |||
343 | //*********************************************** | ||
344 | // mount namespace | ||
345 | //*********************************************** | ||
346 | |||
347 | // remount a directory read-only | ||
348 | void fs_rdonly(const char *dir) { | ||
349 | assert(dir); | ||
350 | // check directory exists | ||
351 | struct stat s; | ||
352 | int rv = stat(dir, &s); | ||
353 | if (rv == 0) { | ||
354 | // mount --bind /bin /bin | ||
355 | if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
356 | errExit("mount read-only"); | ||
357 | // mount --bind -o remount,ro /bin | ||
358 | if (mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) | ||
359 | errExit("mount read-only"); | ||
360 | } | ||
361 | } | ||
362 | void fs_rdonly_noexit(const char *dir) { | ||
363 | assert(dir); | ||
364 | // check directory exists | ||
365 | struct stat s; | ||
366 | int rv = stat(dir, &s); | ||
367 | if (rv == 0) { | ||
368 | int merr = 0; | ||
369 | // mount --bind /bin /bin | ||
370 | if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
371 | merr = 1; | ||
372 | // mount --bind -o remount,ro /bin | ||
373 | if (mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) | ||
374 | merr = 1; | ||
375 | if (merr) | ||
376 | fprintf(stderr, "Warning: cannot mount %s read-only\n", dir); | ||
377 | } | ||
378 | } | ||
379 | |||
380 | // mount /proc and /sys directories | ||
381 | void fs_proc_sys_dev_boot(void) { | ||
382 | struct stat s; | ||
383 | |||
384 | if (arg_debug) | ||
385 | printf("Remounting /proc and /proc/sys filesystems\n"); | ||
386 | if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_REC, NULL) < 0) | ||
387 | errExit("mounting /proc"); | ||
388 | |||
389 | // remount /proc/sys readonly | ||
390 | if (mount("/proc/sys", "/proc/sys", NULL, MS_BIND | MS_REC, NULL) < 0) | ||
391 | errExit("mounting /proc/sys"); | ||
392 | |||
393 | if (mount(NULL, "/proc/sys", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_REC, NULL) < 0) | ||
394 | errExit("mounting /proc/sys"); | ||
395 | |||
396 | |||
397 | /* Mount a version of /sys that describes the network namespace */ | ||
398 | if (arg_debug) | ||
399 | printf("Remounting /sys directory\n"); | ||
400 | if (umount2("/sys", MNT_DETACH) < 0) | ||
401 | fprintf(stderr, "Warning: failed to unmount /sys\n"); | ||
402 | if (mount("sysfs", "/sys", "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REC, NULL) < 0) | ||
403 | fprintf(stderr, "Warning: failed to mount /sys\n"); | ||
404 | |||
405 | // if (mount("sysfs", "/sys", "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REC, NULL) < 0) | ||
406 | // errExit("mounting /sys"); | ||
407 | |||
408 | |||
409 | // mounting firejail kernel module files | ||
410 | if (stat("/proc/firejail-uptime", &s) == 0) { | ||
411 | errno = 0; | ||
412 | FILE *fp = fopen("/proc/firejail", "w"); | ||
413 | int cnt = 0; | ||
414 | while (errno == EBUSY && cnt < 10) { | ||
415 | if (!fp) { | ||
416 | int s = random(); | ||
417 | s /= 200000; | ||
418 | usleep(s); | ||
419 | fp = fopen("/proc/firejail", "w"); | ||
420 | } | ||
421 | else | ||
422 | break; | ||
423 | } | ||
424 | if (!fp) { | ||
425 | fprintf(stderr, "Error: cannot register sandbox with firejail-lkm\n"); | ||
426 | exit(1); | ||
427 | } | ||
428 | if (fp) { | ||
429 | // registration | ||
430 | fprintf(fp, "register\n"); | ||
431 | fflush(0); | ||
432 | // filtering x11 connect calls | ||
433 | if (arg_nox11) { | ||
434 | fprintf(fp, "no connect unix /tmp/.X11\n"); | ||
435 | fflush(0); | ||
436 | printf("X11 access disabled\n"); | ||
437 | } | ||
438 | if (arg_nodbus) { | ||
439 | fprintf(fp, "no connect unix /var/run/dbus/system_bus_socket\n"); | ||
440 | fflush(0); | ||
441 | fprintf(fp, "no connect unix /tmp/dbus\n"); | ||
442 | fflush(0); | ||
443 | printf("D-Bus access disabled\n"); | ||
444 | } | ||
445 | fclose(fp); | ||
446 | if (mount("/proc/firejail-uptime", "/proc/uptime", NULL, MS_BIND|MS_REC, NULL) < 0) | ||
447 | fprintf(stderr, "Warning: cannot mount /proc/firejail-uptime\n"); | ||
448 | } | ||
449 | } | ||
450 | |||
451 | // Disable SysRq | ||
452 | // a linux box can be shut down easily using the following commands (as root): | ||
453 | // # echo 1 > /proc/sys/kernel/sysrq | ||
454 | // #echo b > /proc/sysrq-trigger | ||
455 | // for more information see https://www.kernel.org/doc/Documentation/sysrq.txt | ||
456 | if (arg_debug) | ||
457 | printf("Disable /proc/sysrq-trigger\n"); | ||
458 | fs_rdonly_noexit("/proc/sysrq-trigger"); | ||
459 | |||
460 | // disable hotplug and uevent_helper | ||
461 | if (arg_debug) | ||
462 | printf("Disable /proc/sys/kernel/hotplug\n"); | ||
463 | fs_rdonly_noexit("/proc/sys/kernel/hotplug"); | ||
464 | if (arg_debug) | ||
465 | printf("Disable /sys/kernel/uevent_helper\n"); | ||
466 | fs_rdonly_noexit("/sys/kernel/uevent_helper"); | ||
467 | |||
468 | // read-only /proc/irq and /proc/bus | ||
469 | if (arg_debug) | ||
470 | printf("Disable /proc/irq\n"); | ||
471 | fs_rdonly_noexit("/proc/irq"); | ||
472 | if (arg_debug) | ||
473 | printf("Disable /proc/bus\n"); | ||
474 | fs_rdonly_noexit("/proc/bus"); | ||
475 | |||
476 | // disable /proc/kcore | ||
477 | disable_file(BLACKLIST_FILE, "/proc/kcore", "not used", "/dev/null"); | ||
478 | |||
479 | // disable /proc/kallsyms | ||
480 | disable_file(BLACKLIST_FILE, "/proc/kallsyms", "not used", "/dev/null"); | ||
481 | |||
482 | // disable /boot | ||
483 | if (stat("/boot", &s) == 0) { | ||
484 | if (arg_debug) | ||
485 | printf("Mounting a new /boot directory\n"); | ||
486 | if (mount("tmpfs", "/boot", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | ||
487 | errExit("mounting /boot directory"); | ||
488 | } | ||
489 | |||
490 | // disable /dev/port | ||
491 | if (stat("/dev/port", &s) == 0) { | ||
492 | disable_file(BLACKLIST_FILE, "/dev/port", "not used", "/dev/null"); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | static void sanitize_home(void) { | ||
497 | // extract current /home directory data | ||
498 | struct dirent *dir; | ||
499 | DIR *d = opendir("/home"); | ||
500 | if (d == NULL) | ||
501 | return; | ||
502 | |||
503 | char *emptydir = create_empty_dir(); | ||
504 | while ((dir = readdir(d))) { | ||
505 | if(strcmp(dir->d_name, "." ) == 0 || strcmp(dir->d_name, ".." ) == 0) | ||
506 | continue; | ||
507 | |||
508 | if (dir->d_type == DT_DIR ) { | ||
509 | // get properties | ||
510 | struct stat s; | ||
511 | char *name; | ||
512 | if (asprintf(&name, "/home/%s", dir->d_name) == -1) | ||
513 | continue; | ||
514 | if (stat(name, &s) == -1) | ||
515 | continue; | ||
516 | if (S_ISLNK(s.st_mode)) { | ||
517 | free(name); | ||
518 | continue; | ||
519 | } | ||
520 | |||
521 | if (strcmp(name, cfg.homedir) == 0) | ||
522 | continue; | ||
523 | |||
524 | // printf("directory %u %u:%u #%s#\n", | ||
525 | // s.st_mode, | ||
526 | // s.st_uid, | ||
527 | // s.st_gid, | ||
528 | // name); | ||
529 | |||
530 | // disable directory | ||
531 | disable_file(BLACKLIST_FILE, name, emptydir, "not used"); | ||
532 | free(name); | ||
533 | } | ||
534 | } | ||
535 | closedir(d); | ||
536 | } | ||
537 | |||
538 | |||
539 | |||
540 | |||
541 | |||
542 | |||
543 | // build a basic read-only filesystem | ||
544 | void fs_basic_fs(void) { | ||
545 | if (arg_debug) | ||
546 | printf("Mounting read-only /bin, /sbin, /lib, /lib64, /usr, /etc, /var\n"); | ||
547 | fs_rdonly("/bin"); | ||
548 | fs_rdonly("/sbin"); | ||
549 | fs_rdonly("/lib"); | ||
550 | fs_rdonly("/lib64"); | ||
551 | fs_rdonly("/usr"); | ||
552 | fs_rdonly("/etc"); | ||
553 | fs_rdonly("/var"); | ||
554 | |||
555 | // update /var directory in order to support multiple sandboxes running on the same root directory | ||
556 | if (!arg_private_dev) | ||
557 | fs_dev_shm(); | ||
558 | fs_var_lock(); | ||
559 | fs_var_tmp(); | ||
560 | fs_var_log(); | ||
561 | fs_var_lib(); | ||
562 | fs_var_cache(); | ||
563 | fs_var_utmp(); | ||
564 | |||
565 | // only in user mode | ||
566 | if (getuid()) | ||
567 | sanitize_home(); | ||
568 | } | ||
569 | |||
570 | |||
571 | // mount overlayfs on top of / directory | ||
572 | // mounting an overlay and chrooting into it: | ||
573 | // | ||
574 | // Old Ubuntu kernel | ||
575 | // # cd ~ | ||
576 | // # mkdir -p overlay/root | ||
577 | // # mkdir -p overlay/diff | ||
578 | // # mount -t overlayfs -o lowerdir=/,upperdir=/root/overlay/diff overlayfs /root/overlay/root | ||
579 | // # chroot /root/overlay/root | ||
580 | // to shutdown, first exit the chroot and then unmount the overlay | ||
581 | // # exit | ||
582 | // # umount /root/overlay/root | ||
583 | // | ||
584 | // Kernels 3.18+ | ||
585 | // # cd ~ | ||
586 | // # mkdir -p overlay/root | ||
587 | // # mkdir -p overlay/diff | ||
588 | // # mkdir -p overlay/work | ||
589 | // # mount -t overlay -o lowerdir=/,upperdir=/root/overlay/diff,workdir=/root/overlay/work overlay /root/overlay/root | ||
590 | // # cat /etc/mtab | grep overlay | ||
591 | // /root/overlay /root/overlay/root overlay rw,relatime,lowerdir=/,upperdir=/root/overlay/diff,workdir=/root/overlay/work 0 0 | ||
592 | // # chroot /root/overlay/root | ||
593 | // to shutdown, first exit the chroot and then unmount the overlay | ||
594 | // # exit | ||
595 | // # umount /root/overlay/root | ||
596 | |||
597 | |||
598 | // to do: fix the code below; also, it might work without /dev; impose seccomp/caps filters when not root | ||
599 | #include <sys/utsname.h> | ||
600 | void fs_overlayfs(void) { | ||
601 | // check kernel version | ||
602 | struct utsname u; | ||
603 | int rv = uname(&u); | ||
604 | if (rv != 0) | ||
605 | errExit("uname"); | ||
606 | int major; | ||
607 | int minor; | ||
608 | if (2 != sscanf(u.release, "%d.%d", &major, &minor)) { | ||
609 | fprintf(stderr, "Error: cannot extract Linux kernel version: %s\n", u.version); | ||
610 | exit(1); | ||
611 | } | ||
612 | |||
613 | if (arg_debug) | ||
614 | printf("Linux kernel version %d.%d\n", major, minor); | ||
615 | int oldkernel = 0; | ||
616 | if (major < 3) { | ||
617 | fprintf(stderr, "Error: minimum kernel version required 3.x\n"); | ||
618 | exit(1); | ||
619 | } | ||
620 | if (major == 3 && minor < 18) | ||
621 | oldkernel = 1; | ||
622 | |||
623 | // build overlay directories | ||
624 | fs_build_mnt_dir(); | ||
625 | |||
626 | char *oroot; | ||
627 | if(asprintf(&oroot, "%s/oroot", MNT_DIR) == -1) | ||
628 | errExit("asprintf"); | ||
629 | if (mkdir(oroot, S_IRWXU | S_IRWXG | S_IRWXO)) | ||
630 | errExit("mkdir"); | ||
631 | if (chown(oroot, 0, 0) < 0) | ||
632 | errExit("chown"); | ||
633 | if (chmod(oroot, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | ||
634 | errExit("chmod"); | ||
635 | |||
636 | char *odiff; | ||
637 | if(asprintf(&odiff, "%s/odiff", MNT_DIR) == -1) | ||
638 | errExit("asprintf"); | ||
639 | if (mkdir(odiff, S_IRWXU | S_IRWXG | S_IRWXO)) | ||
640 | errExit("mkdir"); | ||
641 | if (chown(odiff, 0, 0) < 0) | ||
642 | errExit("chown"); | ||
643 | if (chmod(odiff, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | ||
644 | errExit("chmod"); | ||
645 | |||
646 | char *owork; | ||
647 | if(asprintf(&owork, "%s/owork", MNT_DIR) == -1) | ||
648 | errExit("asprintf"); | ||
649 | if (mkdir(owork, S_IRWXU | S_IRWXG | S_IRWXO)) | ||
650 | errExit("mkdir"); | ||
651 | if (chown(owork, 0, 0) < 0) | ||
652 | errExit("chown"); | ||
653 | if (chmod(owork, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | ||
654 | errExit("chmod"); | ||
655 | |||
656 | // mount overlayfs | ||
657 | if (arg_debug) | ||
658 | printf("Mounting OverlayFS\n"); | ||
659 | char *option; | ||
660 | if (oldkernel) { // old Ubuntu/OpenSUSE kernels | ||
661 | if (asprintf(&option, "lowerdir=/,upperdir=%s", odiff) == -1) | ||
662 | errExit("asprintf"); | ||
663 | if (mount("overlayfs", oroot, "overlayfs", MS_MGC_VAL, option) < 0) | ||
664 | errExit("mounting overlayfs"); | ||
665 | } | ||
666 | else { // kernel 3.18 or newer | ||
667 | if (asprintf(&option, "lowerdir=/,upperdir=%s,workdir=%s", odiff, owork) == -1) | ||
668 | errExit("asprintf"); | ||
669 | if (mount("overlay", oroot, "overlay", MS_MGC_VAL, option) < 0) | ||
670 | errExit("mounting overlayfs"); | ||
671 | } | ||
672 | |||
673 | // mount-bind dev directory | ||
674 | if (arg_debug) | ||
675 | printf("Mounting /dev\n"); | ||
676 | char *dev; | ||
677 | if (asprintf(&dev, "%s/dev", oroot) == -1) | ||
678 | errExit("asprintf"); | ||
679 | if (mount("/dev", dev, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
680 | errExit("mounting /dev"); | ||
681 | |||
682 | // chroot in the new filesystem | ||
683 | if (chroot(oroot) == -1) | ||
684 | errExit("chroot"); | ||
685 | // update /var directory in order to support multiple sandboxes running on the same root directory | ||
686 | if (!arg_private_dev) | ||
687 | fs_dev_shm(); | ||
688 | fs_var_lock(); | ||
689 | fs_var_tmp(); | ||
690 | fs_var_log(); | ||
691 | fs_var_lib(); | ||
692 | fs_var_cache(); | ||
693 | fs_var_utmp(); | ||
694 | |||
695 | // only in user mode | ||
696 | if (getuid()) | ||
697 | sanitize_home(); | ||
698 | |||
699 | // cleanup and exit | ||
700 | free(option); | ||
701 | free(oroot); | ||
702 | free(odiff); | ||
703 | } | ||
704 | |||
705 | |||
706 | |||
707 | #ifdef HAVE_CHROOT | ||
708 | // return 1 if error | ||
709 | int fs_check_chroot_dir(const char *rootdir) { | ||
710 | assert(rootdir); | ||
711 | struct stat s; | ||
712 | char *name; | ||
713 | |||
714 | // check /dev | ||
715 | if (asprintf(&name, "%s/dev", rootdir) == -1) | ||
716 | errExit("asprintf"); | ||
717 | if (stat(name, &s) == -1) { | ||
718 | fprintf(stderr, "Error: cannot find /dev in chroot directory\n"); | ||
719 | return 1; | ||
720 | } | ||
721 | free(name); | ||
722 | |||
723 | // check /var/tmp | ||
724 | if (asprintf(&name, "%s/var/tmp", rootdir) == -1) | ||
725 | errExit("asprintf"); | ||
726 | if (stat(name, &s) == -1) { | ||
727 | fprintf(stderr, "Error: cannot find /var/tmp in chroot directory\n"); | ||
728 | return 1; | ||
729 | } | ||
730 | free(name); | ||
731 | |||
732 | // check /proc | ||
733 | if (asprintf(&name, "%s/proc", rootdir) == -1) | ||
734 | errExit("asprintf"); | ||
735 | if (stat(name, &s) == -1) { | ||
736 | fprintf(stderr, "Error: cannot find /proc in chroot directory\n"); | ||
737 | return 1; | ||
738 | } | ||
739 | free(name); | ||
740 | |||
741 | // check /proc | ||
742 | if (asprintf(&name, "%s/tmp", rootdir) == -1) | ||
743 | errExit("asprintf"); | ||
744 | if (stat(name, &s) == -1) { | ||
745 | fprintf(stderr, "Error: cannot find /tmp in chroot directory\n"); | ||
746 | return 1; | ||
747 | } | ||
748 | free(name); | ||
749 | |||
750 | // check /bin/bash | ||
751 | if (asprintf(&name, "%s/bin/bash", rootdir) == -1) | ||
752 | errExit("asprintf"); | ||
753 | if (stat(name, &s) == -1) { | ||
754 | fprintf(stderr, "Error: cannot find /bin/bash in chroot directory\n"); | ||
755 | return 1; | ||
756 | } | ||
757 | free(name); | ||
758 | |||
759 | return 0; | ||
760 | } | ||
761 | |||
762 | // chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf | ||
763 | void fs_chroot(const char *rootdir) { | ||
764 | assert(rootdir); | ||
765 | |||
766 | //*********************************** | ||
767 | // mount-bind a /dev in rootdir | ||
768 | //*********************************** | ||
769 | // mount /dev | ||
770 | char *newdev; | ||
771 | if (asprintf(&newdev, "%s/dev", rootdir) == -1) | ||
772 | errExit("asprintf"); | ||
773 | if (arg_debug) | ||
774 | printf("Mounting /dev on %s\n", newdev); | ||
775 | if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
776 | errExit("mounting /dev"); | ||
777 | |||
778 | // some older distros don't have a /run directory | ||
779 | // create one by default | ||
780 | // no exit on error, let the user deal with any problems | ||
781 | char *rundir; | ||
782 | if (asprintf(&rundir, "%s/run", rootdir) == -1) | ||
783 | errExit("asprintf"); | ||
784 | if (!is_dir(rundir)) { | ||
785 | int rv = mkdir(rundir, S_IRWXU | S_IRWXG | S_IRWXO); | ||
786 | (void) rv; | ||
787 | rv = chown(rundir, 0, 0); | ||
788 | (void) rv; | ||
789 | } | ||
790 | |||
791 | // copy /etc/resolv.conf in chroot directory | ||
792 | // if resolv.conf in chroot is a symbolic link, this will fail | ||
793 | // no exit on error, let the user deal with the problem | ||
794 | char *fname; | ||
795 | if (asprintf(&fname, "%s/etc/resolv.conf", rootdir) == -1) | ||
796 | errExit("asprintf"); | ||
797 | if (arg_debug) | ||
798 | printf("Updating /etc/resolv.conf in %s\n", fname); | ||
799 | if (copy_file("/etc/resolv.conf", fname) == -1) | ||
800 | fprintf(stderr, "Warning: /etc/resolv.conf not initialized\n"); | ||
801 | |||
802 | // chroot into the new directory | ||
803 | if (arg_debug) | ||
804 | printf("Chrooting into %s\n", rootdir); | ||
805 | if (chroot(rootdir) < 0) | ||
806 | errExit("chroot"); | ||
807 | |||
808 | // update /var directory in order to support multiple sandboxes running on the same root directory | ||
809 | if (!arg_private_dev) | ||
810 | fs_dev_shm(); | ||
811 | fs_var_lock(); | ||
812 | fs_var_tmp(); | ||
813 | fs_var_log(); | ||
814 | fs_var_lib(); | ||
815 | fs_var_cache(); | ||
816 | fs_var_utmp(); | ||
817 | |||
818 | // only in user mode | ||
819 | if (getuid()) | ||
820 | sanitize_home(); | ||
821 | |||
822 | } | ||
823 | #endif | ||
824 | |||
825 | |||
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c new file mode 100644 index 000000000..80bd11582 --- /dev/null +++ b/src/firejail/fs_dev.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/mount.h> | ||
22 | #include <sys/stat.h> | ||
23 | #include <linux/limits.h> | ||
24 | #include <glob.h> | ||
25 | #include <dirent.h> | ||
26 | #include <fcntl.h> | ||
27 | #include <pwd.h> | ||
28 | #ifndef _BSD_SOURCE | ||
29 | #define _BSD_SOURCE | ||
30 | #endif | ||
31 | #include <sys/types.h> | ||
32 | |||
33 | static void create_char_dev(const char *path, mode_t mode, int major, int minor) { | ||
34 | dev_t dev = makedev(major, minor); | ||
35 | int rv = mknod(path, S_IFCHR | mode, dev); | ||
36 | if (rv == -1) | ||
37 | goto errexit; | ||
38 | |||
39 | |||
40 | if (chmod(path, mode) < 0) | ||
41 | goto errexit; | ||
42 | if (chown(path, 0, 0) < 0) | ||
43 | goto errexit; | ||
44 | |||
45 | return; | ||
46 | |||
47 | errexit: | ||
48 | fprintf(stderr, "Error: cannot create %s device\n", path); | ||
49 | exit(1); | ||
50 | } | ||
51 | |||
52 | static void create_link(const char *oldpath, const char *newpath) { | ||
53 | if (symlink(oldpath, newpath) == -1) | ||
54 | goto errexit; | ||
55 | if (chown(newpath, 0, 0) < 0) | ||
56 | goto errexit; | ||
57 | return; | ||
58 | |||
59 | errexit: | ||
60 | fprintf(stderr, "Error: cannot create %s device\n", newpath); | ||
61 | exit(1); | ||
62 | } | ||
63 | |||
64 | void fs_private_dev(void){ | ||
65 | // install a new /dev directory | ||
66 | if (arg_debug) | ||
67 | printf("Mounting tmpfs on /dev\n"); | ||
68 | if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | ||
69 | errExit("mounting /dev"); | ||
70 | |||
71 | // create /dev/shm | ||
72 | if (arg_debug) | ||
73 | printf("Create /dev/shm directory\n"); | ||
74 | int rv = mkdir("/dev/shm", S_IRWXU | S_IRWXG | S_IRWXO); | ||
75 | if (rv == -1) | ||
76 | errExit("mkdir"); | ||
77 | if (chown("/dev/shm", 0, 0) < 0) | ||
78 | errExit("chown"); | ||
79 | if (chmod("/dev/shm", S_IRWXU | S_IRWXG | S_IRWXO) < 0) | ||
80 | errExit("chmod"); | ||
81 | |||
82 | // create devices | ||
83 | create_char_dev("/dev/zero", 0666, 1, 5); // mknod -m 666 /dev/zero c 1 5 | ||
84 | create_char_dev("/dev/null", 0666, 1, 3); // mknod -m 666 /dev/null c 1 3 | ||
85 | create_char_dev("/dev/full", 0666, 1, 7); // mknod -m 666 /dev/full c 1 7 | ||
86 | create_char_dev("/dev/random", 0666, 1, 8); // Mknod -m 666 /dev/random c 1 8 | ||
87 | create_char_dev("/dev/urandom", 0666, 1, 9); // mknod -m 666 /dev/urandom c 1 9 | ||
88 | create_char_dev("/dev/tty", 0666, 5, 0); // mknod -m 666 /dev/tty c 5 0 | ||
89 | #if 0 | ||
90 | create_dev("/dev/tty0", "mknod -m 666 /dev/tty0 c 4 0"); | ||
91 | create_dev("/dev/console", "mknod -m 622 /dev/console c 5 1"); | ||
92 | #endif | ||
93 | |||
94 | // pseudo-terminal | ||
95 | rv = mkdir("/dev/pts", 0755); | ||
96 | if (rv == -1) | ||
97 | errExit("mkdir"); | ||
98 | if (chown("/dev/pts", 0, 0) < 0) | ||
99 | errExit("chown"); | ||
100 | if (chmod("/dev/pts", 0755) < 0) | ||
101 | errExit("chmod"); | ||
102 | create_char_dev("/dev/pts/ptmx", 0666, 5, 2); //"mknod -m 666 /dev/pts/ptmx c 5 2"); | ||
103 | create_link("/dev/pts/ptmx", "/dev/ptmx"); | ||
104 | // mount -vt devpts -o newinstance -o ptmxmode=0666 devpts //dev/pts | ||
105 | if (mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL, "newinstance,ptmxmode=0666") < 0) | ||
106 | errExit("mounting /dev/pts"); | ||
107 | |||
108 | #if 0 | ||
109 | // stdin, stdout, stderr | ||
110 | create_link("/proc/self/fd", "/dev/fd"); | ||
111 | create_link("/proc/self/fd/0", "/dev/stdin"); | ||
112 | create_link("/proc/self/fd/1", "/dev/stdout"); | ||
113 | create_link("/proc/self/fd/2", "/dev/stderr"); | ||
114 | #endif | ||
115 | } | ||
116 | |||
117 | |||
118 | void fs_dev_shm(void) { | ||
119 | uid_t uid = getuid(); // set a new shm only if we started as root | ||
120 | if (uid) | ||
121 | return; | ||
122 | |||
123 | if (is_dir("/dev/shm")) { | ||
124 | if (arg_debug) | ||
125 | printf("Mounting tmpfs on /dev/shm\n"); | ||
126 | if (mount("tmpfs", "/dev/shm", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | ||
127 | errExit("mounting /dev/shm"); | ||
128 | } | ||
129 | else { | ||
130 | char *lnk = get_link("/dev/shm"); | ||
131 | if (lnk) { | ||
132 | // convert a link such as "../shm" into "/shm" | ||
133 | char *lnk2 = lnk; | ||
134 | int cnt = 0; | ||
135 | while (strncmp(lnk2, "../", 3) == 0) { | ||
136 | cnt++; | ||
137 | lnk2 = lnk2 + 3; | ||
138 | } | ||
139 | if (cnt != 0) | ||
140 | lnk2 = lnk + (cnt - 1) * 3 + 2; | ||
141 | |||
142 | if (!is_dir(lnk2)) { | ||
143 | // create directory | ||
144 | if (mkdir(lnk2, S_IRWXU|S_IRWXG|S_IRWXO)) | ||
145 | errExit("mkdir"); | ||
146 | if (chown(lnk2, 0, 0)) | ||
147 | errExit("chown"); | ||
148 | if (chmod(lnk2, S_IRWXU|S_IRWXG|S_IRWXO)) | ||
149 | errExit("chmod"); | ||
150 | } | ||
151 | if (arg_debug) | ||
152 | printf("Mounting tmpfs on %s on behalf of /dev/shm\n", lnk2); | ||
153 | if (mount("tmpfs", lnk2, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | ||
154 | errExit("mounting /var/tmp"); | ||
155 | free(lnk); | ||
156 | } | ||
157 | else { | ||
158 | fprintf(stderr, "Warning: /dev/shm not mounted\n"); | ||
159 | dbg_test_dir("/dev/shm"); | ||
160 | } | ||
161 | |||
162 | } | ||
163 | } | ||
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c new file mode 100644 index 000000000..853e3930b --- /dev/null +++ b/src/firejail/fs_home.c | |||
@@ -0,0 +1,494 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/mount.h> | ||
22 | #include <linux/limits.h> | ||
23 | #include <glob.h> | ||
24 | #include <dirent.h> | ||
25 | #include <fcntl.h> | ||
26 | #include <sys/stat.h> | ||
27 | #include <sys/types.h> | ||
28 | #include <sys/wait.h> | ||
29 | #include <unistd.h> | ||
30 | #include <grp.h> | ||
31 | |||
32 | static void skel(const char *homedir, uid_t u, gid_t g) { | ||
33 | char *fname; | ||
34 | // zsh | ||
35 | if (arg_zsh) { | ||
36 | // copy skel files | ||
37 | if (asprintf(&fname, "%s/.zshrc", homedir) == -1) | ||
38 | errExit("asprintf"); | ||
39 | struct stat s; | ||
40 | // don't copy it if we already have the file | ||
41 | if (stat(fname, &s) == 0) | ||
42 | return; | ||
43 | if (stat("/etc/skel/.zshrc", &s) == 0) { | ||
44 | if (copy_file("/etc/skel/.zshrc", fname) == 0) { | ||
45 | if (chown(fname, u, g) == -1) | ||
46 | errExit("chown"); | ||
47 | } | ||
48 | } | ||
49 | else { // | ||
50 | FILE *fp = fopen(fname, "w"); | ||
51 | if (fp) { | ||
52 | fprintf(fp, "\n"); | ||
53 | 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 | } | ||
59 | } | ||
60 | free(fname); | ||
61 | } | ||
62 | // csh | ||
63 | else if (arg_csh) { | ||
64 | // copy skel files | ||
65 | if (asprintf(&fname, "%s/.cshrc", homedir) == -1) | ||
66 | errExit("asprintf"); | ||
67 | struct stat s; | ||
68 | // don't copy it if we already have the file | ||
69 | if (stat(fname, &s) == 0) | ||
70 | return; | ||
71 | if (stat("/etc/skel/.cshrc", &s) == 0) { | ||
72 | if (copy_file("/etc/skel/.cshrc", fname) == 0) { | ||
73 | if (chown(fname, u, g) == -1) | ||
74 | errExit("chown"); | ||
75 | } | ||
76 | } | ||
77 | else { // | ||
78 | /* coverity[toctou] */ | ||
79 | FILE *fp = fopen(fname, "w"); | ||
80 | if (fp) { | ||
81 | fprintf(fp, "\n"); | ||
82 | fclose(fp); | ||
83 | if (chown(fname, u, g) == -1) | ||
84 | errExit("chown"); | ||
85 | if (chmod(fname, S_IRUSR | S_IWUSR) < 0) | ||
86 | errExit("chown"); | ||
87 | } | ||
88 | } | ||
89 | free(fname); | ||
90 | } | ||
91 | // bash etc. | ||
92 | else { | ||
93 | // copy skel files | ||
94 | if (asprintf(&fname, "%s/.bashrc", homedir) == -1) | ||
95 | errExit("asprintf"); | ||
96 | struct stat s; | ||
97 | // don't copy it if we already have the file | ||
98 | if (stat(fname, &s) == 0) | ||
99 | return; | ||
100 | if (stat("/etc/skel/.bashrc", &s) == 0) { | ||
101 | if (copy_file("/etc/skel/.bashrc", fname) == 0) { | ||
102 | /* coverity[toctou] */ | ||
103 | if (chown(fname, u, g) == -1) | ||
104 | errExit("chown"); | ||
105 | } | ||
106 | } | ||
107 | free(fname); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | static int store_xauthority(void) { | ||
112 | // put a copy of .Xauthority in MNT_DIR | ||
113 | fs_build_mnt_dir(); | ||
114 | |||
115 | char *src; | ||
116 | char *dest; | ||
117 | if (asprintf(&src, "%s/.Xauthority", cfg.homedir) == -1) | ||
118 | errExit("asprintf"); | ||
119 | if (asprintf(&dest, "%s/.Xauthority", MNT_DIR) == -1) | ||
120 | errExit("asprintf"); | ||
121 | |||
122 | struct stat s; | ||
123 | if (stat(src, &s) == 0) { | ||
124 | int rv = copy_file(src, dest); | ||
125 | if (rv) { | ||
126 | fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); | ||
127 | return 0; | ||
128 | } | ||
129 | return 1; // file copied | ||
130 | } | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static void copy_xauthority(void) { | ||
136 | // put a copy of .Xauthority in MNT_DIR | ||
137 | fs_build_mnt_dir(); | ||
138 | |||
139 | char *src; | ||
140 | char *dest; | ||
141 | if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) | ||
142 | errExit("asprintf"); | ||
143 | if (asprintf(&src, "%s/.Xauthority", MNT_DIR) == -1) | ||
144 | errExit("asprintf"); | ||
145 | int rv = copy_file(src, dest); | ||
146 | if (rv) | ||
147 | fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); | ||
148 | |||
149 | // set permissions and ownership | ||
150 | if (chown(dest, getuid(), getgid()) < 0) | ||
151 | errExit("chown"); | ||
152 | if (chmod(dest, S_IRUSR | S_IWUSR) < 0) | ||
153 | errExit("chmod"); | ||
154 | |||
155 | // delete the temporary file | ||
156 | unlink(src); | ||
157 | } | ||
158 | |||
159 | // private mode (--private=homedir): | ||
160 | // mount homedir on top of /home/user, | ||
161 | // tmpfs on top of /root in nonroot mode, | ||
162 | // tmpfs on top of /tmp in root mode, | ||
163 | // set skel files, | ||
164 | // restore .Xauthority | ||
165 | void fs_private_homedir(void) { | ||
166 | char *homedir = cfg.homedir; | ||
167 | char *private_homedir = cfg.home_private; | ||
168 | assert(homedir); | ||
169 | assert(private_homedir); | ||
170 | |||
171 | int xflag = store_xauthority(); | ||
172 | |||
173 | uid_t u = getuid(); | ||
174 | gid_t g = getgid(); | ||
175 | struct stat s; | ||
176 | if (stat(homedir, &s) == -1) { | ||
177 | fprintf(stderr, "Error: cannot find user home directory\n"); | ||
178 | exit(1); | ||
179 | } | ||
180 | |||
181 | |||
182 | // mount bind private_homedir on top of homedir | ||
183 | if (arg_debug) | ||
184 | printf("Mount-bind %s on top of %s\n", private_homedir, homedir); | ||
185 | if (mount(private_homedir, homedir, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
186 | errExit("mount bind"); | ||
187 | // preserve mode and ownership | ||
188 | // if (chown(homedir, s.st_uid, s.st_gid) == -1) | ||
189 | // errExit("mount-bind chown"); | ||
190 | // if (chmod(homedir, s.st_mode) == -1) | ||
191 | // errExit("mount-bind chmod"); | ||
192 | |||
193 | if (u != 0) { | ||
194 | // mask /root | ||
195 | if (arg_debug) | ||
196 | printf("Mounting a new /root directory\n"); | ||
197 | if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0) | ||
198 | errExit("mounting home directory"); | ||
199 | } | ||
200 | else { | ||
201 | // mask /home | ||
202 | if (arg_debug) | ||
203 | printf("Mounting a new /home directory\n"); | ||
204 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
205 | errExit("mounting home directory"); | ||
206 | |||
207 | // mask /tmp only in root mode; KDE keeps all kind of sockets in /tmp! | ||
208 | if (arg_debug) | ||
209 | printf("Mounting a new /tmp directory\n"); | ||
210 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | ||
211 | errExit("mounting tmp directory"); | ||
212 | } | ||
213 | |||
214 | |||
215 | skel(homedir, u, g); | ||
216 | if (xflag) | ||
217 | copy_xauthority(); | ||
218 | } | ||
219 | |||
220 | // private mode (--private): | ||
221 | // mount tmpfs over /home/user, | ||
222 | // tmpfs on top of /root in nonroot mode, | ||
223 | // tmpfs on top of /tmp in root mode | ||
224 | // set skel files, | ||
225 | // restore .Xauthority | ||
226 | void fs_private(void) { | ||
227 | char *homedir = cfg.homedir; | ||
228 | assert(homedir); | ||
229 | uid_t u = getuid(); | ||
230 | gid_t g = getgid(); | ||
231 | |||
232 | int xflag = store_xauthority(); | ||
233 | |||
234 | // mask /home | ||
235 | if (arg_debug) | ||
236 | printf("Mounting a new /home directory\n"); | ||
237 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
238 | errExit("mounting home directory"); | ||
239 | |||
240 | // mask /root | ||
241 | if (arg_debug) | ||
242 | printf("Mounting a new /root directory\n"); | ||
243 | if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0) | ||
244 | errExit("mounting home directory"); | ||
245 | |||
246 | if (u != 0) { | ||
247 | // create /home/user | ||
248 | if (arg_debug) | ||
249 | printf("Create a new user directory\n"); | ||
250 | int rv = mkdir(homedir, S_IRWXU); | ||
251 | if (rv == -1) | ||
252 | errExit("mkdir"); | ||
253 | if (chown(homedir, u, g) < 0) | ||
254 | errExit("chown"); | ||
255 | } | ||
256 | else { | ||
257 | // mask tmp only in root mode; KDE keeps all kind of sockets in /tmp! | ||
258 | if (arg_debug) | ||
259 | printf("Mounting a new /tmp directory\n"); | ||
260 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | ||
261 | errExit("mounting tmp directory"); | ||
262 | } | ||
263 | |||
264 | skel(homedir, u, g); | ||
265 | if (xflag) | ||
266 | copy_xauthority(); | ||
267 | } | ||
268 | |||
269 | static void check_dir_or_file(const char *name) { | ||
270 | assert(name); | ||
271 | struct stat s; | ||
272 | char *fname; | ||
273 | if (asprintf(&fname, "%s/%s", cfg.homedir, name) == -1) | ||
274 | errExit("asprintf"); | ||
275 | if (arg_debug) | ||
276 | printf("***************Checking %s\n", fname); | ||
277 | if (stat(fname, &s) == -1) { | ||
278 | fprintf(stderr, "Error: file %s not found.\n", fname); | ||
279 | exit(1); | ||
280 | } | ||
281 | |||
282 | // check uid | ||
283 | uid_t uid = getuid(); | ||
284 | gid_t gid = getgid(); | ||
285 | if (s.st_uid != uid || s.st_gid != gid) { | ||
286 | fprintf(stderr, "Error: only files or directories created by the current user are allowed.\n"); | ||
287 | exit(1); | ||
288 | } | ||
289 | |||
290 | // dir or regular file | ||
291 | if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { | ||
292 | free(fname); | ||
293 | return; | ||
294 | } | ||
295 | |||
296 | if (!is_link(fname)) { | ||
297 | free(fname); | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | fprintf(stderr, "Error: invalid file type, %s.\n", fname); | ||
302 | exit(1); | ||
303 | } | ||
304 | |||
305 | // check directory linst specified by user (--private.keep option) - exit if it fails | ||
306 | void fs_check_home_list(void) { | ||
307 | if (strstr(cfg.home_private_keep, "..")) { | ||
308 | fprintf(stderr, "Error: invalid private.keep list\n"); | ||
309 | exit(1); | ||
310 | } | ||
311 | |||
312 | char *dlist = strdup(cfg.home_private_keep); | ||
313 | if (!dlist) | ||
314 | errExit("strdup"); | ||
315 | |||
316 | char *ptr = strtok(dlist, ","); | ||
317 | check_dir_or_file(ptr); | ||
318 | while ((ptr = strtok(NULL, ",")) != NULL) | ||
319 | check_dir_or_file(ptr); | ||
320 | |||
321 | free(dlist); | ||
322 | } | ||
323 | |||
324 | // check new private home directory (--private= option) - exit if it fails | ||
325 | void fs_check_private_dir(void) { | ||
326 | // if the directory starts with ~, expand the home directory | ||
327 | if (*cfg.home_private == '~') { | ||
328 | char *tmp; | ||
329 | if (asprintf(&tmp, "%s%s", cfg.homedir, cfg.home_private + 1) == -1) | ||
330 | errExit("asprintf"); | ||
331 | cfg.home_private = tmp; | ||
332 | } | ||
333 | |||
334 | if (!is_dir(cfg.home_private) || is_link(cfg.home_private) || strstr(cfg.home_private, "..")) { | ||
335 | fprintf(stderr, "Error: invalid private directory\n"); | ||
336 | exit(1); | ||
337 | } | ||
338 | |||
339 | // check home directory and chroot home directory have the same owner | ||
340 | struct stat s2; | ||
341 | int rv = stat(cfg.home_private, &s2); | ||
342 | if (rv < 0) { | ||
343 | fprintf(stderr, "Error: cannot find %s directory\n", cfg.home_private); | ||
344 | exit(1); | ||
345 | } | ||
346 | |||
347 | struct stat s1; | ||
348 | rv = stat(cfg.homedir, &s1); | ||
349 | if (rv < 0) { | ||
350 | fprintf(stderr, "Error: cannot find %s directory, full path name required\n", cfg.homedir); | ||
351 | exit(1); | ||
352 | } | ||
353 | if (s1.st_uid != s2.st_uid) { | ||
354 | printf("Error: the two home directories must have the same owner\n"); | ||
355 | exit(1); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | #if 0 | ||
360 | static int mkpath(char* file_path, mode_t mode) { | ||
361 | assert(file_path && *file_path); | ||
362 | char* p; | ||
363 | for (p=strchr(file_path+1, '/'); p; p=strchr(p+1, '/')) { | ||
364 | *p='\0'; | ||
365 | if (mkdir(file_path, mode)==-1) { | ||
366 | if (errno!=EEXIST) { *p='/'; return -1; } | ||
367 | } | ||
368 | *p='/'; | ||
369 | } | ||
370 | return 0; | ||
371 | } | ||
372 | #endif | ||
373 | |||
374 | static void duplicate(char *fname) { | ||
375 | char *cmd; | ||
376 | |||
377 | // copy the file | ||
378 | if (asprintf(&cmd, "cp -a --parents %s/%s %s", cfg.homedir, fname, HOME_DIR) == -1) | ||
379 | errExit("asprintf"); | ||
380 | if (arg_debug) | ||
381 | printf("%s\n", cmd); | ||
382 | if (system(cmd)) | ||
383 | errExit("system cp -a --parents"); | ||
384 | free(cmd); | ||
385 | } | ||
386 | |||
387 | |||
388 | // private mode (--private.keep=list): | ||
389 | // mount homedir on top of /home/user, | ||
390 | // tmpfs on top of /root in nonroot mode, | ||
391 | // tmpfs on top of /tmp in root mode, | ||
392 | // set skel files, | ||
393 | // restore .Xauthority | ||
394 | void fs_private_home_list(void) { | ||
395 | char *homedir = cfg.homedir; | ||
396 | char *private_list = cfg.home_private_keep; | ||
397 | assert(homedir); | ||
398 | assert(private_list); | ||
399 | |||
400 | int xflag = store_xauthority(); | ||
401 | |||
402 | uid_t u = getuid(); | ||
403 | gid_t g = getgid(); | ||
404 | struct stat s; | ||
405 | if (stat(homedir, &s) == -1) { | ||
406 | fprintf(stderr, "Error: cannot find user home directory\n"); | ||
407 | exit(1); | ||
408 | } | ||
409 | |||
410 | // create /tmp/firejail/mnt/home directory | ||
411 | fs_build_mnt_dir(); | ||
412 | int rv = mkdir(HOME_DIR, S_IRWXU | S_IRWXG | S_IRWXO); | ||
413 | if (rv == -1) | ||
414 | errExit("mkdir"); | ||
415 | if (chown(HOME_DIR, u, g) < 0) | ||
416 | errExit("chown"); | ||
417 | if (chmod(HOME_DIR, 0755) < 0) | ||
418 | errExit("chmod"); | ||
419 | |||
420 | // copy the list of files in the new home directory | ||
421 | // using a new child process without root privileges | ||
422 | pid_t child = fork(); | ||
423 | if (child < 0) | ||
424 | errExit("fork"); | ||
425 | if (child == 0) { | ||
426 | if (arg_debug) | ||
427 | printf("Copying files in the new home:\n"); | ||
428 | |||
429 | // drop privileges | ||
430 | if (setgroups(0, NULL) < 0) | ||
431 | errExit("setgroups"); | ||
432 | if (setgid(getgid()) < 0) | ||
433 | errExit("setgid/getgid"); | ||
434 | if (setuid(getuid()) < 0) | ||
435 | errExit("setuid/getuid"); | ||
436 | |||
437 | // copy the list of files in the new home directory | ||
438 | char *dlist = strdup(cfg.home_private_keep); | ||
439 | if (!dlist) | ||
440 | errExit("strdup"); | ||
441 | |||
442 | char *ptr = strtok(dlist, ","); | ||
443 | duplicate(ptr); | ||
444 | |||
445 | while ((ptr = strtok(NULL, ",")) != NULL) | ||
446 | duplicate(ptr); | ||
447 | free(dlist); | ||
448 | exit(0); | ||
449 | } | ||
450 | // wait for the child to finish | ||
451 | waitpid(child, NULL, 0); | ||
452 | |||
453 | // mount bind private_homedir on top of homedir | ||
454 | char *newhome; | ||
455 | if (asprintf(&newhome, "%s%s", HOME_DIR, cfg.homedir) == -1) | ||
456 | errExit("asprintf"); | ||
457 | |||
458 | if (arg_debug) | ||
459 | printf("Mount-bind %s on top of %s\n", newhome, homedir); | ||
460 | if (mount(newhome, homedir, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
461 | errExit("mount bind"); | ||
462 | // preserve mode and ownership | ||
463 | // if (chown(homedir, s.st_uid, s.st_gid) == -1) | ||
464 | // errExit("mount-bind chown"); | ||
465 | // if (chmod(homedir, s.st_mode) == -1) | ||
466 | // errExit("mount-bind chmod"); | ||
467 | |||
468 | if (u != 0) { | ||
469 | // mask /root | ||
470 | if (arg_debug) | ||
471 | printf("Mounting a new /root directory\n"); | ||
472 | if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0) | ||
473 | errExit("mounting home directory"); | ||
474 | } | ||
475 | else { | ||
476 | // mask /home | ||
477 | if (arg_debug) | ||
478 | printf("Mounting a new /home directory\n"); | ||
479 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
480 | errExit("mounting home directory"); | ||
481 | |||
482 | // mask /tmp only in root mode; KDE keeps all kind of sockets in /tmp! | ||
483 | if (arg_debug) | ||
484 | printf("Mounting a new /tmp directory\n"); | ||
485 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | ||
486 | errExit("mounting tmp directory"); | ||
487 | } | ||
488 | |||
489 | skel(homedir, u, g); | ||
490 | if (xflag) | ||
491 | copy_xauthority(); | ||
492 | |||
493 | } | ||
494 | |||
diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c new file mode 100644 index 000000000..fb3fc530e --- /dev/null +++ b/src/firejail/fs_hostname.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/mount.h> | ||
22 | #include <sys/stat.h> | ||
23 | #include <linux/limits.h> | ||
24 | #include <glob.h> | ||
25 | #include <dirent.h> | ||
26 | #include <fcntl.h> | ||
27 | |||
28 | void fs_hostname(const char *hostname) { | ||
29 | struct stat s; | ||
30 | fs_build_mnt_dir(); | ||
31 | |||
32 | // create a new /etc/hostname | ||
33 | if (stat("/etc/hostname", &s) == 0) { | ||
34 | if (arg_debug) | ||
35 | printf("Creating a new /etc/hostname file\n"); | ||
36 | char *fhost; | ||
37 | if (asprintf(&fhost, "%s/hostname", MNT_DIR) == -1) | ||
38 | errExit("asprintf"); | ||
39 | FILE *fp = fopen(fhost, "w"); | ||
40 | if (!fp) { | ||
41 | fprintf(stderr, "Error: cannot create %s\n", fhost); | ||
42 | free(fhost); | ||
43 | exit(1); | ||
44 | } | ||
45 | fprintf(fp, "%s\n", hostname); | ||
46 | fclose(fp); | ||
47 | |||
48 | // mode and owner | ||
49 | if (chown(fhost, 0, 0) < 0) | ||
50 | errExit("chown"); | ||
51 | if (chmod(fhost, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) | ||
52 | errExit("chmod"); | ||
53 | |||
54 | // bind-mount the file on top of /etc/hostname | ||
55 | if (mount(fhost, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0) | ||
56 | errExit("mount bind /etc/hostname"); | ||
57 | free(fhost); | ||
58 | } | ||
59 | |||
60 | // create a new /etc/hosts | ||
61 | if (stat("/etc/hosts", &s) == 0) { | ||
62 | if (arg_debug) | ||
63 | printf("Creating a new /etc/hosts file\n"); | ||
64 | char *fhost; | ||
65 | if (asprintf(&fhost, "%s/hosts", MNT_DIR) == -1) | ||
66 | errExit("asprintf"); | ||
67 | // copy /etc/host into our new file, and modify it on the fly | ||
68 | /* coverity[toctou] */ | ||
69 | FILE *fp1 = fopen("/etc/hosts", "r"); | ||
70 | if (!fp1) { | ||
71 | fprintf(stderr, "Error: cannot open /etc/hosts\n"); | ||
72 | free(fhost); | ||
73 | exit(1); | ||
74 | } | ||
75 | FILE *fp2 = fopen(fhost, "w"); | ||
76 | if (!fp2) { | ||
77 | fprintf(stderr, "Error: cannot create %s\n", fhost); | ||
78 | free(fhost); | ||
79 | exit(1); | ||
80 | } | ||
81 | |||
82 | char buf[4096]; | ||
83 | while (fgets(buf, sizeof(buf), fp1)) { | ||
84 | // remove '\n' | ||
85 | char *ptr = strchr(buf, '\n'); | ||
86 | if (ptr) | ||
87 | *ptr = '\0'; | ||
88 | |||
89 | // copy line | ||
90 | if (strstr(buf, "127.0.0.1")) | ||
91 | fprintf(fp2, "%s %s\n", buf, hostname); | ||
92 | else | ||
93 | fprintf(fp2, "%s\n", buf); | ||
94 | } | ||
95 | fclose(fp1); | ||
96 | fclose(fp2); | ||
97 | |||
98 | // mode and owner | ||
99 | if (chown(fhost, 0, 0) < 0) | ||
100 | errExit("chown"); | ||
101 | if (chmod(fhost, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) | ||
102 | errExit("chmod"); | ||
103 | |||
104 | // bind-mount the file on top of /etc/hostname | ||
105 | if (mount(fhost, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0) | ||
106 | errExit("mount bind /etc/hosts"); | ||
107 | free(fhost); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | void fs_resolvconf(void) { | ||
112 | if (cfg.dns1 == 0) | ||
113 | return; | ||
114 | |||
115 | struct stat s; | ||
116 | fs_build_mnt_dir(); | ||
117 | |||
118 | // create a new /etc/hostname | ||
119 | if (stat("/etc/resolv.conf", &s) == 0) { | ||
120 | if (arg_debug) | ||
121 | printf("Creating a new /etc/resolv.conf file\n"); | ||
122 | char *fname; | ||
123 | if (asprintf(&fname, "%s/resolv.conf", MNT_DIR) == -1) | ||
124 | errExit("asprintf"); | ||
125 | FILE *fp = fopen(fname, "w"); | ||
126 | if (!fp) { | ||
127 | fprintf(stderr, "Error: cannot create %s\n", fname); | ||
128 | free(fname); | ||
129 | exit(1); | ||
130 | } | ||
131 | |||
132 | if (cfg.dns1) | ||
133 | fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns1)); | ||
134 | if (cfg.dns2) | ||
135 | fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns2)); | ||
136 | if (cfg.dns3) | ||
137 | fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns3)); | ||
138 | fclose(fp); | ||
139 | |||
140 | // mode and owner | ||
141 | if (chown(fname, 0, 0) < 0) | ||
142 | errExit("chown"); | ||
143 | if (chmod(fname, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) | ||
144 | errExit("chmod"); | ||
145 | |||
146 | // bind-mount the file on top of /etc/hostname | ||
147 | if (mount(fname, "/etc/resolv.conf", NULL, MS_BIND|MS_REC, NULL) < 0) | ||
148 | errExit("mount bind /etc/resolv.conf"); | ||
149 | free(fname); | ||
150 | } | ||
151 | else { | ||
152 | fprintf(stderr, "Error: cannot set DNS servers, /etc/resolv.conf file is missing\n"); | ||
153 | exit(1); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | |||
diff --git a/src/firejail/fs_trace.c b/src/firejail/fs_trace.c new file mode 100644 index 000000000..1c7ef5cbe --- /dev/null +++ b/src/firejail/fs_trace.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/mount.h> | ||
22 | #include <sys/stat.h> | ||
23 | #include <linux/limits.h> | ||
24 | #include <glob.h> | ||
25 | #include <dirent.h> | ||
26 | #include <fcntl.h> | ||
27 | #include <pwd.h> | ||
28 | |||
29 | void fs_trace_preload(void) { | ||
30 | struct stat s; | ||
31 | |||
32 | // create an empty /etc/ld.so.preload | ||
33 | if (stat("/etc/ld.so.preload", &s)) { | ||
34 | if (arg_debug) | ||
35 | printf("Creating an empty /etc/ld.so.preload file\n"); | ||
36 | /* coverity[toctou] */ | ||
37 | FILE *fp = fopen("/etc/ld.so.preload", "w"); | ||
38 | if (!fp) | ||
39 | errExit("fopen"); | ||
40 | fclose(fp); | ||
41 | if (chown("/etc/ld.so.preload", 0, 0) < 0) | ||
42 | errExit("chown"); | ||
43 | if (chmod("/etc/ld.so.preload", S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) | ||
44 | errExit("chmod"); | ||
45 | } | ||
46 | } | ||
47 | |||
48 | void fs_trace(void) { | ||
49 | // create /tmp/firejail/mnt directory | ||
50 | fs_build_mnt_dir(); | ||
51 | |||
52 | // create the new ld.so.preload file and mount-bind it | ||
53 | if (arg_debug) | ||
54 | printf("Create the new ld.so.preload file\n"); | ||
55 | char *preload; | ||
56 | if (asprintf(&preload, "%s/ld.so.preload", MNT_DIR) == -1) | ||
57 | errExit("asprintf"); | ||
58 | FILE *fp = fopen(preload, "w"); | ||
59 | if (!fp) | ||
60 | errExit("fopen"); | ||
61 | fprintf(fp, "%s/lib/firejail/libtrace.so\n", PREFIX); | ||
62 | fclose(fp); | ||
63 | if (chown(preload, 0, 0) < 0) | ||
64 | errExit("chown"); | ||
65 | if (chmod(preload, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) | ||
66 | errExit("chmod"); | ||
67 | |||
68 | // mount the new preload file | ||
69 | if (arg_debug) | ||
70 | printf("Mount the new ld.so.preload file\n"); | ||
71 | if (mount(preload, "/etc/ld.so.preload", NULL, MS_BIND|MS_REC, NULL) < 0) | ||
72 | errExit("mount bind ls.so.preload"); | ||
73 | } | ||
74 | |||
75 | |||
76 | \ No newline at end of file | ||
diff --git a/src/firejail/fs_var.c b/src/firejail/fs_var.c new file mode 100644 index 000000000..ee0f81828 --- /dev/null +++ b/src/firejail/fs_var.c | |||
@@ -0,0 +1,388 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/mount.h> | ||
22 | #include <sys/stat.h> | ||
23 | #include <linux/limits.h> | ||
24 | #include <glob.h> | ||
25 | #include <dirent.h> | ||
26 | #include <fcntl.h> | ||
27 | #include <pwd.h> | ||
28 | #include <utmp.h> | ||
29 | #include <time.h> | ||
30 | |||
31 | typedef struct dirdata_t{ | ||
32 | struct dirdata_t *next; | ||
33 | char *name; | ||
34 | mode_t st_mode; | ||
35 | uid_t st_uid; | ||
36 | gid_t st_gid; | ||
37 | } DirData; | ||
38 | |||
39 | static DirData *dirlist = NULL; | ||
40 | |||
41 | static void release_all(void) { | ||
42 | DirData *ptr = dirlist; | ||
43 | while (ptr) { | ||
44 | DirData *next = ptr->next; | ||
45 | free(ptr->name); | ||
46 | free(ptr); | ||
47 | ptr = next; | ||
48 | } | ||
49 | dirlist = NULL; | ||
50 | } | ||
51 | |||
52 | static void build_list(const char *srcdir) { | ||
53 | // extract current /var/log directory data | ||
54 | struct dirent *dir; | ||
55 | DIR *d = opendir(srcdir); | ||
56 | if (d == NULL) | ||
57 | return; | ||
58 | |||
59 | while ((dir = readdir(d))) { | ||
60 | if(strcmp(dir->d_name, "." ) == 0 || strcmp(dir->d_name, ".." ) == 0) | ||
61 | continue; | ||
62 | |||
63 | if (dir->d_type == DT_DIR ) { | ||
64 | // get properties | ||
65 | struct stat s; | ||
66 | char *name; | ||
67 | if (asprintf(&name, "%s/%s", srcdir, dir->d_name) == -1) | ||
68 | continue; | ||
69 | if (stat(name, &s) == -1) | ||
70 | continue; | ||
71 | if (S_ISLNK(s.st_mode)) { | ||
72 | free(name); | ||
73 | continue; | ||
74 | } | ||
75 | |||
76 | // printf("directory %u %u:%u %s\n", | ||
77 | // s.st_mode, | ||
78 | // s.st_uid, | ||
79 | // s.st_gid, | ||
80 | // dir->d_name); | ||
81 | |||
82 | DirData *ptr = malloc(sizeof(DirData)); | ||
83 | if (ptr == NULL) | ||
84 | errExit("malloc"); | ||
85 | memset(ptr, 0, sizeof(DirData)); | ||
86 | ptr->name = name; | ||
87 | ptr->st_mode = s.st_mode; | ||
88 | ptr->st_uid = s.st_uid; | ||
89 | ptr->st_gid = s.st_gid; | ||
90 | ptr->next = dirlist; | ||
91 | dirlist = ptr; | ||
92 | } | ||
93 | } | ||
94 | closedir(d); | ||
95 | } | ||
96 | |||
97 | static void build_dirs(void) { | ||
98 | // create directories under /var/log | ||
99 | DirData *ptr = dirlist; | ||
100 | while (ptr) { | ||
101 | if (mkdir(ptr->name, ptr->st_mode)) | ||
102 | errExit("mkdir"); | ||
103 | if (chown(ptr->name, ptr->st_uid, ptr->st_gid)) | ||
104 | errExit("chown"); | ||
105 | ptr = ptr->next; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | void fs_var_log(void) { | ||
110 | build_list("/var/log"); | ||
111 | |||
112 | // create /var/log if it does't exit | ||
113 | if (is_dir("/var/log")) { | ||
114 | // extract group id for /var/log/wtmp | ||
115 | struct stat s; | ||
116 | gid_t wtmp_group = 0; | ||
117 | if (stat("/var/log/wtmp", &s) == 0) | ||
118 | wtmp_group = s.st_gid; | ||
119 | |||
120 | // mount a tmpfs on top of /var/log | ||
121 | if (arg_debug) | ||
122 | printf("Mounting tmpfs on /var/log\n"); | ||
123 | if (mount("tmpfs", "/var/log", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
124 | errExit("mounting /var/log"); | ||
125 | |||
126 | build_dirs(); | ||
127 | release_all(); | ||
128 | |||
129 | // create an empty /var/log/wtmp file | ||
130 | /* coverity[toctou] */ | ||
131 | FILE *fp = fopen("/var/log/wtmp", "w"); | ||
132 | if (fp) | ||
133 | fclose(fp); | ||
134 | if (chown("/var/log/wtmp", 0, wtmp_group) < 0) | ||
135 | errExit("chown"); | ||
136 | if (chmod("/var/log/wtmp", S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH ) < 0) | ||
137 | errExit("chmod"); | ||
138 | |||
139 | // create an empty /var/log/btmp file | ||
140 | fp = fopen("/var/log/btmp", "w"); | ||
141 | if (fp) | ||
142 | fclose(fp); | ||
143 | if (chown("/var/log/btmp", 0, wtmp_group) < 0) | ||
144 | errExit("chown"); | ||
145 | if (chmod("/var/log/btmp", S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP) < 0) | ||
146 | errExit("chmod"); | ||
147 | } | ||
148 | else | ||
149 | fprintf(stderr, "Warning: cannot mount tmpfs in top of /var/log\n"); | ||
150 | } | ||
151 | |||
152 | void fs_var_lib(void) { | ||
153 | struct stat s; | ||
154 | |||
155 | // ISC DHCP multiserver | ||
156 | if (stat("/var/lib/dhcp", &s) == 0) { | ||
157 | if (arg_debug) | ||
158 | printf("Mounting tmpfs on /var/lib/dhcp\n"); | ||
159 | if (mount("tmpfs", "/var/lib/dhcp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
160 | errExit("mounting /var/lib/dhcp"); | ||
161 | |||
162 | // isc dhcp server requires a /var/lib/dhcp/dhcpd.leases file | ||
163 | FILE *fp = fopen("/var/lib/dhcp/dhcpd.leases", "w"); | ||
164 | |||
165 | if (fp) { | ||
166 | fprintf(fp, "\n"); | ||
167 | fclose(fp); | ||
168 | if (chown("/var/lib/dhcp/dhcpd.leases", 0, 0) == -1) | ||
169 | errExit("chown"); | ||
170 | if (chmod("/var/lib/dhcp/dhcpd.leases", S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) | ||
171 | errExit("chmod"); | ||
172 | } | ||
173 | } | ||
174 | |||
175 | // nginx multiserver | ||
176 | if (stat("/var/lib/nginx", &s) == 0) { | ||
177 | if (arg_debug) | ||
178 | printf("Mounting tmpfs on /var/lib/nginx\n"); | ||
179 | if (mount("tmpfs", "/var/lib/nginx", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
180 | errExit("mounting /var/lib/nginx"); | ||
181 | } | ||
182 | |||
183 | // net-snmp multiserver | ||
184 | if (stat("/var/lib/snmp", &s) == 0) { | ||
185 | if (arg_debug) | ||
186 | printf("Mounting tmpfs on /var/lib/snmp\n"); | ||
187 | if (mount("tmpfs", "/var/lib/snmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
188 | errExit("mounting /var/lib/snmp"); | ||
189 | } | ||
190 | |||
191 | // this is where sudo remembers its state | ||
192 | if (stat("/var/lib/sudo", &s) == 0) { | ||
193 | if (arg_debug) | ||
194 | printf("Mounting tmpfs on /var/lib/sudo\n"); | ||
195 | if (mount("tmpfs", "/var/lib/sudo", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
196 | errExit("mounting /var/lib/sudo"); | ||
197 | } | ||
198 | } | ||
199 | |||
200 | void fs_var_cache(void) { | ||
201 | struct stat s; | ||
202 | |||
203 | if (stat("/var/cache/apache2", &s) == 0) { | ||
204 | if (arg_debug) | ||
205 | printf("Mounting tmpfs on /var/cache/apache2\n"); | ||
206 | if (mount("tmpfs", "/var/cache/apache2", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
207 | errExit("mounting /var/cahce/apache2"); | ||
208 | } | ||
209 | |||
210 | if (stat("/var/cache/lighttpd", &s) == 0) { | ||
211 | if (arg_debug) | ||
212 | printf("Mounting tmpfs on /var/cache/lighttpd\n"); | ||
213 | if (mount("tmpfs", "/var/cache/lighttpd", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
214 | errExit("mounting /var/cache/lighttpd"); | ||
215 | |||
216 | struct passwd *p = getpwnam("www-data"); | ||
217 | uid_t uid = 0; | ||
218 | gid_t gid = 0; | ||
219 | if (p) { | ||
220 | uid = p->pw_uid; | ||
221 | gid = p->pw_gid; | ||
222 | } | ||
223 | |||
224 | int rv = mkdir("/var/cache/lighttpd/compress", S_IRWXU | S_IRWXG | S_IRWXO); | ||
225 | if (rv == -1) | ||
226 | errExit("mkdir"); | ||
227 | if (chown("/var/cache/lighttpd/compress", uid, gid) < 0) | ||
228 | errExit("chown"); | ||
229 | |||
230 | rv = mkdir("/var/cache/lighttpd/uploads", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); | ||
231 | if (rv == -1) | ||
232 | errExit("mkdir"); | ||
233 | if (chown("/var/cache/lighttpd/uploads", uid, gid) < 0) | ||
234 | errExit("chown"); | ||
235 | } | ||
236 | } | ||
237 | |||
238 | void dbg_test_dir(const char *dir) { | ||
239 | if (arg_debug) { | ||
240 | if (is_dir(dir)) | ||
241 | printf("%s is a directory\n", dir); | ||
242 | if (is_link(dir)) { | ||
243 | char *lnk = get_link(dir); | ||
244 | if (lnk) { | ||
245 | printf("%s is a symbolic link to %s\n", dir, lnk); | ||
246 | free(lnk); | ||
247 | } | ||
248 | } | ||
249 | } | ||
250 | } | ||
251 | |||
252 | |||
253 | void fs_var_lock(void) { | ||
254 | |||
255 | if (is_dir("/var/lock")) { | ||
256 | if (arg_debug) | ||
257 | printf("Mounting tmpfs on /var/lock\n"); | ||
258 | if (mount("tmpfs", "/var/lock", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | ||
259 | errExit("mounting /lock"); | ||
260 | } | ||
261 | else { | ||
262 | char *lnk = get_link("/var/lock"); | ||
263 | if (lnk) { | ||
264 | // convert a link such as "../shm" into "/shm" | ||
265 | char *lnk2 = lnk; | ||
266 | int cnt = 0; | ||
267 | while (strncmp(lnk2, "../", 3) == 0) { | ||
268 | cnt++; | ||
269 | lnk2 = lnk2 + 3; | ||
270 | } | ||
271 | if (cnt != 0) | ||
272 | lnk2 = lnk + (cnt - 1) * 3 + 2; | ||
273 | |||
274 | if (!is_dir(lnk2)) { | ||
275 | // create directory | ||
276 | if (mkdir(lnk2, S_IRWXU|S_IRWXG|S_IRWXO)) | ||
277 | errExit("mkdir"); | ||
278 | if (chown(lnk2, 0, 0)) | ||
279 | errExit("chown"); | ||
280 | if (chmod(lnk2, S_IRWXU|S_IRWXG|S_IRWXO)) | ||
281 | errExit("chmod"); | ||
282 | } | ||
283 | if (arg_debug) | ||
284 | printf("Mounting tmpfs on %s on behalf of /var/lock\n", lnk2); | ||
285 | if (mount("tmpfs", lnk2, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | ||
286 | errExit("mounting /var/lock"); | ||
287 | free(lnk); | ||
288 | } | ||
289 | else { | ||
290 | fprintf(stderr, "Warning: /var/lock not mounted\n"); | ||
291 | dbg_test_dir("/var/lock"); | ||
292 | } | ||
293 | } | ||
294 | } | ||
295 | |||
296 | void fs_var_tmp(void) { | ||
297 | |||
298 | if (!is_link("/var/tmp")) { | ||
299 | if (arg_debug) | ||
300 | printf("Mounting tmpfs on /var/tmp\n"); | ||
301 | if (mount("tmpfs", "/var/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | ||
302 | errExit("mounting /var/tmp"); | ||
303 | } | ||
304 | else { | ||
305 | fprintf(stderr, "Warning: /var/tmp not mounted\n"); | ||
306 | dbg_test_dir("/var/tmp"); | ||
307 | } | ||
308 | } | ||
309 | |||
310 | void fs_var_utmp(void) { | ||
311 | struct stat s; | ||
312 | |||
313 | // extract utmp group id | ||
314 | gid_t utmp_group = 0; | ||
315 | if (stat("/var/run/utmp", &s) == 0) | ||
316 | utmp_group = s.st_gid; | ||
317 | else { | ||
318 | fprintf(stderr, "Warning: cannot find /var/run/utmp\n"); | ||
319 | return; | ||
320 | } | ||
321 | |||
322 | // create /tmp/firejail/mnt directory | ||
323 | fs_build_mnt_dir(); | ||
324 | |||
325 | // create a new utmp file | ||
326 | if (arg_debug) | ||
327 | printf("Create the new utmp file\n"); | ||
328 | char *utmp; | ||
329 | if (asprintf(&utmp, "%s/utmp", MNT_DIR) == -1) | ||
330 | errExit("asprintf"); | ||
331 | FILE *fp = fopen(utmp, "w"); | ||
332 | if (!fp) | ||
333 | errExit("fopen"); | ||
334 | |||
335 | // read current utmp | ||
336 | struct utmp *u; | ||
337 | struct utmp u_boot; | ||
338 | setutent(); | ||
339 | while ((u = getutent()) != NULL) { | ||
340 | if (u->ut_type == BOOT_TIME) { | ||
341 | memcpy(&u_boot, u, sizeof(u_boot)); | ||
342 | u_boot.ut_tv.tv_sec = (unsigned) time(NULL); | ||
343 | } | ||
344 | } | ||
345 | endutent(); | ||
346 | |||
347 | // save new utmp file | ||
348 | fwrite(&u_boot, sizeof(u_boot), 1, fp); | ||
349 | fclose(fp); | ||
350 | if (chown(utmp, 0, utmp_group) < 0) | ||
351 | errExit("chown"); | ||
352 | if (chmod(utmp, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH ) < 0) | ||
353 | errExit("chmod"); | ||
354 | |||
355 | // mount the new utmp file | ||
356 | if (arg_debug) | ||
357 | printf("Mount the new utmp file\n"); | ||
358 | if (mount(utmp, "/var/run/utmp", NULL, MS_BIND|MS_REC, NULL) < 0) | ||
359 | errExit("mount bind utmp"); | ||
360 | } | ||
361 | |||
362 | |||
363 | #if 0 | ||
364 | Testing servers: | ||
365 | |||
366 | brctl addbr br0 | ||
367 | ifconfig br0 10.10.20.1/24 | ||
368 | |||
369 | apt-get install snmpd | ||
370 | insserv -r snmpd | ||
371 | sudo firejail --net=br0 --ip=10.10.20.10 "/etc/init.d/rsyslog start; /etc/init.d/ssh start; /etc/init.d/snmpd start; sleep inf" | ||
372 | |||
373 | apt-get install apache2 | ||
374 | insserv -r apache2 | ||
375 | sudo firejail --net=br0 --ip=10.10.20.10 "/etc/init.d/rsyslog start; /etc/init.d/ssh start; /etc/init.d/apache2 start; sleep inf" | ||
376 | |||
377 | apt-get install nginx | ||
378 | insserv -r nginx | ||
379 | sudo firejail --net=br0 --ip=10.10.20.10 "/etc/init.d/rsyslog start; /etc/init.d/ssh start; /etc/init.d/nginx start; sleep inf" | ||
380 | |||
381 | apt-get install lighttpd | ||
382 | insserv -r lighttpd | ||
383 | sudo firejail --net=br0 --ip=10.10.20.10 "/etc/init.d/rsyslog start; /etc/init.d/ssh start; /etc/init.d/lighttpd start; sleep inf" | ||
384 | |||
385 | apt-get install isc-dhcp-server | ||
386 | insserv -r isc-dhcp-server | ||
387 | sudo firejail --net=br0 --ip=10.10.20.10 "/etc/init.d/rsyslog start; /etc/init.d/ssh start; /etc/init.d/isc-dhcp-server start; sleep inf" | ||
388 | #endif | ||
diff --git a/src/firejail/join.c b/src/firejail/join.c new file mode 100644 index 000000000..e2d2ca7fc --- /dev/null +++ b/src/firejail/join.c | |||
@@ -0,0 +1,364 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/stat.h> | ||
22 | #include <sys/wait.h> | ||
23 | #include <fcntl.h> | ||
24 | #include <unistd.h> | ||
25 | #include <sys/prctl.h> | ||
26 | |||
27 | static int apply_caps = 0; | ||
28 | static uint64_t caps = 0; | ||
29 | static int apply_seccomp = 0; | ||
30 | #define BUFLEN 4096 | ||
31 | |||
32 | static void extract_command(int argc, char **argv, int index) { | ||
33 | if (index >= argc) | ||
34 | return; | ||
35 | |||
36 | // doubledash followed by positional parameters | ||
37 | if (strcmp(argv[index], "--") == 0) { | ||
38 | arg_doubledash = 1; | ||
39 | index++; | ||
40 | if (index >= argc) | ||
41 | return; | ||
42 | } | ||
43 | |||
44 | // first argv needs to be a valid command | ||
45 | if (arg_doubledash == 0 && *argv[index] == '-') { | ||
46 | fprintf(stderr, "Error: invalid option %s after --join\n", argv[index]); | ||
47 | exit(1); | ||
48 | } | ||
49 | |||
50 | |||
51 | int len = 0; | ||
52 | int i; | ||
53 | // calculate command length | ||
54 | for (i = index; i < argc; i++) { | ||
55 | len += strlen(argv[i]) + 1; | ||
56 | } | ||
57 | assert(len > 0); | ||
58 | |||
59 | // build command | ||
60 | cfg.command_line = malloc(len + 1); | ||
61 | *cfg.command_line = '\0'; | ||
62 | for (i = index; i < argc; i++) { | ||
63 | strcat(cfg.command_line, argv[i]); | ||
64 | strcat(cfg.command_line, " "); | ||
65 | } | ||
66 | if (arg_debug) | ||
67 | printf("Extracted command #%s#\n", cfg.command_line); | ||
68 | } | ||
69 | |||
70 | static void extract_nogroups(pid_t pid) { | ||
71 | char *fname; | ||
72 | if (asprintf(&fname, "/proc/%d/root%s/groups", pid, MNT_DIR) == -1) | ||
73 | errExit("asprintf"); | ||
74 | |||
75 | struct stat s; | ||
76 | if (stat(fname, &s) == -1) | ||
77 | return; | ||
78 | |||
79 | arg_nogroups = 1; | ||
80 | free(fname); | ||
81 | } | ||
82 | |||
83 | static void extract_cpu(pid_t pid) { | ||
84 | char *fname; | ||
85 | if (asprintf(&fname, "/proc/%d/root%s/cpu", pid, MNT_DIR) == -1) | ||
86 | errExit("asprintf"); | ||
87 | |||
88 | struct stat s; | ||
89 | if (stat(fname, &s) == -1) | ||
90 | return; | ||
91 | |||
92 | // there is a cpu file in MNT_DIR; load the information from the file | ||
93 | load_cpu(fname); | ||
94 | free(fname); | ||
95 | } | ||
96 | |||
97 | static void extract_cgroup(pid_t pid) { | ||
98 | char *fname; | ||
99 | if (asprintf(&fname, "/proc/%d/root%s/cgroup", pid, MNT_DIR) == -1) | ||
100 | errExit("asprintf"); | ||
101 | |||
102 | struct stat s; | ||
103 | if (stat(fname, &s) == -1) | ||
104 | return; | ||
105 | |||
106 | // there is a cgroup file in MNT_DIR; load the information from the file | ||
107 | load_cgroup(fname); | ||
108 | free(fname); | ||
109 | } | ||
110 | |||
111 | static void extract_caps_seccomp(pid_t pid) { | ||
112 | // open stat file | ||
113 | char *file; | ||
114 | if (asprintf(&file, "/proc/%u/status", pid) == -1) { | ||
115 | perror("asprintf"); | ||
116 | exit(1); | ||
117 | } | ||
118 | FILE *fp = fopen(file, "r"); | ||
119 | if (!fp) { | ||
120 | free(file); | ||
121 | fprintf(stderr, "Error: cannot open stat file for process %u\n", pid); | ||
122 | exit(1); | ||
123 | } | ||
124 | |||
125 | char buf[BUFLEN]; | ||
126 | while (fgets(buf, BUFLEN - 1, fp)) { | ||
127 | if (strncmp(buf, "Seccomp:", 8) == 0) { | ||
128 | char *ptr = buf + 8; | ||
129 | int val; | ||
130 | sscanf(ptr, "%d", &val); | ||
131 | if (val == 2) | ||
132 | apply_seccomp = 1; | ||
133 | break; | ||
134 | } | ||
135 | else if (strncmp(buf, "CapBnd:", 7) == 0) { | ||
136 | char *ptr = buf + 8; | ||
137 | unsigned long long val; | ||
138 | sscanf(ptr, "%llx", &val); | ||
139 | apply_caps = 1; | ||
140 | caps = val; | ||
141 | } | ||
142 | } | ||
143 | fclose(fp); | ||
144 | free(file); | ||
145 | } | ||
146 | |||
147 | void extract_user_namespace(pid_t pid) { | ||
148 | // test user namespaces available in the kernel | ||
149 | struct stat s1; | ||
150 | struct stat s2; | ||
151 | struct stat s3; | ||
152 | if (stat("/proc/self/ns/user", &s1) == 0 && | ||
153 | stat("/proc/self/uid_map", &s2) == 0 && | ||
154 | stat("/proc/self/gid_map", &s3) == 0); | ||
155 | else | ||
156 | return; | ||
157 | |||
158 | // read uid map | ||
159 | char *uidmap; | ||
160 | if (asprintf(&uidmap, "/proc/%u/uid_map", pid) == -1) | ||
161 | errExit("asprintf"); | ||
162 | FILE *fp = fopen(uidmap, "r"); | ||
163 | if (!fp) { | ||
164 | free(uidmap); | ||
165 | return; | ||
166 | } | ||
167 | |||
168 | // check uid map | ||
169 | int u1; | ||
170 | int u2; | ||
171 | if (fscanf(fp, "%d %d", &u1, &u2) == 2) { | ||
172 | if (arg_debug) | ||
173 | printf("User namespace detected: %s, %d, %d\n", uidmap, u1, u2); | ||
174 | if (u1 != 0 || u2 != 0) | ||
175 | arg_noroot = 1; | ||
176 | } | ||
177 | fclose(fp); | ||
178 | free(uidmap); | ||
179 | } | ||
180 | |||
181 | void join_name(const char *name, const char *homedir, int argc, char **argv, int index) { | ||
182 | if (!name || strlen(name) == 0) { | ||
183 | fprintf(stderr, "Error: invalid sandbox name\n"); | ||
184 | exit(1); | ||
185 | } | ||
186 | pid_t pid; | ||
187 | if (name2pid(name, &pid)) { | ||
188 | fprintf(stderr, "Error: cannot find sandbox %s\n", name); | ||
189 | exit(1); | ||
190 | } | ||
191 | |||
192 | join(pid, homedir, argc, argv, index); | ||
193 | } | ||
194 | |||
195 | void join(pid_t pid, const char *homedir, int argc, char **argv, int index) { | ||
196 | extract_command(argc, argv, index); | ||
197 | |||
198 | // if the pid is that of a firejail process, use the pid of the first child process | ||
199 | char *comm = pid_proc_comm(pid); | ||
200 | if (comm) { | ||
201 | // remove \n | ||
202 | char *ptr = strchr(comm, '\n'); | ||
203 | if (ptr) | ||
204 | *ptr = '\0'; | ||
205 | if (strcmp(comm, "firejail") == 0) { | ||
206 | pid_t child; | ||
207 | if (find_child(pid, &child) == 0) { | ||
208 | pid = child; | ||
209 | printf("Switching to pid %u, the first child process inside the sandbox\n", (unsigned) pid); | ||
210 | } | ||
211 | } | ||
212 | free(comm); | ||
213 | } | ||
214 | |||
215 | // check privileges for non-root users | ||
216 | uid_t uid = getuid(); | ||
217 | if (uid != 0) { | ||
218 | struct stat s; | ||
219 | char *dir; | ||
220 | if (asprintf(&dir, "/proc/%u/ns", pid) == -1) | ||
221 | errExit("asprintf"); | ||
222 | if (stat(dir, &s) < 0) | ||
223 | errExit("stat"); | ||
224 | if (s.st_uid != uid) { | ||
225 | fprintf(stderr, "Error: permission is denied to join a sandbox created by a different user.\n"); | ||
226 | exit(1); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | // in user mode set caps seccomp, cpu, cgroup, etc | ||
231 | if (getuid() != 0) { | ||
232 | extract_caps_seccomp(pid); | ||
233 | extract_cpu(pid); | ||
234 | extract_cgroup(pid); | ||
235 | extract_nogroups(pid); | ||
236 | extract_user_namespace(pid); | ||
237 | } | ||
238 | |||
239 | // set cgroup | ||
240 | if (cfg.cgroup) | ||
241 | set_cgroup(cfg.cgroup); | ||
242 | |||
243 | // join namespaces | ||
244 | if (join_namespace(pid, "ipc")) | ||
245 | exit(1); | ||
246 | if (join_namespace(pid, "net")) | ||
247 | exit(1); | ||
248 | if (join_namespace(pid, "pid")) | ||
249 | exit(1); | ||
250 | if (join_namespace(pid, "uts")) | ||
251 | exit(1); | ||
252 | if (join_namespace(pid, "mnt")) | ||
253 | exit(1); | ||
254 | |||
255 | pid_t child = fork(); | ||
256 | if (child < 0) | ||
257 | errExit("fork"); | ||
258 | if (child == 0) { | ||
259 | // chroot into /proc/PID/root directory | ||
260 | char *rootdir; | ||
261 | if (asprintf(&rootdir, "/proc/%d/root", pid) == -1) | ||
262 | errExit("asprintf"); | ||
263 | |||
264 | int rv = chroot(rootdir); // this will fail for processes in sandboxes not started with --chroot option | ||
265 | if (rv == 0) | ||
266 | printf("changing root to %s\n", rootdir); | ||
267 | |||
268 | prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died | ||
269 | if (chdir("/") < 0) | ||
270 | errExit("chdir"); | ||
271 | if (homedir) { | ||
272 | struct stat s; | ||
273 | if (stat(homedir, &s) == 0) { | ||
274 | /* coverity[toctou] */ | ||
275 | if (chdir(homedir) < 0) | ||
276 | errExit("chdir"); | ||
277 | } | ||
278 | } | ||
279 | |||
280 | // set cpu affinity | ||
281 | if (cfg.cpus) | ||
282 | set_cpu_affinity(); | ||
283 | |||
284 | // set caps filter | ||
285 | if (apply_caps == 1) | ||
286 | caps_set(caps); | ||
287 | #ifdef HAVE_SECCOMP | ||
288 | // set seccomp filter | ||
289 | if (apply_seccomp == 1) | ||
290 | seccomp_set(); | ||
291 | #endif | ||
292 | |||
293 | // fix qt 4.8 | ||
294 | if (setenv("QT_X11_NO_MITSHM", "1", 1) < 0) | ||
295 | errExit("setenv"); | ||
296 | if (setenv("container", "firejail", 1) < 0) // LXC sets container=lxc, | ||
297 | errExit("setenv"); | ||
298 | |||
299 | // mount user namespace or drop privileges | ||
300 | if (arg_noroot) { | ||
301 | if (arg_debug) | ||
302 | printf("Joining user namespace\n"); | ||
303 | if (join_namespace(1, "user")) | ||
304 | exit(1); | ||
305 | } | ||
306 | else | ||
307 | drop_privs(arg_nogroups); | ||
308 | |||
309 | // set prompt color to green | ||
310 | //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' | ||
311 | if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0) | ||
312 | errExit("setenv"); | ||
313 | |||
314 | // run icmdline trough /bin/bash | ||
315 | if (cfg.command_line == NULL) | ||
316 | // replace the process with a regular bash session | ||
317 | execlp("/bin/bash", "/bin/bash", NULL); | ||
318 | else { | ||
319 | // run the command supplied by the user | ||
320 | int cwd = 0; | ||
321 | if (cfg.cwd) { | ||
322 | if (chdir(cfg.cwd) == 0) | ||
323 | cwd = 1; | ||
324 | } | ||
325 | |||
326 | if (!cwd) { | ||
327 | if (chdir("/") < 0) | ||
328 | errExit("chdir"); | ||
329 | if (cfg.homedir) { | ||
330 | struct stat s; | ||
331 | if (stat(cfg.homedir, &s) == 0) { | ||
332 | if (chdir(cfg.homedir) < 0) | ||
333 | errExit("chdir"); | ||
334 | } | ||
335 | } | ||
336 | } | ||
337 | |||
338 | char *arg[5]; | ||
339 | arg[0] = "/bin/bash"; | ||
340 | arg[1] = "-c"; | ||
341 | if (arg_debug) | ||
342 | printf("Starting %s\n", cfg.command_line); | ||
343 | if (!arg_doubledash) { | ||
344 | arg[2] = cfg.command_line; | ||
345 | arg[3] = NULL; | ||
346 | } | ||
347 | else { | ||
348 | arg[2] = "--"; | ||
349 | arg[3] = cfg.command_line; | ||
350 | arg[4] = NULL; | ||
351 | } | ||
352 | execvp("/bin/bash", arg); | ||
353 | } | ||
354 | |||
355 | // it will never get here!!! | ||
356 | } | ||
357 | |||
358 | // wait for the child to finish | ||
359 | waitpid(child, NULL, 0); | ||
360 | exit(0); | ||
361 | } | ||
362 | |||
363 | |||
364 | |||
diff --git a/src/firejail/list.c b/src/firejail/list.c new file mode 100644 index 000000000..c2c4e801f --- /dev/null +++ b/src/firejail/list.c | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | |||
22 | void top(void) { | ||
23 | drop_privs(1); | ||
24 | |||
25 | char *arg[4]; | ||
26 | arg[0] = "bash"; | ||
27 | arg[1] = "-c"; | ||
28 | arg[2] = "firemon --top"; | ||
29 | arg[3] = NULL; | ||
30 | execvp("/bin/bash", arg); | ||
31 | } | ||
32 | |||
33 | void netstats(void) { | ||
34 | drop_privs(1); | ||
35 | |||
36 | char *arg[4]; | ||
37 | arg[0] = "bash"; | ||
38 | arg[1] = "-c"; | ||
39 | arg[2] = "firemon --netstats"; | ||
40 | arg[3] = NULL; | ||
41 | execvp("/bin/bash", arg); | ||
42 | } | ||
43 | |||
44 | void list(void) { | ||
45 | drop_privs(1); | ||
46 | |||
47 | char *arg[4]; | ||
48 | arg[0] = "bash"; | ||
49 | arg[1] = "-c"; | ||
50 | arg[2] = "firemon --list"; | ||
51 | arg[3] = NULL; | ||
52 | execvp("/bin/bash", arg); | ||
53 | } | ||
54 | |||
55 | void tree(void) { | ||
56 | drop_privs(1); | ||
57 | |||
58 | char *arg[4]; | ||
59 | arg[0] = "bash"; | ||
60 | arg[1] = "-c"; | ||
61 | arg[2] = "firemon --tree"; | ||
62 | arg[3] = NULL; | ||
63 | execvp("/bin/bash", arg); | ||
64 | } | ||
65 | |||
diff --git a/src/firejail/main.c b/src/firejail/main.c new file mode 100644 index 000000000..78971aa86 --- /dev/null +++ b/src/firejail/main.c | |||
@@ -0,0 +1,1168 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include "../include/pid.h" | ||
22 | #define _GNU_SOURCE | ||
23 | #include <sys/utsname.h> | ||
24 | #include <sched.h> | ||
25 | #include <sys/mount.h> | ||
26 | #include <sys/wait.h> | ||
27 | #include <sys/stat.h> | ||
28 | #include <fcntl.h> | ||
29 | #include <dirent.h> | ||
30 | #include <pwd.h> | ||
31 | #include <errno.h> | ||
32 | #include <limits.h> | ||
33 | #include <sys/file.h> | ||
34 | #include <sys/prctl.h> | ||
35 | #include <signal.h> | ||
36 | #include <time.h> | ||
37 | #include <net/if.h> | ||
38 | |||
39 | #if 0 | ||
40 | #include <sys/times.h> | ||
41 | { | ||
42 | struct tms tm; | ||
43 | clock_t systick = times(&tm); | ||
44 | printf("time %s:%d %u\n", __FILE__, __LINE__, (uint32_t) systick); | ||
45 | } | ||
46 | #endif | ||
47 | |||
48 | #define STACK_SIZE (1024 * 1024) | ||
49 | static char child_stack[STACK_SIZE]; // space for child's stack | ||
50 | Config cfg; // configuration | ||
51 | int arg_private = 0; // mount private /home and /tmp directoryu | ||
52 | int arg_debug = 0; // print debug messages | ||
53 | int arg_nonetwork = 0; // --net=none | ||
54 | int arg_command = 0; // -c | ||
55 | int arg_overlay = 0; // --overlay | ||
56 | int arg_zsh = 0; // use zsh as default shell | ||
57 | int arg_csh = 0; // use csh as default shell | ||
58 | |||
59 | int arg_seccomp = 0; // enable default seccomp filter | ||
60 | char *arg_seccomp_list = NULL; // optional seccomp list on top of default filter | ||
61 | char *arg_seccomp_list_drop = NULL; // seccomp drop list | ||
62 | char *arg_seccomp_list_keep = NULL; // seccomp keep list | ||
63 | |||
64 | int arg_caps_default_filter = 0; // enable default capabilities filter | ||
65 | int arg_caps_drop = 0; // drop list | ||
66 | int arg_caps_drop_all = 0; // drop all capabilities | ||
67 | int arg_caps_keep = 0; // keep list | ||
68 | char *arg_caps_list = NULL; // optional caps list | ||
69 | |||
70 | int arg_trace = 0; // syscall tracing support | ||
71 | int arg_rlimit_nofile = 0; // rlimit nofile | ||
72 | int arg_rlimit_nproc = 0; // rlimit nproc | ||
73 | int arg_rlimit_fsize = 0; // rlimit fsize | ||
74 | int arg_rlimit_sigpending = 0; // rlimit fsize | ||
75 | int arg_nox11 = 0; // kill the program if x11 unix domain socket is accessed | ||
76 | int arg_nodbus = 0; // kill the program if D-Bus is accessed | ||
77 | int arg_nogroups = 0; // disable supplementary groups | ||
78 | int arg_noroot = 0; // create a new user namespace and disable root user | ||
79 | int arg_netfilter; // enable netfilter | ||
80 | char *arg_netfilter_file = NULL; // netfilter file | ||
81 | int arg_doubledash = 0; // double dash | ||
82 | int arg_shell_none = 0; // run the program directly without a shell | ||
83 | int arg_private_dev = 0; // private dev directory | ||
84 | int arg_scan = 0; // arp-scan all interfaces | ||
85 | |||
86 | int parent_to_child_fds[2]; | ||
87 | int child_to_parent_fds[2]; | ||
88 | |||
89 | char *fullargv[MAX_ARGS]; // expanded argv for restricted shell | ||
90 | int fullargc = 0; | ||
91 | static pid_t child = 0; | ||
92 | pid_t sandbox_pid; | ||
93 | |||
94 | static void myexit(int rv) { | ||
95 | logmsg("exiting..."); | ||
96 | if (!arg_command) | ||
97 | printf("\nparent is shutting down, bye...\n"); | ||
98 | |||
99 | struct stat s; | ||
100 | if (stat("/proc/firejail", &s) == 0) { | ||
101 | /* coverity[toctou] */ | ||
102 | FILE *fp = fopen("/proc/firejail", "w"); | ||
103 | if (fp) { | ||
104 | // deregistration | ||
105 | fprintf(fp, "release\n"); | ||
106 | fflush(0); | ||
107 | fclose(fp); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | // delete sandbox files in shared memory | ||
112 | bandwidth_shm_del_file(sandbox_pid); // bandwidht file | ||
113 | network_shm_del_file(sandbox_pid); // network map file | ||
114 | |||
115 | exit(rv); | ||
116 | } | ||
117 | |||
118 | static void my_handler(int s){ | ||
119 | printf("\nSignal %d caught, shutting down the child process\n", s); | ||
120 | logsignal(s); | ||
121 | kill(child, SIGKILL); | ||
122 | myexit(1); | ||
123 | } | ||
124 | |||
125 | static void extract_user_data(void) { | ||
126 | // check suid | ||
127 | if (geteuid()) { | ||
128 | fprintf(stderr, "Error: the sandbox is not setuid root\n"); | ||
129 | exit(1); | ||
130 | } | ||
131 | |||
132 | struct passwd *pw = getpwuid(getuid()); | ||
133 | if (!pw) | ||
134 | errExit("getpwuid"); | ||
135 | cfg.username = strdup(pw->pw_name); | ||
136 | if (!cfg.username) | ||
137 | errExit("strdup"); | ||
138 | |||
139 | // build home directory name | ||
140 | cfg.homedir = NULL; | ||
141 | if (pw->pw_dir != NULL) { | ||
142 | cfg.homedir = strdup(pw->pw_dir); | ||
143 | if (!cfg.homedir) | ||
144 | errExit("strdup"); | ||
145 | } | ||
146 | else { | ||
147 | fprintf(stderr, "Error: user %s doesn't have a user directory assigned\n", cfg.username); | ||
148 | exit(1); | ||
149 | } | ||
150 | |||
151 | cfg.cwd = getcwd(NULL, 0); | ||
152 | } | ||
153 | |||
154 | |||
155 | |||
156 | |||
157 | static inline Bridge *last_bridge_configured(void) { | ||
158 | if (cfg.bridge3.configured) | ||
159 | return &cfg.bridge3; | ||
160 | else if (cfg.bridge2.configured) | ||
161 | return &cfg.bridge2; | ||
162 | else if (cfg.bridge1.configured) | ||
163 | return &cfg.bridge1; | ||
164 | else if (cfg.bridge0.configured) | ||
165 | return &cfg.bridge0; | ||
166 | else | ||
167 | return NULL; | ||
168 | } | ||
169 | |||
170 | |||
171 | |||
172 | // return 1 if error, 0 if a valid pid was found | ||
173 | static int read_pid(char *str, pid_t *pid) { | ||
174 | char *endptr; | ||
175 | errno = 0; | ||
176 | pid_t pidtmp = strtol(str, &endptr, 10); | ||
177 | if ((errno == ERANGE && (pidtmp == LONG_MAX || pidtmp == LONG_MIN)) | ||
178 | || (errno != 0 && pidtmp == 0)) { | ||
179 | return 1; | ||
180 | } | ||
181 | if (endptr == str) { | ||
182 | return 1; | ||
183 | } | ||
184 | *pid = pidtmp; | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static void init_cfg(void) { | ||
189 | memset(&cfg, 0, sizeof(cfg)); | ||
190 | |||
191 | cfg.bridge0.devsandbox = "eth0"; | ||
192 | cfg.bridge1.devsandbox = "eth1"; | ||
193 | cfg.bridge2.devsandbox = "eth2"; | ||
194 | cfg.bridge3.devsandbox = "eth3"; | ||
195 | |||
196 | extract_user_data(); | ||
197 | } | ||
198 | |||
199 | static void check_network(Bridge *br) { | ||
200 | assert(br); | ||
201 | if (br->macvlan == 0) // for bridge devices check network range or arp-scan and assign address | ||
202 | net_configure_sandbox_ip(br); | ||
203 | else if (br->ipsandbox) { // for macvlan check network range | ||
204 | char *rv = in_netrange(br->ipsandbox, br->ip, br->mask); | ||
205 | if (rv) { | ||
206 | fprintf(stderr, "%s", rv); | ||
207 | exit(1); | ||
208 | } | ||
209 | } | ||
210 | } | ||
211 | |||
212 | |||
213 | void check_user_namespace(void) { | ||
214 | if (getuid() == 0) { | ||
215 | fprintf(stderr, "Error: --noroot option cannot be used when starting the sandbox as root.\n"); | ||
216 | exit(1); | ||
217 | } | ||
218 | |||
219 | // test user namespaces available in the kernel | ||
220 | struct stat s1; | ||
221 | struct stat s2; | ||
222 | struct stat s3; | ||
223 | if (stat("/proc/self/ns/user", &s1) == 0 && | ||
224 | stat("/proc/self/uid_map", &s2) == 0 && | ||
225 | stat("/proc/self/gid_map", &s3) == 0) | ||
226 | arg_noroot = 1; | ||
227 | else { | ||
228 | fprintf(stderr, "Warning: user namespaces not available in the current kernel.\n"); | ||
229 | arg_noroot = 0; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | //******************************************* | ||
234 | // Main program | ||
235 | //******************************************* | ||
236 | int main(int argc, char **argv) { | ||
237 | int i; | ||
238 | int prog_index = -1; // index in argv where the program command starts | ||
239 | int lockfd = -1; | ||
240 | int arg_ipc = 0; | ||
241 | int arg_cgroup = 0; | ||
242 | int custom_profile = 0; // custom profile loaded | ||
243 | |||
244 | // initialize globals | ||
245 | init_cfg(); | ||
246 | cfg.original_argv = argv; | ||
247 | cfg.original_argc = argc; | ||
248 | |||
249 | |||
250 | // initialize random number generator | ||
251 | sandbox_pid = getpid(); | ||
252 | time_t t = time(NULL); | ||
253 | srand(t ^ sandbox_pid); | ||
254 | |||
255 | // check firejail directories | ||
256 | fs_build_firejail_dir(); | ||
257 | shm_create_firejail_dir(); | ||
258 | bandwidth_shm_del_file(sandbox_pid); | ||
259 | |||
260 | // is this a login shell? | ||
261 | if (*argv[0] == '-') { | ||
262 | fullargc = restricted_shell(cfg.username); | ||
263 | if (fullargc) { | ||
264 | int j; | ||
265 | for (i = 1, j = fullargc; i < argc && j < MAX_ARGS; i++, j++, fullargc++) | ||
266 | fullargv[j] = argv[i]; | ||
267 | |||
268 | // replace argc/argv with fullargc/fullargv | ||
269 | argv = fullargv; | ||
270 | argc = j; | ||
271 | } | ||
272 | } | ||
273 | else { | ||
274 | // check --output option and execute it; | ||
275 | check_output(argc, argv); // the function will not return if --output option was found | ||
276 | } | ||
277 | |||
278 | // parse arguments | ||
279 | for (i = 1; i < argc; i++) { | ||
280 | //************************************* | ||
281 | // basic arguments | ||
282 | //************************************* | ||
283 | if (strcmp(argv[i], "--help") == 0 || | ||
284 | strcmp(argv[i], "-?") == 0) { | ||
285 | usage(); | ||
286 | exit(0); | ||
287 | } | ||
288 | else if (strcmp(argv[i], "--version") == 0) { | ||
289 | printf("firejail version %s\n", VERSION); | ||
290 | exit(0); | ||
291 | } | ||
292 | else if (strcmp(argv[i], "--debug") == 0) | ||
293 | arg_debug = 1; | ||
294 | |||
295 | else if (strncmp(argv[i], "--bandwidth=", 12) == 0) { | ||
296 | logargs(argc, argv); | ||
297 | |||
298 | // extract the command | ||
299 | if ((i + 1) == argc) { | ||
300 | fprintf(stderr, "Error: command expected after --bandwidth option\n"); | ||
301 | exit(1); | ||
302 | } | ||
303 | char *cmd = argv[i + 1]; | ||
304 | if (strcmp(cmd, "status") && strcmp(cmd, "clear") && strcmp(cmd, "set")) { | ||
305 | fprintf(stderr, "Error: invalid --bandwidth command\n"); | ||
306 | exit(1); | ||
307 | } | ||
308 | |||
309 | // extract network name | ||
310 | char *dev = NULL; | ||
311 | int down = 0; | ||
312 | int up = 0; | ||
313 | if (strcmp(cmd, "set") == 0 || strcmp(cmd, "clear") == 0) { | ||
314 | // extract device name | ||
315 | if ((i + 2) == argc) { | ||
316 | fprintf(stderr, "Error: network name expected after --bandwidth %s option\n", cmd); | ||
317 | exit(1); | ||
318 | } | ||
319 | dev = argv[i + 2]; | ||
320 | |||
321 | // check device name | ||
322 | if (if_nametoindex(dev) == 0) { | ||
323 | fprintf(stderr, "Error: network device %s not found\n", dev); | ||
324 | exit(1); | ||
325 | } | ||
326 | |||
327 | // extract bandwidth | ||
328 | if (strcmp(cmd, "set") == 0) { | ||
329 | if ((i + 4) >= argc) { | ||
330 | fprintf(stderr, "Error: invalid --bandwidth set command\n"); | ||
331 | exit(1); | ||
332 | } | ||
333 | |||
334 | down = atoi(argv[i + 3]); | ||
335 | if (down < 0) { | ||
336 | fprintf(stderr, "Error: invalid download speed\n"); | ||
337 | exit(1); | ||
338 | } | ||
339 | up = atoi(argv[i + 4]); | ||
340 | if (up < 0) { | ||
341 | fprintf(stderr, "Error: invalid upload speed\n"); | ||
342 | exit(1); | ||
343 | } | ||
344 | } | ||
345 | } | ||
346 | |||
347 | // extract pid or sandbox name | ||
348 | pid_t pid; | ||
349 | if (read_pid(argv[i] + 12, &pid) == 0) | ||
350 | bandwidth_pid(pid, cmd, dev, down, up); | ||
351 | else | ||
352 | bandwidth_name(argv[i] + 12, cmd, dev, down, up); | ||
353 | |||
354 | // it will never get here | ||
355 | exit(0); | ||
356 | } | ||
357 | |||
358 | //************************************* | ||
359 | // independent commands - the program will exit! | ||
360 | //************************************* | ||
361 | #ifdef HAVE_SECCOMP | ||
362 | else if (strcmp(argv[i], "--debug-syscalls") == 0) { | ||
363 | syscall_print(); | ||
364 | exit(0); | ||
365 | } | ||
366 | else if (strncmp(argv[i], "--seccomp.print=", 16) == 0) { | ||
367 | // join sandbox by pid or by name | ||
368 | pid_t pid; | ||
369 | if (read_pid(argv[i] + 16, &pid) == 0) | ||
370 | seccomp_print_filter(pid); | ||
371 | else | ||
372 | seccomp_print_filter_name(argv[i] + 16); | ||
373 | |||
374 | // it will never get here!!! | ||
375 | exit(0); | ||
376 | } | ||
377 | #endif | ||
378 | else if (strncmp(argv[i], "--caps.print=", 13) == 0) { | ||
379 | // join sandbox by pid or by name | ||
380 | pid_t pid; | ||
381 | if (read_pid(argv[i] + 13, &pid) == 0) | ||
382 | caps_print_filter(pid); | ||
383 | else | ||
384 | caps_print_filter_name(argv[i] + 13); | ||
385 | |||
386 | // it will never get here!!! | ||
387 | exit(0); | ||
388 | } | ||
389 | |||
390 | else if (strncmp(argv[i], "--dns.print=", 12) == 0) { | ||
391 | // join sandbox by pid or by name | ||
392 | pid_t pid; | ||
393 | if (read_pid(argv[i] + 12, &pid) == 0) | ||
394 | net_dns_print(pid); | ||
395 | else | ||
396 | net_dns_print_name(argv[i] + 12); | ||
397 | |||
398 | // it will never get here!!! | ||
399 | exit(0); | ||
400 | } | ||
401 | else if (strcmp(argv[i], "--debug-caps") == 0) { | ||
402 | caps_print(); | ||
403 | exit(0); | ||
404 | } | ||
405 | else if (strcmp(argv[i], "--list") == 0) { | ||
406 | list(); | ||
407 | exit(0); | ||
408 | } | ||
409 | else if (strcmp(argv[i], "--tree") == 0) { | ||
410 | tree(); | ||
411 | exit(0); | ||
412 | } | ||
413 | else if (strcmp(argv[i], "--top") == 0) { | ||
414 | top(); | ||
415 | exit(0); | ||
416 | } | ||
417 | else if (strcmp(argv[i], "--netstats") == 0) { | ||
418 | netstats(); | ||
419 | exit(0); | ||
420 | } | ||
421 | else if (strncmp(argv[i], "--join=", 7) == 0) { | ||
422 | logargs(argc, argv); | ||
423 | |||
424 | // join sandbox by pid or by name | ||
425 | pid_t pid; | ||
426 | if (read_pid(argv[i] + 7, &pid) == 0) | ||
427 | join(pid, cfg.homedir, argc, argv, i + 1); | ||
428 | else | ||
429 | join_name(argv[i] + 7, cfg.homedir, argc, argv, i + 1); | ||
430 | |||
431 | // it will never get here!!! | ||
432 | exit(0); | ||
433 | } | ||
434 | else if (strncmp(argv[i], "--shutdown=", 11) == 0) { | ||
435 | logargs(argc, argv); | ||
436 | |||
437 | // shutdown sandbox by pid or by name | ||
438 | pid_t pid; | ||
439 | if (read_pid(argv[i] + 11, &pid) == 0) | ||
440 | shut(pid); | ||
441 | else | ||
442 | shut_name(argv[i] + 11); | ||
443 | |||
444 | // it will never get here!!! | ||
445 | exit(0); | ||
446 | } | ||
447 | |||
448 | //************************************* | ||
449 | // filtering | ||
450 | //************************************* | ||
451 | #ifdef HAVE_SECCOMP | ||
452 | else if (strcmp(argv[i], "--seccomp") == 0) { | ||
453 | if (arg_seccomp) { | ||
454 | fprintf(stderr, "Error: seccomp already enabled\n"); | ||
455 | exit(1); | ||
456 | } | ||
457 | arg_seccomp = 1; | ||
458 | } | ||
459 | else if (strncmp(argv[i], "--seccomp=", 10) == 0) { | ||
460 | if (arg_seccomp) { | ||
461 | fprintf(stderr, "Error: seccomp already enabled\n"); | ||
462 | exit(1); | ||
463 | } | ||
464 | arg_seccomp = 1; | ||
465 | arg_seccomp_list = strdup(argv[i] + 10); | ||
466 | if (!arg_seccomp_list) | ||
467 | errExit("strdup"); | ||
468 | } | ||
469 | else if (strncmp(argv[i], "--seccomp.drop=", 15) == 0) { | ||
470 | if (arg_seccomp) { | ||
471 | fprintf(stderr, "Error: seccomp already enabled\n"); | ||
472 | exit(1); | ||
473 | } | ||
474 | arg_seccomp = 1; | ||
475 | arg_seccomp_list_drop = strdup(argv[i] + 15); | ||
476 | if (!arg_seccomp_list_drop) | ||
477 | errExit("strdup"); | ||
478 | } | ||
479 | else if (strncmp(argv[i], "--seccomp.keep=", 15) == 0) { | ||
480 | if (arg_seccomp) { | ||
481 | fprintf(stderr, "Error: seccomp already enabled\n"); | ||
482 | exit(1); | ||
483 | } | ||
484 | arg_seccomp = 1; | ||
485 | arg_seccomp_list_keep = strdup(argv[i] + 15); | ||
486 | if (!arg_seccomp_list_keep) | ||
487 | errExit("strdup"); | ||
488 | } | ||
489 | #endif | ||
490 | else if (strcmp(argv[i], "--caps") == 0) | ||
491 | arg_caps_default_filter = 1; | ||
492 | else if (strcmp(argv[i], "--caps.drop=all") == 0) | ||
493 | arg_caps_drop_all = 1; | ||
494 | else if (strncmp(argv[i], "--caps.drop=", 12) == 0) { | ||
495 | arg_caps_drop = 1; | ||
496 | arg_caps_list = strdup(argv[i] + 12); | ||
497 | if (!arg_caps_list) | ||
498 | errExit("strdup"); | ||
499 | // verify caps list and exit if problems | ||
500 | if (caps_check_list(arg_caps_list, NULL)) | ||
501 | return 1; | ||
502 | } | ||
503 | else if (strncmp(argv[i], "--caps.keep=", 12) == 0) { | ||
504 | arg_caps_keep = 1; | ||
505 | arg_caps_list = strdup(argv[i] + 12); | ||
506 | if (!arg_caps_list) | ||
507 | errExit("strdup"); | ||
508 | // verify caps list and exit if problems | ||
509 | if (caps_check_list(arg_caps_list, NULL)) | ||
510 | return 1; | ||
511 | } | ||
512 | |||
513 | |||
514 | else if (strcmp(argv[i], "--trace") == 0) | ||
515 | arg_trace = 1; | ||
516 | else if (strncmp(argv[i], "--rlimit-nofile=", 16) == 0) { | ||
517 | if (not_unsigned(argv[i] + 16)) { | ||
518 | fprintf(stderr, "Error: invalid rlimt nofile\n"); | ||
519 | exit(1); | ||
520 | } | ||
521 | sscanf(argv[i] + 16, "%u", &cfg.rlimit_nofile); | ||
522 | arg_rlimit_nofile = 1; | ||
523 | } | ||
524 | else if (strncmp(argv[i], "--rlimit-nproc=", 15) == 0) { | ||
525 | if (not_unsigned(argv[i] + 15)) { | ||
526 | fprintf(stderr, "Error: invalid rlimt nproc\n"); | ||
527 | exit(1); | ||
528 | } | ||
529 | sscanf(argv[i] + 15, "%u", &cfg.rlimit_nproc); | ||
530 | arg_rlimit_nproc = 1; | ||
531 | } | ||
532 | else if (strncmp(argv[i], "--rlimit-fsize=", 15) == 0) { | ||
533 | if (not_unsigned(argv[i] + 15)) { | ||
534 | fprintf(stderr, "Error: invalid rlimt fsize\n"); | ||
535 | exit(1); | ||
536 | } | ||
537 | sscanf(argv[i] + 15, "%u", &cfg.rlimit_fsize); | ||
538 | arg_rlimit_fsize = 1; | ||
539 | } | ||
540 | else if (strncmp(argv[i], "--rlimit-sigpending=", 20) == 0) { | ||
541 | if (not_unsigned(argv[i] + 20)) { | ||
542 | fprintf(stderr, "Error: invalid rlimt sigpending\n"); | ||
543 | exit(1); | ||
544 | } | ||
545 | sscanf(argv[i] + 20, "%u", &cfg.rlimit_sigpending); | ||
546 | arg_rlimit_sigpending = 1; | ||
547 | } | ||
548 | else if (strncmp(argv[i], "--ipc-namespace", 15) == 0) | ||
549 | arg_ipc = 1; | ||
550 | else if (strncmp(argv[i], "--cpu=", 6) == 0) | ||
551 | read_cpu_list(argv[i] + 6); | ||
552 | else if (strcmp(argv[i], "--nox11") == 0) { | ||
553 | // check if firejail lkm is present | ||
554 | struct stat s; | ||
555 | if (stat("/proc/firejail", &s) < 0) { | ||
556 | fprintf(stderr, "Error: firejail Linux kernel module not found. The module" | ||
557 | " is required for --nox11 option to work.\n"); | ||
558 | exit(1); | ||
559 | } | ||
560 | arg_nox11 = 1; | ||
561 | } | ||
562 | else if (strcmp(argv[i], "--nodbus") == 0) { | ||
563 | // check if firejail lkm is present | ||
564 | struct stat s; | ||
565 | if (stat("/proc/firejail", &s) < 0) { | ||
566 | fprintf(stderr, "Error: firejail Linux kernel module not found. The module" | ||
567 | " is required for --nodbus option to work.\n"); | ||
568 | exit(1); | ||
569 | } | ||
570 | arg_nodbus = 1; | ||
571 | } | ||
572 | else if (strncmp(argv[i], "--cgroup=", 9) == 0) { | ||
573 | if (arg_cgroup) { | ||
574 | fprintf(stderr, "Error: only a cgroup can be defined\n"); | ||
575 | exit(1); | ||
576 | } | ||
577 | arg_cgroup = 1; | ||
578 | cfg.cgroup = strdup(argv[i] + 9); | ||
579 | if (!cfg.cgroup) | ||
580 | errExit("strdup"); | ||
581 | set_cgroup(cfg.cgroup); | ||
582 | } | ||
583 | |||
584 | //************************************* | ||
585 | // filesystem | ||
586 | //************************************* | ||
587 | #ifdef HAVE_BIND | ||
588 | else if (strncmp(argv[i], "--bind=", 7) == 0) { | ||
589 | char *line; | ||
590 | if (asprintf(&line, "bind %s", argv[i] + 7) == -1) | ||
591 | errExit("asprintf"); | ||
592 | |||
593 | profile_check_line(line, 0); // will exit if something wrong | ||
594 | profile_add(line); | ||
595 | } | ||
596 | #endif | ||
597 | else if (strncmp(argv[i], "--tmpfs=", 8) == 0) { | ||
598 | char *line; | ||
599 | if (asprintf(&line, "tmpfs %s", argv[i] + 8) == -1) | ||
600 | errExit("asprintf"); | ||
601 | |||
602 | profile_check_line(line, 0); // will exit if something wrong | ||
603 | profile_add(line); | ||
604 | } | ||
605 | else if (strncmp(argv[i], "--blacklist=", 12) == 0) { | ||
606 | char *line; | ||
607 | if (asprintf(&line, "blacklist %s", argv[i] + 12) == -1) | ||
608 | errExit("asprintf"); | ||
609 | |||
610 | profile_check_line(line, 0); // will exit if something wrong | ||
611 | profile_add(line); | ||
612 | } | ||
613 | else if (strncmp(argv[i], "--read-only=", 12) == 0) { | ||
614 | char *line; | ||
615 | if (asprintf(&line, "read-only %s", argv[i] + 12) == -1) | ||
616 | errExit("asprintf"); | ||
617 | |||
618 | profile_check_line(line, 0); // will exit if something wrong | ||
619 | profile_add(line); | ||
620 | } | ||
621 | else if (strcmp(argv[i], "--overlay") == 0) { | ||
622 | if (cfg.chrootdir) { | ||
623 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | ||
624 | exit(1); | ||
625 | } | ||
626 | arg_overlay = 1; | ||
627 | } | ||
628 | else if (strncmp(argv[i], "--profile=", 10) == 0) { | ||
629 | // multiple profile files are allowed! | ||
630 | char *ptr = argv[i] + 10; | ||
631 | if (is_dir(ptr) || is_link(ptr) || strstr(ptr, "..")) { | ||
632 | fprintf(stderr, "Error: invalid profile file\n"); | ||
633 | exit(1); | ||
634 | } | ||
635 | |||
636 | // access call checks as real UID/GID, not as effective UID/GID | ||
637 | if (access(argv[i] + 10, R_OK)) { | ||
638 | fprintf(stderr, "Error: cannot access profile file\n"); | ||
639 | return 1; | ||
640 | } | ||
641 | |||
642 | profile_read(argv[i] + 10, NULL, NULL); | ||
643 | custom_profile = 1; | ||
644 | } | ||
645 | #ifdef HAVE_CHROOT | ||
646 | else if (strncmp(argv[i], "--chroot=", 9) == 0) { | ||
647 | if (arg_overlay) { | ||
648 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | ||
649 | exit(1); | ||
650 | } | ||
651 | |||
652 | // extract chroot dirname | ||
653 | cfg.chrootdir = argv[i] + 9; | ||
654 | // if the directory starts with ~, expand the home directory | ||
655 | if (*cfg.chrootdir == '~') { | ||
656 | char *tmp; | ||
657 | if (asprintf(&tmp, "%s%s", cfg.homedir, cfg.chrootdir + 1) == -1) | ||
658 | errExit("asprintf"); | ||
659 | cfg.chrootdir = tmp; | ||
660 | } | ||
661 | |||
662 | // check chroot dirname exists | ||
663 | if (strstr(cfg.chrootdir, "..") || !is_dir(cfg.chrootdir) || is_link(cfg.chrootdir)) { | ||
664 | fprintf(stderr, "Error: invalid directory %s\n", cfg.chrootdir); | ||
665 | return 1; | ||
666 | } | ||
667 | |||
668 | // check chroot directory structure | ||
669 | if (fs_check_chroot_dir(cfg.chrootdir)) { | ||
670 | fprintf(stderr, "Error: invalid chroot\n"); | ||
671 | exit(1); | ||
672 | } | ||
673 | } | ||
674 | #endif | ||
675 | else if (strcmp(argv[i], "--private") == 0) | ||
676 | arg_private = 1; | ||
677 | else if (strncmp(argv[i], "--private=", 10) == 0) { | ||
678 | if (cfg.home_private_keep) { | ||
679 | fprintf(stderr, "Error: a private list of files was already defined with --private.keep option.\n"); | ||
680 | exit(1); | ||
681 | } | ||
682 | |||
683 | // extract private home dirname | ||
684 | cfg.home_private = argv[i] + 10; | ||
685 | fs_check_private_dir(); | ||
686 | arg_private = 1; | ||
687 | } | ||
688 | else if (strncmp(argv[i], "--private.keep=", 15) == 0) { | ||
689 | if (cfg.home_private) { | ||
690 | fprintf(stderr, "Error: a private home directory was already defined with --private option.\n"); | ||
691 | exit(1); | ||
692 | } | ||
693 | |||
694 | // extract private home dirname | ||
695 | cfg.home_private_keep = argv[i] + 15; | ||
696 | fs_check_home_list(); | ||
697 | arg_private = 1; | ||
698 | } | ||
699 | else if (strcmp(argv[i], "--private-dev") == 0) { | ||
700 | arg_private_dev = 1; | ||
701 | } | ||
702 | |||
703 | |||
704 | |||
705 | //************************************* | ||
706 | // hostname, etc | ||
707 | //************************************* | ||
708 | else if (strncmp(argv[i], "--name=", 7) == 0) { | ||
709 | cfg.hostname = argv[i] + 7; | ||
710 | if (strlen(cfg.hostname) == 0) { | ||
711 | fprintf(stderr, "Error: please provide a name for sandbox\n"); | ||
712 | return 1; | ||
713 | } | ||
714 | } | ||
715 | else if (strcmp(argv[i], "--nogroups") == 0) | ||
716 | arg_nogroups = 1; | ||
717 | else if (strcmp(argv[i], "--noroot") == 0) { | ||
718 | check_user_namespace(); | ||
719 | } | ||
720 | |||
721 | //************************************* | ||
722 | // network | ||
723 | //************************************* | ||
724 | else if (strncmp(argv[i], "--net=", 6) == 0) { | ||
725 | if (strcmp(argv[i] + 6, "none") == 0) { | ||
726 | arg_nonetwork = 1; | ||
727 | cfg.bridge0.configured = 0; | ||
728 | cfg.bridge1.configured = 0; | ||
729 | cfg.bridge2.configured = 0; | ||
730 | cfg.bridge3.configured = 0; | ||
731 | continue; | ||
732 | } | ||
733 | if (strcmp(argv[i] + 6, "lo") == 0) { | ||
734 | fprintf(stderr, "Error: cannot attach to lo device\n"); | ||
735 | exit(1); | ||
736 | } | ||
737 | |||
738 | Bridge *br; | ||
739 | if (cfg.bridge0.configured == 0) | ||
740 | br = &cfg.bridge0; | ||
741 | else if (cfg.bridge1.configured == 0) | ||
742 | br = &cfg.bridge1; | ||
743 | else if (cfg.bridge2.configured == 0) | ||
744 | br = &cfg.bridge2; | ||
745 | else if (cfg.bridge3.configured == 0) | ||
746 | br = &cfg.bridge3; | ||
747 | else { | ||
748 | fprintf(stderr, "Error: maximum 4 network devices allowed\n"); | ||
749 | return 1; | ||
750 | } | ||
751 | net_configure_bridge(br, argv[i] + 6); | ||
752 | } | ||
753 | else if (strcmp(argv[i], "--scan") == 0) { | ||
754 | arg_scan = 1; | ||
755 | } | ||
756 | else if (strncmp(argv[i], "--iprange=", 10) == 0) { | ||
757 | Bridge *br = last_bridge_configured(); | ||
758 | if (br == NULL) { | ||
759 | fprintf(stderr, "Error: no network device configured\n"); | ||
760 | return 1; | ||
761 | } | ||
762 | if (br->iprange_start || br->iprange_end) { | ||
763 | fprintf(stderr, "Error: cannot configure the IP range twice for the same interface\n"); | ||
764 | return 1; | ||
765 | } | ||
766 | |||
767 | // parse option arguments | ||
768 | char *firstip = argv[i] + 10; | ||
769 | char *secondip = firstip; | ||
770 | while (*secondip != '\0') { | ||
771 | if (*secondip == ',') | ||
772 | break; | ||
773 | secondip++; | ||
774 | } | ||
775 | if (*secondip == '\0') { | ||
776 | fprintf(stderr, "Error: invalid IP range\n"); | ||
777 | return 1; | ||
778 | } | ||
779 | *secondip = '\0'; | ||
780 | secondip++; | ||
781 | |||
782 | // check addresses | ||
783 | if (atoip(firstip, &br->iprange_start) || atoip(secondip, &br->iprange_end) || | ||
784 | br->iprange_start >= br->iprange_end) { | ||
785 | fprintf(stderr, "Error: invalid IP range\n"); | ||
786 | return 1; | ||
787 | } | ||
788 | if (in_netrange(br->iprange_start, br->ip, br->mask) || in_netrange(br->iprange_end, br->ip, br->mask)) { | ||
789 | fprintf(stderr, "Error: IP range addresses not in network range\n"); | ||
790 | return 1; | ||
791 | } | ||
792 | } | ||
793 | else if (strncmp(argv[i], "--mac=", 6) == 0) { | ||
794 | Bridge *br = last_bridge_configured(); | ||
795 | if (br == NULL) { | ||
796 | fprintf(stderr, "Error: no network device configured\n"); | ||
797 | return 1; | ||
798 | } | ||
799 | if (mac_not_zero(br->macsandbox)) { | ||
800 | fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n"); | ||
801 | return 1; | ||
802 | } | ||
803 | |||
804 | // read the address | ||
805 | if (atomac(argv[i] + 6, br->macsandbox)) { | ||
806 | fprintf(stderr, "Error: invalid MAC address\n"); | ||
807 | return 1; | ||
808 | } | ||
809 | } | ||
810 | else if (strncmp(argv[i], "--ip=", 5) == 0) { | ||
811 | Bridge *br = last_bridge_configured(); | ||
812 | if (br == NULL) { | ||
813 | fprintf(stderr, "Error: no network device configured\n"); | ||
814 | return 1; | ||
815 | } | ||
816 | if (br->arg_ip_none || br->ipsandbox) { | ||
817 | fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n"); | ||
818 | return 1; | ||
819 | } | ||
820 | |||
821 | // configure this IP address for the last bridge defined | ||
822 | if (strcmp(argv[i] + 5, "none") == 0) | ||
823 | br->arg_ip_none = 1; | ||
824 | else { | ||
825 | if (atoip(argv[i] + 5, &br->ipsandbox)) { | ||
826 | fprintf(stderr, "Error: invalid IP address\n"); | ||
827 | return 1; | ||
828 | } | ||
829 | } | ||
830 | } | ||
831 | else if (strncmp(argv[i], "--defaultgw=", 12) == 0) { | ||
832 | if (atoip(argv[i] + 12, &cfg.defaultgw)) { | ||
833 | fprintf(stderr, "Error: invalid IP address\n"); | ||
834 | return 1; | ||
835 | } | ||
836 | } | ||
837 | else if (strncmp(argv[i], "--dns=", 6) == 0) { | ||
838 | uint32_t dns; | ||
839 | if (atoip(argv[i] + 6, &dns)) { | ||
840 | fprintf(stderr, "Error: invalid DNS server IP address\n"); | ||
841 | return 1; | ||
842 | } | ||
843 | |||
844 | if (cfg.dns1 == 0) | ||
845 | cfg.dns1 = dns; | ||
846 | else if (cfg.dns2 == 0) | ||
847 | cfg.dns2 = dns; | ||
848 | else if (cfg.dns3 == 0) | ||
849 | cfg.dns3 = dns; | ||
850 | else { | ||
851 | fprintf(stderr, "Error: up to 3 DNS servers can be specified\n"); | ||
852 | return 1; | ||
853 | } | ||
854 | } | ||
855 | else if (strcmp(argv[i], "--netfilter") == 0) | ||
856 | arg_netfilter = 1; | ||
857 | else if (strncmp(argv[i], "--netfilter=", 12) == 0) { | ||
858 | arg_netfilter = 1; | ||
859 | arg_netfilter_file = argv[i] + 12; | ||
860 | check_netfilter_file(arg_netfilter_file); | ||
861 | } | ||
862 | |||
863 | //************************************* | ||
864 | // command | ||
865 | //************************************* | ||
866 | else if (strcmp(argv[i], "--csh") == 0) { | ||
867 | if (arg_shell_none) { | ||
868 | fprintf(stderr, "Error: --shell=none was already specified.\n"); | ||
869 | return 1; | ||
870 | } | ||
871 | if (arg_zsh || cfg.shell ) { | ||
872 | fprintf(stderr, "Error: only one default user shell can be specified\n"); | ||
873 | return 1; | ||
874 | } | ||
875 | arg_csh = 1; | ||
876 | } | ||
877 | else if (strcmp(argv[i], "--zsh") == 0) { | ||
878 | if (arg_shell_none) { | ||
879 | fprintf(stderr, "Error: --shell=none was already specified.\n"); | ||
880 | return 1; | ||
881 | } | ||
882 | if (arg_csh || cfg.shell ) { | ||
883 | fprintf(stderr, "Error: only one default user shell can be specified\n"); | ||
884 | return 1; | ||
885 | } | ||
886 | arg_zsh = 1; | ||
887 | } | ||
888 | else if (strcmp(argv[i], "--shell=none") == 0) { | ||
889 | arg_shell_none = 1; | ||
890 | if (arg_csh || arg_zsh || cfg.shell) { | ||
891 | fprintf(stderr, "Error: a shell was already specified\n"); | ||
892 | return 1; | ||
893 | } | ||
894 | } | ||
895 | else if (strncmp(argv[i], "--shell=", 8) == 0) { | ||
896 | if (arg_shell_none) { | ||
897 | fprintf(stderr, "Error: --shell=none was already specified.\n"); | ||
898 | return 1; | ||
899 | } | ||
900 | if (arg_csh || arg_zsh || cfg.shell) { | ||
901 | fprintf(stderr, "Error: only one user shell can be specified\n"); | ||
902 | return 1; | ||
903 | } | ||
904 | cfg.shell = argv[i] + 8; | ||
905 | |||
906 | if (is_dir(cfg.shell) || is_link(cfg.shell) || strstr(cfg.shell, "..")) { | ||
907 | fprintf(stderr, "Error: invalid shell\n"); | ||
908 | exit(1); | ||
909 | } | ||
910 | |||
911 | // access call checks as real UID/GID, not as effective UID/GID | ||
912 | if (access(cfg.shell, R_OK)) { | ||
913 | fprintf(stderr, "Error: cannot access shell file\n"); | ||
914 | exit(1); | ||
915 | } | ||
916 | } | ||
917 | else if (strcmp(argv[i], "-c") == 0) { | ||
918 | arg_command = 1; | ||
919 | if (i == (argc - 1)) { | ||
920 | fprintf(stderr, "Error: option -c requires an argument\n"); | ||
921 | return 1; | ||
922 | } | ||
923 | } | ||
924 | else if (strcmp(argv[i], "--") == 0) { | ||
925 | // double dash - positional params to follow | ||
926 | arg_doubledash = 1; | ||
927 | i++; | ||
928 | if (i >= argc) { | ||
929 | fprintf(stderr, "Error: program name not found\n"); | ||
930 | exit(1); | ||
931 | } | ||
932 | extract_command_name(argv[i]); | ||
933 | prog_index = i; | ||
934 | cfg.original_program_index = i; | ||
935 | break; | ||
936 | } | ||
937 | else { | ||
938 | // is this an invalid option? | ||
939 | if (*argv[i] == '-') { | ||
940 | fprintf(stderr, "Error: invalid %s command line option\n", argv[i]); | ||
941 | return 1; | ||
942 | } | ||
943 | |||
944 | // we have a program name coming | ||
945 | extract_command_name(argv[i]); | ||
946 | prog_index = i; | ||
947 | cfg.original_program_index = i; | ||
948 | break; | ||
949 | } | ||
950 | } | ||
951 | |||
952 | // check network configuration options - it will exit if anything went wrong | ||
953 | net_check_cfg(); | ||
954 | |||
955 | // check user namespace (--noroot) options | ||
956 | if (arg_noroot) { | ||
957 | if (arg_overlay) { | ||
958 | fprintf(stderr, "Error: --overlay and --noroot are mutually exclusive.\n"); | ||
959 | exit(1); | ||
960 | } | ||
961 | else if (cfg.chrootdir) { | ||
962 | fprintf(stderr, "Error: --chroot and --noroot are mutually exclusive.\n"); | ||
963 | exit(1); | ||
964 | } | ||
965 | } | ||
966 | |||
967 | // log command | ||
968 | logargs(argc, argv); | ||
969 | if (fullargc) { | ||
970 | char *msg; | ||
971 | if (asprintf(&msg, "user %s entering restricted shell", cfg.username) == -1) | ||
972 | errExit("asprintf"); | ||
973 | logmsg(msg); | ||
974 | free(msg); | ||
975 | } | ||
976 | |||
977 | // build the sandbox command | ||
978 | if (prog_index == -1 && arg_zsh) { | ||
979 | cfg.command_line = "/usr/bin/zsh"; | ||
980 | cfg.command_name = "zsh"; | ||
981 | } | ||
982 | else if (prog_index == -1 && arg_csh) { | ||
983 | cfg.command_line = "/bin/csh"; | ||
984 | cfg.command_name = "csh"; | ||
985 | } | ||
986 | else if (prog_index == -1 && cfg.shell) { | ||
987 | cfg.command_line = cfg.shell; | ||
988 | cfg.command_name = cfg.shell; | ||
989 | } | ||
990 | else if (prog_index == -1) { | ||
991 | cfg.command_line = "/bin/bash"; | ||
992 | cfg.command_name = "bash"; | ||
993 | } | ||
994 | else { | ||
995 | // calculate the length of the command | ||
996 | int i; | ||
997 | int len = 0; | ||
998 | int argcnt = argc - prog_index; | ||
999 | for (i = 0; i < argcnt; i++) | ||
1000 | len += strlen(argv[i + prog_index]) + 1; // + ' ' | ||
1001 | |||
1002 | // build the string | ||
1003 | cfg.command_line = malloc(len + 1); // + '\0' | ||
1004 | if (!cfg.command_line) | ||
1005 | errExit("malloc"); | ||
1006 | char *ptr = cfg.command_line; | ||
1007 | for (i = 0; i < argcnt; i++) { | ||
1008 | sprintf(ptr, "%s ", argv[i + prog_index]); | ||
1009 | ptr += strlen(ptr); | ||
1010 | } | ||
1011 | } | ||
1012 | |||
1013 | // load the profile | ||
1014 | { | ||
1015 | assert(cfg.command_name); | ||
1016 | if (arg_debug) | ||
1017 | printf("Command name #%s#\n", cfg.command_name); | ||
1018 | if (!custom_profile) { | ||
1019 | // look for a profile in ~/.config/firejail directory | ||
1020 | char *usercfgdir; | ||
1021 | if (asprintf(&usercfgdir, "%s/.config/firejail", cfg.homedir) == -1) | ||
1022 | errExit("asprintf"); | ||
1023 | int rv = profile_find(cfg.command_name, usercfgdir); | ||
1024 | free(usercfgdir); | ||
1025 | custom_profile = rv; | ||
1026 | } | ||
1027 | if (!custom_profile) { | ||
1028 | // look for a user profile in /etc/firejail directory | ||
1029 | int rv = profile_find(cfg.command_name, "/etc/firejail"); | ||
1030 | custom_profile = rv; | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1034 | // check and assign an IP address - for macvlan it will be done again in the sandbox! | ||
1035 | if (any_bridge_configured()) { | ||
1036 | lockfd = open("/tmp/firejail/firejail.lock", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); | ||
1037 | if (lockfd != -1) { | ||
1038 | int rv = fchown(lockfd, 0, 0); | ||
1039 | (void) rv; | ||
1040 | flock(lockfd, LOCK_EX); | ||
1041 | } | ||
1042 | |||
1043 | check_network(&cfg.bridge0); | ||
1044 | check_network(&cfg.bridge1); | ||
1045 | check_network(&cfg.bridge2); | ||
1046 | check_network(&cfg.bridge3); | ||
1047 | |||
1048 | // save network mapping in shared memory | ||
1049 | network_shm_set_file(sandbox_pid); | ||
1050 | } | ||
1051 | |||
1052 | // create the parent-child communication pipe | ||
1053 | if (pipe(parent_to_child_fds) < 0) | ||
1054 | errExit("pipe"); | ||
1055 | if (pipe(child_to_parent_fds) < 0) | ||
1056 | errExit("pipe"); | ||
1057 | |||
1058 | // clone environment | ||
1059 | int flags = CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWUTS | SIGCHLD; | ||
1060 | |||
1061 | // in root mode also enable CLONE_NEWIPC | ||
1062 | // in user mode CLONE_NEWIPC will break MIT Shared Memory Extension (MIT-SHM) | ||
1063 | if (getuid() == 0 || arg_ipc) | ||
1064 | flags |= CLONE_NEWIPC; | ||
1065 | |||
1066 | if (any_bridge_configured() || arg_nonetwork) { | ||
1067 | flags |= CLONE_NEWNET; | ||
1068 | } | ||
1069 | else if (arg_debug) | ||
1070 | printf("Using the local network stack\n"); | ||
1071 | |||
1072 | child = clone(sandbox, | ||
1073 | child_stack + STACK_SIZE, | ||
1074 | flags, | ||
1075 | NULL); | ||
1076 | if (child == -1) | ||
1077 | errExit("clone"); | ||
1078 | |||
1079 | if (!arg_command) { | ||
1080 | printf("Parent pid %u, child pid %u\n", sandbox_pid, child); | ||
1081 | // print the path of the new log directory | ||
1082 | if (getuid() == 0) // only for root | ||
1083 | printf("The new log directory is /proc/%d/root/var/log\n", child); | ||
1084 | } | ||
1085 | |||
1086 | |||
1087 | |||
1088 | // create veth pair or macvlan device | ||
1089 | if (cfg.bridge0.configured && !arg_nonetwork) { | ||
1090 | if (cfg.bridge0.macvlan == 0) | ||
1091 | net_configure_veth_pair(&cfg.bridge0, "eth0", child); | ||
1092 | else | ||
1093 | net_create_macvlan(cfg.bridge0.devsandbox, cfg.bridge0.dev, child); | ||
1094 | } | ||
1095 | |||
1096 | if (cfg.bridge1.configured && !arg_nonetwork) { | ||
1097 | if (cfg.bridge1.macvlan == 0) | ||
1098 | net_configure_veth_pair(&cfg.bridge1, "eth1", child); | ||
1099 | else | ||
1100 | net_create_macvlan(cfg.bridge1.devsandbox, cfg.bridge1.dev, child); | ||
1101 | } | ||
1102 | |||
1103 | if (cfg.bridge2.configured && !arg_nonetwork) { | ||
1104 | if (cfg.bridge2.macvlan == 0) | ||
1105 | net_configure_veth_pair(&cfg.bridge2, "eth2", child); | ||
1106 | else | ||
1107 | net_create_macvlan(cfg.bridge2.devsandbox, cfg.bridge2.dev, child); | ||
1108 | } | ||
1109 | |||
1110 | if (cfg.bridge3.configured && !arg_nonetwork) { | ||
1111 | if (cfg.bridge3.macvlan == 0) | ||
1112 | net_configure_veth_pair(&cfg.bridge3, "eth3", child); | ||
1113 | else | ||
1114 | net_create_macvlan(cfg.bridge3.devsandbox, cfg.bridge3.dev, child); | ||
1115 | } | ||
1116 | |||
1117 | // close each end of the unused pipes | ||
1118 | close(parent_to_child_fds[0]); | ||
1119 | close(child_to_parent_fds[1]); | ||
1120 | |||
1121 | // notify child that base setup is complete | ||
1122 | notify_other(parent_to_child_fds[1]); | ||
1123 | |||
1124 | // wait for child to create new user namespace with CLONE_NEWUSER | ||
1125 | wait_for_other(child_to_parent_fds[0]); | ||
1126 | close(child_to_parent_fds[0]); | ||
1127 | |||
1128 | if (arg_noroot) { | ||
1129 | // update the UID and GID maps in the new child user namespace | ||
1130 | // uid | ||
1131 | char *map_path; | ||
1132 | if (asprintf(&map_path, "/proc/%d/uid_map", child) == -1) | ||
1133 | errExit("asprintf"); | ||
1134 | char *map; | ||
1135 | uid_t uid = getuid(); | ||
1136 | if (asprintf(&map, "%d %d 1", uid, uid) == -1) | ||
1137 | errExit("asprintf"); | ||
1138 | update_map(map, map_path); | ||
1139 | free(map); | ||
1140 | free(map_path); | ||
1141 | |||
1142 | //gid | ||
1143 | if (asprintf(&map_path, "/proc/%d/gid_map", child) == -1) | ||
1144 | errExit("asprintf"); | ||
1145 | gid_t gid = getgid(); | ||
1146 | if (asprintf(&map, "%d %d 1", gid, gid) == -1) | ||
1147 | errExit("asprintf"); | ||
1148 | update_map(map, map_path); | ||
1149 | free(map); | ||
1150 | free(map_path); | ||
1151 | } | ||
1152 | |||
1153 | // notify child that UID/GID mapping is complete | ||
1154 | notify_other(parent_to_child_fds[1]); | ||
1155 | close(parent_to_child_fds[1]); | ||
1156 | |||
1157 | if (lockfd != -1) | ||
1158 | flock(lockfd, LOCK_UN); | ||
1159 | |||
1160 | // handle CTRL-C in parent | ||
1161 | signal (SIGINT, my_handler); | ||
1162 | signal (SIGTERM, my_handler); | ||
1163 | |||
1164 | // wait for the child to finish | ||
1165 | waitpid(child, NULL, 0); | ||
1166 | myexit(0); | ||
1167 | return 0; | ||
1168 | } | ||
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c new file mode 100644 index 000000000..dbed4ac30 --- /dev/null +++ b/src/firejail/netfilter.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/mount.h> | ||
22 | #include <sys/stat.h> | ||
23 | #include <sys/types.h> | ||
24 | #include <sys/wait.h> | ||
25 | #include <fcntl.h> | ||
26 | |||
27 | static char *client_filter = | ||
28 | "*filter\n" | ||
29 | ":INPUT DROP [0:0]\n" | ||
30 | ":FORWARD DROP [0:0]\n" | ||
31 | ":OUTPUT ACCEPT [0:0]\n" | ||
32 | "-A INPUT -i lo -j ACCEPT\n" | ||
33 | "# echo replay is handled by -m state RELEATED/ESTABLISHED below\n" | ||
34 | "#-A INPUT -p icmp --icmp-type echo-reply -j ACCEPT\n" | ||
35 | "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n" | ||
36 | "-A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT\n" | ||
37 | "-A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT\n" | ||
38 | "-A INPUT -p icmp --icmp-type echo-request -j ACCEPT \n" | ||
39 | "COMMIT\n"; | ||
40 | |||
41 | void check_netfilter_file(const char *fname) { | ||
42 | if (is_dir(fname) || is_link(fname) || strstr(fname, "..")) { | ||
43 | fprintf(stderr, "Error: invalid network filter file\n"); | ||
44 | exit(1); | ||
45 | } | ||
46 | |||
47 | // access call checks as real UID/GID, not as effective UID/GID | ||
48 | if (access(fname, R_OK)) { | ||
49 | fprintf(stderr, "Error: cannot access network filter file\n"); | ||
50 | exit(1); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | |||
55 | void netfilter(const char *fname) { | ||
56 | // default filter | ||
57 | char *filter = client_filter; | ||
58 | |||
59 | // custom filter | ||
60 | int allocated = 0; | ||
61 | if (fname) { | ||
62 | // buffer the filter | ||
63 | struct stat s; | ||
64 | if (stat(fname, &s) == -1) { | ||
65 | fprintf(stderr, "Error: cannot find network filter file\n"); | ||
66 | exit(1); | ||
67 | } | ||
68 | |||
69 | filter = malloc(s.st_size + 1); // + '\0' | ||
70 | memset(filter, 0, s.st_size + 1); | ||
71 | if (!filter) | ||
72 | errExit("malloc"); | ||
73 | |||
74 | /* coverity[toctou] */ | ||
75 | FILE *fp = fopen(fname, "r"); | ||
76 | if (!fp) { | ||
77 | fprintf(stderr, "Error: cannot open network filter file\n"); | ||
78 | exit(1); | ||
79 | } | ||
80 | |||
81 | size_t sz = fread(filter, 1, s.st_size, fp); | ||
82 | if (sz != s.st_size) { | ||
83 | fprintf(stderr, "Error: cannot read network filter file\n"); | ||
84 | exit(1); | ||
85 | } | ||
86 | fclose(fp); | ||
87 | allocated = 1; | ||
88 | } | ||
89 | |||
90 | // mount a tempfs on top of /tmp directory | ||
91 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
92 | errExit("mounting /tmp"); | ||
93 | |||
94 | // create the filter file | ||
95 | FILE *fp = fopen("/tmp/netfilter", "w"); | ||
96 | if (!fp) { | ||
97 | fprintf(stderr, "Error: cannot open /tmp/netfilter file\n"); | ||
98 | exit(1); | ||
99 | } | ||
100 | fprintf(fp, "%s\n", filter); | ||
101 | fclose(fp); | ||
102 | |||
103 | // find iptables command | ||
104 | struct stat s; | ||
105 | char *iptables = NULL; | ||
106 | char *iptables_restore = NULL; | ||
107 | if (stat("/sbin/iptables", &s) == 0) { | ||
108 | iptables = "/sbin/iptables"; | ||
109 | iptables_restore = "/sbin/iptables-restore"; | ||
110 | } | ||
111 | else if (stat("/usr/sbin/iptables", &s) == 0) { | ||
112 | iptables = "/usr/sbin/iptables"; | ||
113 | iptables_restore = "/usr/sbin/iptables-restore"; | ||
114 | } | ||
115 | if (iptables == NULL || iptables_restore == NULL) { | ||
116 | fprintf(stderr, "Error: iptables command not found\n"); | ||
117 | goto doexit; | ||
118 | } | ||
119 | |||
120 | // push filter | ||
121 | pid_t child = fork(); | ||
122 | if (child < 0) | ||
123 | errExit("fork"); | ||
124 | if (child == 0) { | ||
125 | if (arg_debug) | ||
126 | printf("Installing network filter:\n%s\n", filter); | ||
127 | |||
128 | int fd; | ||
129 | if((fd = open("/tmp/netfilter", O_RDONLY)) == -1) { | ||
130 | fprintf(stderr,"Error: cannot open /tmp/netfilter\n"); | ||
131 | exit(1); | ||
132 | } | ||
133 | dup2(fd,STDIN_FILENO); | ||
134 | close(fd); | ||
135 | |||
136 | // wipe out environment variables | ||
137 | environ = NULL; | ||
138 | execl(iptables_restore, iptables_restore, NULL); | ||
139 | // it will never get here!!! | ||
140 | } | ||
141 | // wait for the child to finish | ||
142 | waitpid(child, NULL, 0); | ||
143 | |||
144 | // debug | ||
145 | if (arg_debug) { | ||
146 | child = fork(); | ||
147 | if (child < 0) | ||
148 | errExit("fork"); | ||
149 | if (child == 0) { | ||
150 | environ = NULL; | ||
151 | execl(iptables, iptables, "-vL", NULL); | ||
152 | // it will never get here!!! | ||
153 | } | ||
154 | // wait for the child to finish | ||
155 | waitpid(child, NULL, 0); | ||
156 | } | ||
157 | |||
158 | doexit: | ||
159 | // unmount /tmp | ||
160 | umount("/tmp"); | ||
161 | |||
162 | if (allocated) | ||
163 | free(filter); | ||
164 | } | ||
diff --git a/src/firejail/network.c b/src/firejail/network.c new file mode 100644 index 000000000..6a1d52744 --- /dev/null +++ b/src/firejail/network.c | |||
@@ -0,0 +1,362 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <arpa/inet.h> | ||
22 | #include <sys/socket.h> | ||
23 | #include <sys/ioctl.h> | ||
24 | #include <netdb.h> | ||
25 | #include <ifaddrs.h> | ||
26 | #include <net/if.h> | ||
27 | #include <net/if_arp.h> | ||
28 | #include <net/route.h> | ||
29 | #include <linux/if_bridge.h> | ||
30 | |||
31 | // scan interfaces in current namespace and print IP address/mask for each interface | ||
32 | void net_ifprint(void) { | ||
33 | uint32_t ip; | ||
34 | uint32_t mask; | ||
35 | struct ifaddrs *ifaddr, *ifa; | ||
36 | |||
37 | if (getifaddrs(&ifaddr) == -1) | ||
38 | errExit("getifaddrs"); | ||
39 | |||
40 | printf("%-17.17s%-19.19s%-17.17s%-17.17s%-6.6s\n", | ||
41 | "Interface", "MAC", "IP", "Mask", "Status"); | ||
42 | // walk through the linked list | ||
43 | for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { | ||
44 | if (ifa->ifa_addr == NULL) | ||
45 | continue; | ||
46 | |||
47 | if (ifa->ifa_addr->sa_family == AF_INET) { | ||
48 | struct sockaddr_in *si = (struct sockaddr_in *) ifa->ifa_netmask; | ||
49 | mask = ntohl(si->sin_addr.s_addr); | ||
50 | si = (struct sockaddr_in *) ifa->ifa_addr; | ||
51 | ip = ntohl(si->sin_addr.s_addr); | ||
52 | |||
53 | // interface status | ||
54 | char *status; | ||
55 | if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP) | ||
56 | status = "UP"; | ||
57 | else | ||
58 | status = "DOWN"; | ||
59 | |||
60 | // ip address and mask | ||
61 | char ipstr[30]; | ||
62 | sprintf(ipstr, "%d.%d.%d.%d", PRINT_IP(ip)); | ||
63 | char maskstr[30]; | ||
64 | sprintf(maskstr, "%d.%d.%d.%d", PRINT_IP(mask)); | ||
65 | |||
66 | // mac address | ||
67 | unsigned char mac[6]; | ||
68 | net_get_mac(ifa->ifa_name, mac); | ||
69 | char macstr[30]; | ||
70 | if (strcmp(ifa->ifa_name, "lo") == 0) | ||
71 | macstr[0] = '\0'; | ||
72 | else | ||
73 | sprintf(macstr, "%02x:%02x:%02x:%02x:%02x:%02x", PRINT_MAC(mac)); | ||
74 | |||
75 | |||
76 | printf("%-17.17s%-19.19s%-17.17s%-17.17s%-6.6s\n", | ||
77 | ifa->ifa_name, macstr, ipstr, maskstr, status); | ||
78 | |||
79 | // network scanning | ||
80 | if (!arg_scan) // scanning disabled | ||
81 | continue; | ||
82 | if (strcmp(ifa->ifa_name, "lo") == 0) // no loopbabck scanning | ||
83 | continue; | ||
84 | if (mask2bits(mask) < 16) // not scanning large networks | ||
85 | continue; | ||
86 | if (!ip) // if not configured | ||
87 | continue; | ||
88 | // only if the interface is up and running | ||
89 | if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP) | ||
90 | arp_scan(ifa->ifa_name, ip, mask); | ||
91 | } | ||
92 | } | ||
93 | freeifaddrs(ifaddr); | ||
94 | } | ||
95 | |||
96 | |||
97 | // return -1 if the interface was not found; if the interface was found retrn 0 and fill in IP address and mask | ||
98 | int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6]) { | ||
99 | assert(bridge); | ||
100 | assert(ip); | ||
101 | assert(mask); | ||
102 | int rv = -1; | ||
103 | struct ifaddrs *ifaddr, *ifa; | ||
104 | |||
105 | if (getifaddrs(&ifaddr) == -1) | ||
106 | errExit("getifaddrs"); | ||
107 | |||
108 | // walk through the linked list; if the interface is found, extract IP address and mask | ||
109 | for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { | ||
110 | if (ifa->ifa_addr == NULL) | ||
111 | continue; | ||
112 | if (strcmp(ifa->ifa_name, bridge) != 0) | ||
113 | continue; | ||
114 | |||
115 | if (ifa->ifa_addr->sa_family == AF_INET) { | ||
116 | struct sockaddr_in *si = (struct sockaddr_in *) ifa->ifa_netmask; | ||
117 | *mask = ntohl(si->sin_addr.s_addr); | ||
118 | si = (struct sockaddr_in *) ifa->ifa_addr; | ||
119 | *ip = ntohl(si->sin_addr.s_addr); | ||
120 | if (strcmp(ifa->ifa_name, "lo") != 0) | ||
121 | net_get_mac(ifa->ifa_name, mac); | ||
122 | |||
123 | rv = 0; | ||
124 | break; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | freeifaddrs(ifaddr); | ||
129 | return rv; | ||
130 | } | ||
131 | |||
132 | // bring interface up | ||
133 | void net_if_up(const char *ifname) { | ||
134 | if (strlen(ifname) > IFNAMSIZ) { | ||
135 | fprintf(stderr, "Error: invalid network device name %s\n", ifname); | ||
136 | exit(1); | ||
137 | } | ||
138 | |||
139 | int sock = socket(AF_INET,SOCK_DGRAM,0); | ||
140 | if (sock < 0) | ||
141 | errExit("socket"); | ||
142 | |||
143 | // get the existing interface flags | ||
144 | struct ifreq ifr; | ||
145 | memset(&ifr, 0, sizeof(ifr)); | ||
146 | strncpy(ifr.ifr_name, ifname, IFNAMSIZ); | ||
147 | ifr.ifr_addr.sa_family = AF_INET; | ||
148 | |||
149 | // read the existing flags | ||
150 | if (ioctl(sock, SIOCGIFFLAGS, &ifr ) < 0) { | ||
151 | close(sock); | ||
152 | errExit("ioctl"); | ||
153 | } | ||
154 | |||
155 | ifr.ifr_flags |= IFF_UP; | ||
156 | |||
157 | // set the new flags | ||
158 | if (ioctl( sock, SIOCSIFFLAGS, &ifr ) < 0) { | ||
159 | close(sock); | ||
160 | errExit("ioctl"); | ||
161 | } | ||
162 | |||
163 | // checking | ||
164 | // read the existing flags | ||
165 | if (ioctl(sock, SIOCGIFFLAGS, &ifr ) < 0) { | ||
166 | close(sock); | ||
167 | errExit("ioctl"); | ||
168 | } | ||
169 | |||
170 | // wait not more than 500ms for the interface to come up | ||
171 | int cnt = 0; | ||
172 | while (cnt < 50) { | ||
173 | usleep(10000); // sleep 10ms | ||
174 | |||
175 | // read the existing flags | ||
176 | if (ioctl(sock, SIOCGIFFLAGS, &ifr ) < 0) { | ||
177 | close(sock); | ||
178 | errExit("ioctl"); | ||
179 | } | ||
180 | if (ifr.ifr_flags & IFF_RUNNING) | ||
181 | break; | ||
182 | cnt++; | ||
183 | } | ||
184 | |||
185 | close(sock); | ||
186 | } | ||
187 | |||
188 | // configure interface | ||
189 | void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask) { | ||
190 | if (strlen(ifname) > IFNAMSIZ) { | ||
191 | fprintf(stderr, "Error: invalid network device name %s\n", ifname); | ||
192 | exit(1); | ||
193 | } | ||
194 | |||
195 | int sock = socket(AF_INET,SOCK_DGRAM,0); | ||
196 | if (sock < 0) | ||
197 | errExit("socket"); | ||
198 | |||
199 | struct ifreq ifr; | ||
200 | memset(&ifr, 0, sizeof(ifr)); | ||
201 | strncpy(ifr.ifr_name, ifname, IFNAMSIZ); | ||
202 | ifr.ifr_addr.sa_family = AF_INET; | ||
203 | |||
204 | ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr = htonl(ip); | ||
205 | if (ioctl( sock, SIOCSIFADDR, &ifr ) < 0) { | ||
206 | close(sock); | ||
207 | errExit("ioctl"); | ||
208 | } | ||
209 | |||
210 | if (ip != 0) { | ||
211 | ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr = htonl(mask); | ||
212 | if (ioctl( sock, SIOCSIFNETMASK, &ifr ) < 0) { | ||
213 | close(sock); | ||
214 | errExit("ioctl"); | ||
215 | } | ||
216 | } | ||
217 | |||
218 | close(sock); | ||
219 | usleep(10000); // sleep 10ms | ||
220 | } | ||
221 | |||
222 | |||
223 | // add an IP route, return -1 if error, 0 if the route was added | ||
224 | int net_add_route(uint32_t ip, uint32_t mask, uint32_t gw) { | ||
225 | int sock; | ||
226 | struct rtentry route; | ||
227 | struct sockaddr_in *addr; | ||
228 | int err = 0; | ||
229 | |||
230 | // create the socket | ||
231 | if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) | ||
232 | errExit("socket"); | ||
233 | |||
234 | memset(&route, 0, sizeof(route)); | ||
235 | |||
236 | addr = (struct sockaddr_in*) &route.rt_gateway; | ||
237 | addr->sin_family = AF_INET; | ||
238 | addr->sin_addr.s_addr = htonl(gw); | ||
239 | |||
240 | addr = (struct sockaddr_in*) &route.rt_dst; | ||
241 | addr->sin_family = AF_INET; | ||
242 | addr->sin_addr.s_addr = htonl(ip); | ||
243 | |||
244 | addr = (struct sockaddr_in*) &route.rt_genmask; | ||
245 | addr->sin_family = AF_INET; | ||
246 | addr->sin_addr.s_addr = htonl(mask); | ||
247 | |||
248 | route.rt_flags = RTF_UP | RTF_GATEWAY; | ||
249 | route.rt_metric = 0; | ||
250 | if ((err = ioctl(sock, SIOCADDRT, &route)) != 0) { | ||
251 | close(sock); | ||
252 | return -1; | ||
253 | } | ||
254 | |||
255 | close(sock); | ||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | |||
260 | // add a veth device to a bridge | ||
261 | void net_bridge_add_interface(const char *bridge, const char *dev) { | ||
262 | if (strlen(bridge) > IFNAMSIZ) { | ||
263 | fprintf(stderr, "Error: invalid network device name %s\n", bridge); | ||
264 | exit(1); | ||
265 | } | ||
266 | |||
267 | struct ifreq ifr; | ||
268 | int err; | ||
269 | int ifindex = if_nametoindex(dev); | ||
270 | |||
271 | if (ifindex <= 0) | ||
272 | errExit("if_nametoindex"); | ||
273 | |||
274 | int sock; | ||
275 | if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) | ||
276 | errExit("socket"); | ||
277 | |||
278 | memset(&ifr, 0, sizeof(ifr)); | ||
279 | strncpy(ifr.ifr_name, bridge, IFNAMSIZ); | ||
280 | #ifdef SIOCBRADDIF | ||
281 | ifr.ifr_ifindex = ifindex; | ||
282 | err = ioctl(sock, SIOCBRADDIF, &ifr); | ||
283 | if (err < 0) | ||
284 | #endif | ||
285 | { | ||
286 | unsigned long args[4] = { BRCTL_ADD_IF, ifindex, 0, 0 }; | ||
287 | |||
288 | ifr.ifr_data = (char *) args; | ||
289 | err = ioctl(sock, SIOCDEVPRIVATE, &ifr); | ||
290 | } | ||
291 | (void) err; | ||
292 | close(sock); | ||
293 | } | ||
294 | |||
295 | #define BUFSIZE 1024 | ||
296 | uint32_t network_get_defaultgw(void) { | ||
297 | FILE *fp = fopen("/proc/self/net/route", "r"); | ||
298 | if (!fp) | ||
299 | errExit("fopen"); | ||
300 | |||
301 | char buf[BUFSIZE]; | ||
302 | uint32_t retval = 0; | ||
303 | while (fgets(buf, BUFSIZE, fp)) { | ||
304 | if (strncmp(buf, "Iface", 5) == 0) | ||
305 | continue; | ||
306 | |||
307 | char *ptr = buf; | ||
308 | while (*ptr != ' ' && *ptr != '\t') | ||
309 | ptr++; | ||
310 | while (*ptr == ' ' || *ptr == '\t') | ||
311 | ptr++; | ||
312 | |||
313 | unsigned dest; | ||
314 | unsigned gw; | ||
315 | int rv = sscanf(ptr, "%x %x", &dest, &gw); | ||
316 | if (rv == 2 && dest == 0) { | ||
317 | retval = ntohl(gw); | ||
318 | break; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | fclose(fp); | ||
323 | return retval; | ||
324 | } | ||
325 | |||
326 | int net_config_mac(const char *ifname, const unsigned char mac[6]) { | ||
327 | struct ifreq ifr; | ||
328 | int sock; | ||
329 | |||
330 | if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) | ||
331 | errExit("socket"); | ||
332 | |||
333 | memset(&ifr, 0, sizeof(ifr)); | ||
334 | strncpy(ifr.ifr_name, ifname, IFNAMSIZ); | ||
335 | ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; | ||
336 | memcpy(ifr.ifr_hwaddr.sa_data, mac, 6); | ||
337 | |||
338 | if (ioctl(sock, SIOCSIFHWADDR, &ifr) == -1) | ||
339 | errExit("ioctl"); | ||
340 | close(sock); | ||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | int net_get_mac(const char *ifname, unsigned char mac[6]) { | ||
345 | |||
346 | struct ifreq ifr; | ||
347 | int sock; | ||
348 | |||
349 | if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) | ||
350 | errExit("socket"); | ||
351 | |||
352 | memset(&ifr, 0, sizeof(ifr)); | ||
353 | strncpy(ifr.ifr_name, ifname, IFNAMSIZ); | ||
354 | ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; | ||
355 | |||
356 | if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) | ||
357 | errExit("ioctl"); | ||
358 | memcpy(mac, ifr.ifr_hwaddr.sa_data, 6); | ||
359 | |||
360 | close(sock); | ||
361 | return 0; | ||
362 | } | ||
diff --git a/src/firejail/network.txt b/src/firejail/network.txt new file mode 100644 index 000000000..673d5b941 --- /dev/null +++ b/src/firejail/network.txt | |||
@@ -0,0 +1,95 @@ | |||
1 | struct Bridge { | ||
2 | char *dev; // bridge device name | ||
3 | uint32_t ip; // bridge device IP address | ||
4 | uint32_t mask; // bridge device mask | ||
5 | uint32_t ipsandbox // sandbox interface IP address | ||
6 | } | ||
7 | |||
8 | net_configure_bridge(br, device) { | ||
9 | br->dev = devname; | ||
10 | br->ip = extracted from kernel device - using net_get_if_addr() in network.c | ||
11 | br->mask = extracted from kernel device - using net_get_if_addr() in network.c | ||
12 | check available network range; /31 networks are not supported | ||
13 | } | ||
14 | |||
15 | net_configure_sandbox_ip(br) { | ||
16 | if br->ip_snadbox | ||
17 | check br->ipsandbox inside the bridge network | ||
18 | arp_check(br->ipsandbox) // send an arp req to check if anybody else is using this address | ||
19 | else | ||
20 | br->ipsandbox = arp_assign(); | ||
21 | } | ||
22 | |||
23 | net_configure_veth_pair { | ||
24 | create a veth pair | ||
25 | place one interface end in the bridge | ||
26 | place the other end in the namespace of the child process | ||
27 | } | ||
28 | |||
29 | net_bridge_wait_ip { | ||
30 | arp_check br->ipsandbox address to come up | ||
31 | wait for not more than 5 seconds | ||
32 | } | ||
33 | |||
34 | main() { | ||
35 | |||
36 | foreach argv[i] { | ||
37 | if --net | ||
38 | br = next bridge available | ||
39 | net_configure_bridge(br, device name from argv[i]); | ||
40 | else if --ip | ||
41 | br = last bridge configured | ||
42 | br->ipsandbox = ip address extracted from argv[i] | ||
43 | else if --defaultgw | ||
44 | cfg.defaultgw = ip address extracted from argv[i] | ||
45 | } | ||
46 | |||
47 | net_check_cfg(); // check the validity of network configuration so far | ||
48 | |||
49 | if (any bridge configured) { | ||
50 | lock /var/lock/firejail.lock file | ||
51 | for each bridge | ||
52 | net_configure_sandbox_ip(br) | ||
53 | } | ||
54 | |||
55 | clone (new network namespace if any bridge configured or --net=none) | ||
56 | |||
57 | if (any bridge configured) { | ||
58 | for each bridge | ||
59 | net_configure_veth_pair | ||
60 | } | ||
61 | |||
62 | notify child init is done | ||
63 | |||
64 | if (any bridge configured) { | ||
65 | for each bridge | ||
66 | net_bridge_wait_ip | ||
67 | unlock /var/lock/firejail.lock file | ||
68 | } | ||
69 | |||
70 | wait on child | ||
71 | exit | ||
72 | } | ||
73 | |||
74 | |||
75 | ****************************************************** | ||
76 | * macvlan notes | ||
77 | ****************************************************** | ||
78 | Configure a macvlan interface | ||
79 | |||
80 | # ip link add virtual0 link eth0 type macvlan mode bridge | ||
81 | (you can configure it with # ifconfig virtual0 192.168.1.52/24 up) | ||
82 | |||
83 | Create a new network namespace and move the interface in the new network namespace | ||
84 | |||
85 | # ip netns add dummy0 | ||
86 | # ip link set virtual0 netns dummy0 | ||
87 | |||
88 | Join the namespace and configure the interfaces | ||
89 | |||
90 | # ip netns exec dummy0 bash | ||
91 | # ifconfig lo up | ||
92 | # ifconfig virtual0 192.168.1.52/24 | ||
93 | |||
94 | Investigate ipvlan interface - added to linux kernel 3.19 | ||
95 | https://github.com/torvalds/linux/blob/master/Documentation/networking/ipvlan.txt | ||
diff --git a/src/firejail/network_main.c b/src/firejail/network_main.c new file mode 100644 index 000000000..c2459b0cd --- /dev/null +++ b/src/firejail/network_main.c | |||
@@ -0,0 +1,268 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include "firejail.h" | ||
22 | #include <sys/types.h> | ||
23 | #include <sys/stat.h> | ||
24 | #include <unistd.h> | ||
25 | #include <net/if.h> | ||
26 | |||
27 | // configure bridge structure | ||
28 | // - extract ip address and mask from the bridge interface | ||
29 | void net_configure_bridge(Bridge *br, char *dev_name) { | ||
30 | assert(br); | ||
31 | assert(dev_name); | ||
32 | |||
33 | br->dev = dev_name; | ||
34 | |||
35 | // check the bridge device exists | ||
36 | char sysbridge[30 + strlen(br->dev)]; | ||
37 | sprintf(sysbridge, "/sys/class/net/%s/bridge", br->dev); | ||
38 | struct stat s; | ||
39 | int rv = stat(sysbridge, &s); | ||
40 | if (rv == 0) { | ||
41 | // this is a bridge device | ||
42 | br->macvlan = 0; | ||
43 | } | ||
44 | else { | ||
45 | // is this a regular Ethernet interface | ||
46 | if (if_nametoindex(br->dev) > 0) { | ||
47 | br->macvlan = 1; | ||
48 | char *newname; | ||
49 | if (asprintf(&newname, "%s-%u", br->devsandbox, getpid()) == -1) | ||
50 | errExit("asprintf"); | ||
51 | br->devsandbox = newname; | ||
52 | } | ||
53 | else { | ||
54 | fprintf(stderr, "Error: cannot find network device %s\n", br->dev); | ||
55 | exit(1); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac)) { | ||
60 | fprintf(stderr, "Error: interface %s is not configured\n", br->dev); | ||
61 | exit(1); | ||
62 | } | ||
63 | if (arg_debug) { | ||
64 | if (br->macvlan == 0) | ||
65 | printf("Bridge device %s at %d.%d.%d.%d/%d\n", | ||
66 | br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); | ||
67 | else | ||
68 | printf("macvlan parent device %s at %d.%d.%d.%d/%d\n", | ||
69 | br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); | ||
70 | } | ||
71 | |||
72 | uint32_t range = ~br->mask + 1; // the number of potential addresses | ||
73 | // this software is not supported for /31 networks | ||
74 | if (range < 4) { | ||
75 | fprintf(stderr, "Error: the software is not supported for /31 networks\n"); | ||
76 | exit(1); | ||
77 | } | ||
78 | br->configured = 1; | ||
79 | } | ||
80 | |||
81 | |||
82 | void net_configure_sandbox_ip(Bridge *br) { | ||
83 | assert(br); | ||
84 | if (br->configured == 0) | ||
85 | return; | ||
86 | |||
87 | if (br->arg_ip_none) | ||
88 | br->ipsandbox = 0; | ||
89 | else if (br->ipsandbox) { | ||
90 | // check network range | ||
91 | char *rv = in_netrange(br->ipsandbox, br->ip, br->mask); | ||
92 | if (rv) { | ||
93 | fprintf(stderr, "%s", rv); | ||
94 | exit(1); | ||
95 | } | ||
96 | // send an ARP request and check if there is anybody on this IP address | ||
97 | if (arp_check(br->dev, br->ipsandbox, br->ip)) { | ||
98 | fprintf(stderr, "Error: IP address %d.%d.%d.%d is already in use\n", PRINT_IP(br->ipsandbox)); | ||
99 | exit(1); | ||
100 | } | ||
101 | } | ||
102 | else | ||
103 | // ip address assigned by arp-scan for a bridge device | ||
104 | br->ipsandbox = arp_assign(br->dev, br); //br->ip, br->mask); | ||
105 | } | ||
106 | |||
107 | |||
108 | // create a veth pair | ||
109 | // - br - bridge device | ||
110 | // - ifname - interface name in sandbox namespace | ||
111 | // - child - child process running the namespace | ||
112 | |||
113 | void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child) { | ||
114 | assert(br); | ||
115 | if (br->configured == 0) | ||
116 | return; | ||
117 | |||
118 | // create a veth pair | ||
119 | char *dev; | ||
120 | if (asprintf(&dev, "veth%u%s", getpid(), ifname) < 0) | ||
121 | errExit("asprintf"); | ||
122 | net_create_veth(dev, ifname, child); | ||
123 | |||
124 | // bring up the interface | ||
125 | net_if_up(dev); | ||
126 | |||
127 | // add interface to the bridge | ||
128 | net_bridge_add_interface(br->dev, dev); | ||
129 | |||
130 | char *msg; | ||
131 | if (asprintf(&msg, "%d.%d.%d.%d address assigned to sandbox", PRINT_IP(br->ipsandbox)) == -1) | ||
132 | errExit("asprintf"); | ||
133 | logmsg(msg); | ||
134 | fflush(0); | ||
135 | free(msg); | ||
136 | } | ||
137 | |||
138 | // the default address should be in the range of at least on of the bridge devices | ||
139 | void check_default_gw(uint32_t defaultgw) { | ||
140 | assert(defaultgw); | ||
141 | |||
142 | if (cfg.bridge0.configured) { | ||
143 | char *rv = in_netrange(defaultgw, cfg.bridge0.ip, cfg.bridge0.mask); | ||
144 | if (rv == 0) | ||
145 | return; | ||
146 | } | ||
147 | if (cfg.bridge1.configured) { | ||
148 | char *rv = in_netrange(defaultgw, cfg.bridge1.ip, cfg.bridge1.mask); | ||
149 | if (rv == 0) | ||
150 | return; | ||
151 | } | ||
152 | if (cfg.bridge2.configured) { | ||
153 | char *rv = in_netrange(defaultgw, cfg.bridge2.ip, cfg.bridge2.mask); | ||
154 | if (rv == 0) | ||
155 | return; | ||
156 | } | ||
157 | if (cfg.bridge3.configured) { | ||
158 | char *rv = in_netrange(defaultgw, cfg.bridge3.ip, cfg.bridge3.mask); | ||
159 | if (rv == 0) | ||
160 | return; | ||
161 | } | ||
162 | |||
163 | fprintf(stderr, "Error: default gateway %d.%d.%d.%d is not in the range of any network\n", PRINT_IP(defaultgw)); | ||
164 | exit(1); | ||
165 | } | ||
166 | |||
167 | void net_check_cfg(void) { | ||
168 | int net_configured = 0; | ||
169 | if (cfg.bridge0.configured) | ||
170 | net_configured++; | ||
171 | if (cfg.bridge1.configured) | ||
172 | net_configured++; | ||
173 | if (cfg.bridge2.configured) | ||
174 | net_configured++; | ||
175 | if (cfg.bridge3.configured) | ||
176 | net_configured++; | ||
177 | |||
178 | // --defaultgw requires a network | ||
179 | if (cfg.defaultgw && net_configured == 0) { | ||
180 | fprintf(stderr, "Error: option --defaultgw requires at least one network to be configured\n"); | ||
181 | exit(1); | ||
182 | } | ||
183 | |||
184 | if (net_configured == 0) // nothing to check | ||
185 | return; | ||
186 | |||
187 | // --net=none | ||
188 | if (arg_nonetwork && net_configured) { | ||
189 | fprintf(stderr, "Error: --net and --net=none are mutually exclusive\n"); | ||
190 | exit(1); | ||
191 | } | ||
192 | |||
193 | // check default gateway address or assign one | ||
194 | assert(cfg.bridge0.configured); | ||
195 | if (cfg.defaultgw) | ||
196 | check_default_gw(cfg.defaultgw); | ||
197 | else { | ||
198 | // first network is a regular bridge | ||
199 | if (cfg.bridge0.macvlan == 0) | ||
200 | cfg.defaultgw = cfg.bridge0.ip; | ||
201 | // first network is a mac device | ||
202 | else { | ||
203 | // get the host default gw | ||
204 | uint32_t gw = network_get_defaultgw(); | ||
205 | // check the gateway is network range | ||
206 | if (in_netrange(gw, cfg.bridge0.ip, cfg.bridge0.mask)) | ||
207 | gw = 0; | ||
208 | cfg.defaultgw = gw; | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | |||
213 | |||
214 | |||
215 | void net_dns_print_name(const char *name) { | ||
216 | if (!name || strlen(name) == 0) { | ||
217 | fprintf(stderr, "Error: invalid sandbox name\n"); | ||
218 | exit(1); | ||
219 | } | ||
220 | pid_t pid; | ||
221 | if (name2pid(name, &pid)) { | ||
222 | fprintf(stderr, "Error: cannot find sandbox %s\n", name); | ||
223 | exit(1); | ||
224 | } | ||
225 | |||
226 | net_dns_print(pid); | ||
227 | } | ||
228 | |||
229 | #define MAXBUF 4096 | ||
230 | void net_dns_print(pid_t pid) { | ||
231 | // drop privileges - will not be able to read /etc/resolv.conf for --noroot option | ||
232 | // drop_privs(1); | ||
233 | |||
234 | // if the pid is that of a firejail process, use the pid of the first child process | ||
235 | char *comm = pid_proc_comm(pid); | ||
236 | if (comm) { | ||
237 | // remove \n | ||
238 | char *ptr = strchr(comm, '\n'); | ||
239 | if (ptr) | ||
240 | *ptr = '\0'; | ||
241 | if (strcmp(comm, "firejail") == 0) { | ||
242 | pid_t child; | ||
243 | if (find_child(pid, &child) == 0) { | ||
244 | pid = child; | ||
245 | } | ||
246 | } | ||
247 | free(comm); | ||
248 | } | ||
249 | |||
250 | char *fname; | ||
251 | if (asprintf(&fname, "/proc/%d/root/etc/resolv.conf", pid) == -1) | ||
252 | errExit("asprintf"); | ||
253 | |||
254 | // access /etc/resolv.conf | ||
255 | FILE *fp = fopen(fname, "r"); | ||
256 | if (!fp) { | ||
257 | fprintf(stderr, "Error: cannot access /etc/resolv.conf\n"); | ||
258 | exit(1); | ||
259 | } | ||
260 | |||
261 | char buf[MAXBUF]; | ||
262 | while (fgets(buf, MAXBUF, fp)) | ||
263 | printf("%s", buf); | ||
264 | printf("\n"); | ||
265 | fclose(fp); | ||
266 | free(fname); | ||
267 | exit(0); | ||
268 | } | ||
diff --git a/src/firejail/output.c b/src/firejail/output.c new file mode 100644 index 000000000..32adac108 --- /dev/null +++ b/src/firejail/output.c | |||
@@ -0,0 +1,84 @@ | |||
1 | #include "firejail.h" | ||
2 | #include <sys/types.h> | ||
3 | #include <sys/stat.h> | ||
4 | #include <unistd.h> | ||
5 | |||
6 | void check_output(int argc, char **argv) { | ||
7 | int i; | ||
8 | char *outfile = NULL; | ||
9 | // drop_privs(0); | ||
10 | |||
11 | int found = 0; | ||
12 | for (i = 1; i < argc; i++) { | ||
13 | if (strncmp(argv[i], "--output=", 9) == 0) { | ||
14 | found = 1; | ||
15 | outfile = argv[i] + 9; | ||
16 | |||
17 | // do not accept directories, links, and files with ".." | ||
18 | if (strstr(outfile, "..") || is_link(outfile) || is_dir(outfile)) { | ||
19 | fprintf(stderr, "Error: invalid output file. Links, directories and files with \"..\" are not allowed.\n"); | ||
20 | exit(1); | ||
21 | } | ||
22 | |||
23 | struct stat s; | ||
24 | if (stat(outfile, &s) == 0) { | ||
25 | // check permissions | ||
26 | if (s.st_uid != getuid() || s.st_gid != getgid()) { | ||
27 | fprintf(stderr, "Error: the output file needs to be owned by the current user.\n"); | ||
28 | exit(1); | ||
29 | } | ||
30 | |||
31 | // check hard links | ||
32 | if (s.st_nlink != 1) { | ||
33 | fprintf(stderr, "Error: no hard links allowed.\n"); | ||
34 | exit(1); | ||
35 | } | ||
36 | } | ||
37 | |||
38 | // drop privileges and try to open the file for writing | ||
39 | drop_privs(0); | ||
40 | /* coverity[toctou] */ | ||
41 | FILE *fp = fopen(outfile, "a"); | ||
42 | if (!fp) { | ||
43 | fprintf(stderr, "Error: cannot open output file %s\n", outfile); | ||
44 | exit(1); | ||
45 | } | ||
46 | fclose(fp); | ||
47 | break; | ||
48 | } | ||
49 | } | ||
50 | if (!found) | ||
51 | return; | ||
52 | |||
53 | |||
54 | // build the new command line | ||
55 | int len = 0; | ||
56 | for (i = 0; i < argc; i++) { | ||
57 | len += strlen(argv[i]) + 1; // + ' ' | ||
58 | } | ||
59 | len += 50 + strlen(outfile); // tee command | ||
60 | |||
61 | char *cmd = malloc(len + 1); // + '\0' | ||
62 | if (!cmd) | ||
63 | errExit("malloc"); | ||
64 | |||
65 | char *ptr = cmd; | ||
66 | for (i = 0; i < argc; i++) { | ||
67 | if (strncmp(argv[i], "--output=", 9) == 0) | ||
68 | continue; | ||
69 | ptr += sprintf(ptr, "%s ", argv[i]); | ||
70 | } | ||
71 | sprintf(ptr, "| %s/lib/firejail/ftee %s", PREFIX, outfile); | ||
72 | |||
73 | // run command | ||
74 | char *a[4]; | ||
75 | a[0] = "/bin/bash"; | ||
76 | a[1] = "-c"; | ||
77 | a[2] = cmd; | ||
78 | a[3] = NULL; | ||
79 | |||
80 | execvp(a[0], a); | ||
81 | |||
82 | perror("execvp"); | ||
83 | exit(1); | ||
84 | } | ||
diff --git a/src/firejail/profile.c b/src/firejail/profile.c new file mode 100644 index 000000000..343907584 --- /dev/null +++ b/src/firejail/profile.c | |||
@@ -0,0 +1,444 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <dirent.h> | ||
22 | #include <sys/stat.h> | ||
23 | |||
24 | #define MAX_READ 8192 // line buffer for profile files | ||
25 | |||
26 | // find and read the profile specified by name from dir directory | ||
27 | int profile_find(const char *name, const char *dir) { | ||
28 | assert(name); | ||
29 | assert(dir); | ||
30 | |||
31 | int rv = 0; | ||
32 | DIR *dp; | ||
33 | char *pname; | ||
34 | if (asprintf(&pname, "%s.profile", name) == -1) | ||
35 | errExit("asprintf"); | ||
36 | |||
37 | dp = opendir (dir); | ||
38 | if (dp != NULL) { | ||
39 | struct dirent *ep; | ||
40 | while ((ep = readdir(dp)) != NULL) { | ||
41 | if (strcmp(ep->d_name, pname) == 0) { | ||
42 | if (arg_debug) | ||
43 | printf("Found %s profile in %s directory\n", name, dir); | ||
44 | char *etcpname; | ||
45 | if (asprintf(&etcpname, "%s/%s", dir, pname) == -1) | ||
46 | errExit("asprintf"); | ||
47 | profile_read(etcpname, NULL, NULL); | ||
48 | free(etcpname); | ||
49 | rv = 1; | ||
50 | break; | ||
51 | } | ||
52 | } | ||
53 | (void) closedir (dp); | ||
54 | } | ||
55 | |||
56 | free(pname); | ||
57 | return rv; | ||
58 | } | ||
59 | |||
60 | |||
61 | //*************************************************** | ||
62 | // run-time profiles | ||
63 | //*************************************************** | ||
64 | static void check_file_name(char *ptr, int lineno) { | ||
65 | if (strncmp(ptr, "${HOME}", 7) == 0) | ||
66 | ptr += 7; | ||
67 | else if (strncmp(ptr, "${PATH}", 7) == 0) | ||
68 | ptr += 7; | ||
69 | |||
70 | int len = strlen(ptr); | ||
71 | // file globbing ('*') is allowed | ||
72 | if (strcspn(ptr, "\\&!?\"'<>%^(){}[];, ") != len) { | ||
73 | if (lineno == 0) | ||
74 | fprintf(stderr, "Error: \"%s\" is an invalid filename\n", ptr); | ||
75 | else | ||
76 | fprintf(stderr, "Error: line %d in the custom profile is invalid\n", lineno); | ||
77 | exit(1); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | |||
82 | // check profile line; if line == 0, this was generated from a command line option | ||
83 | // return 1 if the command is to be added to the linked list of profile commands | ||
84 | // return 0 if the command was already executed inside the function | ||
85 | int profile_check_line(char *ptr, int lineno) { | ||
86 | // seccomp, caps, private, user namespace | ||
87 | if (strcmp(ptr, "noroot") == 0) { | ||
88 | check_user_namespace(); | ||
89 | return 0; | ||
90 | } | ||
91 | else if (strcmp(ptr, "seccomp") == 0) { | ||
92 | arg_seccomp = 1; | ||
93 | return 0; | ||
94 | } | ||
95 | else if (strcmp(ptr, "caps") == 0) { | ||
96 | arg_caps_default_filter = 1; | ||
97 | return 0; | ||
98 | } | ||
99 | else if (strcmp(ptr, "caps.drop all") == 0) { | ||
100 | arg_caps_drop_all = 1; | ||
101 | return 0; | ||
102 | } | ||
103 | else if (strcmp(ptr, "shell none") == 0) { | ||
104 | arg_shell_none = 1; | ||
105 | return 0; | ||
106 | } | ||
107 | else if (strcmp(ptr, "private") == 0) { | ||
108 | arg_private = 1; | ||
109 | return 0; | ||
110 | } | ||
111 | else if (strcmp(ptr, "private-dev") == 0) { | ||
112 | arg_private_dev = 1; | ||
113 | return 0; | ||
114 | } | ||
115 | else if (strcmp(ptr, "nogroups") == 0) { | ||
116 | arg_nogroups = 1; | ||
117 | return 0; | ||
118 | } | ||
119 | else if (strcmp(ptr, "netfilter") == 0) { | ||
120 | arg_netfilter = 1; | ||
121 | return 0; | ||
122 | } | ||
123 | else if (strncmp(ptr, "netfilter ", 10) == 0) { | ||
124 | arg_netfilter = 1; | ||
125 | arg_netfilter_file = strdup(ptr + 10); | ||
126 | if (!arg_netfilter_file) | ||
127 | errExit("strdup"); | ||
128 | check_netfilter_file(arg_netfilter_file); | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | // seccomp drop list on top of default list | ||
133 | if (strncmp(ptr, "seccomp ", 8) == 0) { | ||
134 | arg_seccomp = 1; | ||
135 | #ifdef HAVE_SECCOMP | ||
136 | arg_seccomp_list = strdup(ptr + 8); | ||
137 | if (!arg_seccomp_list) | ||
138 | errExit("strdup"); | ||
139 | #endif | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | // seccomp drop list without default list | ||
144 | if (strncmp(ptr, "seccomp.drop ", 13) == 0) { | ||
145 | arg_seccomp = 1; | ||
146 | #ifdef HAVE_SECCOMP | ||
147 | arg_seccomp_list_drop = strdup(ptr + 13); | ||
148 | if (!arg_seccomp_list_drop) | ||
149 | errExit("strdup"); | ||
150 | #endif | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | // seccomp keep list | ||
155 | if (strncmp(ptr, "seccomp.keep ", 13) == 0) { | ||
156 | arg_seccomp = 1; | ||
157 | #ifdef HAVE_SECCOMP | ||
158 | arg_seccomp_list_keep= strdup(ptr + 13); | ||
159 | if (!arg_seccomp_list_keep) | ||
160 | errExit("strdup"); | ||
161 | #endif | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | // caps drop list | ||
166 | if (strncmp(ptr, "caps.drop ", 10) == 0) { | ||
167 | arg_caps_drop = 1; | ||
168 | arg_caps_list = strdup(ptr + 10); | ||
169 | if (!arg_caps_list) | ||
170 | errExit("strdup"); | ||
171 | // verify seccomp list and exit if problems | ||
172 | if (caps_check_list(arg_caps_list, NULL)) | ||
173 | exit(1); | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | // caps keep list | ||
178 | if (strncmp(ptr, "caps.keep ", 10) == 0) { | ||
179 | arg_caps_keep = 1; | ||
180 | arg_caps_list = strdup(ptr + 10); | ||
181 | if (!arg_caps_list) | ||
182 | errExit("strdup"); | ||
183 | // verify seccomp list and exit if problems | ||
184 | if (caps_check_list(arg_caps_list, NULL)) | ||
185 | exit(1); | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | // dns | ||
190 | if (strncmp(ptr, "dns ", 4) == 0) { | ||
191 | uint32_t dns; | ||
192 | if (atoip(ptr + 4, &dns)) { | ||
193 | fprintf(stderr, "Error: invalid DNS server IP address\n"); | ||
194 | return 1; | ||
195 | } | ||
196 | |||
197 | if (cfg.dns1 == 0) | ||
198 | cfg.dns1 = dns; | ||
199 | else if (cfg.dns2 == 0) | ||
200 | cfg.dns2 = dns; | ||
201 | else if (cfg.dns3 == 0) | ||
202 | cfg.dns3 = dns; | ||
203 | else { | ||
204 | fprintf(stderr, "Error: up to 3 DNS servers can be specified\n"); | ||
205 | return 1; | ||
206 | } | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | // cpu affinity | ||
211 | if (strncmp(ptr, "cpu ", 4) == 0) { | ||
212 | read_cpu_list(ptr + 4); | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | // cgroup | ||
217 | if (strncmp(ptr, "cgroup ", 7) == 0) { | ||
218 | set_cgroup(ptr + 7); | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | // private directory | ||
223 | if (strncmp(ptr, "private ", 8) == 0) { | ||
224 | cfg.home_private = ptr + 8; | ||
225 | fs_check_private_dir(); | ||
226 | arg_private = 1; | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | // private list of files and directories | ||
231 | if (strncmp(ptr, "private.keep ", 13) == 0) { | ||
232 | cfg.home_private_keep = ptr + 13; | ||
233 | fs_check_home_list(); | ||
234 | arg_private = 1; | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | // filesystem bind | ||
239 | if (strncmp(ptr, "bind ", 5) == 0) { | ||
240 | if (getuid() != 0) { | ||
241 | fprintf(stderr, "Error: --bind option is available only if running as root\n"); | ||
242 | exit(1); | ||
243 | } | ||
244 | |||
245 | // extract two directories | ||
246 | char *dname1 = ptr + 5; | ||
247 | char *dname2 = split_comma(dname1); // this inserts a '0 to separate the two dierctories | ||
248 | if (dname2 == NULL) { | ||
249 | fprintf(stderr, "Error: mising second directory for bind\n"); | ||
250 | exit(1); | ||
251 | } | ||
252 | |||
253 | // check directories | ||
254 | check_file_name(dname1, lineno); | ||
255 | check_file_name(dname2, lineno); | ||
256 | if (strstr(dname1, "..") || strstr(dname2, "..")) { | ||
257 | fprintf(stderr, "Error: invalid file name.\n"); | ||
258 | exit(1); | ||
259 | } | ||
260 | |||
261 | // insert comma back | ||
262 | *(dname2 - 1) = ','; | ||
263 | return 1; | ||
264 | } | ||
265 | |||
266 | // rlimit | ||
267 | if (strncmp(ptr, "rlimit", 6) == 0) { | ||
268 | if (strncmp(ptr, "rlimit-nofile ", 14) == 0) { | ||
269 | ptr += 14; | ||
270 | if (not_unsigned(ptr)) { | ||
271 | fprintf(stderr, "Invalid rlimit option on line %d\n", lineno); | ||
272 | exit(1); | ||
273 | } | ||
274 | sscanf(ptr, "%u", &cfg.rlimit_nofile); | ||
275 | arg_rlimit_nofile = 1; | ||
276 | } | ||
277 | else if (strncmp(ptr, "rlimit-nproc ", 13) == 0) { | ||
278 | ptr += 13; | ||
279 | if (not_unsigned(ptr)) { | ||
280 | fprintf(stderr, "Invalid rlimit option on line %d\n", lineno); | ||
281 | exit(1); | ||
282 | } | ||
283 | sscanf(ptr, "%u", &cfg.rlimit_nproc); | ||
284 | arg_rlimit_nproc = 1; | ||
285 | } | ||
286 | else if (strncmp(ptr, "rlimit-fsize ", 13) == 0) { | ||
287 | ptr += 13; | ||
288 | if (not_unsigned(ptr)) { | ||
289 | fprintf(stderr, "Invalid rlimit option on line %d\n", lineno); | ||
290 | exit(1); | ||
291 | } | ||
292 | sscanf(ptr, "%u", &cfg.rlimit_fsize); | ||
293 | arg_rlimit_fsize = 1; | ||
294 | } | ||
295 | else if (strncmp(ptr, "rlimit-sigpending ", 18) == 0) { | ||
296 | ptr += 18; | ||
297 | if (not_unsigned(ptr)) { | ||
298 | fprintf(stderr, "Invalid rlimit option on line %d\n", lineno); | ||
299 | exit(1); | ||
300 | } | ||
301 | sscanf(ptr, "%u", &cfg.rlimit_sigpending); | ||
302 | arg_rlimit_sigpending = 1; | ||
303 | } | ||
304 | else { | ||
305 | fprintf(stderr, "Invalid rlimit option on line %d\n", lineno); | ||
306 | exit(1); | ||
307 | } | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | // rest of filesystem | ||
313 | if (strncmp(ptr, "blacklist ", 10) == 0) | ||
314 | ptr += 10; | ||
315 | else if (strncmp(ptr, "read-only ", 10) == 0) | ||
316 | ptr += 10; | ||
317 | else if (strncmp(ptr, "tmpfs ", 6) == 0) | ||
318 | ptr += 6; | ||
319 | else { | ||
320 | if (lineno == 0) | ||
321 | fprintf(stderr, "Error: \"%s\" as a command line option is invalid\n", ptr); | ||
322 | else | ||
323 | fprintf(stderr, "Error: line %d in the custom profile is invalid\n", lineno); | ||
324 | exit(1); | ||
325 | } | ||
326 | |||
327 | // some characters just don't belong in filenames | ||
328 | check_file_name(ptr, lineno); | ||
329 | if (strstr(ptr, "..")) { | ||
330 | if (lineno == 0) | ||
331 | fprintf(stderr, "Error: \"%s\" is an invalid filename\n", ptr); | ||
332 | else | ||
333 | fprintf(stderr, "Error: line %d in the custom profile is invalid\n", lineno); | ||
334 | exit(1); | ||
335 | } | ||
336 | return 1; | ||
337 | } | ||
338 | |||
339 | // add a profile entry in cfg.profile list; use str to populate the list | ||
340 | void profile_add(char *str) { | ||
341 | ProfileEntry *prf = malloc(sizeof(ProfileEntry)); | ||
342 | if (!prf) | ||
343 | errExit("malloc"); | ||
344 | prf->next = NULL; | ||
345 | prf->data = str; | ||
346 | |||
347 | // add prf to the list | ||
348 | if (cfg.profile == NULL) { | ||
349 | cfg.profile = prf; | ||
350 | return; | ||
351 | } | ||
352 | ProfileEntry *ptr = cfg.profile; | ||
353 | while (ptr->next != NULL) | ||
354 | ptr = ptr->next; | ||
355 | ptr->next = prf; | ||
356 | } | ||
357 | |||
358 | // read a profile file | ||
359 | static int include_level = 0; | ||
360 | // skip1, skip2 - if the string is found in the line, the line is not interpreted | ||
361 | void profile_read(const char *fname, const char *skip1, const char *skip2) { | ||
362 | // exit program if maximum include level was reached | ||
363 | if (include_level > MAX_INCLUDE_LEVEL) { | ||
364 | fprintf(stderr, "Error: maximum profile include level was reached\n"); | ||
365 | exit(1); | ||
366 | } | ||
367 | |||
368 | if (strlen(fname) == 0) { | ||
369 | fprintf(stderr, "Error: invalid profile file\n"); | ||
370 | exit(1); | ||
371 | } | ||
372 | |||
373 | // open profile file: | ||
374 | FILE *fp = fopen(fname, "r"); | ||
375 | if (fp == NULL) { | ||
376 | fprintf(stderr, "Error: cannot open profile file\n"); | ||
377 | exit(1); | ||
378 | } | ||
379 | |||
380 | fprintf(stderr, "Reading profile %s\n", fname); | ||
381 | |||
382 | // read the file line by line | ||
383 | char buf[MAX_READ + 1]; | ||
384 | int lineno = 0; | ||
385 | while (fgets(buf, MAX_READ, fp)) { | ||
386 | ++lineno; | ||
387 | // remove empty space - ptr in allocated memory | ||
388 | char *ptr = line_remove_spaces(buf); | ||
389 | if (ptr == NULL) | ||
390 | continue; | ||
391 | |||
392 | // comments | ||
393 | if (*ptr == '#' || *ptr == '\0') { | ||
394 | free(ptr); | ||
395 | continue; | ||
396 | } | ||
397 | |||
398 | // process include | ||
399 | if (strncmp(ptr, "include ", 8) == 0) { | ||
400 | include_level++; | ||
401 | |||
402 | // extract profile filename and new skip params | ||
403 | char *newprofile = ptr + 8; // profile name | ||
404 | char *newskip1 = NULL; // new skip1 | ||
405 | char *newskip2 = NULL; // new skip2 | ||
406 | char *p = newprofile; | ||
407 | while (*p != '\0') { | ||
408 | if (*p == ' ') { | ||
409 | *p = '\0'; | ||
410 | if (newskip1 == NULL) | ||
411 | newskip1 = p + 1; | ||
412 | else if (newskip2 == NULL) | ||
413 | newskip2 = p + 1; | ||
414 | } | ||
415 | p++; | ||
416 | } | ||
417 | |||
418 | // recursivity | ||
419 | profile_read(newprofile, newskip1, newskip2); | ||
420 | include_level--; | ||
421 | free(ptr); | ||
422 | continue; | ||
423 | } | ||
424 | |||
425 | // skip | ||
426 | if (skip1) { | ||
427 | if (strstr(ptr, skip1)) { | ||
428 | free(ptr); | ||
429 | continue; | ||
430 | } | ||
431 | } | ||
432 | if (skip2) { | ||
433 | if (strstr(ptr, skip2)) { | ||
434 | free(ptr); | ||
435 | continue; | ||
436 | } | ||
437 | } | ||
438 | |||
439 | // verify syntax, exit in case of error | ||
440 | if (profile_check_line(ptr, lineno)) | ||
441 | profile_add(ptr); | ||
442 | } | ||
443 | fclose(fp); | ||
444 | } | ||
diff --git a/src/firejail/restricted_shell.c b/src/firejail/restricted_shell.c new file mode 100644 index 000000000..ba3aae759 --- /dev/null +++ b/src/firejail/restricted_shell.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | |||
22 | #define MAX_READ 4096 // maximum line length | ||
23 | char *restricted_user = NULL; | ||
24 | |||
25 | |||
26 | int restricted_shell(const char *user) { | ||
27 | assert(user); | ||
28 | |||
29 | // open profile file: | ||
30 | FILE *fp = fopen("/etc/firejail/login.users", "r"); | ||
31 | if (fp == NULL) | ||
32 | return 0; | ||
33 | |||
34 | int lineno = 0; | ||
35 | char buf[MAX_READ]; | ||
36 | while (fgets(buf, MAX_READ, fp)) { | ||
37 | lineno++; | ||
38 | |||
39 | // remove empty spaces at the beginning of the line | ||
40 | char *ptr = buf; | ||
41 | while (*ptr == ' ' || *ptr == '\t') { | ||
42 | ptr++; | ||
43 | } | ||
44 | if (*ptr == '\n' || *ptr == '#') | ||
45 | continue; | ||
46 | |||
47 | // parse line | ||
48 | char *usr = ptr; | ||
49 | char *args = strchr(usr, ':'); | ||
50 | if (args == NULL) { | ||
51 | fprintf(stderr, "Error: users.conf line %d\n", lineno); | ||
52 | exit(1); | ||
53 | } | ||
54 | *args = '\0'; | ||
55 | args++; | ||
56 | ptr = strchr(args, '\n'); | ||
57 | if (ptr) | ||
58 | *ptr = '\0'; | ||
59 | |||
60 | if (strcmp(user, usr) == 0) { | ||
61 | restricted_user = strdup(user); | ||
62 | // extract program arguments | ||
63 | |||
64 | fullargv[0] = "firejail"; | ||
65 | int i; | ||
66 | ptr = args; | ||
67 | for (i = 1; i < MAX_ARGS; i++) { | ||
68 | fullargv[i] = ptr; | ||
69 | while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') | ||
70 | ptr++; | ||
71 | if (*ptr != '\0') { | ||
72 | *ptr ='\0'; | ||
73 | fullargv[i] = strdup(fullargv[i]); | ||
74 | if (fullargv[i] == NULL) { | ||
75 | fprintf(stderr, "Error: cannot allocate memory\n"); | ||
76 | exit(1); | ||
77 | } | ||
78 | ptr++; | ||
79 | while (*ptr == ' ' || *ptr == '\t') | ||
80 | ptr++; | ||
81 | if (*ptr != '\0') | ||
82 | continue; | ||
83 | } | ||
84 | fullargv[i] = strdup(fullargv[i]); | ||
85 | fclose(fp); | ||
86 | return i + 1; | ||
87 | } | ||
88 | fprintf(stderr, "Error: too many program arguments in users.conf line %d\n", lineno); | ||
89 | exit(1); | ||
90 | } | ||
91 | } | ||
92 | fclose(fp); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
diff --git a/src/firejail/rlimit.c b/src/firejail/rlimit.c new file mode 100644 index 000000000..6c755a08d --- /dev/null +++ b/src/firejail/rlimit.c | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/time.h> | ||
22 | #include <sys/resource.h> | ||
23 | |||
24 | void set_rlimits(void) { | ||
25 | // resource limits | ||
26 | struct rlimit rl; | ||
27 | if (arg_rlimit_nofile) { | ||
28 | rl.rlim_cur = (rlim_t) cfg.rlimit_nofile; | ||
29 | rl.rlim_max = (rlim_t) cfg.rlimit_nofile; | ||
30 | if (setrlimit(RLIMIT_NOFILE, &rl) == -1) | ||
31 | errExit("setrlimit"); | ||
32 | if (arg_debug) | ||
33 | printf("Config rlimit: number of open file descriptors %u\n", cfg.rlimit_nofile); | ||
34 | } | ||
35 | |||
36 | if (arg_rlimit_nproc) { | ||
37 | rl.rlim_cur = (rlim_t) cfg.rlimit_nproc; | ||
38 | rl.rlim_max = (rlim_t) cfg.rlimit_nproc; | ||
39 | if (setrlimit(RLIMIT_NPROC, &rl) == -1) | ||
40 | errExit("setrlimit"); | ||
41 | if (arg_debug) | ||
42 | printf("Config rlimit: number of processes %u\n", cfg.rlimit_nproc); | ||
43 | } | ||
44 | |||
45 | if (arg_rlimit_fsize) { | ||
46 | rl.rlim_cur = (rlim_t) cfg.rlimit_fsize; | ||
47 | rl.rlim_max = (rlim_t) cfg.rlimit_fsize; | ||
48 | if (setrlimit(RLIMIT_FSIZE, &rl) == -1) | ||
49 | errExit("setrlimit"); | ||
50 | if (arg_debug) | ||
51 | printf("Config rlimit: maximum file size %u\n", cfg.rlimit_fsize); | ||
52 | } | ||
53 | |||
54 | if (arg_rlimit_sigpending) { | ||
55 | rl.rlim_cur = (rlim_t) cfg.rlimit_sigpending; | ||
56 | rl.rlim_max = (rlim_t) cfg.rlimit_sigpending; | ||
57 | if (setrlimit(RLIMIT_SIGPENDING, &rl) == -1) | ||
58 | errExit("setrlimit"); | ||
59 | if (arg_debug) | ||
60 | printf("Config rlimit: maximum number of signals pending %u\n", cfg.rlimit_sigpending); | ||
61 | } | ||
62 | } | ||
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c new file mode 100644 index 000000000..3f5fb51fa --- /dev/null +++ b/src/firejail/sandbox.c | |||
@@ -0,0 +1,490 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include "firejail.h" | ||
22 | #include <sys/mount.h> | ||
23 | #include <sys/wait.h> | ||
24 | #include <sys/stat.h> | ||
25 | #include <sys/prctl.h> | ||
26 | #include <sys/time.h> | ||
27 | #include <sys/resource.h> | ||
28 | |||
29 | #include <sched.h> | ||
30 | #ifndef CLONE_NEWUSER | ||
31 | #define CLONE_NEWUSER 0x10000000 | ||
32 | #endif | ||
33 | |||
34 | static void set_caps(void) { | ||
35 | if (arg_caps_drop_all) | ||
36 | caps_drop_all(); | ||
37 | else if (arg_caps_drop) | ||
38 | caps_drop_list(arg_caps_list); | ||
39 | else if (arg_caps_keep) | ||
40 | caps_keep_list(arg_caps_list); | ||
41 | else if (arg_caps_default_filter) | ||
42 | caps_default_filter(); | ||
43 | } | ||
44 | |||
45 | void save_nogroups(void) { | ||
46 | if (arg_nogroups == 0) | ||
47 | return; | ||
48 | |||
49 | char *fname; | ||
50 | if (asprintf(&fname, "%s/groups", MNT_DIR) == -1) | ||
51 | errExit("asprintf"); | ||
52 | FILE *fp = fopen(fname, "w"); | ||
53 | if (fp) { | ||
54 | fprintf(fp, "\n"); | ||
55 | fclose(fp); | ||
56 | if (chown(fname, 0, 0) < 0) | ||
57 | errExit("chown"); | ||
58 | } | ||
59 | else { | ||
60 | fprintf(stderr, "Error: cannot save nogroups state\n"); | ||
61 | free(fname); | ||
62 | exit(1); | ||
63 | } | ||
64 | |||
65 | free(fname); | ||
66 | } | ||
67 | |||
68 | static void sandbox_if_up(Bridge *br) { | ||
69 | assert(br); | ||
70 | if (!br->configured) | ||
71 | return; | ||
72 | |||
73 | char *dev = br->devsandbox; | ||
74 | net_if_up(dev); | ||
75 | |||
76 | if (br->arg_ip_none == 1); // do nothing | ||
77 | else if (br->arg_ip_none == 0 && br->macvlan == 0) { | ||
78 | if (br->ipsandbox == br->ip) { | ||
79 | fprintf(stderr, "Error: %d.%d.%d.%d is interface %s address.\n", PRINT_IP(br->ipsandbox), br->dev); | ||
80 | exit(1); | ||
81 | } | ||
82 | |||
83 | // just assign the address | ||
84 | assert(br->ipsandbox); | ||
85 | if (arg_debug) | ||
86 | printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev); | ||
87 | net_if_ip(dev, br->ipsandbox, br->mask); | ||
88 | net_if_up(dev); | ||
89 | } | ||
90 | else if (br->arg_ip_none == 0 && br->macvlan == 1) { | ||
91 | // reassign the macvlan address | ||
92 | if (br->ipsandbox == 0) | ||
93 | // ip address assigned by arp-scan for a macvlan device | ||
94 | br->ipsandbox = arp_assign(dev, br); //br->ip, br->mask); | ||
95 | else { | ||
96 | if (br->ipsandbox == br->ip) { | ||
97 | fprintf(stderr, "Error: %d.%d.%d.%d is interface %s address.\n", PRINT_IP(br->ipsandbox), br->dev); | ||
98 | exit(1); | ||
99 | } | ||
100 | |||
101 | uint32_t rv = arp_check(dev, br->ipsandbox, br->ip); | ||
102 | if (rv) { | ||
103 | fprintf(stderr, "Error: the address %d.%d.%d.%d is already in use.\n", PRINT_IP(br->ipsandbox)); | ||
104 | exit(1); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | if (arg_debug) | ||
109 | printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev); | ||
110 | net_if_ip(dev, br->ipsandbox, br->mask); | ||
111 | net_if_up(dev); | ||
112 | } | ||
113 | } | ||
114 | |||
115 | static void chk_chroot(void) { | ||
116 | // if we are starting firejail inside some other container technology, we don't care about this | ||
117 | char *mycont = getenv("container"); | ||
118 | if (mycont) | ||
119 | return; | ||
120 | |||
121 | // check if this is a regular chroot | ||
122 | struct stat s; | ||
123 | if (stat("/", &s) == 0) { | ||
124 | if (s.st_ino != 2) | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | fprintf(stderr, "Error: cannot mount filesystem as slave\n"); | ||
129 | exit(1); | ||
130 | } | ||
131 | |||
132 | int sandbox(void* sandbox_arg) { | ||
133 | pid_t child_pid = getpid(); | ||
134 | if (arg_debug) | ||
135 | printf("Initializing child process\n"); | ||
136 | |||
137 | // close each end of the unused pipes | ||
138 | close(parent_to_child_fds[1]); | ||
139 | close(child_to_parent_fds[0]); | ||
140 | |||
141 | // wait for parent to do base setup | ||
142 | wait_for_other(parent_to_child_fds[0]); | ||
143 | |||
144 | if (arg_debug && child_pid == 1) | ||
145 | printf("PID namespace installed\n"); | ||
146 | |||
147 | //**************************** | ||
148 | // set hostname | ||
149 | //**************************** | ||
150 | if (cfg.hostname) { | ||
151 | if (sethostname(cfg.hostname, strlen(cfg.hostname)) < 0) | ||
152 | errExit("sethostname"); | ||
153 | } | ||
154 | |||
155 | //**************************** | ||
156 | // mount namespace | ||
157 | //**************************** | ||
158 | // mount events are not forwarded between the host the sandbox | ||
159 | if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) { | ||
160 | chk_chroot(); | ||
161 | } | ||
162 | |||
163 | //**************************** | ||
164 | // netfilter | ||
165 | //**************************** | ||
166 | if (arg_netfilter && any_bridge_configured()) { // assuming by default the client filter | ||
167 | netfilter(arg_netfilter_file); | ||
168 | } | ||
169 | |||
170 | //**************************** | ||
171 | // trace pre-install | ||
172 | //**************************** | ||
173 | if (arg_trace) | ||
174 | fs_trace_preload(); | ||
175 | |||
176 | //**************************** | ||
177 | // configure filesystem | ||
178 | //**************************** | ||
179 | #ifdef HAVE_CHROOT | ||
180 | if (cfg.chrootdir) { | ||
181 | fs_chroot(cfg.chrootdir); | ||
182 | // force caps and seccomp if not started as root | ||
183 | if (getuid() != 0) { | ||
184 | // force default seccomp inside the chroot, no keep or drop list | ||
185 | // the list build on top of the default drop list is kept intact | ||
186 | arg_seccomp = 1; | ||
187 | if (arg_seccomp_list_drop) { | ||
188 | free(arg_seccomp_list_drop); | ||
189 | arg_seccomp_list_drop = NULL; | ||
190 | } | ||
191 | if (arg_seccomp_list_keep) { | ||
192 | free(arg_seccomp_list_keep); | ||
193 | arg_seccomp_list_keep = NULL; | ||
194 | } | ||
195 | |||
196 | // disable all capabilities | ||
197 | if (arg_caps_default_filter || arg_caps_list) | ||
198 | fprintf(stderr, "Warning: all capabilities disabled for a regular user during chroot\n"); | ||
199 | arg_caps_drop_all = 1; | ||
200 | |||
201 | // drop all supplementary groups; /etc/group file inside chroot | ||
202 | // is controlled by a regular usr | ||
203 | arg_nogroups = 1; | ||
204 | printf("Dropping all Linux capabilities and enforcing default seccomp filter\n"); | ||
205 | } | ||
206 | |||
207 | //**************************** | ||
208 | // trace pre-install, this time inside chroot | ||
209 | //**************************** | ||
210 | if (arg_trace) | ||
211 | fs_trace_preload(); | ||
212 | } | ||
213 | else | ||
214 | #endif | ||
215 | if (arg_overlay) | ||
216 | fs_overlayfs(); | ||
217 | else | ||
218 | fs_basic_fs(); | ||
219 | |||
220 | |||
221 | //**************************** | ||
222 | // set hostname in /etc/hostname | ||
223 | //**************************** | ||
224 | if (cfg.hostname) { | ||
225 | fs_hostname(cfg.hostname); | ||
226 | } | ||
227 | |||
228 | //**************************** | ||
229 | // apply the profile file | ||
230 | //**************************** | ||
231 | if (cfg.profile) | ||
232 | fs_blacklist(cfg.homedir); | ||
233 | |||
234 | //**************************** | ||
235 | // private mode | ||
236 | //**************************** | ||
237 | if (arg_private) { | ||
238 | if (cfg.home_private) // --private= | ||
239 | fs_private_homedir(); | ||
240 | else if (cfg.home_private_keep) // --private.keep= | ||
241 | fs_private_home_list(); | ||
242 | else // --private | ||
243 | fs_private(); | ||
244 | } | ||
245 | |||
246 | if (arg_private_dev) | ||
247 | fs_private_dev(); | ||
248 | |||
249 | //**************************** | ||
250 | // install trace | ||
251 | //**************************** | ||
252 | if (arg_trace) | ||
253 | fs_trace(); | ||
254 | |||
255 | //**************************** | ||
256 | // update /proc, /dev, /boot directorymy | ||
257 | //**************************** | ||
258 | fs_proc_sys_dev_boot(); | ||
259 | |||
260 | //**************************** | ||
261 | // networking | ||
262 | //**************************** | ||
263 | if (arg_nonetwork) { | ||
264 | net_if_up("lo"); | ||
265 | } | ||
266 | else if (any_bridge_configured()) { | ||
267 | // configure lo and eth0...eth3 | ||
268 | net_if_up("lo"); | ||
269 | |||
270 | if (mac_not_zero(cfg.bridge0.macsandbox)) | ||
271 | net_config_mac(cfg.bridge0.devsandbox, cfg.bridge0.macsandbox); | ||
272 | sandbox_if_up(&cfg.bridge0); | ||
273 | |||
274 | if (mac_not_zero(cfg.bridge1.macsandbox)) | ||
275 | net_config_mac(cfg.bridge1.devsandbox, cfg.bridge1.macsandbox); | ||
276 | sandbox_if_up(&cfg.bridge1); | ||
277 | |||
278 | if (mac_not_zero(cfg.bridge2.macsandbox)) | ||
279 | net_config_mac(cfg.bridge2.devsandbox, cfg.bridge2.macsandbox); | ||
280 | sandbox_if_up(&cfg.bridge2); | ||
281 | |||
282 | if (mac_not_zero(cfg.bridge3.macsandbox)) | ||
283 | net_config_mac(cfg.bridge3.devsandbox, cfg.bridge3.macsandbox); | ||
284 | sandbox_if_up(&cfg.bridge3); | ||
285 | |||
286 | // add a default route | ||
287 | if (cfg.defaultgw) { | ||
288 | // set the default route | ||
289 | if (net_add_route(0, 0, cfg.defaultgw)) | ||
290 | fprintf(stderr, "Warning: cannot configure default route\n"); | ||
291 | } | ||
292 | |||
293 | if (arg_debug) | ||
294 | printf("Network namespace enabled\n"); | ||
295 | } | ||
296 | |||
297 | // if any dns server is configured, it is time to set it now | ||
298 | fs_resolvconf(); | ||
299 | |||
300 | // print network configuration | ||
301 | if (any_bridge_configured() || cfg.defaultgw || cfg.dns1) { | ||
302 | printf("\n"); | ||
303 | if (any_bridge_configured()) | ||
304 | net_ifprint(); | ||
305 | if (cfg.defaultgw != 0) | ||
306 | printf("Default gateway %d.%d.%d.%d\n", PRINT_IP(cfg.defaultgw)); | ||
307 | if (cfg.dns1 != 0) | ||
308 | printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns1)); | ||
309 | if (cfg.dns2 != 0) | ||
310 | printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns2)); | ||
311 | if (cfg.dns3 != 0) | ||
312 | printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns3)); | ||
313 | printf("\n"); | ||
314 | } | ||
315 | |||
316 | |||
317 | |||
318 | //**************************** | ||
319 | // start executable | ||
320 | //**************************** | ||
321 | prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died | ||
322 | int cwd = 0; | ||
323 | if (cfg.cwd) { | ||
324 | if (chdir(cfg.cwd) == 0) | ||
325 | cwd = 1; | ||
326 | } | ||
327 | |||
328 | if (!cwd) { | ||
329 | if (chdir("/") < 0) | ||
330 | errExit("chdir"); | ||
331 | if (cfg.homedir) { | ||
332 | struct stat s; | ||
333 | if (stat(cfg.homedir, &s) == 0) { | ||
334 | /* coverity[toctou] */ | ||
335 | if (chdir(cfg.homedir) < 0) | ||
336 | errExit("chdir"); | ||
337 | } | ||
338 | } | ||
339 | } | ||
340 | |||
341 | // set environment | ||
342 | // fix qt 4.8 | ||
343 | if (setenv("QT_X11_NO_MITSHM", "1", 1) < 0) | ||
344 | errExit("setenv"); | ||
345 | if (setenv("container", "firejail", 1) < 0) // LXC sets container=lxc, | ||
346 | errExit("setenv"); | ||
347 | if (arg_zsh && setenv("SHELL", "/usr/bin/zsh", 1) < 0) | ||
348 | errExit("setenv"); | ||
349 | if (arg_csh && setenv("SHELL", "/bin/csh", 1) < 0) | ||
350 | errExit("setenv"); | ||
351 | if (cfg.shell && setenv("SHELL", cfg.shell, 1) < 0) | ||
352 | errExit("setenv"); | ||
353 | // set prompt color to green | ||
354 | //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' | ||
355 | if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0) | ||
356 | errExit("setenv"); | ||
357 | |||
358 | |||
359 | // set capabilities | ||
360 | if (!arg_noroot) | ||
361 | set_caps(); | ||
362 | |||
363 | // set rlimits | ||
364 | set_rlimits(); | ||
365 | |||
366 | // set seccomp | ||
367 | #ifdef HAVE_SECCOMP | ||
368 | // if a keep list is available, disregard the drop list | ||
369 | if (arg_seccomp == 1) { | ||
370 | if (arg_seccomp_list_keep) | ||
371 | seccomp_filter_keep(); // this will also save the fmyilter to MNT_DIR/seccomp file | ||
372 | else | ||
373 | seccomp_filter_drop(); // this will also save the filter to MNT_DIR/seccomp file | ||
374 | } | ||
375 | #endif | ||
376 | |||
377 | // set cpu affinity | ||
378 | if (cfg.cpus) { | ||
379 | save_cpu(); // save cpu affinity mask to MNT_DIR/cpu file | ||
380 | set_cpu_affinity(); | ||
381 | } | ||
382 | |||
383 | // save cgroup in MNT_DIR/cgroup file | ||
384 | if (cfg.cgroup) | ||
385 | save_cgroup(); | ||
386 | |||
387 | //**************************************** | ||
388 | // drop privileges or create a new user namespace | ||
389 | //**************************************** | ||
390 | save_nogroups(); | ||
391 | if (arg_noroot) { | ||
392 | int rv = unshare(CLONE_NEWUSER); | ||
393 | if (rv == -1) { | ||
394 | fprintf(stderr, "Warning: cannot mount a new user namespace\n"); | ||
395 | perror("unshare"); | ||
396 | drop_privs(arg_nogroups); | ||
397 | } | ||
398 | } | ||
399 | else | ||
400 | drop_privs(arg_nogroups); | ||
401 | |||
402 | // notify parent that new user namespace has been created so a proper | ||
403 | // UID/GID map can be setup | ||
404 | notify_other(child_to_parent_fds[1]); | ||
405 | close(child_to_parent_fds[1]); | ||
406 | |||
407 | // wait for parent to finish setting up a proper UID/GID map | ||
408 | wait_for_other(parent_to_child_fds[0]); | ||
409 | close(parent_to_child_fds[0]); | ||
410 | |||
411 | // somehow, the new user namespace resets capabilities; | ||
412 | // we need to do them again | ||
413 | if (arg_noroot) { | ||
414 | set_caps(); | ||
415 | if (arg_debug) | ||
416 | printf("User namespace (noroot) installed\n"); | ||
417 | } | ||
418 | |||
419 | |||
420 | //**************************************** | ||
421 | // start the program without using a shell | ||
422 | //**************************************** | ||
423 | if (arg_shell_none) { | ||
424 | if (arg_debug) { | ||
425 | int i; | ||
426 | for (i = cfg.original_program_index; i < cfg.original_argc; i++) { | ||
427 | if (cfg.original_argv[i] == NULL) | ||
428 | break; | ||
429 | printf("execvp argument %d: %s\n", i - cfg.original_program_index, cfg.original_argv[i]); | ||
430 | } | ||
431 | } | ||
432 | |||
433 | if (!arg_command) | ||
434 | printf("Child process initialized\n"); | ||
435 | execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index + 1]); | ||
436 | } | ||
437 | //**************************************** | ||
438 | // start the program using a shell | ||
439 | //**************************************** | ||
440 | else { | ||
441 | // choose the shell requested by the user, or use bash as default | ||
442 | char *sh; | ||
443 | if (cfg.shell) | ||
444 | sh = cfg.shell; | ||
445 | else if (arg_zsh) | ||
446 | sh = "/usr/bin/zsh"; | ||
447 | else if (arg_csh) | ||
448 | sh = "/bin/csh"; | ||
449 | else | ||
450 | sh = "/bin/bash"; | ||
451 | |||
452 | char *arg[5]; | ||
453 | int index = 0; | ||
454 | arg[index++] = sh; | ||
455 | arg[index++] = "-c"; | ||
456 | assert(cfg.command_line); | ||
457 | if (arg_debug) | ||
458 | printf("Starting %s\n", cfg.command_line); | ||
459 | if (arg_doubledash) | ||
460 | arg[index++] = "--"; | ||
461 | arg[index++] = cfg.command_line; | ||
462 | arg[index] = NULL; | ||
463 | assert(index < 5); | ||
464 | |||
465 | if (arg_debug) { | ||
466 | char *msg; | ||
467 | if (asprintf(&msg, "sandbox %d, execvp into %s", sandbox_pid, cfg.command_line) == -1) | ||
468 | errExit("asprintf"); | ||
469 | logmsg(msg); | ||
470 | free(msg); | ||
471 | } | ||
472 | |||
473 | if (arg_debug) { | ||
474 | int i; | ||
475 | for (i = 0; i < 5; i++) { | ||
476 | if (arg[i] == NULL) | ||
477 | break; | ||
478 | printf("execvp argument %d: %s\n", i, arg[i]); | ||
479 | } | ||
480 | } | ||
481 | |||
482 | if (!arg_command) | ||
483 | printf("Child process initialized\n"); | ||
484 | execvp(sh, arg); | ||
485 | } | ||
486 | |||
487 | |||
488 | perror("execvp"); | ||
489 | return 0; | ||
490 | } | ||
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c new file mode 100644 index 000000000..c03eb6848 --- /dev/null +++ b/src/firejail/seccomp.c | |||
@@ -0,0 +1,658 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | /* default seccomp filter | ||
22 | // seccomp | ||
23 | struct sock_filter filter[] = { | ||
24 | VALIDATE_ARCHITECTURE, | ||
25 | EXAMINE_SYSCALL, | ||
26 | BLACKLIST(SYS_mount), // mount/unmount filesystems | ||
27 | BLACKLIST(SYS_umount2), | ||
28 | BLACKLIST(SYS_ptrace), // trace processes | ||
29 | BLACKLIST(SYS_kexec_load), // loading a different kernel | ||
30 | BLACKLIST(SYS_open_by_handle_at), // open by handle | ||
31 | BLACKLIST(SYS_init_module), // kernel module handling | ||
32 | #ifdef SYS_finit_module // introduced in 2013 | ||
33 | BLACKLIST(SYS_finit_module), | ||
34 | #endif | ||
35 | BLACKLIST(SYS_delete_module), | ||
36 | BLACKLIST(SYS_iopl), // io permisions | ||
37 | #ifdef SYS_ioperm | ||
38 | BLACKLIST(SYS_ioperm), | ||
39 | #endif | ||
40 | SYS_iopl | ||
41 | BLACKLIST(SYS_iopl), // io permisions | ||
42 | #endif | ||
43 | #ifdef SYS_ni_syscall), // new io permisions call on arm devices | ||
44 | BLACKLIST(SYS_ni_syscall), | ||
45 | #endif | ||
46 | BLACKLIST(SYS_swapon), // swap on/off | ||
47 | BLACKLIST(SYS_swapoff), | ||
48 | BLACKLIST(SYS_syslog), // kernel printk control | ||
49 | RETURN_ALLOW | ||
50 | }; | ||
51 | */ | ||
52 | #ifdef HAVE_SECCOMP | ||
53 | #include "firejail.h" | ||
54 | #include <errno.h> | ||
55 | #include <linux/filter.h> | ||
56 | #include <sys/syscall.h> | ||
57 | #include <linux/capability.h> | ||
58 | #include <linux/audit.h> | ||
59 | #include <sys/stat.h> | ||
60 | #include <fcntl.h> | ||
61 | |||
62 | #include <sys/prctl.h> | ||
63 | #ifndef PR_SET_NO_NEW_PRIVS | ||
64 | # define PR_SET_NO_NEW_PRIVS 38 | ||
65 | #endif | ||
66 | |||
67 | #if HAVE_SECCOMP_H | ||
68 | #include <linux/seccomp.h> | ||
69 | #else | ||
70 | #define SECCOMP_MODE_FILTER 2 | ||
71 | #define SECCOMP_RET_KILL 0x00000000U | ||
72 | #define SECCOMP_RET_TRAP 0x00030000U | ||
73 | #define SECCOMP_RET_ALLOW 0x7fff0000U | ||
74 | #define SECCOMP_RET_ERRNO 0x00050000U | ||
75 | #define SECCOMP_RET_DATA 0x0000ffffU | ||
76 | struct seccomp_data { | ||
77 | int nr; | ||
78 | __u32 arch; | ||
79 | __u64 instruction_pointer; | ||
80 | __u64 args[6]; | ||
81 | }; | ||
82 | #endif | ||
83 | |||
84 | #if defined(__i386__) | ||
85 | # define ARCH_NR AUDIT_ARCH_I386 | ||
86 | #elif defined(__x86_64__) | ||
87 | # define ARCH_NR AUDIT_ARCH_X86_64 | ||
88 | #elif defined(__arm__) | ||
89 | # define ARCH_NR AUDIT_ARCH_ARM | ||
90 | #else | ||
91 | # warning "Platform does not support seccomp filter yet" | ||
92 | # define ARCH_NR 0 | ||
93 | #endif | ||
94 | |||
95 | |||
96 | #define VALIDATE_ARCHITECTURE \ | ||
97 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))), \ | ||
98 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \ | ||
99 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) | ||
100 | |||
101 | #define EXAMINE_SYSCALL BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ | ||
102 | (offsetof(struct seccomp_data, nr))) | ||
103 | |||
104 | #define BLACKLIST(syscall_nr) \ | ||
105 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, syscall_nr, 0, 1), \ | ||
106 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) | ||
107 | |||
108 | #define WHITELIST(syscall_nr) \ | ||
109 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, syscall_nr, 0, 1), \ | ||
110 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) | ||
111 | |||
112 | #define RETURN_ALLOW \ | ||
113 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) | ||
114 | |||
115 | #define KILL_PROCESS \ | ||
116 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) | ||
117 | |||
118 | #define SECSIZE 128 // initial filter size | ||
119 | static struct sock_filter *sfilter = NULL; | ||
120 | static int sfilter_alloc_size = 0; | ||
121 | static int sfilter_index = 0; | ||
122 | |||
123 | // debug filter | ||
124 | void filter_debug(void) { | ||
125 | // start filter | ||
126 | struct sock_filter filter[] = { | ||
127 | VALIDATE_ARCHITECTURE, | ||
128 | EXAMINE_SYSCALL | ||
129 | }; | ||
130 | |||
131 | // print sizes | ||
132 | printf("SECCOMP Filter:\n"); | ||
133 | if (sfilter == NULL) { | ||
134 | printf("SECCOMP filter not allocated\n"); | ||
135 | return; | ||
136 | } | ||
137 | if (sfilter_index < 4) | ||
138 | return; | ||
139 | |||
140 | // test the start of the filter | ||
141 | if (memcmp(sfilter, filter, sizeof(filter)) == 0) { | ||
142 | printf(" VALIDATE_ARCHITECTURE\n"); | ||
143 | printf(" EXAMINE_SYSCAL\n"); | ||
144 | } | ||
145 | |||
146 | // loop trough blacklists | ||
147 | int i = 4; | ||
148 | while (i < sfilter_index) { | ||
149 | // minimal parsing! | ||
150 | unsigned char *ptr = (unsigned char *) &sfilter[i]; | ||
151 | int *nr = (int *) (ptr + 4); | ||
152 | if (*ptr == 0x15 && *(ptr +14) == 0xff && *(ptr + 15) == 0x7f ) { | ||
153 | printf(" WHITELIST %d %s\n", *nr, syscall_find_nr(*nr)); | ||
154 | i += 2; | ||
155 | } | ||
156 | else if (*ptr == 0x15 && *(ptr +14) == 0 && *(ptr + 15) == 0) { | ||
157 | printf(" BLACKLIST %d %s\n", *nr, syscall_find_nr(*nr)); | ||
158 | i += 2; | ||
159 | } | ||
160 | else if (*ptr == 0x06 && *(ptr +6) == 0 && *(ptr + 7) == 0 ) { | ||
161 | printf(" KILL_PROCESS\n"); | ||
162 | i++; | ||
163 | } | ||
164 | else if (*ptr == 0x06 && *(ptr +6) == 0xff && *(ptr + 7) == 0x7f ) { | ||
165 | printf(" RETURN_ALLOW\n"); | ||
166 | i++; | ||
167 | } | ||
168 | else { | ||
169 | printf(" UNKNOWN ENTRY!!!\n"); | ||
170 | i++; | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | |||
175 | // initialize filter | ||
176 | static void filter_init(void) { | ||
177 | if (sfilter) { | ||
178 | assert(0); | ||
179 | return; | ||
180 | } | ||
181 | |||
182 | if (arg_debug) | ||
183 | printf("Initialize seccomp filter\n"); | ||
184 | // allocate a filter of SECSIZE | ||
185 | sfilter = malloc(sizeof(struct sock_filter) * SECSIZE); | ||
186 | if (!sfilter) | ||
187 | errExit("malloc"); | ||
188 | memset(sfilter, 0, sizeof(struct sock_filter) * SECSIZE); | ||
189 | sfilter_alloc_size = SECSIZE; | ||
190 | |||
191 | // copy the start entries | ||
192 | struct sock_filter filter[] = { | ||
193 | VALIDATE_ARCHITECTURE, | ||
194 | EXAMINE_SYSCALL | ||
195 | }; | ||
196 | sfilter_index = sizeof(filter) / sizeof(struct sock_filter); | ||
197 | memcpy(sfilter, filter, sizeof(filter)); | ||
198 | } | ||
199 | |||
200 | static void filter_realloc(void) { | ||
201 | assert(sfilter); | ||
202 | assert(sfilter_alloc_size); | ||
203 | assert(sfilter_index); | ||
204 | if (arg_debug) | ||
205 | printf("Allocating more seccomp filter entries\n"); | ||
206 | |||
207 | // allocate the new memory | ||
208 | struct sock_filter *old = sfilter; | ||
209 | sfilter = malloc(sizeof(struct sock_filter) * (sfilter_alloc_size + SECSIZE)); | ||
210 | if (!sfilter) | ||
211 | errExit("malloc"); | ||
212 | memset(sfilter, 0, sizeof(struct sock_filter) * (sfilter_alloc_size + SECSIZE)); | ||
213 | |||
214 | // copy old filter | ||
215 | memcpy(sfilter, old, sizeof(struct sock_filter) * sfilter_alloc_size); | ||
216 | sfilter_alloc_size += SECSIZE; | ||
217 | } | ||
218 | |||
219 | static void filter_add_whitelist(int syscall) { | ||
220 | assert(sfilter); | ||
221 | assert(sfilter_alloc_size); | ||
222 | assert(sfilter_index); | ||
223 | if (arg_debug) | ||
224 | printf("Whitelisting syscall %d %s\n", syscall, syscall_find_nr(syscall)); | ||
225 | |||
226 | if ((sfilter_index + 2) > sfilter_alloc_size) | ||
227 | filter_realloc(); | ||
228 | |||
229 | struct sock_filter filter[] = { | ||
230 | WHITELIST(syscall) | ||
231 | }; | ||
232 | #if 0 | ||
233 | { | ||
234 | int i; | ||
235 | unsigned char *ptr = (unsigned char *) &filter[0]; | ||
236 | for (i = 0; i < sizeof(filter); i++, ptr++) | ||
237 | printf("%x, ", (*ptr) & 0xff); | ||
238 | printf("\n"); | ||
239 | } | ||
240 | #endif | ||
241 | memcpy(&sfilter[sfilter_index], filter, sizeof(filter)); | ||
242 | sfilter_index += sizeof(filter) / sizeof(struct sock_filter); | ||
243 | } | ||
244 | |||
245 | static void filter_add_blacklist(int syscall) { | ||
246 | assert(sfilter); | ||
247 | assert(sfilter_alloc_size); | ||
248 | assert(sfilter_index); | ||
249 | if (arg_debug) | ||
250 | printf("Blacklisting syscall %d %s\n", syscall, syscall_find_nr(syscall)); | ||
251 | |||
252 | if ((sfilter_index + 2) > sfilter_alloc_size) | ||
253 | filter_realloc(); | ||
254 | |||
255 | struct sock_filter filter[] = { | ||
256 | BLACKLIST(syscall) | ||
257 | }; | ||
258 | #if 0 | ||
259 | { | ||
260 | int i; | ||
261 | unsigned char *ptr = (unsigned char *) &filter[0]; | ||
262 | for (i = 0; i < sizeof(filter); i++, ptr++) | ||
263 | printf("%x, ", (*ptr) & 0xff); | ||
264 | printf("\n"); | ||
265 | } | ||
266 | #endif | ||
267 | memcpy(&sfilter[sfilter_index], filter, sizeof(filter)); | ||
268 | sfilter_index += sizeof(filter) / sizeof(struct sock_filter); | ||
269 | } | ||
270 | |||
271 | static void filter_end_blacklist(void) { | ||
272 | assert(sfilter); | ||
273 | assert(sfilter_alloc_size); | ||
274 | assert(sfilter_index); | ||
275 | if (arg_debug) | ||
276 | printf("Ending syscall filter\n"); | ||
277 | |||
278 | if ((sfilter_index + 2) > sfilter_alloc_size) | ||
279 | filter_realloc(); | ||
280 | |||
281 | struct sock_filter filter[] = { | ||
282 | RETURN_ALLOW | ||
283 | }; | ||
284 | #if 0 | ||
285 | { | ||
286 | int i; | ||
287 | unsigned char *ptr = (unsigned char *) &filter[0]; | ||
288 | for (i = 0; i < sizeof(filter); i++, ptr++) | ||
289 | printf("%x, ", (*ptr) & 0xff); | ||
290 | printf("\n"); | ||
291 | } | ||
292 | #endif | ||
293 | memcpy(&sfilter[sfilter_index], filter, sizeof(filter)); | ||
294 | sfilter_index += sizeof(filter) / sizeof(struct sock_filter); | ||
295 | } | ||
296 | |||
297 | static void filter_end_whitelist(void) { | ||
298 | assert(sfilter); | ||
299 | assert(sfilter_alloc_size); | ||
300 | assert(sfilter_index); | ||
301 | if (arg_debug) | ||
302 | printf("Ending syscall filter\n"); | ||
303 | |||
304 | if ((sfilter_index + 2) > sfilter_alloc_size) | ||
305 | filter_realloc(); | ||
306 | |||
307 | struct sock_filter filter[] = { | ||
308 | KILL_PROCESS | ||
309 | }; | ||
310 | #if 0 | ||
311 | { | ||
312 | int i; | ||
313 | unsigned char *ptr = (unsigned char *) &filter[0]; | ||
314 | for (i = 0; i < sizeof(filter); i++, ptr++) | ||
315 | printf("%x, ", (*ptr) & 0xff); | ||
316 | printf("\n"); | ||
317 | } | ||
318 | #endif | ||
319 | memcpy(&sfilter[sfilter_index], filter, sizeof(filter)); | ||
320 | sfilter_index += sizeof(filter) / sizeof(struct sock_filter); | ||
321 | } | ||
322 | |||
323 | |||
324 | // save seccomp filter in /tmp/firejail/mnt/seccomp | ||
325 | static void write_seccomp_file(void) { | ||
326 | fs_build_mnt_dir(); | ||
327 | assert(sfilter); | ||
328 | |||
329 | char *fname; | ||
330 | if (asprintf(&fname, "%s/seccomp", MNT_DIR) == -1) | ||
331 | errExit("asprintf"); | ||
332 | int fd = open(fname, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); | ||
333 | if (fd == -1) | ||
334 | errExit("open"); | ||
335 | |||
336 | if (arg_debug) | ||
337 | printf("Save seccomp filter, size %lu bytes\n", sfilter_index * sizeof(struct sock_filter)); | ||
338 | errno = 0; | ||
339 | ssize_t sz = write(fd, sfilter, sfilter_index * sizeof(struct sock_filter)); | ||
340 | if (sz != (sfilter_index * sizeof(struct sock_filter))) { | ||
341 | fprintf(stderr, "Error: cannot save seccomp filter\n"); | ||
342 | exit(1); | ||
343 | } | ||
344 | close(fd); | ||
345 | if (chown(fname, 0, 0) < 0) | ||
346 | errExit("chown"); | ||
347 | free(fname); | ||
348 | } | ||
349 | |||
350 | // read seccomp filter from /tmp/firejail/mnt/seccomp | ||
351 | static void read_seccomp_file(char *file_name) { | ||
352 | assert(sfilter == NULL && sfilter_index == 0); | ||
353 | |||
354 | char *fname; | ||
355 | if (file_name) | ||
356 | fname = file_name; | ||
357 | else { | ||
358 | if (asprintf(&fname, "%s/seccomp", MNT_DIR) == -1) | ||
359 | errExit("asprintf"); | ||
360 | } | ||
361 | |||
362 | // check file | ||
363 | struct stat s; | ||
364 | if (stat(fname, &s) == -1) { | ||
365 | fprintf(stderr, "Error: seccomp file not found\n"); | ||
366 | exit(1); | ||
367 | } | ||
368 | ssize_t sz = s.st_size; | ||
369 | if (sz == 0 || (sz % sizeof(struct sock_filter)) != 0) { | ||
370 | fprintf(stderr, "Error: invalid seccomp file\n"); | ||
371 | exit(1); | ||
372 | } | ||
373 | sfilter = malloc(sz); | ||
374 | if (!sfilter) | ||
375 | errExit("malloc"); | ||
376 | |||
377 | // read file | ||
378 | /* coverity[toctou] */ | ||
379 | int fd = open(fname,O_RDONLY); | ||
380 | if (fd == -1) | ||
381 | errExit("open"); | ||
382 | errno = 0; | ||
383 | ssize_t size = read(fd, sfilter, sz); | ||
384 | if (size != sz) { | ||
385 | fprintf(stderr, "Error: invalid seccomp file\n"); | ||
386 | exit(1); | ||
387 | } | ||
388 | sfilter_index = sz / sizeof(struct sock_filter); | ||
389 | |||
390 | if (arg_debug) | ||
391 | printf("Read seccomp filter, size %lu bytes\n", sfilter_index * sizeof(struct sock_filter)); | ||
392 | |||
393 | close(fd); | ||
394 | free(fname); | ||
395 | |||
396 | if (arg_debug) | ||
397 | filter_debug(); | ||
398 | } | ||
399 | |||
400 | |||
401 | // drop filter for seccomp option | ||
402 | int seccomp_filter_drop(void) { | ||
403 | filter_init(); | ||
404 | |||
405 | // default seccomp | ||
406 | if (arg_seccomp_list_drop == NULL) { | ||
407 | #ifdef SYS_mount | ||
408 | filter_add_blacklist(SYS_mount); | ||
409 | #endif | ||
410 | #ifdef SYS_umount2 | ||
411 | filter_add_blacklist(SYS_umount2); | ||
412 | #endif | ||
413 | #ifdef SYS_ptrace | ||
414 | filter_add_blacklist(SYS_ptrace); | ||
415 | #endif | ||
416 | #ifdef SYS_kexec_load | ||
417 | filter_add_blacklist(SYS_kexec_load); | ||
418 | #endif | ||
419 | #ifdef SYS_open_by_handle_at | ||
420 | filter_add_blacklist(SYS_open_by_handle_at); | ||
421 | #endif | ||
422 | #ifdef SYS_init_module | ||
423 | filter_add_blacklist(SYS_init_module); | ||
424 | #endif | ||
425 | #ifdef SYS_finit_module // introduced in 2013 | ||
426 | filter_add_blacklist(SYS_finit_module); | ||
427 | #endif | ||
428 | #ifdef SYS_delete_module | ||
429 | filter_add_blacklist(SYS_delete_module); | ||
430 | #endif | ||
431 | #ifdef SYS_iopl | ||
432 | filter_add_blacklist(SYS_iopl); | ||
433 | #endif | ||
434 | #ifdef SYS_ioperm | ||
435 | filter_add_blacklist(SYS_ioperm); | ||
436 | #endif | ||
437 | #ifdef SYS_ni_syscall // new io permisions call on arm devices | ||
438 | filter_add_blacklist(SYS_ni_syscall); | ||
439 | #endif | ||
440 | #ifdef SYS_swapon | ||
441 | filter_add_blacklist(SYS_swapon); | ||
442 | #endif | ||
443 | #ifdef SYS_swapoff | ||
444 | filter_add_blacklist(SYS_swapoff); | ||
445 | #endif | ||
446 | #ifdef SYS_syslog | ||
447 | filter_add_blacklist(SYS_syslog); | ||
448 | #endif | ||
449 | #ifdef SYS_process_vm_readv | ||
450 | filter_add_blacklist(SYS_process_vm_readv); | ||
451 | #endif | ||
452 | #ifdef SYS_process_vm_writev | ||
453 | filter_add_blacklist(SYS_process_vm_writev); | ||
454 | #endif | ||
455 | #ifdef SYS_mknod | ||
456 | filter_add_blacklist(SYS_mknod); | ||
457 | #endif | ||
458 | |||
459 | // new syscalls in 0.9,23 | ||
460 | #ifdef SYS_sysfs | ||
461 | filter_add_blacklist(SYS_sysfs); | ||
462 | #endif | ||
463 | #ifdef SYS__sysctl | ||
464 | filter_add_blacklist(SYS__sysctl); | ||
465 | #endif | ||
466 | #ifdef SYS_adjtimex | ||
467 | filter_add_blacklist(SYS_adjtimex); | ||
468 | #endif | ||
469 | #ifdef SYS_clock_adjtime | ||
470 | filter_add_blacklist(SYS_clock_adjtime); | ||
471 | #endif | ||
472 | #ifdef SYS_lookup_dcookie | ||
473 | filter_add_blacklist(SYS_lookup_dcookie); | ||
474 | #endif | ||
475 | #ifdef SYS_perf_event_open | ||
476 | filter_add_blacklist(SYS_perf_event_open); | ||
477 | #endif | ||
478 | #ifdef SYS_fanotify_init | ||
479 | filter_add_blacklist(SYS_fanotify_init); | ||
480 | #endif | ||
481 | #ifdef SYS_kcmp | ||
482 | filter_add_blacklist(SYS_kcmp); | ||
483 | #endif | ||
484 | } | ||
485 | |||
486 | // default seccomp filter with additional drop list | ||
487 | if (arg_seccomp_list && arg_seccomp_list_drop == NULL) { | ||
488 | if (syscall_check_list(arg_seccomp_list, filter_add_blacklist)) { | ||
489 | fprintf(stderr, "Error: cannot load seccomp filter\n"); | ||
490 | exit(1); | ||
491 | } | ||
492 | } | ||
493 | // drop list | ||
494 | else if (arg_seccomp_list == NULL && arg_seccomp_list_drop) { | ||
495 | if (syscall_check_list(arg_seccomp_list_drop, filter_add_blacklist)) { | ||
496 | fprintf(stderr, "Error: cannot load seccomp filter\n"); | ||
497 | exit(1); | ||
498 | } | ||
499 | } | ||
500 | |||
501 | |||
502 | filter_end_blacklist(); | ||
503 | if (arg_debug) | ||
504 | filter_debug(); | ||
505 | |||
506 | // save seccomp filter in /tmp/firejail/mnt/seccomp | ||
507 | // in order to use it in --join operations | ||
508 | write_seccomp_file(); | ||
509 | |||
510 | |||
511 | struct sock_fprog prog = { | ||
512 | .len = sfilter_index, | ||
513 | .filter = sfilter, | ||
514 | }; | ||
515 | |||
516 | if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { | ||
517 | fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); | ||
518 | return 1; | ||
519 | } | ||
520 | else if (arg_debug) { | ||
521 | printf("seccomp enabled\n"); | ||
522 | } | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | // keep filter for seccomp option | ||
528 | int seccomp_filter_keep(void) { | ||
529 | filter_init(); | ||
530 | |||
531 | // these 4 syscalls are used by firejail after the seccomp filter is initialized | ||
532 | filter_add_whitelist(SYS_setuid); | ||
533 | filter_add_whitelist(SYS_setgid); | ||
534 | filter_add_whitelist(SYS_setgroups); | ||
535 | filter_add_whitelist(SYS_dup); | ||
536 | |||
537 | // apply keep list | ||
538 | if (arg_seccomp_list_keep) { | ||
539 | if (syscall_check_list(arg_seccomp_list_keep, filter_add_whitelist)) { | ||
540 | fprintf(stderr, "Error: cannot load seccomp filter\n"); | ||
541 | exit(1); | ||
542 | } | ||
543 | } | ||
544 | |||
545 | filter_end_whitelist(); | ||
546 | if (arg_debug) | ||
547 | filter_debug(); | ||
548 | |||
549 | // save seccomp filter in /tmp/firejail/mnt/seccomp | ||
550 | // in order to use it in --join operations | ||
551 | write_seccomp_file(); | ||
552 | |||
553 | |||
554 | struct sock_fprog prog = { | ||
555 | .len = sfilter_index, | ||
556 | .filter = sfilter, | ||
557 | }; | ||
558 | |||
559 | if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { | ||
560 | fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); | ||
561 | return 1; | ||
562 | } | ||
563 | else if (arg_debug) { | ||
564 | printf("seccomp enabled\n"); | ||
565 | } | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | |||
571 | |||
572 | void seccomp_set(void) { | ||
573 | // read seccomp filter from /tmp/firejail/mnt/seccomp | ||
574 | read_seccomp_file(NULL); | ||
575 | |||
576 | // apply filter | ||
577 | struct sock_fprog prog = { | ||
578 | .len = sfilter_index, | ||
579 | .filter = sfilter, | ||
580 | }; | ||
581 | |||
582 | if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { | ||
583 | fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); | ||
584 | return; | ||
585 | } | ||
586 | else if (arg_debug) { | ||
587 | printf("seccomp enabled\n"); | ||
588 | } | ||
589 | } | ||
590 | |||
591 | void seccomp_print_filter_name(const char *name) { | ||
592 | if (!name || strlen(name) == 0) { | ||
593 | fprintf(stderr, "Error: invalid sandbox name\n"); | ||
594 | exit(1); | ||
595 | } | ||
596 | pid_t pid; | ||
597 | if (name2pid(name, &pid)) { | ||
598 | fprintf(stderr, "Error: cannot find sandbox %s\n", name); | ||
599 | exit(1); | ||
600 | } | ||
601 | |||
602 | seccomp_print_filter(pid); | ||
603 | } | ||
604 | |||
605 | void seccomp_print_filter(pid_t pid) { | ||
606 | // if the pid is that of a firejail process, use the pid of the first child process | ||
607 | char *comm = pid_proc_comm(pid); | ||
608 | if (comm) { | ||
609 | // remove \n | ||
610 | char *ptr = strchr(comm, '\n'); | ||
611 | if (ptr) | ||
612 | *ptr = '\0'; | ||
613 | if (strcmp(comm, "firejail") == 0) { | ||
614 | pid_t child; | ||
615 | if (find_child(pid, &child) == 0) { | ||
616 | pid = child; | ||
617 | } | ||
618 | } | ||
619 | free(comm); | ||
620 | } | ||
621 | |||
622 | // check privileges for non-root users | ||
623 | uid_t uid = getuid(); | ||
624 | if (uid != 0) { | ||
625 | struct stat s; | ||
626 | char *dir; | ||
627 | if (asprintf(&dir, "/proc/%u/ns", pid) == -1) | ||
628 | errExit("asprintf"); | ||
629 | if (stat(dir, &s) < 0) | ||
630 | errExit("stat"); | ||
631 | if (s.st_uid != uid) { | ||
632 | printf("Error: permission denied.\n"); | ||
633 | exit(1); | ||
634 | } | ||
635 | } | ||
636 | |||
637 | |||
638 | // find the seccomp filter | ||
639 | char *fname; | ||
640 | if (asprintf(&fname, "/proc/%d/root/tmp/firejail/mnt/seccomp", pid) == -1) | ||
641 | errExit("asprintf"); | ||
642 | |||
643 | struct stat s; | ||
644 | if (stat(fname, &s) == -1) { | ||
645 | printf("Cannot access seccomp filter.\n"); | ||
646 | exit(1); | ||
647 | } | ||
648 | |||
649 | // read and print the filter | ||
650 | read_seccomp_file(fname); | ||
651 | drop_privs(1); | ||
652 | filter_debug(); | ||
653 | |||
654 | exit(0); | ||
655 | } | ||
656 | |||
657 | #endif // HAVE_SECCOMP | ||
658 | |||
diff --git a/src/firejail/shutdown.c b/src/firejail/shutdown.c new file mode 100644 index 000000000..b666996df --- /dev/null +++ b/src/firejail/shutdown.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/stat.h> | ||
22 | #include <sys/wait.h> | ||
23 | #include <fcntl.h> | ||
24 | #include <sys/prctl.h> | ||
25 | |||
26 | void shut_name(const char *name) { | ||
27 | if (!name || strlen(name) == 0) { | ||
28 | fprintf(stderr, "Error: invalid sandbox name\n"); | ||
29 | exit(1); | ||
30 | } | ||
31 | |||
32 | pid_t pid; | ||
33 | if (name2pid(name, &pid)) { | ||
34 | fprintf(stderr, "Error: cannot find sandbox %s\n", name); | ||
35 | exit(1); | ||
36 | } | ||
37 | |||
38 | shut(pid); | ||
39 | } | ||
40 | |||
41 | void shut(pid_t pid) { | ||
42 | pid_t parent = pid; | ||
43 | // if the pid is that of a firejail process, use the pid of a child process inside the sandbox | ||
44 | char *comm = pid_proc_comm(pid); | ||
45 | if (comm) { | ||
46 | // remove \n | ||
47 | char *ptr = strchr(comm, '\n'); | ||
48 | if (ptr) | ||
49 | *ptr = '\0'; | ||
50 | if (strcmp(comm, "firejail") == 0) { | ||
51 | pid_t child; | ||
52 | if (find_child(pid, &child) == 0) { | ||
53 | pid = child; | ||
54 | printf("Switching to pid %u, the first child process inside the sandbox\n", (unsigned) pid); | ||
55 | } | ||
56 | } | ||
57 | free(comm); | ||
58 | } | ||
59 | |||
60 | // check privileges for non-root users | ||
61 | uid_t uid = getuid(); | ||
62 | if (uid != 0) { | ||
63 | struct stat s; | ||
64 | char *dir; | ||
65 | if (asprintf(&dir, "/proc/%u/ns", pid) == -1) | ||
66 | errExit("asprintf"); | ||
67 | if (stat(dir, &s) < 0) | ||
68 | errExit("stat"); | ||
69 | if (s.st_uid != uid) { | ||
70 | fprintf(stderr, "Error: permission is denied to shutdown a sandbox created by a different user.\n"); | ||
71 | exit(1); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | printf("Sending SIGTERM to %u\n", pid); | ||
76 | kill(pid, SIGTERM); | ||
77 | sleep(2); | ||
78 | |||
79 | // if the process is still running, terminate it using SIGKILL | ||
80 | // try to open stat file | ||
81 | char *file; | ||
82 | if (asprintf(&file, "/proc/%u/status", pid) == -1) { | ||
83 | perror("asprintf"); | ||
84 | exit(1); | ||
85 | } | ||
86 | FILE *fp = fopen(file, "r"); | ||
87 | if (!fp) | ||
88 | return; | ||
89 | fclose(fp); | ||
90 | |||
91 | // kill the process and also the parent | ||
92 | printf("Sending SIGKILL to %u\n", pid); | ||
93 | kill(pid, SIGKILL); | ||
94 | if (parent != pid) { | ||
95 | printf("Sending SIGKILL to %u\n", parent); | ||
96 | kill(parent, SIGKILL); | ||
97 | } | ||
98 | } | ||
diff --git a/src/firejail/syscall.c b/src/firejail/syscall.c new file mode 100644 index 000000000..50bff7f5a --- /dev/null +++ b/src/firejail/syscall.c | |||
@@ -0,0 +1,4942 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #ifdef HAVE_SECCOMP | ||
22 | #include "firejail.h" | ||
23 | #include <sys/syscall.h> | ||
24 | |||
25 | typedef struct { | ||
26 | char *name; | ||
27 | int nr; | ||
28 | } SyscallEntry; | ||
29 | |||
30 | static SyscallEntry syslist[] = { | ||
31 | // | ||
32 | // code generated using tools/extract-syscall | ||
33 | // | ||
34 | #ifndef _SYSCALL_H | ||
35 | #endif | ||
36 | #if !defined __x86_64__ | ||
37 | #ifdef SYS__llseek | ||
38 | #ifdef __NR__llseek | ||
39 | {"_llseek", __NR__llseek}, | ||
40 | #endif | ||
41 | #endif | ||
42 | #ifdef SYS__newselect | ||
43 | #ifdef __NR__newselect | ||
44 | {"_newselect", __NR__newselect}, | ||
45 | #endif | ||
46 | #endif | ||
47 | #ifdef SYS__sysctl | ||
48 | #ifdef __NR__sysctl | ||
49 | {"_sysctl", __NR__sysctl}, | ||
50 | #endif | ||
51 | #endif | ||
52 | #ifdef SYS_access | ||
53 | #ifdef __NR_access | ||
54 | {"access", __NR_access}, | ||
55 | #endif | ||
56 | #endif | ||
57 | #ifdef SYS_acct | ||
58 | #ifdef __NR_acct | ||
59 | {"acct", __NR_acct}, | ||
60 | #endif | ||
61 | #endif | ||
62 | #ifdef SYS_add_key | ||
63 | #ifdef __NR_add_key | ||
64 | {"add_key", __NR_add_key}, | ||
65 | #endif | ||
66 | #endif | ||
67 | #ifdef SYS_adjtimex | ||
68 | #ifdef __NR_adjtimex | ||
69 | {"adjtimex", __NR_adjtimex}, | ||
70 | #endif | ||
71 | #endif | ||
72 | #ifdef SYS_afs_syscall | ||
73 | #ifdef __NR_afs_syscall | ||
74 | {"afs_syscall", __NR_afs_syscall}, | ||
75 | #endif | ||
76 | #endif | ||
77 | #ifdef SYS_alarm | ||
78 | #ifdef __NR_alarm | ||
79 | {"alarm", __NR_alarm}, | ||
80 | #endif | ||
81 | #endif | ||
82 | #ifdef SYS_bdflush | ||
83 | #ifdef __NR_bdflush | ||
84 | {"bdflush", __NR_bdflush}, | ||
85 | #endif | ||
86 | #endif | ||
87 | #ifdef SYS_break | ||
88 | #ifdef __NR_break | ||
89 | {"break", __NR_break}, | ||
90 | #endif | ||
91 | #endif | ||
92 | #ifdef SYS_brk | ||
93 | #ifdef __NR_brk | ||
94 | {"brk", __NR_brk}, | ||
95 | #endif | ||
96 | #endif | ||
97 | #ifdef SYS_capget | ||
98 | #ifdef __NR_capget | ||
99 | {"capget", __NR_capget}, | ||
100 | #endif | ||
101 | #endif | ||
102 | #ifdef SYS_capset | ||
103 | #ifdef __NR_capset | ||
104 | {"capset", __NR_capset}, | ||
105 | #endif | ||
106 | #endif | ||
107 | #ifdef SYS_chdir | ||
108 | #ifdef __NR_chdir | ||
109 | {"chdir", __NR_chdir}, | ||
110 | #endif | ||
111 | #endif | ||
112 | #ifdef SYS_chmod | ||
113 | #ifdef __NR_chmod | ||
114 | {"chmod", __NR_chmod}, | ||
115 | #endif | ||
116 | #endif | ||
117 | #ifdef SYS_chown | ||
118 | #ifdef __NR_chown | ||
119 | {"chown", __NR_chown}, | ||
120 | #endif | ||
121 | #endif | ||
122 | #ifdef SYS_chown32 | ||
123 | #ifdef __NR_chown32 | ||
124 | {"chown32", __NR_chown32}, | ||
125 | #endif | ||
126 | #endif | ||
127 | #ifdef SYS_chroot | ||
128 | #ifdef __NR_chroot | ||
129 | {"chroot", __NR_chroot}, | ||
130 | #endif | ||
131 | #endif | ||
132 | #ifdef SYS_clock_adjtime | ||
133 | #ifdef __NR_clock_adjtime | ||
134 | {"clock_adjtime", __NR_clock_adjtime}, | ||
135 | #endif | ||
136 | #endif | ||
137 | #ifdef SYS_clock_getres | ||
138 | #ifdef __NR_clock_getres | ||
139 | {"clock_getres", __NR_clock_getres}, | ||
140 | #endif | ||
141 | #endif | ||
142 | #ifdef SYS_clock_gettime | ||
143 | #ifdef __NR_clock_gettime | ||
144 | {"clock_gettime", __NR_clock_gettime}, | ||
145 | #endif | ||
146 | #endif | ||
147 | #ifdef SYS_clock_nanosleep | ||
148 | #ifdef __NR_clock_nanosleep | ||
149 | {"clock_nanosleep", __NR_clock_nanosleep}, | ||
150 | #endif | ||
151 | #endif | ||
152 | #ifdef SYS_clock_settime | ||
153 | #ifdef __NR_clock_settime | ||
154 | {"clock_settime", __NR_clock_settime}, | ||
155 | #endif | ||
156 | #endif | ||
157 | #ifdef SYS_clone | ||
158 | #ifdef __NR_clone | ||
159 | {"clone", __NR_clone}, | ||
160 | #endif | ||
161 | #endif | ||
162 | #ifdef SYS_close | ||
163 | #ifdef __NR_close | ||
164 | {"close", __NR_close}, | ||
165 | #endif | ||
166 | #endif | ||
167 | #ifdef SYS_creat | ||
168 | #ifdef __NR_creat | ||
169 | {"creat", __NR_creat}, | ||
170 | #endif | ||
171 | #endif | ||
172 | #ifdef SYS_create_module | ||
173 | #ifdef __NR_create_module | ||
174 | {"create_module", __NR_create_module}, | ||
175 | #endif | ||
176 | #endif | ||
177 | #ifdef SYS_delete_module | ||
178 | #ifdef __NR_delete_module | ||
179 | {"delete_module", __NR_delete_module}, | ||
180 | #endif | ||
181 | #endif | ||
182 | #ifdef SYS_dup | ||
183 | #ifdef __NR_dup | ||
184 | {"dup", __NR_dup}, | ||
185 | #endif | ||
186 | #endif | ||
187 | #ifdef SYS_dup2 | ||
188 | #ifdef __NR_dup2 | ||
189 | {"dup2", __NR_dup2}, | ||
190 | #endif | ||
191 | #endif | ||
192 | #ifdef SYS_dup3 | ||
193 | #ifdef __NR_dup3 | ||
194 | {"dup3", __NR_dup3}, | ||
195 | #endif | ||
196 | #endif | ||
197 | #ifdef SYS_epoll_create | ||
198 | #ifdef __NR_epoll_create | ||
199 | {"epoll_create", __NR_epoll_create}, | ||
200 | #endif | ||
201 | #endif | ||
202 | #ifdef SYS_epoll_create1 | ||
203 | #ifdef __NR_epoll_create1 | ||
204 | {"epoll_create1", __NR_epoll_create1}, | ||
205 | #endif | ||
206 | #endif | ||
207 | #ifdef SYS_epoll_ctl | ||
208 | #ifdef __NR_epoll_ctl | ||
209 | {"epoll_ctl", __NR_epoll_ctl}, | ||
210 | #endif | ||
211 | #endif | ||
212 | #ifdef SYS_epoll_pwait | ||
213 | #ifdef __NR_epoll_pwait | ||
214 | {"epoll_pwait", __NR_epoll_pwait}, | ||
215 | #endif | ||
216 | #endif | ||
217 | #ifdef SYS_epoll_wait | ||
218 | #ifdef __NR_epoll_wait | ||
219 | {"epoll_wait", __NR_epoll_wait}, | ||
220 | #endif | ||
221 | #endif | ||
222 | #ifdef SYS_eventfd | ||
223 | #ifdef __NR_eventfd | ||
224 | {"eventfd", __NR_eventfd}, | ||
225 | #endif | ||
226 | #endif | ||
227 | #ifdef SYS_eventfd2 | ||
228 | #ifdef __NR_eventfd2 | ||
229 | {"eventfd2", __NR_eventfd2}, | ||
230 | #endif | ||
231 | #endif | ||
232 | #ifdef SYS_execve | ||
233 | #ifdef __NR_execve | ||
234 | {"execve", __NR_execve}, | ||
235 | #endif | ||
236 | #endif | ||
237 | #ifdef SYS_exit | ||
238 | #ifdef __NR_exit | ||
239 | {"exit", __NR_exit}, | ||
240 | #endif | ||
241 | #endif | ||
242 | #ifdef SYS_exit_group | ||
243 | #ifdef __NR_exit_group | ||
244 | {"exit_group", __NR_exit_group}, | ||
245 | #endif | ||
246 | #endif | ||
247 | #ifdef SYS_faccessat | ||
248 | #ifdef __NR_faccessat | ||
249 | {"faccessat", __NR_faccessat}, | ||
250 | #endif | ||
251 | #endif | ||
252 | #ifdef SYS_fadvise64 | ||
253 | #ifdef __NR_fadvise64 | ||
254 | {"fadvise64", __NR_fadvise64}, | ||
255 | #endif | ||
256 | #endif | ||
257 | #ifdef SYS_fadvise64_64 | ||
258 | #ifdef __NR_fadvise64_64 | ||
259 | {"fadvise64_64", __NR_fadvise64_64}, | ||
260 | #endif | ||
261 | #endif | ||
262 | #ifdef SYS_fallocate | ||
263 | #ifdef __NR_fallocate | ||
264 | {"fallocate", __NR_fallocate}, | ||
265 | #endif | ||
266 | #endif | ||
267 | #ifdef SYS_fanotify_init | ||
268 | #ifdef __NR_fanotify_init | ||
269 | {"fanotify_init", __NR_fanotify_init}, | ||
270 | #endif | ||
271 | #endif | ||
272 | #ifdef SYS_fanotify_mark | ||
273 | #ifdef __NR_fanotify_mark | ||
274 | {"fanotify_mark", __NR_fanotify_mark}, | ||
275 | #endif | ||
276 | #endif | ||
277 | #ifdef SYS_fchdir | ||
278 | #ifdef __NR_fchdir | ||
279 | {"fchdir", __NR_fchdir}, | ||
280 | #endif | ||
281 | #endif | ||
282 | #ifdef SYS_fchmod | ||
283 | #ifdef __NR_fchmod | ||
284 | {"fchmod", __NR_fchmod}, | ||
285 | #endif | ||
286 | #endif | ||
287 | #ifdef SYS_fchmodat | ||
288 | #ifdef __NR_fchmodat | ||
289 | {"fchmodat", __NR_fchmodat}, | ||
290 | #endif | ||
291 | #endif | ||
292 | #ifdef SYS_fchown | ||
293 | #ifdef __NR_fchown | ||
294 | {"fchown", __NR_fchown}, | ||
295 | #endif | ||
296 | #endif | ||
297 | #ifdef SYS_fchown32 | ||
298 | #ifdef __NR_fchown32 | ||
299 | {"fchown32", __NR_fchown32}, | ||
300 | #endif | ||
301 | #endif | ||
302 | #ifdef SYS_fchownat | ||
303 | #ifdef __NR_fchownat | ||
304 | {"fchownat", __NR_fchownat}, | ||
305 | #endif | ||
306 | #endif | ||
307 | #ifdef SYS_fcntl | ||
308 | #ifdef __NR_fcntl | ||
309 | {"fcntl", __NR_fcntl}, | ||
310 | #endif | ||
311 | #endif | ||
312 | #ifdef SYS_fcntl64 | ||
313 | #ifdef __NR_fcntl64 | ||
314 | {"fcntl64", __NR_fcntl64}, | ||
315 | #endif | ||
316 | #endif | ||
317 | #ifdef SYS_fdatasync | ||
318 | #ifdef __NR_fdatasync | ||
319 | {"fdatasync", __NR_fdatasync}, | ||
320 | #endif | ||
321 | #endif | ||
322 | #ifdef SYS_fgetxattr | ||
323 | #ifdef __NR_fgetxattr | ||
324 | {"fgetxattr", __NR_fgetxattr}, | ||
325 | #endif | ||
326 | #endif | ||
327 | #ifdef SYS_finit_module | ||
328 | #ifdef __NR_finit_module | ||
329 | {"finit_module", __NR_finit_module}, | ||
330 | #endif | ||
331 | #endif | ||
332 | #ifdef SYS_flistxattr | ||
333 | #ifdef __NR_flistxattr | ||
334 | {"flistxattr", __NR_flistxattr}, | ||
335 | #endif | ||
336 | #endif | ||
337 | #ifdef SYS_flock | ||
338 | #ifdef __NR_flock | ||
339 | {"flock", __NR_flock}, | ||
340 | #endif | ||
341 | #endif | ||
342 | #ifdef SYS_fork | ||
343 | #ifdef __NR_fork | ||
344 | {"fork", __NR_fork}, | ||
345 | #endif | ||
346 | #endif | ||
347 | #ifdef SYS_fremovexattr | ||
348 | #ifdef __NR_fremovexattr | ||
349 | {"fremovexattr", __NR_fremovexattr}, | ||
350 | #endif | ||
351 | #endif | ||
352 | #ifdef SYS_fsetxattr | ||
353 | #ifdef __NR_fsetxattr | ||
354 | {"fsetxattr", __NR_fsetxattr}, | ||
355 | #endif | ||
356 | #endif | ||
357 | #ifdef SYS_fstat | ||
358 | #ifdef __NR_fstat | ||
359 | {"fstat", __NR_fstat}, | ||
360 | #endif | ||
361 | #endif | ||
362 | #ifdef SYS_fstat64 | ||
363 | #ifdef __NR_fstat64 | ||
364 | {"fstat64", __NR_fstat64}, | ||
365 | #endif | ||
366 | #endif | ||
367 | #ifdef SYS_fstatat64 | ||
368 | #ifdef __NR_fstatat64 | ||
369 | {"fstatat64", __NR_fstatat64}, | ||
370 | #endif | ||
371 | #endif | ||
372 | #ifdef SYS_fstatfs | ||
373 | #ifdef __NR_fstatfs | ||
374 | {"fstatfs", __NR_fstatfs}, | ||
375 | #endif | ||
376 | #endif | ||
377 | #ifdef SYS_fstatfs64 | ||
378 | #ifdef __NR_fstatfs64 | ||
379 | {"fstatfs64", __NR_fstatfs64}, | ||
380 | #endif | ||
381 | #endif | ||
382 | #ifdef SYS_fsync | ||
383 | #ifdef __NR_fsync | ||
384 | {"fsync", __NR_fsync}, | ||
385 | #endif | ||
386 | #endif | ||
387 | #ifdef SYS_ftime | ||
388 | #ifdef __NR_ftime | ||
389 | {"ftime", __NR_ftime}, | ||
390 | #endif | ||
391 | #endif | ||
392 | #ifdef SYS_ftruncate | ||
393 | #ifdef __NR_ftruncate | ||
394 | {"ftruncate", __NR_ftruncate}, | ||
395 | #endif | ||
396 | #endif | ||
397 | #ifdef SYS_ftruncate64 | ||
398 | #ifdef __NR_ftruncate64 | ||
399 | {"ftruncate64", __NR_ftruncate64}, | ||
400 | #endif | ||
401 | #endif | ||
402 | #ifdef SYS_futex | ||
403 | #ifdef __NR_futex | ||
404 | {"futex", __NR_futex}, | ||
405 | #endif | ||
406 | #endif | ||
407 | #ifdef SYS_futimesat | ||
408 | #ifdef __NR_futimesat | ||
409 | {"futimesat", __NR_futimesat}, | ||
410 | #endif | ||
411 | #endif | ||
412 | #ifdef SYS_get_kernel_syms | ||
413 | #ifdef __NR_get_kernel_syms | ||
414 | {"get_kernel_syms", __NR_get_kernel_syms}, | ||
415 | #endif | ||
416 | #endif | ||
417 | #ifdef SYS_get_mempolicy | ||
418 | #ifdef __NR_get_mempolicy | ||
419 | {"get_mempolicy", __NR_get_mempolicy}, | ||
420 | #endif | ||
421 | #endif | ||
422 | #ifdef SYS_get_robust_list | ||
423 | #ifdef __NR_get_robust_list | ||
424 | {"get_robust_list", __NR_get_robust_list}, | ||
425 | #endif | ||
426 | #endif | ||
427 | #ifdef SYS_get_thread_area | ||
428 | #ifdef __NR_get_thread_area | ||
429 | {"get_thread_area", __NR_get_thread_area}, | ||
430 | #endif | ||
431 | #endif | ||
432 | #ifdef SYS_getcpu | ||
433 | #ifdef __NR_getcpu | ||
434 | {"getcpu", __NR_getcpu}, | ||
435 | #endif | ||
436 | #endif | ||
437 | #ifdef SYS_getcwd | ||
438 | #ifdef __NR_getcwd | ||
439 | {"getcwd", __NR_getcwd}, | ||
440 | #endif | ||
441 | #endif | ||
442 | #ifdef SYS_getdents | ||
443 | #ifdef __NR_getdents | ||
444 | {"getdents", __NR_getdents}, | ||
445 | #endif | ||
446 | #endif | ||
447 | #ifdef SYS_getdents64 | ||
448 | #ifdef __NR_getdents64 | ||
449 | {"getdents64", __NR_getdents64}, | ||
450 | #endif | ||
451 | #endif | ||
452 | #ifdef SYS_getegid | ||
453 | #ifdef __NR_getegid | ||
454 | {"getegid", __NR_getegid}, | ||
455 | #endif | ||
456 | #endif | ||
457 | #ifdef SYS_getegid32 | ||
458 | #ifdef __NR_getegid32 | ||
459 | {"getegid32", __NR_getegid32}, | ||
460 | #endif | ||
461 | #endif | ||
462 | #ifdef SYS_geteuid | ||
463 | #ifdef __NR_geteuid | ||
464 | {"geteuid", __NR_geteuid}, | ||
465 | #endif | ||
466 | #endif | ||
467 | #ifdef SYS_geteuid32 | ||
468 | #ifdef __NR_geteuid32 | ||
469 | {"geteuid32", __NR_geteuid32}, | ||
470 | #endif | ||
471 | #endif | ||
472 | #ifdef SYS_getgid | ||
473 | #ifdef __NR_getgid | ||
474 | {"getgid", __NR_getgid}, | ||
475 | #endif | ||
476 | #endif | ||
477 | #ifdef SYS_getgid32 | ||
478 | #ifdef __NR_getgid32 | ||
479 | {"getgid32", __NR_getgid32}, | ||
480 | #endif | ||
481 | #endif | ||
482 | #ifdef SYS_getgroups | ||
483 | #ifdef __NR_getgroups | ||
484 | {"getgroups", __NR_getgroups}, | ||
485 | #endif | ||
486 | #endif | ||
487 | #ifdef SYS_getgroups32 | ||
488 | #ifdef __NR_getgroups32 | ||
489 | {"getgroups32", __NR_getgroups32}, | ||
490 | #endif | ||
491 | #endif | ||
492 | #ifdef SYS_getitimer | ||
493 | #ifdef __NR_getitimer | ||
494 | {"getitimer", __NR_getitimer}, | ||
495 | #endif | ||
496 | #endif | ||
497 | #ifdef SYS_getpgid | ||
498 | #ifdef __NR_getpgid | ||
499 | {"getpgid", __NR_getpgid}, | ||
500 | #endif | ||
501 | #endif | ||
502 | #ifdef SYS_getpgrp | ||
503 | #ifdef __NR_getpgrp | ||
504 | {"getpgrp", __NR_getpgrp}, | ||
505 | #endif | ||
506 | #endif | ||
507 | #ifdef SYS_getpid | ||
508 | #ifdef __NR_getpid | ||
509 | {"getpid", __NR_getpid}, | ||
510 | #endif | ||
511 | #endif | ||
512 | #ifdef SYS_getpmsg | ||
513 | #ifdef __NR_getpmsg | ||
514 | {"getpmsg", __NR_getpmsg}, | ||
515 | #endif | ||
516 | #endif | ||
517 | #ifdef SYS_getppid | ||
518 | #ifdef __NR_getppid | ||
519 | {"getppid", __NR_getppid}, | ||
520 | #endif | ||
521 | #endif | ||
522 | #ifdef SYS_getpriority | ||
523 | #ifdef __NR_getpriority | ||
524 | {"getpriority", __NR_getpriority}, | ||
525 | #endif | ||
526 | #endif | ||
527 | #ifdef SYS_getresgid | ||
528 | #ifdef __NR_getresgid | ||
529 | {"getresgid", __NR_getresgid}, | ||
530 | #endif | ||
531 | #endif | ||
532 | #ifdef SYS_getresgid32 | ||
533 | #ifdef __NR_getresgid32 | ||
534 | {"getresgid32", __NR_getresgid32}, | ||
535 | #endif | ||
536 | #endif | ||
537 | #ifdef SYS_getresuid | ||
538 | #ifdef __NR_getresuid | ||
539 | {"getresuid", __NR_getresuid}, | ||
540 | #endif | ||
541 | #endif | ||
542 | #ifdef SYS_getresuid32 | ||
543 | #ifdef __NR_getresuid32 | ||
544 | {"getresuid32", __NR_getresuid32}, | ||
545 | #endif | ||
546 | #endif | ||
547 | #ifdef SYS_getrlimit | ||
548 | #ifdef __NR_getrlimit | ||
549 | {"getrlimit", __NR_getrlimit}, | ||
550 | #endif | ||
551 | #endif | ||
552 | #ifdef SYS_getrusage | ||
553 | #ifdef __NR_getrusage | ||
554 | {"getrusage", __NR_getrusage}, | ||
555 | #endif | ||
556 | #endif | ||
557 | #ifdef SYS_getsid | ||
558 | #ifdef __NR_getsid | ||
559 | {"getsid", __NR_getsid}, | ||
560 | #endif | ||
561 | #endif | ||
562 | #ifdef SYS_gettid | ||
563 | #ifdef __NR_gettid | ||
564 | {"gettid", __NR_gettid}, | ||
565 | #endif | ||
566 | #endif | ||
567 | #ifdef SYS_gettimeofday | ||
568 | #ifdef __NR_gettimeofday | ||
569 | {"gettimeofday", __NR_gettimeofday}, | ||
570 | #endif | ||
571 | #endif | ||
572 | #ifdef SYS_getuid | ||
573 | #ifdef __NR_getuid | ||
574 | {"getuid", __NR_getuid}, | ||
575 | #endif | ||
576 | #endif | ||
577 | #ifdef SYS_getuid32 | ||
578 | #ifdef __NR_getuid32 | ||
579 | {"getuid32", __NR_getuid32}, | ||
580 | #endif | ||
581 | #endif | ||
582 | #ifdef SYS_getxattr | ||
583 | #ifdef __NR_getxattr | ||
584 | {"getxattr", __NR_getxattr}, | ||
585 | #endif | ||
586 | #endif | ||
587 | #ifdef SYS_gtty | ||
588 | #ifdef __NR_gtty | ||
589 | {"gtty", __NR_gtty}, | ||
590 | #endif | ||
591 | #endif | ||
592 | #ifdef SYS_idle | ||
593 | #ifdef __NR_idle | ||
594 | {"idle", __NR_idle}, | ||
595 | #endif | ||
596 | #endif | ||
597 | #ifdef SYS_init_module | ||
598 | #ifdef __NR_init_module | ||
599 | {"init_module", __NR_init_module}, | ||
600 | #endif | ||
601 | #endif | ||
602 | #ifdef SYS_inotify_add_watch | ||
603 | #ifdef __NR_inotify_add_watch | ||
604 | {"inotify_add_watch", __NR_inotify_add_watch}, | ||
605 | #endif | ||
606 | #endif | ||
607 | #ifdef SYS_inotify_init | ||
608 | #ifdef __NR_inotify_init | ||
609 | {"inotify_init", __NR_inotify_init}, | ||
610 | #endif | ||
611 | #endif | ||
612 | #ifdef SYS_inotify_init1 | ||
613 | #ifdef __NR_inotify_init1 | ||
614 | {"inotify_init1", __NR_inotify_init1}, | ||
615 | #endif | ||
616 | #endif | ||
617 | #ifdef SYS_inotify_rm_watch | ||
618 | #ifdef __NR_inotify_rm_watch | ||
619 | {"inotify_rm_watch", __NR_inotify_rm_watch}, | ||
620 | #endif | ||
621 | #endif | ||
622 | #ifdef SYS_io_cancel | ||
623 | #ifdef __NR_io_cancel | ||
624 | {"io_cancel", __NR_io_cancel}, | ||
625 | #endif | ||
626 | #endif | ||
627 | #ifdef SYS_io_destroy | ||
628 | #ifdef __NR_io_destroy | ||
629 | {"io_destroy", __NR_io_destroy}, | ||
630 | #endif | ||
631 | #endif | ||
632 | #ifdef SYS_io_getevents | ||
633 | #ifdef __NR_io_getevents | ||
634 | {"io_getevents", __NR_io_getevents}, | ||
635 | #endif | ||
636 | #endif | ||
637 | #ifdef SYS_io_setup | ||
638 | #ifdef __NR_io_setup | ||
639 | {"io_setup", __NR_io_setup}, | ||
640 | #endif | ||
641 | #endif | ||
642 | #ifdef SYS_io_submit | ||
643 | #ifdef __NR_io_submit | ||
644 | {"io_submit", __NR_io_submit}, | ||
645 | #endif | ||
646 | #endif | ||
647 | #ifdef SYS_ioctl | ||
648 | #ifdef __NR_ioctl | ||
649 | {"ioctl", __NR_ioctl}, | ||
650 | #endif | ||
651 | #endif | ||
652 | #ifdef SYS_ioperm | ||
653 | #ifdef __NR_ioperm | ||
654 | {"ioperm", __NR_ioperm}, | ||
655 | #endif | ||
656 | #endif | ||
657 | #ifdef SYS_iopl | ||
658 | #ifdef __NR_iopl | ||
659 | {"iopl", __NR_iopl}, | ||
660 | #endif | ||
661 | #endif | ||
662 | #ifdef SYS_ioprio_get | ||
663 | #ifdef __NR_ioprio_get | ||
664 | {"ioprio_get", __NR_ioprio_get}, | ||
665 | #endif | ||
666 | #endif | ||
667 | #ifdef SYS_ioprio_set | ||
668 | #ifdef __NR_ioprio_set | ||
669 | {"ioprio_set", __NR_ioprio_set}, | ||
670 | #endif | ||
671 | #endif | ||
672 | #ifdef SYS_ipc | ||
673 | #ifdef __NR_ipc | ||
674 | {"ipc", __NR_ipc}, | ||
675 | #endif | ||
676 | #endif | ||
677 | #ifdef SYS_kcmp | ||
678 | #ifdef __NR_kcmp | ||
679 | {"kcmp", __NR_kcmp}, | ||
680 | #endif | ||
681 | #endif | ||
682 | #ifdef SYS_kexec_load | ||
683 | #ifdef __NR_kexec_load | ||
684 | {"kexec_load", __NR_kexec_load}, | ||
685 | #endif | ||
686 | #endif | ||
687 | #ifdef SYS_keyctl | ||
688 | #ifdef __NR_keyctl | ||
689 | {"keyctl", __NR_keyctl}, | ||
690 | #endif | ||
691 | #endif | ||
692 | #ifdef SYS_kill | ||
693 | #ifdef __NR_kill | ||
694 | {"kill", __NR_kill}, | ||
695 | #endif | ||
696 | #endif | ||
697 | #ifdef SYS_lchown | ||
698 | #ifdef __NR_lchown | ||
699 | {"lchown", __NR_lchown}, | ||
700 | #endif | ||
701 | #endif | ||
702 | #ifdef SYS_lchown32 | ||
703 | #ifdef __NR_lchown32 | ||
704 | {"lchown32", __NR_lchown32}, | ||
705 | #endif | ||
706 | #endif | ||
707 | #ifdef SYS_lgetxattr | ||
708 | #ifdef __NR_lgetxattr | ||
709 | {"lgetxattr", __NR_lgetxattr}, | ||
710 | #endif | ||
711 | #endif | ||
712 | #ifdef SYS_link | ||
713 | #ifdef __NR_link | ||
714 | {"link", __NR_link}, | ||
715 | #endif | ||
716 | #endif | ||
717 | #ifdef SYS_linkat | ||
718 | #ifdef __NR_linkat | ||
719 | {"linkat", __NR_linkat}, | ||
720 | #endif | ||
721 | #endif | ||
722 | #ifdef SYS_listxattr | ||
723 | #ifdef __NR_listxattr | ||
724 | {"listxattr", __NR_listxattr}, | ||
725 | #endif | ||
726 | #endif | ||
727 | #ifdef SYS_llistxattr | ||
728 | #ifdef __NR_llistxattr | ||
729 | {"llistxattr", __NR_llistxattr}, | ||
730 | #endif | ||
731 | #endif | ||
732 | #ifdef SYS_lock | ||
733 | #ifdef __NR_lock | ||
734 | {"lock", __NR_lock}, | ||
735 | #endif | ||
736 | #endif | ||
737 | #ifdef SYS_lookup_dcookie | ||
738 | #ifdef __NR_lookup_dcookie | ||
739 | {"lookup_dcookie", __NR_lookup_dcookie}, | ||
740 | #endif | ||
741 | #endif | ||
742 | #ifdef SYS_lremovexattr | ||
743 | #ifdef __NR_lremovexattr | ||
744 | {"lremovexattr", __NR_lremovexattr}, | ||
745 | #endif | ||
746 | #endif | ||
747 | #ifdef SYS_lseek | ||
748 | #ifdef __NR_lseek | ||
749 | {"lseek", __NR_lseek}, | ||
750 | #endif | ||
751 | #endif | ||
752 | #ifdef SYS_lsetxattr | ||
753 | #ifdef __NR_lsetxattr | ||
754 | {"lsetxattr", __NR_lsetxattr}, | ||
755 | #endif | ||
756 | #endif | ||
757 | #ifdef SYS_lstat | ||
758 | #ifdef __NR_lstat | ||
759 | {"lstat", __NR_lstat}, | ||
760 | #endif | ||
761 | #endif | ||
762 | #ifdef SYS_lstat64 | ||
763 | #ifdef __NR_lstat64 | ||
764 | {"lstat64", __NR_lstat64}, | ||
765 | #endif | ||
766 | #endif | ||
767 | #ifdef SYS_madvise | ||
768 | #ifdef __NR_madvise | ||
769 | {"madvise", __NR_madvise}, | ||
770 | #endif | ||
771 | #endif | ||
772 | #ifdef SYS_mbind | ||
773 | #ifdef __NR_mbind | ||
774 | {"mbind", __NR_mbind}, | ||
775 | #endif | ||
776 | #endif | ||
777 | #ifdef SYS_migrate_pages | ||
778 | #ifdef __NR_migrate_pages | ||
779 | {"migrate_pages", __NR_migrate_pages}, | ||
780 | #endif | ||
781 | #endif | ||
782 | #ifdef SYS_mincore | ||
783 | #ifdef __NR_mincore | ||
784 | {"mincore", __NR_mincore}, | ||
785 | #endif | ||
786 | #endif | ||
787 | #ifdef SYS_mkdir | ||
788 | #ifdef __NR_mkdir | ||
789 | {"mkdir", __NR_mkdir}, | ||
790 | #endif | ||
791 | #endif | ||
792 | #ifdef SYS_mkdirat | ||
793 | #ifdef __NR_mkdirat | ||
794 | {"mkdirat", __NR_mkdirat}, | ||
795 | #endif | ||
796 | #endif | ||
797 | #ifdef SYS_mknod | ||
798 | #ifdef __NR_mknod | ||
799 | {"mknod", __NR_mknod}, | ||
800 | #endif | ||
801 | #endif | ||
802 | #ifdef SYS_mknodat | ||
803 | #ifdef __NR_mknodat | ||
804 | {"mknodat", __NR_mknodat}, | ||
805 | #endif | ||
806 | #endif | ||
807 | #ifdef SYS_mlock | ||
808 | #ifdef __NR_mlock | ||
809 | {"mlock", __NR_mlock}, | ||
810 | #endif | ||
811 | #endif | ||
812 | #ifdef SYS_mlockall | ||
813 | #ifdef __NR_mlockall | ||
814 | {"mlockall", __NR_mlockall}, | ||
815 | #endif | ||
816 | #endif | ||
817 | #ifdef SYS_mmap | ||
818 | #ifdef __NR_mmap | ||
819 | {"mmap", __NR_mmap}, | ||
820 | #endif | ||
821 | #endif | ||
822 | #ifdef SYS_mmap2 | ||
823 | #ifdef __NR_mmap2 | ||
824 | {"mmap2", __NR_mmap2}, | ||
825 | #endif | ||
826 | #endif | ||
827 | #ifdef SYS_modify_ldt | ||
828 | #ifdef __NR_modify_ldt | ||
829 | {"modify_ldt", __NR_modify_ldt}, | ||
830 | #endif | ||
831 | #endif | ||
832 | #ifdef SYS_mount | ||
833 | #ifdef __NR_mount | ||
834 | {"mount", __NR_mount}, | ||
835 | #endif | ||
836 | #endif | ||
837 | #ifdef SYS_move_pages | ||
838 | #ifdef __NR_move_pages | ||
839 | {"move_pages", __NR_move_pages}, | ||
840 | #endif | ||
841 | #endif | ||
842 | #ifdef SYS_mprotect | ||
843 | #ifdef __NR_mprotect | ||
844 | {"mprotect", __NR_mprotect}, | ||
845 | #endif | ||
846 | #endif | ||
847 | #ifdef SYS_mpx | ||
848 | #ifdef __NR_mpx | ||
849 | {"mpx", __NR_mpx}, | ||
850 | #endif | ||
851 | #endif | ||
852 | #ifdef SYS_mq_getsetattr | ||
853 | #ifdef __NR_mq_getsetattr | ||
854 | {"mq_getsetattr", __NR_mq_getsetattr}, | ||
855 | #endif | ||
856 | #endif | ||
857 | #ifdef SYS_mq_notify | ||
858 | #ifdef __NR_mq_notify | ||
859 | {"mq_notify", __NR_mq_notify}, | ||
860 | #endif | ||
861 | #endif | ||
862 | #ifdef SYS_mq_open | ||
863 | #ifdef __NR_mq_open | ||
864 | {"mq_open", __NR_mq_open}, | ||
865 | #endif | ||
866 | #endif | ||
867 | #ifdef SYS_mq_timedreceive | ||
868 | #ifdef __NR_mq_timedreceive | ||
869 | {"mq_timedreceive", __NR_mq_timedreceive}, | ||
870 | #endif | ||
871 | #endif | ||
872 | #ifdef SYS_mq_timedsend | ||
873 | #ifdef __NR_mq_timedsend | ||
874 | {"mq_timedsend", __NR_mq_timedsend}, | ||
875 | #endif | ||
876 | #endif | ||
877 | #ifdef SYS_mq_unlink | ||
878 | #ifdef __NR_mq_unlink | ||
879 | {"mq_unlink", __NR_mq_unlink}, | ||
880 | #endif | ||
881 | #endif | ||
882 | #ifdef SYS_mremap | ||
883 | #ifdef __NR_mremap | ||
884 | {"mremap", __NR_mremap}, | ||
885 | #endif | ||
886 | #endif | ||
887 | #ifdef SYS_msync | ||
888 | #ifdef __NR_msync | ||
889 | {"msync", __NR_msync}, | ||
890 | #endif | ||
891 | #endif | ||
892 | #ifdef SYS_munlock | ||
893 | #ifdef __NR_munlock | ||
894 | {"munlock", __NR_munlock}, | ||
895 | #endif | ||
896 | #endif | ||
897 | #ifdef SYS_munlockall | ||
898 | #ifdef __NR_munlockall | ||
899 | {"munlockall", __NR_munlockall}, | ||
900 | #endif | ||
901 | #endif | ||
902 | #ifdef SYS_munmap | ||
903 | #ifdef __NR_munmap | ||
904 | {"munmap", __NR_munmap}, | ||
905 | #endif | ||
906 | #endif | ||
907 | #ifdef SYS_name_to_handle_at | ||
908 | #ifdef __NR_name_to_handle_at | ||
909 | {"name_to_handle_at", __NR_name_to_handle_at}, | ||
910 | #endif | ||
911 | #endif | ||
912 | #ifdef SYS_nanosleep | ||
913 | #ifdef __NR_nanosleep | ||
914 | {"nanosleep", __NR_nanosleep}, | ||
915 | #endif | ||
916 | #endif | ||
917 | #ifdef SYS_nfsservctl | ||
918 | #ifdef __NR_nfsservctl | ||
919 | {"nfsservctl", __NR_nfsservctl}, | ||
920 | #endif | ||
921 | #endif | ||
922 | #ifdef SYS_nice | ||
923 | #ifdef __NR_nice | ||
924 | {"nice", __NR_nice}, | ||
925 | #endif | ||
926 | #endif | ||
927 | #ifdef SYS_oldfstat | ||
928 | #ifdef __NR_oldfstat | ||
929 | {"oldfstat", __NR_oldfstat}, | ||
930 | #endif | ||
931 | #endif | ||
932 | #ifdef SYS_oldlstat | ||
933 | #ifdef __NR_oldlstat | ||
934 | {"oldlstat", __NR_oldlstat}, | ||
935 | #endif | ||
936 | #endif | ||
937 | #ifdef SYS_oldolduname | ||
938 | #ifdef __NR_oldolduname | ||
939 | {"oldolduname", __NR_oldolduname}, | ||
940 | #endif | ||
941 | #endif | ||
942 | #ifdef SYS_oldstat | ||
943 | #ifdef __NR_oldstat | ||
944 | {"oldstat", __NR_oldstat}, | ||
945 | #endif | ||
946 | #endif | ||
947 | #ifdef SYS_olduname | ||
948 | #ifdef __NR_olduname | ||
949 | {"olduname", __NR_olduname}, | ||
950 | #endif | ||
951 | #endif | ||
952 | #ifdef SYS_open | ||
953 | #ifdef __NR_open | ||
954 | {"open", __NR_open}, | ||
955 | #endif | ||
956 | #endif | ||
957 | #ifdef SYS_open_by_handle_at | ||
958 | #ifdef __NR_open_by_handle_at | ||
959 | {"open_by_handle_at", __NR_open_by_handle_at}, | ||
960 | #endif | ||
961 | #endif | ||
962 | #ifdef SYS_openat | ||
963 | #ifdef __NR_openat | ||
964 | {"openat", __NR_openat}, | ||
965 | #endif | ||
966 | #endif | ||
967 | #ifdef SYS_pause | ||
968 | #ifdef __NR_pause | ||
969 | {"pause", __NR_pause}, | ||
970 | #endif | ||
971 | #endif | ||
972 | #ifdef SYS_perf_event_open | ||
973 | #ifdef __NR_perf_event_open | ||
974 | {"perf_event_open", __NR_perf_event_open}, | ||
975 | #endif | ||
976 | #endif | ||
977 | #ifdef SYS_personality | ||
978 | #ifdef __NR_personality | ||
979 | {"personality", __NR_personality}, | ||
980 | #endif | ||
981 | #endif | ||
982 | #ifdef SYS_pipe | ||
983 | #ifdef __NR_pipe | ||
984 | {"pipe", __NR_pipe}, | ||
985 | #endif | ||
986 | #endif | ||
987 | #ifdef SYS_pipe2 | ||
988 | #ifdef __NR_pipe2 | ||
989 | {"pipe2", __NR_pipe2}, | ||
990 | #endif | ||
991 | #endif | ||
992 | #ifdef SYS_pivot_root | ||
993 | #ifdef __NR_pivot_root | ||
994 | {"pivot_root", __NR_pivot_root}, | ||
995 | #endif | ||
996 | #endif | ||
997 | #ifdef SYS_poll | ||
998 | #ifdef __NR_poll | ||
999 | {"poll", __NR_poll}, | ||
1000 | #endif | ||
1001 | #endif | ||
1002 | #ifdef SYS_ppoll | ||
1003 | #ifdef __NR_ppoll | ||
1004 | {"ppoll", __NR_ppoll}, | ||
1005 | #endif | ||
1006 | #endif | ||
1007 | #ifdef SYS_prctl | ||
1008 | #ifdef __NR_prctl | ||
1009 | {"prctl", __NR_prctl}, | ||
1010 | #endif | ||
1011 | #endif | ||
1012 | #ifdef SYS_pread64 | ||
1013 | #ifdef __NR_pread64 | ||
1014 | {"pread64", __NR_pread64}, | ||
1015 | #endif | ||
1016 | #endif | ||
1017 | #ifdef SYS_preadv | ||
1018 | #ifdef __NR_preadv | ||
1019 | {"preadv", __NR_preadv}, | ||
1020 | #endif | ||
1021 | #endif | ||
1022 | #ifdef SYS_prlimit64 | ||
1023 | #ifdef __NR_prlimit64 | ||
1024 | {"prlimit64", __NR_prlimit64}, | ||
1025 | #endif | ||
1026 | #endif | ||
1027 | #ifdef SYS_process_vm_readv | ||
1028 | #ifdef __NR_process_vm_readv | ||
1029 | {"process_vm_readv", __NR_process_vm_readv}, | ||
1030 | #endif | ||
1031 | #endif | ||
1032 | #ifdef SYS_process_vm_writev | ||
1033 | #ifdef __NR_process_vm_writev | ||
1034 | {"process_vm_writev", __NR_process_vm_writev}, | ||
1035 | #endif | ||
1036 | #endif | ||
1037 | #ifdef SYS_prof | ||
1038 | #ifdef __NR_prof | ||
1039 | {"prof", __NR_prof}, | ||
1040 | #endif | ||
1041 | #endif | ||
1042 | #ifdef SYS_profil | ||
1043 | #ifdef __NR_profil | ||
1044 | {"profil", __NR_profil}, | ||
1045 | #endif | ||
1046 | #endif | ||
1047 | #ifdef SYS_pselect6 | ||
1048 | #ifdef __NR_pselect6 | ||
1049 | {"pselect6", __NR_pselect6}, | ||
1050 | #endif | ||
1051 | #endif | ||
1052 | #ifdef SYS_ptrace | ||
1053 | #ifdef __NR_ptrace | ||
1054 | {"ptrace", __NR_ptrace}, | ||
1055 | #endif | ||
1056 | #endif | ||
1057 | #ifdef SYS_putpmsg | ||
1058 | #ifdef __NR_putpmsg | ||
1059 | {"putpmsg", __NR_putpmsg}, | ||
1060 | #endif | ||
1061 | #endif | ||
1062 | #ifdef SYS_pwrite64 | ||
1063 | #ifdef __NR_pwrite64 | ||
1064 | {"pwrite64", __NR_pwrite64}, | ||
1065 | #endif | ||
1066 | #endif | ||
1067 | #ifdef SYS_pwritev | ||
1068 | #ifdef __NR_pwritev | ||
1069 | {"pwritev", __NR_pwritev}, | ||
1070 | #endif | ||
1071 | #endif | ||
1072 | #ifdef SYS_query_module | ||
1073 | #ifdef __NR_query_module | ||
1074 | {"query_module", __NR_query_module}, | ||
1075 | #endif | ||
1076 | #endif | ||
1077 | #ifdef SYS_quotactl | ||
1078 | #ifdef __NR_quotactl | ||
1079 | {"quotactl", __NR_quotactl}, | ||
1080 | #endif | ||
1081 | #endif | ||
1082 | #ifdef SYS_read | ||
1083 | #ifdef __NR_read | ||
1084 | {"read", __NR_read}, | ||
1085 | #endif | ||
1086 | #endif | ||
1087 | #ifdef SYS_readahead | ||
1088 | #ifdef __NR_readahead | ||
1089 | {"readahead", __NR_readahead}, | ||
1090 | #endif | ||
1091 | #endif | ||
1092 | #ifdef SYS_readdir | ||
1093 | #ifdef __NR_readdir | ||
1094 | {"readdir", __NR_readdir}, | ||
1095 | #endif | ||
1096 | #endif | ||
1097 | #ifdef SYS_readlink | ||
1098 | #ifdef __NR_readlink | ||
1099 | {"readlink", __NR_readlink}, | ||
1100 | #endif | ||
1101 | #endif | ||
1102 | #ifdef SYS_readlinkat | ||
1103 | #ifdef __NR_readlinkat | ||
1104 | {"readlinkat", __NR_readlinkat}, | ||
1105 | #endif | ||
1106 | #endif | ||
1107 | #ifdef SYS_readv | ||
1108 | #ifdef __NR_readv | ||
1109 | {"readv", __NR_readv}, | ||
1110 | #endif | ||
1111 | #endif | ||
1112 | #ifdef SYS_reboot | ||
1113 | #ifdef __NR_reboot | ||
1114 | {"reboot", __NR_reboot}, | ||
1115 | #endif | ||
1116 | #endif | ||
1117 | #ifdef SYS_recvmmsg | ||
1118 | #ifdef __NR_recvmmsg | ||
1119 | {"recvmmsg", __NR_recvmmsg}, | ||
1120 | #endif | ||
1121 | #endif | ||
1122 | #ifdef SYS_remap_file_pages | ||
1123 | #ifdef __NR_remap_file_pages | ||
1124 | {"remap_file_pages", __NR_remap_file_pages}, | ||
1125 | #endif | ||
1126 | #endif | ||
1127 | #ifdef SYS_removexattr | ||
1128 | #ifdef __NR_removexattr | ||
1129 | {"removexattr", __NR_removexattr}, | ||
1130 | #endif | ||
1131 | #endif | ||
1132 | #ifdef SYS_rename | ||
1133 | #ifdef __NR_rename | ||
1134 | {"rename", __NR_rename}, | ||
1135 | #endif | ||
1136 | #endif | ||
1137 | #ifdef SYS_renameat | ||
1138 | #ifdef __NR_renameat | ||
1139 | {"renameat", __NR_renameat}, | ||
1140 | #endif | ||
1141 | #endif | ||
1142 | #ifdef SYS_request_key | ||
1143 | #ifdef __NR_request_key | ||
1144 | {"request_key", __NR_request_key}, | ||
1145 | #endif | ||
1146 | #endif | ||
1147 | #ifdef SYS_restart_syscall | ||
1148 | #ifdef __NR_restart_syscall | ||
1149 | {"restart_syscall", __NR_restart_syscall}, | ||
1150 | #endif | ||
1151 | #endif | ||
1152 | #ifdef SYS_rmdir | ||
1153 | #ifdef __NR_rmdir | ||
1154 | {"rmdir", __NR_rmdir}, | ||
1155 | #endif | ||
1156 | #endif | ||
1157 | #ifdef SYS_rt_sigaction | ||
1158 | #ifdef __NR_rt_sigaction | ||
1159 | {"rt_sigaction", __NR_rt_sigaction}, | ||
1160 | #endif | ||
1161 | #endif | ||
1162 | #ifdef SYS_rt_sigpending | ||
1163 | #ifdef __NR_rt_sigpending | ||
1164 | {"rt_sigpending", __NR_rt_sigpending}, | ||
1165 | #endif | ||
1166 | #endif | ||
1167 | #ifdef SYS_rt_sigprocmask | ||
1168 | #ifdef __NR_rt_sigprocmask | ||
1169 | {"rt_sigprocmask", __NR_rt_sigprocmask}, | ||
1170 | #endif | ||
1171 | #endif | ||
1172 | #ifdef SYS_rt_sigqueueinfo | ||
1173 | #ifdef __NR_rt_sigqueueinfo | ||
1174 | {"rt_sigqueueinfo", __NR_rt_sigqueueinfo}, | ||
1175 | #endif | ||
1176 | #endif | ||
1177 | #ifdef SYS_rt_sigreturn | ||
1178 | #ifdef __NR_rt_sigreturn | ||
1179 | {"rt_sigreturn", __NR_rt_sigreturn}, | ||
1180 | #endif | ||
1181 | #endif | ||
1182 | #ifdef SYS_rt_sigsuspend | ||
1183 | #ifdef __NR_rt_sigsuspend | ||
1184 | {"rt_sigsuspend", __NR_rt_sigsuspend}, | ||
1185 | #endif | ||
1186 | #endif | ||
1187 | #ifdef SYS_rt_sigtimedwait | ||
1188 | #ifdef __NR_rt_sigtimedwait | ||
1189 | {"rt_sigtimedwait", __NR_rt_sigtimedwait}, | ||
1190 | #endif | ||
1191 | #endif | ||
1192 | #ifdef SYS_rt_tgsigqueueinfo | ||
1193 | #ifdef __NR_rt_tgsigqueueinfo | ||
1194 | {"rt_tgsigqueueinfo", __NR_rt_tgsigqueueinfo}, | ||
1195 | #endif | ||
1196 | #endif | ||
1197 | #ifdef SYS_sched_get_priority_max | ||
1198 | #ifdef __NR_sched_get_priority_max | ||
1199 | {"sched_get_priority_max", __NR_sched_get_priority_max}, | ||
1200 | #endif | ||
1201 | #endif | ||
1202 | #ifdef SYS_sched_get_priority_min | ||
1203 | #ifdef __NR_sched_get_priority_min | ||
1204 | {"sched_get_priority_min", __NR_sched_get_priority_min}, | ||
1205 | #endif | ||
1206 | #endif | ||
1207 | #ifdef SYS_sched_getaffinity | ||
1208 | #ifdef __NR_sched_getaffinity | ||
1209 | {"sched_getaffinity", __NR_sched_getaffinity}, | ||
1210 | #endif | ||
1211 | #endif | ||
1212 | #ifdef SYS_sched_getparam | ||
1213 | #ifdef __NR_sched_getparam | ||
1214 | {"sched_getparam", __NR_sched_getparam}, | ||
1215 | #endif | ||
1216 | #endif | ||
1217 | #ifdef SYS_sched_getscheduler | ||
1218 | #ifdef __NR_sched_getscheduler | ||
1219 | {"sched_getscheduler", __NR_sched_getscheduler}, | ||
1220 | #endif | ||
1221 | #endif | ||
1222 | #ifdef SYS_sched_rr_get_interval | ||
1223 | #ifdef __NR_sched_rr_get_interval | ||
1224 | {"sched_rr_get_interval", __NR_sched_rr_get_interval}, | ||
1225 | #endif | ||
1226 | #endif | ||
1227 | #ifdef SYS_sched_setaffinity | ||
1228 | #ifdef __NR_sched_setaffinity | ||
1229 | {"sched_setaffinity", __NR_sched_setaffinity}, | ||
1230 | #endif | ||
1231 | #endif | ||
1232 | #ifdef SYS_sched_setparam | ||
1233 | #ifdef __NR_sched_setparam | ||
1234 | {"sched_setparam", __NR_sched_setparam}, | ||
1235 | #endif | ||
1236 | #endif | ||
1237 | #ifdef SYS_sched_setscheduler | ||
1238 | #ifdef __NR_sched_setscheduler | ||
1239 | {"sched_setscheduler", __NR_sched_setscheduler}, | ||
1240 | #endif | ||
1241 | #endif | ||
1242 | #ifdef SYS_sched_yield | ||
1243 | #ifdef __NR_sched_yield | ||
1244 | {"sched_yield", __NR_sched_yield}, | ||
1245 | #endif | ||
1246 | #endif | ||
1247 | #ifdef SYS_select | ||
1248 | #ifdef __NR_select | ||
1249 | {"select", __NR_select}, | ||
1250 | #endif | ||
1251 | #endif | ||
1252 | #ifdef SYS_sendfile | ||
1253 | #ifdef __NR_sendfile | ||
1254 | {"sendfile", __NR_sendfile}, | ||
1255 | #endif | ||
1256 | #endif | ||
1257 | #ifdef SYS_sendfile64 | ||
1258 | #ifdef __NR_sendfile64 | ||
1259 | {"sendfile64", __NR_sendfile64}, | ||
1260 | #endif | ||
1261 | #endif | ||
1262 | #ifdef SYS_sendmmsg | ||
1263 | #ifdef __NR_sendmmsg | ||
1264 | {"sendmmsg", __NR_sendmmsg}, | ||
1265 | #endif | ||
1266 | #endif | ||
1267 | #ifdef SYS_set_mempolicy | ||
1268 | #ifdef __NR_set_mempolicy | ||
1269 | {"set_mempolicy", __NR_set_mempolicy}, | ||
1270 | #endif | ||
1271 | #endif | ||
1272 | #ifdef SYS_set_robust_list | ||
1273 | #ifdef __NR_set_robust_list | ||
1274 | {"set_robust_list", __NR_set_robust_list}, | ||
1275 | #endif | ||
1276 | #endif | ||
1277 | #ifdef SYS_set_thread_area | ||
1278 | #ifdef __NR_set_thread_area | ||
1279 | {"set_thread_area", __NR_set_thread_area}, | ||
1280 | #endif | ||
1281 | #endif | ||
1282 | #ifdef SYS_set_tid_address | ||
1283 | #ifdef __NR_set_tid_address | ||
1284 | {"set_tid_address", __NR_set_tid_address}, | ||
1285 | #endif | ||
1286 | #endif | ||
1287 | #ifdef SYS_setdomainname | ||
1288 | #ifdef __NR_setdomainname | ||
1289 | {"setdomainname", __NR_setdomainname}, | ||
1290 | #endif | ||
1291 | #endif | ||
1292 | #ifdef SYS_setfsgid | ||
1293 | #ifdef __NR_setfsgid | ||
1294 | {"setfsgid", __NR_setfsgid}, | ||
1295 | #endif | ||
1296 | #endif | ||
1297 | #ifdef SYS_setfsgid32 | ||
1298 | #ifdef __NR_setfsgid32 | ||
1299 | {"setfsgid32", __NR_setfsgid32}, | ||
1300 | #endif | ||
1301 | #endif | ||
1302 | #ifdef SYS_setfsuid | ||
1303 | #ifdef __NR_setfsuid | ||
1304 | {"setfsuid", __NR_setfsuid}, | ||
1305 | #endif | ||
1306 | #endif | ||
1307 | #ifdef SYS_setfsuid32 | ||
1308 | #ifdef __NR_setfsuid32 | ||
1309 | {"setfsuid32", __NR_setfsuid32}, | ||
1310 | #endif | ||
1311 | #endif | ||
1312 | #ifdef SYS_setgid | ||
1313 | #ifdef __NR_setgid | ||
1314 | {"setgid", __NR_setgid}, | ||
1315 | #endif | ||
1316 | #endif | ||
1317 | #ifdef SYS_setgid32 | ||
1318 | #ifdef __NR_setgid32 | ||
1319 | {"setgid32", __NR_setgid32}, | ||
1320 | #endif | ||
1321 | #endif | ||
1322 | #ifdef SYS_setgroups | ||
1323 | #ifdef __NR_setgroups | ||
1324 | {"setgroups", __NR_setgroups}, | ||
1325 | #endif | ||
1326 | #endif | ||
1327 | #ifdef SYS_setgroups32 | ||
1328 | #ifdef __NR_setgroups32 | ||
1329 | {"setgroups32", __NR_setgroups32}, | ||
1330 | #endif | ||
1331 | #endif | ||
1332 | #ifdef SYS_sethostname | ||
1333 | #ifdef __NR_sethostname | ||
1334 | {"sethostname", __NR_sethostname}, | ||
1335 | #endif | ||
1336 | #endif | ||
1337 | #ifdef SYS_setitimer | ||
1338 | #ifdef __NR_setitimer | ||
1339 | {"setitimer", __NR_setitimer}, | ||
1340 | #endif | ||
1341 | #endif | ||
1342 | #ifdef SYS_setns | ||
1343 | #ifdef __NR_setns | ||
1344 | {"setns", __NR_setns}, | ||
1345 | #endif | ||
1346 | #endif | ||
1347 | #ifdef SYS_setpgid | ||
1348 | #ifdef __NR_setpgid | ||
1349 | {"setpgid", __NR_setpgid}, | ||
1350 | #endif | ||
1351 | #endif | ||
1352 | #ifdef SYS_setpriority | ||
1353 | #ifdef __NR_setpriority | ||
1354 | {"setpriority", __NR_setpriority}, | ||
1355 | #endif | ||
1356 | #endif | ||
1357 | #ifdef SYS_setregid | ||
1358 | #ifdef __NR_setregid | ||
1359 | {"setregid", __NR_setregid}, | ||
1360 | #endif | ||
1361 | #endif | ||
1362 | #ifdef SYS_setregid32 | ||
1363 | #ifdef __NR_setregid32 | ||
1364 | {"setregid32", __NR_setregid32}, | ||
1365 | #endif | ||
1366 | #endif | ||
1367 | #ifdef SYS_setresgid | ||
1368 | #ifdef __NR_setresgid | ||
1369 | {"setresgid", __NR_setresgid}, | ||
1370 | #endif | ||
1371 | #endif | ||
1372 | #ifdef SYS_setresgid32 | ||
1373 | #ifdef __NR_setresgid32 | ||
1374 | {"setresgid32", __NR_setresgid32}, | ||
1375 | #endif | ||
1376 | #endif | ||
1377 | #ifdef SYS_setresuid | ||
1378 | #ifdef __NR_setresuid | ||
1379 | {"setresuid", __NR_setresuid}, | ||
1380 | #endif | ||
1381 | #endif | ||
1382 | #ifdef SYS_setresuid32 | ||
1383 | #ifdef __NR_setresuid32 | ||
1384 | {"setresuid32", __NR_setresuid32}, | ||
1385 | #endif | ||
1386 | #endif | ||
1387 | #ifdef SYS_setreuid | ||
1388 | #ifdef __NR_setreuid | ||
1389 | {"setreuid", __NR_setreuid}, | ||
1390 | #endif | ||
1391 | #endif | ||
1392 | #ifdef SYS_setreuid32 | ||
1393 | #ifdef __NR_setreuid32 | ||
1394 | {"setreuid32", __NR_setreuid32}, | ||
1395 | #endif | ||
1396 | #endif | ||
1397 | #ifdef SYS_setrlimit | ||
1398 | #ifdef __NR_setrlimit | ||
1399 | {"setrlimit", __NR_setrlimit}, | ||
1400 | #endif | ||
1401 | #endif | ||
1402 | #ifdef SYS_setsid | ||
1403 | #ifdef __NR_setsid | ||
1404 | {"setsid", __NR_setsid}, | ||
1405 | #endif | ||
1406 | #endif | ||
1407 | #ifdef SYS_settimeofday | ||
1408 | #ifdef __NR_settimeofday | ||
1409 | {"settimeofday", __NR_settimeofday}, | ||
1410 | #endif | ||
1411 | #endif | ||
1412 | #ifdef SYS_setuid | ||
1413 | #ifdef __NR_setuid | ||
1414 | {"setuid", __NR_setuid}, | ||
1415 | #endif | ||
1416 | #endif | ||
1417 | #ifdef SYS_setuid32 | ||
1418 | #ifdef __NR_setuid32 | ||
1419 | {"setuid32", __NR_setuid32}, | ||
1420 | #endif | ||
1421 | #endif | ||
1422 | #ifdef SYS_setxattr | ||
1423 | #ifdef __NR_setxattr | ||
1424 | {"setxattr", __NR_setxattr}, | ||
1425 | #endif | ||
1426 | #endif | ||
1427 | #ifdef SYS_sgetmask | ||
1428 | #ifdef __NR_sgetmask | ||
1429 | {"sgetmask", __NR_sgetmask}, | ||
1430 | #endif | ||
1431 | #endif | ||
1432 | #ifdef SYS_sigaction | ||
1433 | #ifdef __NR_sigaction | ||
1434 | {"sigaction", __NR_sigaction}, | ||
1435 | #endif | ||
1436 | #endif | ||
1437 | #ifdef SYS_sigaltstack | ||
1438 | #ifdef __NR_sigaltstack | ||
1439 | {"sigaltstack", __NR_sigaltstack}, | ||
1440 | #endif | ||
1441 | #endif | ||
1442 | #ifdef SYS_signal | ||
1443 | #ifdef __NR_signal | ||
1444 | {"signal", __NR_signal}, | ||
1445 | #endif | ||
1446 | #endif | ||
1447 | #ifdef SYS_signalfd | ||
1448 | #ifdef __NR_signalfd | ||
1449 | {"signalfd", __NR_signalfd}, | ||
1450 | #endif | ||
1451 | #endif | ||
1452 | #ifdef SYS_signalfd4 | ||
1453 | #ifdef __NR_signalfd4 | ||
1454 | {"signalfd4", __NR_signalfd4}, | ||
1455 | #endif | ||
1456 | #endif | ||
1457 | #ifdef SYS_sigpending | ||
1458 | #ifdef __NR_sigpending | ||
1459 | {"sigpending", __NR_sigpending}, | ||
1460 | #endif | ||
1461 | #endif | ||
1462 | #ifdef SYS_sigprocmask | ||
1463 | #ifdef __NR_sigprocmask | ||
1464 | {"sigprocmask", __NR_sigprocmask}, | ||
1465 | #endif | ||
1466 | #endif | ||
1467 | #ifdef SYS_sigreturn | ||
1468 | #ifdef __NR_sigreturn | ||
1469 | {"sigreturn", __NR_sigreturn}, | ||
1470 | #endif | ||
1471 | #endif | ||
1472 | #ifdef SYS_sigsuspend | ||
1473 | #ifdef __NR_sigsuspend | ||
1474 | {"sigsuspend", __NR_sigsuspend}, | ||
1475 | #endif | ||
1476 | #endif | ||
1477 | #ifdef SYS_socketcall | ||
1478 | #ifdef __NR_socketcall | ||
1479 | {"socketcall", __NR_socketcall}, | ||
1480 | #endif | ||
1481 | #endif | ||
1482 | #ifdef SYS_splice | ||
1483 | #ifdef __NR_splice | ||
1484 | {"splice", __NR_splice}, | ||
1485 | #endif | ||
1486 | #endif | ||
1487 | #ifdef SYS_ssetmask | ||
1488 | #ifdef __NR_ssetmask | ||
1489 | {"ssetmask", __NR_ssetmask}, | ||
1490 | #endif | ||
1491 | #endif | ||
1492 | #ifdef SYS_stat | ||
1493 | #ifdef __NR_stat | ||
1494 | {"stat", __NR_stat}, | ||
1495 | #endif | ||
1496 | #endif | ||
1497 | #ifdef SYS_stat64 | ||
1498 | #ifdef __NR_stat64 | ||
1499 | {"stat64", __NR_stat64}, | ||
1500 | #endif | ||
1501 | #endif | ||
1502 | #ifdef SYS_statfs | ||
1503 | #ifdef __NR_statfs | ||
1504 | {"statfs", __NR_statfs}, | ||
1505 | #endif | ||
1506 | #endif | ||
1507 | #ifdef SYS_statfs64 | ||
1508 | #ifdef __NR_statfs64 | ||
1509 | {"statfs64", __NR_statfs64}, | ||
1510 | #endif | ||
1511 | #endif | ||
1512 | #ifdef SYS_stime | ||
1513 | #ifdef __NR_stime | ||
1514 | {"stime", __NR_stime}, | ||
1515 | #endif | ||
1516 | #endif | ||
1517 | #ifdef SYS_stty | ||
1518 | #ifdef __NR_stty | ||
1519 | {"stty", __NR_stty}, | ||
1520 | #endif | ||
1521 | #endif | ||
1522 | #ifdef SYS_swapoff | ||
1523 | #ifdef __NR_swapoff | ||
1524 | {"swapoff", __NR_swapoff}, | ||
1525 | #endif | ||
1526 | #endif | ||
1527 | #ifdef SYS_swapon | ||
1528 | #ifdef __NR_swapon | ||
1529 | {"swapon", __NR_swapon}, | ||
1530 | #endif | ||
1531 | #endif | ||
1532 | #ifdef SYS_symlink | ||
1533 | #ifdef __NR_symlink | ||
1534 | {"symlink", __NR_symlink}, | ||
1535 | #endif | ||
1536 | #endif | ||
1537 | #ifdef SYS_symlinkat | ||
1538 | #ifdef __NR_symlinkat | ||
1539 | {"symlinkat", __NR_symlinkat}, | ||
1540 | #endif | ||
1541 | #endif | ||
1542 | #ifdef SYS_sync | ||
1543 | #ifdef __NR_sync | ||
1544 | {"sync", __NR_sync}, | ||
1545 | #endif | ||
1546 | #endif | ||
1547 | #ifdef SYS_sync_file_range | ||
1548 | #ifdef __NR_sync_file_range | ||
1549 | {"sync_file_range", __NR_sync_file_range}, | ||
1550 | #endif | ||
1551 | #endif | ||
1552 | #ifdef SYS_syncfs | ||
1553 | #ifdef __NR_syncfs | ||
1554 | {"syncfs", __NR_syncfs}, | ||
1555 | #endif | ||
1556 | #endif | ||
1557 | #ifdef SYS_sysfs | ||
1558 | #ifdef __NR_sysfs | ||
1559 | {"sysfs", __NR_sysfs}, | ||
1560 | #endif | ||
1561 | #endif | ||
1562 | #ifdef SYS_sysinfo | ||
1563 | #ifdef __NR_sysinfo | ||
1564 | {"sysinfo", __NR_sysinfo}, | ||
1565 | #endif | ||
1566 | #endif | ||
1567 | #ifdef SYS_syslog | ||
1568 | #ifdef __NR_syslog | ||
1569 | {"syslog", __NR_syslog}, | ||
1570 | #endif | ||
1571 | #endif | ||
1572 | #ifdef SYS_tee | ||
1573 | #ifdef __NR_tee | ||
1574 | {"tee", __NR_tee}, | ||
1575 | #endif | ||
1576 | #endif | ||
1577 | #ifdef SYS_tgkill | ||
1578 | #ifdef __NR_tgkill | ||
1579 | {"tgkill", __NR_tgkill}, | ||
1580 | #endif | ||
1581 | #endif | ||
1582 | #ifdef SYS_time | ||
1583 | #ifdef __NR_time | ||
1584 | {"time", __NR_time}, | ||
1585 | #endif | ||
1586 | #endif | ||
1587 | #ifdef SYS_timer_create | ||
1588 | #ifdef __NR_timer_create | ||
1589 | {"timer_create", __NR_timer_create}, | ||
1590 | #endif | ||
1591 | #endif | ||
1592 | #ifdef SYS_timer_delete | ||
1593 | #ifdef __NR_timer_delete | ||
1594 | {"timer_delete", __NR_timer_delete}, | ||
1595 | #endif | ||
1596 | #endif | ||
1597 | #ifdef SYS_timer_getoverrun | ||
1598 | #ifdef __NR_timer_getoverrun | ||
1599 | {"timer_getoverrun", __NR_timer_getoverrun}, | ||
1600 | #endif | ||
1601 | #endif | ||
1602 | #ifdef SYS_timer_gettime | ||
1603 | #ifdef __NR_timer_gettime | ||
1604 | {"timer_gettime", __NR_timer_gettime}, | ||
1605 | #endif | ||
1606 | #endif | ||
1607 | #ifdef SYS_timer_settime | ||
1608 | #ifdef __NR_timer_settime | ||
1609 | {"timer_settime", __NR_timer_settime}, | ||
1610 | #endif | ||
1611 | #endif | ||
1612 | #ifdef SYS_timerfd_create | ||
1613 | #ifdef __NR_timerfd_create | ||
1614 | {"timerfd_create", __NR_timerfd_create}, | ||
1615 | #endif | ||
1616 | #endif | ||
1617 | #ifdef SYS_timerfd_gettime | ||
1618 | #ifdef __NR_timerfd_gettime | ||
1619 | {"timerfd_gettime", __NR_timerfd_gettime}, | ||
1620 | #endif | ||
1621 | #endif | ||
1622 | #ifdef SYS_timerfd_settime | ||
1623 | #ifdef __NR_timerfd_settime | ||
1624 | {"timerfd_settime", __NR_timerfd_settime}, | ||
1625 | #endif | ||
1626 | #endif | ||
1627 | #ifdef SYS_times | ||
1628 | #ifdef __NR_times | ||
1629 | {"times", __NR_times}, | ||
1630 | #endif | ||
1631 | #endif | ||
1632 | #ifdef SYS_tkill | ||
1633 | #ifdef __NR_tkill | ||
1634 | {"tkill", __NR_tkill}, | ||
1635 | #endif | ||
1636 | #endif | ||
1637 | #ifdef SYS_truncate | ||
1638 | #ifdef __NR_truncate | ||
1639 | {"truncate", __NR_truncate}, | ||
1640 | #endif | ||
1641 | #endif | ||
1642 | #ifdef SYS_truncate64 | ||
1643 | #ifdef __NR_truncate64 | ||
1644 | {"truncate64", __NR_truncate64}, | ||
1645 | #endif | ||
1646 | #endif | ||
1647 | #ifdef SYS_ugetrlimit | ||
1648 | #ifdef __NR_ugetrlimit | ||
1649 | {"ugetrlimit", __NR_ugetrlimit}, | ||
1650 | #endif | ||
1651 | #endif | ||
1652 | #ifdef SYS_ulimit | ||
1653 | #ifdef __NR_ulimit | ||
1654 | {"ulimit", __NR_ulimit}, | ||
1655 | #endif | ||
1656 | #endif | ||
1657 | #ifdef SYS_umask | ||
1658 | #ifdef __NR_umask | ||
1659 | {"umask", __NR_umask}, | ||
1660 | #endif | ||
1661 | #endif | ||
1662 | #ifdef SYS_umount | ||
1663 | #ifdef __NR_umount | ||
1664 | {"umount", __NR_umount}, | ||
1665 | #endif | ||
1666 | #endif | ||
1667 | #ifdef SYS_umount2 | ||
1668 | #ifdef __NR_umount2 | ||
1669 | {"umount2", __NR_umount2}, | ||
1670 | #endif | ||
1671 | #endif | ||
1672 | #ifdef SYS_uname | ||
1673 | #ifdef __NR_uname | ||
1674 | {"uname", __NR_uname}, | ||
1675 | #endif | ||
1676 | #endif | ||
1677 | #ifdef SYS_unlink | ||
1678 | #ifdef __NR_unlink | ||
1679 | {"unlink", __NR_unlink}, | ||
1680 | #endif | ||
1681 | #endif | ||
1682 | #ifdef SYS_unlinkat | ||
1683 | #ifdef __NR_unlinkat | ||
1684 | {"unlinkat", __NR_unlinkat}, | ||
1685 | #endif | ||
1686 | #endif | ||
1687 | #ifdef SYS_unshare | ||
1688 | #ifdef __NR_unshare | ||
1689 | {"unshare", __NR_unshare}, | ||
1690 | #endif | ||
1691 | #endif | ||
1692 | #ifdef SYS_uselib | ||
1693 | #ifdef __NR_uselib | ||
1694 | {"uselib", __NR_uselib}, | ||
1695 | #endif | ||
1696 | #endif | ||
1697 | #ifdef SYS_ustat | ||
1698 | #ifdef __NR_ustat | ||
1699 | {"ustat", __NR_ustat}, | ||
1700 | #endif | ||
1701 | #endif | ||
1702 | #ifdef SYS_utime | ||
1703 | #ifdef __NR_utime | ||
1704 | {"utime", __NR_utime}, | ||
1705 | #endif | ||
1706 | #endif | ||
1707 | #ifdef SYS_utimensat | ||
1708 | #ifdef __NR_utimensat | ||
1709 | {"utimensat", __NR_utimensat}, | ||
1710 | #endif | ||
1711 | #endif | ||
1712 | #ifdef SYS_utimes | ||
1713 | #ifdef __NR_utimes | ||
1714 | {"utimes", __NR_utimes}, | ||
1715 | #endif | ||
1716 | #endif | ||
1717 | #ifdef SYS_vfork | ||
1718 | #ifdef __NR_vfork | ||
1719 | {"vfork", __NR_vfork}, | ||
1720 | #endif | ||
1721 | #endif | ||
1722 | #ifdef SYS_vhangup | ||
1723 | #ifdef __NR_vhangup | ||
1724 | {"vhangup", __NR_vhangup}, | ||
1725 | #endif | ||
1726 | #endif | ||
1727 | #ifdef SYS_vm86 | ||
1728 | #ifdef __NR_vm86 | ||
1729 | {"vm86", __NR_vm86}, | ||
1730 | #endif | ||
1731 | #endif | ||
1732 | #ifdef SYS_vm86old | ||
1733 | #ifdef __NR_vm86old | ||
1734 | {"vm86old", __NR_vm86old}, | ||
1735 | #endif | ||
1736 | #endif | ||
1737 | #ifdef SYS_vmsplice | ||
1738 | #ifdef __NR_vmsplice | ||
1739 | {"vmsplice", __NR_vmsplice}, | ||
1740 | #endif | ||
1741 | #endif | ||
1742 | #ifdef SYS_vserver | ||
1743 | #ifdef __NR_vserver | ||
1744 | {"vserver", __NR_vserver}, | ||
1745 | #endif | ||
1746 | #endif | ||
1747 | #ifdef SYS_wait4 | ||
1748 | #ifdef __NR_wait4 | ||
1749 | {"wait4", __NR_wait4}, | ||
1750 | #endif | ||
1751 | #endif | ||
1752 | #ifdef SYS_waitid | ||
1753 | #ifdef __NR_waitid | ||
1754 | {"waitid", __NR_waitid}, | ||
1755 | #endif | ||
1756 | #endif | ||
1757 | #ifdef SYS_waitpid | ||
1758 | #ifdef __NR_waitpid | ||
1759 | {"waitpid", __NR_waitpid}, | ||
1760 | #endif | ||
1761 | #endif | ||
1762 | #ifdef SYS_write | ||
1763 | #ifdef __NR_write | ||
1764 | {"write", __NR_write}, | ||
1765 | #endif | ||
1766 | #endif | ||
1767 | #ifdef SYS_writev | ||
1768 | #ifdef __NR_writev | ||
1769 | {"writev", __NR_writev}, | ||
1770 | #endif | ||
1771 | #endif | ||
1772 | #endif | ||
1773 | #if defined __x86_64__ && defined __LP64__ | ||
1774 | #ifdef SYS__sysctl | ||
1775 | #ifdef __NR__sysctl | ||
1776 | {"_sysctl", __NR__sysctl}, | ||
1777 | #endif | ||
1778 | #endif | ||
1779 | #ifdef SYS_accept | ||
1780 | #ifdef __NR_accept | ||
1781 | {"accept", __NR_accept}, | ||
1782 | #endif | ||
1783 | #endif | ||
1784 | #ifdef SYS_accept4 | ||
1785 | #ifdef __NR_accept4 | ||
1786 | {"accept4", __NR_accept4}, | ||
1787 | #endif | ||
1788 | #endif | ||
1789 | #ifdef SYS_access | ||
1790 | #ifdef __NR_access | ||
1791 | {"access", __NR_access}, | ||
1792 | #endif | ||
1793 | #endif | ||
1794 | #ifdef SYS_acct | ||
1795 | #ifdef __NR_acct | ||
1796 | {"acct", __NR_acct}, | ||
1797 | #endif | ||
1798 | #endif | ||
1799 | #ifdef SYS_add_key | ||
1800 | #ifdef __NR_add_key | ||
1801 | {"add_key", __NR_add_key}, | ||
1802 | #endif | ||
1803 | #endif | ||
1804 | #ifdef SYS_adjtimex | ||
1805 | #ifdef __NR_adjtimex | ||
1806 | {"adjtimex", __NR_adjtimex}, | ||
1807 | #endif | ||
1808 | #endif | ||
1809 | #ifdef SYS_afs_syscall | ||
1810 | #ifdef __NR_afs_syscall | ||
1811 | {"afs_syscall", __NR_afs_syscall}, | ||
1812 | #endif | ||
1813 | #endif | ||
1814 | #ifdef SYS_alarm | ||
1815 | #ifdef __NR_alarm | ||
1816 | {"alarm", __NR_alarm}, | ||
1817 | #endif | ||
1818 | #endif | ||
1819 | #ifdef SYS_arch_prctl | ||
1820 | #ifdef __NR_arch_prctl | ||
1821 | {"arch_prctl", __NR_arch_prctl}, | ||
1822 | #endif | ||
1823 | #endif | ||
1824 | #ifdef SYS_bind | ||
1825 | #ifdef __NR_bind | ||
1826 | {"bind", __NR_bind}, | ||
1827 | #endif | ||
1828 | #endif | ||
1829 | #ifdef SYS_brk | ||
1830 | #ifdef __NR_brk | ||
1831 | {"brk", __NR_brk}, | ||
1832 | #endif | ||
1833 | #endif | ||
1834 | #ifdef SYS_capget | ||
1835 | #ifdef __NR_capget | ||
1836 | {"capget", __NR_capget}, | ||
1837 | #endif | ||
1838 | #endif | ||
1839 | #ifdef SYS_capset | ||
1840 | #ifdef __NR_capset | ||
1841 | {"capset", __NR_capset}, | ||
1842 | #endif | ||
1843 | #endif | ||
1844 | #ifdef SYS_chdir | ||
1845 | #ifdef __NR_chdir | ||
1846 | {"chdir", __NR_chdir}, | ||
1847 | #endif | ||
1848 | #endif | ||
1849 | #ifdef SYS_chmod | ||
1850 | #ifdef __NR_chmod | ||
1851 | {"chmod", __NR_chmod}, | ||
1852 | #endif | ||
1853 | #endif | ||
1854 | #ifdef SYS_chown | ||
1855 | #ifdef __NR_chown | ||
1856 | {"chown", __NR_chown}, | ||
1857 | #endif | ||
1858 | #endif | ||
1859 | #ifdef SYS_chroot | ||
1860 | #ifdef __NR_chroot | ||
1861 | {"chroot", __NR_chroot}, | ||
1862 | #endif | ||
1863 | #endif | ||
1864 | #ifdef SYS_clock_adjtime | ||
1865 | #ifdef __NR_clock_adjtime | ||
1866 | {"clock_adjtime", __NR_clock_adjtime}, | ||
1867 | #endif | ||
1868 | #endif | ||
1869 | #ifdef SYS_clock_getres | ||
1870 | #ifdef __NR_clock_getres | ||
1871 | {"clock_getres", __NR_clock_getres}, | ||
1872 | #endif | ||
1873 | #endif | ||
1874 | #ifdef SYS_clock_gettime | ||
1875 | #ifdef __NR_clock_gettime | ||
1876 | {"clock_gettime", __NR_clock_gettime}, | ||
1877 | #endif | ||
1878 | #endif | ||
1879 | #ifdef SYS_clock_nanosleep | ||
1880 | #ifdef __NR_clock_nanosleep | ||
1881 | {"clock_nanosleep", __NR_clock_nanosleep}, | ||
1882 | #endif | ||
1883 | #endif | ||
1884 | #ifdef SYS_clock_settime | ||
1885 | #ifdef __NR_clock_settime | ||
1886 | {"clock_settime", __NR_clock_settime}, | ||
1887 | #endif | ||
1888 | #endif | ||
1889 | #ifdef SYS_clone | ||
1890 | #ifdef __NR_clone | ||
1891 | {"clone", __NR_clone}, | ||
1892 | #endif | ||
1893 | #endif | ||
1894 | #ifdef SYS_close | ||
1895 | #ifdef __NR_close | ||
1896 | {"close", __NR_close}, | ||
1897 | #endif | ||
1898 | #endif | ||
1899 | #ifdef SYS_connect | ||
1900 | #ifdef __NR_connect | ||
1901 | {"connect", __NR_connect}, | ||
1902 | #endif | ||
1903 | #endif | ||
1904 | #ifdef SYS_creat | ||
1905 | #ifdef __NR_creat | ||
1906 | {"creat", __NR_creat}, | ||
1907 | #endif | ||
1908 | #endif | ||
1909 | #ifdef SYS_create_module | ||
1910 | #ifdef __NR_create_module | ||
1911 | {"create_module", __NR_create_module}, | ||
1912 | #endif | ||
1913 | #endif | ||
1914 | #ifdef SYS_delete_module | ||
1915 | #ifdef __NR_delete_module | ||
1916 | {"delete_module", __NR_delete_module}, | ||
1917 | #endif | ||
1918 | #endif | ||
1919 | #ifdef SYS_dup | ||
1920 | #ifdef __NR_dup | ||
1921 | {"dup", __NR_dup}, | ||
1922 | #endif | ||
1923 | #endif | ||
1924 | #ifdef SYS_dup2 | ||
1925 | #ifdef __NR_dup2 | ||
1926 | {"dup2", __NR_dup2}, | ||
1927 | #endif | ||
1928 | #endif | ||
1929 | #ifdef SYS_dup3 | ||
1930 | #ifdef __NR_dup3 | ||
1931 | {"dup3", __NR_dup3}, | ||
1932 | #endif | ||
1933 | #endif | ||
1934 | #ifdef SYS_epoll_create | ||
1935 | #ifdef __NR_epoll_create | ||
1936 | {"epoll_create", __NR_epoll_create}, | ||
1937 | #endif | ||
1938 | #endif | ||
1939 | #ifdef SYS_epoll_create1 | ||
1940 | #ifdef __NR_epoll_create1 | ||
1941 | {"epoll_create1", __NR_epoll_create1}, | ||
1942 | #endif | ||
1943 | #endif | ||
1944 | #ifdef SYS_epoll_ctl | ||
1945 | #ifdef __NR_epoll_ctl | ||
1946 | {"epoll_ctl", __NR_epoll_ctl}, | ||
1947 | #endif | ||
1948 | #endif | ||
1949 | #ifdef SYS_epoll_ctl_old | ||
1950 | #ifdef __NR_epoll_ctl_old | ||
1951 | {"epoll_ctl_old", __NR_epoll_ctl_old}, | ||
1952 | #endif | ||
1953 | #endif | ||
1954 | #ifdef SYS_epoll_pwait | ||
1955 | #ifdef __NR_epoll_pwait | ||
1956 | {"epoll_pwait", __NR_epoll_pwait}, | ||
1957 | #endif | ||
1958 | #endif | ||
1959 | #ifdef SYS_epoll_wait | ||
1960 | #ifdef __NR_epoll_wait | ||
1961 | {"epoll_wait", __NR_epoll_wait}, | ||
1962 | #endif | ||
1963 | #endif | ||
1964 | #ifdef SYS_epoll_wait_old | ||
1965 | #ifdef __NR_epoll_wait_old | ||
1966 | {"epoll_wait_old", __NR_epoll_wait_old}, | ||
1967 | #endif | ||
1968 | #endif | ||
1969 | #ifdef SYS_eventfd | ||
1970 | #ifdef __NR_eventfd | ||
1971 | {"eventfd", __NR_eventfd}, | ||
1972 | #endif | ||
1973 | #endif | ||
1974 | #ifdef SYS_eventfd2 | ||
1975 | #ifdef __NR_eventfd2 | ||
1976 | {"eventfd2", __NR_eventfd2}, | ||
1977 | #endif | ||
1978 | #endif | ||
1979 | #ifdef SYS_execve | ||
1980 | #ifdef __NR_execve | ||
1981 | {"execve", __NR_execve}, | ||
1982 | #endif | ||
1983 | #endif | ||
1984 | #ifdef SYS_exit | ||
1985 | #ifdef __NR_exit | ||
1986 | {"exit", __NR_exit}, | ||
1987 | #endif | ||
1988 | #endif | ||
1989 | #ifdef SYS_exit_group | ||
1990 | #ifdef __NR_exit_group | ||
1991 | {"exit_group", __NR_exit_group}, | ||
1992 | #endif | ||
1993 | #endif | ||
1994 | #ifdef SYS_faccessat | ||
1995 | #ifdef __NR_faccessat | ||
1996 | {"faccessat", __NR_faccessat}, | ||
1997 | #endif | ||
1998 | #endif | ||
1999 | #ifdef SYS_fadvise64 | ||
2000 | #ifdef __NR_fadvise64 | ||
2001 | {"fadvise64", __NR_fadvise64}, | ||
2002 | #endif | ||
2003 | #endif | ||
2004 | #ifdef SYS_fallocate | ||
2005 | #ifdef __NR_fallocate | ||
2006 | {"fallocate", __NR_fallocate}, | ||
2007 | #endif | ||
2008 | #endif | ||
2009 | #ifdef SYS_fanotify_init | ||
2010 | #ifdef __NR_fanotify_init | ||
2011 | {"fanotify_init", __NR_fanotify_init}, | ||
2012 | #endif | ||
2013 | #endif | ||
2014 | #ifdef SYS_fanotify_mark | ||
2015 | #ifdef __NR_fanotify_mark | ||
2016 | {"fanotify_mark", __NR_fanotify_mark}, | ||
2017 | #endif | ||
2018 | #endif | ||
2019 | #ifdef SYS_fchdir | ||
2020 | #ifdef __NR_fchdir | ||
2021 | {"fchdir", __NR_fchdir}, | ||
2022 | #endif | ||
2023 | #endif | ||
2024 | #ifdef SYS_fchmod | ||
2025 | #ifdef __NR_fchmod | ||
2026 | {"fchmod", __NR_fchmod}, | ||
2027 | #endif | ||
2028 | #endif | ||
2029 | #ifdef SYS_fchmodat | ||
2030 | #ifdef __NR_fchmodat | ||
2031 | {"fchmodat", __NR_fchmodat}, | ||
2032 | #endif | ||
2033 | #endif | ||
2034 | #ifdef SYS_fchown | ||
2035 | #ifdef __NR_fchown | ||
2036 | {"fchown", __NR_fchown}, | ||
2037 | #endif | ||
2038 | #endif | ||
2039 | #ifdef SYS_fchownat | ||
2040 | #ifdef __NR_fchownat | ||
2041 | {"fchownat", __NR_fchownat}, | ||
2042 | #endif | ||
2043 | #endif | ||
2044 | #ifdef SYS_fcntl | ||
2045 | #ifdef __NR_fcntl | ||
2046 | {"fcntl", __NR_fcntl}, | ||
2047 | #endif | ||
2048 | #endif | ||
2049 | #ifdef SYS_fdatasync | ||
2050 | #ifdef __NR_fdatasync | ||
2051 | {"fdatasync", __NR_fdatasync}, | ||
2052 | #endif | ||
2053 | #endif | ||
2054 | #ifdef SYS_fgetxattr | ||
2055 | #ifdef __NR_fgetxattr | ||
2056 | {"fgetxattr", __NR_fgetxattr}, | ||
2057 | #endif | ||
2058 | #endif | ||
2059 | #ifdef SYS_finit_module | ||
2060 | #ifdef __NR_finit_module | ||
2061 | {"finit_module", __NR_finit_module}, | ||
2062 | #endif | ||
2063 | #endif | ||
2064 | #ifdef SYS_flistxattr | ||
2065 | #ifdef __NR_flistxattr | ||
2066 | {"flistxattr", __NR_flistxattr}, | ||
2067 | #endif | ||
2068 | #endif | ||
2069 | #ifdef SYS_flock | ||
2070 | #ifdef __NR_flock | ||
2071 | {"flock", __NR_flock}, | ||
2072 | #endif | ||
2073 | #endif | ||
2074 | #ifdef SYS_fork | ||
2075 | #ifdef __NR_fork | ||
2076 | {"fork", __NR_fork}, | ||
2077 | #endif | ||
2078 | #endif | ||
2079 | #ifdef SYS_fremovexattr | ||
2080 | #ifdef __NR_fremovexattr | ||
2081 | {"fremovexattr", __NR_fremovexattr}, | ||
2082 | #endif | ||
2083 | #endif | ||
2084 | #ifdef SYS_fsetxattr | ||
2085 | #ifdef __NR_fsetxattr | ||
2086 | {"fsetxattr", __NR_fsetxattr}, | ||
2087 | #endif | ||
2088 | #endif | ||
2089 | #ifdef SYS_fstat | ||
2090 | #ifdef __NR_fstat | ||
2091 | {"fstat", __NR_fstat}, | ||
2092 | #endif | ||
2093 | #endif | ||
2094 | #ifdef SYS_fstatfs | ||
2095 | #ifdef __NR_fstatfs | ||
2096 | {"fstatfs", __NR_fstatfs}, | ||
2097 | #endif | ||
2098 | #endif | ||
2099 | #ifdef SYS_fsync | ||
2100 | #ifdef __NR_fsync | ||
2101 | {"fsync", __NR_fsync}, | ||
2102 | #endif | ||
2103 | #endif | ||
2104 | #ifdef SYS_ftruncate | ||
2105 | #ifdef __NR_ftruncate | ||
2106 | {"ftruncate", __NR_ftruncate}, | ||
2107 | #endif | ||
2108 | #endif | ||
2109 | #ifdef SYS_futex | ||
2110 | #ifdef __NR_futex | ||
2111 | {"futex", __NR_futex}, | ||
2112 | #endif | ||
2113 | #endif | ||
2114 | #ifdef SYS_futimesat | ||
2115 | #ifdef __NR_futimesat | ||
2116 | {"futimesat", __NR_futimesat}, | ||
2117 | #endif | ||
2118 | #endif | ||
2119 | #ifdef SYS_get_kernel_syms | ||
2120 | #ifdef __NR_get_kernel_syms | ||
2121 | {"get_kernel_syms", __NR_get_kernel_syms}, | ||
2122 | #endif | ||
2123 | #endif | ||
2124 | #ifdef SYS_get_mempolicy | ||
2125 | #ifdef __NR_get_mempolicy | ||
2126 | {"get_mempolicy", __NR_get_mempolicy}, | ||
2127 | #endif | ||
2128 | #endif | ||
2129 | #ifdef SYS_get_robust_list | ||
2130 | #ifdef __NR_get_robust_list | ||
2131 | {"get_robust_list", __NR_get_robust_list}, | ||
2132 | #endif | ||
2133 | #endif | ||
2134 | #ifdef SYS_get_thread_area | ||
2135 | #ifdef __NR_get_thread_area | ||
2136 | {"get_thread_area", __NR_get_thread_area}, | ||
2137 | #endif | ||
2138 | #endif | ||
2139 | #ifdef SYS_getcpu | ||
2140 | #ifdef __NR_getcpu | ||
2141 | {"getcpu", __NR_getcpu}, | ||
2142 | #endif | ||
2143 | #endif | ||
2144 | #ifdef SYS_getcwd | ||
2145 | #ifdef __NR_getcwd | ||
2146 | {"getcwd", __NR_getcwd}, | ||
2147 | #endif | ||
2148 | #endif | ||
2149 | #ifdef SYS_getdents | ||
2150 | #ifdef __NR_getdents | ||
2151 | {"getdents", __NR_getdents}, | ||
2152 | #endif | ||
2153 | #endif | ||
2154 | #ifdef SYS_getdents64 | ||
2155 | #ifdef __NR_getdents64 | ||
2156 | {"getdents64", __NR_getdents64}, | ||
2157 | #endif | ||
2158 | #endif | ||
2159 | #ifdef SYS_getegid | ||
2160 | #ifdef __NR_getegid | ||
2161 | {"getegid", __NR_getegid}, | ||
2162 | #endif | ||
2163 | #endif | ||
2164 | #ifdef SYS_geteuid | ||
2165 | #ifdef __NR_geteuid | ||
2166 | {"geteuid", __NR_geteuid}, | ||
2167 | #endif | ||
2168 | #endif | ||
2169 | #ifdef SYS_getgid | ||
2170 | #ifdef __NR_getgid | ||
2171 | {"getgid", __NR_getgid}, | ||
2172 | #endif | ||
2173 | #endif | ||
2174 | #ifdef SYS_getgroups | ||
2175 | #ifdef __NR_getgroups | ||
2176 | {"getgroups", __NR_getgroups}, | ||
2177 | #endif | ||
2178 | #endif | ||
2179 | #ifdef SYS_getitimer | ||
2180 | #ifdef __NR_getitimer | ||
2181 | {"getitimer", __NR_getitimer}, | ||
2182 | #endif | ||
2183 | #endif | ||
2184 | #ifdef SYS_getpeername | ||
2185 | #ifdef __NR_getpeername | ||
2186 | {"getpeername", __NR_getpeername}, | ||
2187 | #endif | ||
2188 | #endif | ||
2189 | #ifdef SYS_getpgid | ||
2190 | #ifdef __NR_getpgid | ||
2191 | {"getpgid", __NR_getpgid}, | ||
2192 | #endif | ||
2193 | #endif | ||
2194 | #ifdef SYS_getpgrp | ||
2195 | #ifdef __NR_getpgrp | ||
2196 | {"getpgrp", __NR_getpgrp}, | ||
2197 | #endif | ||
2198 | #endif | ||
2199 | #ifdef SYS_getpid | ||
2200 | #ifdef __NR_getpid | ||
2201 | {"getpid", __NR_getpid}, | ||
2202 | #endif | ||
2203 | #endif | ||
2204 | #ifdef SYS_getpmsg | ||
2205 | #ifdef __NR_getpmsg | ||
2206 | {"getpmsg", __NR_getpmsg}, | ||
2207 | #endif | ||
2208 | #endif | ||
2209 | #ifdef SYS_getppid | ||
2210 | #ifdef __NR_getppid | ||
2211 | {"getppid", __NR_getppid}, | ||
2212 | #endif | ||
2213 | #endif | ||
2214 | #ifdef SYS_getpriority | ||
2215 | #ifdef __NR_getpriority | ||
2216 | {"getpriority", __NR_getpriority}, | ||
2217 | #endif | ||
2218 | #endif | ||
2219 | #ifdef SYS_getresgid | ||
2220 | #ifdef __NR_getresgid | ||
2221 | {"getresgid", __NR_getresgid}, | ||
2222 | #endif | ||
2223 | #endif | ||
2224 | #ifdef SYS_getresuid | ||
2225 | #ifdef __NR_getresuid | ||
2226 | {"getresuid", __NR_getresuid}, | ||
2227 | #endif | ||
2228 | #endif | ||
2229 | #ifdef SYS_getrlimit | ||
2230 | #ifdef __NR_getrlimit | ||
2231 | {"getrlimit", __NR_getrlimit}, | ||
2232 | #endif | ||
2233 | #endif | ||
2234 | #ifdef SYS_getrusage | ||
2235 | #ifdef __NR_getrusage | ||
2236 | {"getrusage", __NR_getrusage}, | ||
2237 | #endif | ||
2238 | #endif | ||
2239 | #ifdef SYS_getsid | ||
2240 | #ifdef __NR_getsid | ||
2241 | {"getsid", __NR_getsid}, | ||
2242 | #endif | ||
2243 | #endif | ||
2244 | #ifdef SYS_getsockname | ||
2245 | #ifdef __NR_getsockname | ||
2246 | {"getsockname", __NR_getsockname}, | ||
2247 | #endif | ||
2248 | #endif | ||
2249 | #ifdef SYS_getsockopt | ||
2250 | #ifdef __NR_getsockopt | ||
2251 | {"getsockopt", __NR_getsockopt}, | ||
2252 | #endif | ||
2253 | #endif | ||
2254 | #ifdef SYS_gettid | ||
2255 | #ifdef __NR_gettid | ||
2256 | {"gettid", __NR_gettid}, | ||
2257 | #endif | ||
2258 | #endif | ||
2259 | #ifdef SYS_gettimeofday | ||
2260 | #ifdef __NR_gettimeofday | ||
2261 | {"gettimeofday", __NR_gettimeofday}, | ||
2262 | #endif | ||
2263 | #endif | ||
2264 | #ifdef SYS_getuid | ||
2265 | #ifdef __NR_getuid | ||
2266 | {"getuid", __NR_getuid}, | ||
2267 | #endif | ||
2268 | #endif | ||
2269 | #ifdef SYS_getxattr | ||
2270 | #ifdef __NR_getxattr | ||
2271 | {"getxattr", __NR_getxattr}, | ||
2272 | #endif | ||
2273 | #endif | ||
2274 | #ifdef SYS_init_module | ||
2275 | #ifdef __NR_init_module | ||
2276 | {"init_module", __NR_init_module}, | ||
2277 | #endif | ||
2278 | #endif | ||
2279 | #ifdef SYS_inotify_add_watch | ||
2280 | #ifdef __NR_inotify_add_watch | ||
2281 | {"inotify_add_watch", __NR_inotify_add_watch}, | ||
2282 | #endif | ||
2283 | #endif | ||
2284 | #ifdef SYS_inotify_init | ||
2285 | #ifdef __NR_inotify_init | ||
2286 | {"inotify_init", __NR_inotify_init}, | ||
2287 | #endif | ||
2288 | #endif | ||
2289 | #ifdef SYS_inotify_init1 | ||
2290 | #ifdef __NR_inotify_init1 | ||
2291 | {"inotify_init1", __NR_inotify_init1}, | ||
2292 | #endif | ||
2293 | #endif | ||
2294 | #ifdef SYS_inotify_rm_watch | ||
2295 | #ifdef __NR_inotify_rm_watch | ||
2296 | {"inotify_rm_watch", __NR_inotify_rm_watch}, | ||
2297 | #endif | ||
2298 | #endif | ||
2299 | #ifdef SYS_io_cancel | ||
2300 | #ifdef __NR_io_cancel | ||
2301 | {"io_cancel", __NR_io_cancel}, | ||
2302 | #endif | ||
2303 | #endif | ||
2304 | #ifdef SYS_io_destroy | ||
2305 | #ifdef __NR_io_destroy | ||
2306 | {"io_destroy", __NR_io_destroy}, | ||
2307 | #endif | ||
2308 | #endif | ||
2309 | #ifdef SYS_io_getevents | ||
2310 | #ifdef __NR_io_getevents | ||
2311 | {"io_getevents", __NR_io_getevents}, | ||
2312 | #endif | ||
2313 | #endif | ||
2314 | #ifdef SYS_io_setup | ||
2315 | #ifdef __NR_io_setup | ||
2316 | {"io_setup", __NR_io_setup}, | ||
2317 | #endif | ||
2318 | #endif | ||
2319 | #ifdef SYS_io_submit | ||
2320 | #ifdef __NR_io_submit | ||
2321 | {"io_submit", __NR_io_submit}, | ||
2322 | #endif | ||
2323 | #endif | ||
2324 | #ifdef SYS_ioctl | ||
2325 | #ifdef __NR_ioctl | ||
2326 | {"ioctl", __NR_ioctl}, | ||
2327 | #endif | ||
2328 | #endif | ||
2329 | #ifdef SYS_ioperm | ||
2330 | #ifdef __NR_ioperm | ||
2331 | {"ioperm", __NR_ioperm}, | ||
2332 | #endif | ||
2333 | #endif | ||
2334 | #ifdef SYS_iopl | ||
2335 | #ifdef __NR_iopl | ||
2336 | {"iopl", __NR_iopl}, | ||
2337 | #endif | ||
2338 | #endif | ||
2339 | #ifdef SYS_ioprio_get | ||
2340 | #ifdef __NR_ioprio_get | ||
2341 | {"ioprio_get", __NR_ioprio_get}, | ||
2342 | #endif | ||
2343 | #endif | ||
2344 | #ifdef SYS_ioprio_set | ||
2345 | #ifdef __NR_ioprio_set | ||
2346 | {"ioprio_set", __NR_ioprio_set}, | ||
2347 | #endif | ||
2348 | #endif | ||
2349 | #ifdef SYS_kcmp | ||
2350 | #ifdef __NR_kcmp | ||
2351 | {"kcmp", __NR_kcmp}, | ||
2352 | #endif | ||
2353 | #endif | ||
2354 | #ifdef SYS_kexec_load | ||
2355 | #ifdef __NR_kexec_load | ||
2356 | {"kexec_load", __NR_kexec_load}, | ||
2357 | #endif | ||
2358 | #endif | ||
2359 | #ifdef SYS_keyctl | ||
2360 | #ifdef __NR_keyctl | ||
2361 | {"keyctl", __NR_keyctl}, | ||
2362 | #endif | ||
2363 | #endif | ||
2364 | #ifdef SYS_kill | ||
2365 | #ifdef __NR_kill | ||
2366 | {"kill", __NR_kill}, | ||
2367 | #endif | ||
2368 | #endif | ||
2369 | #ifdef SYS_lchown | ||
2370 | #ifdef __NR_lchown | ||
2371 | {"lchown", __NR_lchown}, | ||
2372 | #endif | ||
2373 | #endif | ||
2374 | #ifdef SYS_lgetxattr | ||
2375 | #ifdef __NR_lgetxattr | ||
2376 | {"lgetxattr", __NR_lgetxattr}, | ||
2377 | #endif | ||
2378 | #endif | ||
2379 | #ifdef SYS_link | ||
2380 | #ifdef __NR_link | ||
2381 | {"link", __NR_link}, | ||
2382 | #endif | ||
2383 | #endif | ||
2384 | #ifdef SYS_linkat | ||
2385 | #ifdef __NR_linkat | ||
2386 | {"linkat", __NR_linkat}, | ||
2387 | #endif | ||
2388 | #endif | ||
2389 | #ifdef SYS_listen | ||
2390 | #ifdef __NR_listen | ||
2391 | {"listen", __NR_listen}, | ||
2392 | #endif | ||
2393 | #endif | ||
2394 | #ifdef SYS_listxattr | ||
2395 | #ifdef __NR_listxattr | ||
2396 | {"listxattr", __NR_listxattr}, | ||
2397 | #endif | ||
2398 | #endif | ||
2399 | #ifdef SYS_llistxattr | ||
2400 | #ifdef __NR_llistxattr | ||
2401 | {"llistxattr", __NR_llistxattr}, | ||
2402 | #endif | ||
2403 | #endif | ||
2404 | #ifdef SYS_lookup_dcookie | ||
2405 | #ifdef __NR_lookup_dcookie | ||
2406 | {"lookup_dcookie", __NR_lookup_dcookie}, | ||
2407 | #endif | ||
2408 | #endif | ||
2409 | #ifdef SYS_lremovexattr | ||
2410 | #ifdef __NR_lremovexattr | ||
2411 | {"lremovexattr", __NR_lremovexattr}, | ||
2412 | #endif | ||
2413 | #endif | ||
2414 | #ifdef SYS_lseek | ||
2415 | #ifdef __NR_lseek | ||
2416 | {"lseek", __NR_lseek}, | ||
2417 | #endif | ||
2418 | #endif | ||
2419 | #ifdef SYS_lsetxattr | ||
2420 | #ifdef __NR_lsetxattr | ||
2421 | {"lsetxattr", __NR_lsetxattr}, | ||
2422 | #endif | ||
2423 | #endif | ||
2424 | #ifdef SYS_lstat | ||
2425 | #ifdef __NR_lstat | ||
2426 | {"lstat", __NR_lstat}, | ||
2427 | #endif | ||
2428 | #endif | ||
2429 | #ifdef SYS_madvise | ||
2430 | #ifdef __NR_madvise | ||
2431 | {"madvise", __NR_madvise}, | ||
2432 | #endif | ||
2433 | #endif | ||
2434 | #ifdef SYS_mbind | ||
2435 | #ifdef __NR_mbind | ||
2436 | {"mbind", __NR_mbind}, | ||
2437 | #endif | ||
2438 | #endif | ||
2439 | #ifdef SYS_migrate_pages | ||
2440 | #ifdef __NR_migrate_pages | ||
2441 | {"migrate_pages", __NR_migrate_pages}, | ||
2442 | #endif | ||
2443 | #endif | ||
2444 | #ifdef SYS_mincore | ||
2445 | #ifdef __NR_mincore | ||
2446 | {"mincore", __NR_mincore}, | ||
2447 | #endif | ||
2448 | #endif | ||
2449 | #ifdef SYS_mkdir | ||
2450 | #ifdef __NR_mkdir | ||
2451 | {"mkdir", __NR_mkdir}, | ||
2452 | #endif | ||
2453 | #endif | ||
2454 | #ifdef SYS_mkdirat | ||
2455 | #ifdef __NR_mkdirat | ||
2456 | {"mkdirat", __NR_mkdirat}, | ||
2457 | #endif | ||
2458 | #endif | ||
2459 | #ifdef SYS_mknod | ||
2460 | #ifdef __NR_mknod | ||
2461 | {"mknod", __NR_mknod}, | ||
2462 | #endif | ||
2463 | #endif | ||
2464 | #ifdef SYS_mknodat | ||
2465 | #ifdef __NR_mknodat | ||
2466 | {"mknodat", __NR_mknodat}, | ||
2467 | #endif | ||
2468 | #endif | ||
2469 | #ifdef SYS_mlock | ||
2470 | #ifdef __NR_mlock | ||
2471 | {"mlock", __NR_mlock}, | ||
2472 | #endif | ||
2473 | #endif | ||
2474 | #ifdef SYS_mlockall | ||
2475 | #ifdef __NR_mlockall | ||
2476 | {"mlockall", __NR_mlockall}, | ||
2477 | #endif | ||
2478 | #endif | ||
2479 | #ifdef SYS_mmap | ||
2480 | #ifdef __NR_mmap | ||
2481 | {"mmap", __NR_mmap}, | ||
2482 | #endif | ||
2483 | #endif | ||
2484 | #ifdef SYS_modify_ldt | ||
2485 | #ifdef __NR_modify_ldt | ||
2486 | {"modify_ldt", __NR_modify_ldt}, | ||
2487 | #endif | ||
2488 | #endif | ||
2489 | #ifdef SYS_mount | ||
2490 | #ifdef __NR_mount | ||
2491 | {"mount", __NR_mount}, | ||
2492 | #endif | ||
2493 | #endif | ||
2494 | #ifdef SYS_move_pages | ||
2495 | #ifdef __NR_move_pages | ||
2496 | {"move_pages", __NR_move_pages}, | ||
2497 | #endif | ||
2498 | #endif | ||
2499 | #ifdef SYS_mprotect | ||
2500 | #ifdef __NR_mprotect | ||
2501 | {"mprotect", __NR_mprotect}, | ||
2502 | #endif | ||
2503 | #endif | ||
2504 | #ifdef SYS_mq_getsetattr | ||
2505 | #ifdef __NR_mq_getsetattr | ||
2506 | {"mq_getsetattr", __NR_mq_getsetattr}, | ||
2507 | #endif | ||
2508 | #endif | ||
2509 | #ifdef SYS_mq_notify | ||
2510 | #ifdef __NR_mq_notify | ||
2511 | {"mq_notify", __NR_mq_notify}, | ||
2512 | #endif | ||
2513 | #endif | ||
2514 | #ifdef SYS_mq_open | ||
2515 | #ifdef __NR_mq_open | ||
2516 | {"mq_open", __NR_mq_open}, | ||
2517 | #endif | ||
2518 | #endif | ||
2519 | #ifdef SYS_mq_timedreceive | ||
2520 | #ifdef __NR_mq_timedreceive | ||
2521 | {"mq_timedreceive", __NR_mq_timedreceive}, | ||
2522 | #endif | ||
2523 | #endif | ||
2524 | #ifdef SYS_mq_timedsend | ||
2525 | #ifdef __NR_mq_timedsend | ||
2526 | {"mq_timedsend", __NR_mq_timedsend}, | ||
2527 | #endif | ||
2528 | #endif | ||
2529 | #ifdef SYS_mq_unlink | ||
2530 | #ifdef __NR_mq_unlink | ||
2531 | {"mq_unlink", __NR_mq_unlink}, | ||
2532 | #endif | ||
2533 | #endif | ||
2534 | #ifdef SYS_mremap | ||
2535 | #ifdef __NR_mremap | ||
2536 | {"mremap", __NR_mremap}, | ||
2537 | #endif | ||
2538 | #endif | ||
2539 | #ifdef SYS_msgctl | ||
2540 | #ifdef __NR_msgctl | ||
2541 | {"msgctl", __NR_msgctl}, | ||
2542 | #endif | ||
2543 | #endif | ||
2544 | #ifdef SYS_msgget | ||
2545 | #ifdef __NR_msgget | ||
2546 | {"msgget", __NR_msgget}, | ||
2547 | #endif | ||
2548 | #endif | ||
2549 | #ifdef SYS_msgrcv | ||
2550 | #ifdef __NR_msgrcv | ||
2551 | {"msgrcv", __NR_msgrcv}, | ||
2552 | #endif | ||
2553 | #endif | ||
2554 | #ifdef SYS_msgsnd | ||
2555 | #ifdef __NR_msgsnd | ||
2556 | {"msgsnd", __NR_msgsnd}, | ||
2557 | #endif | ||
2558 | #endif | ||
2559 | #ifdef SYS_msync | ||
2560 | #ifdef __NR_msync | ||
2561 | {"msync", __NR_msync}, | ||
2562 | #endif | ||
2563 | #endif | ||
2564 | #ifdef SYS_munlock | ||
2565 | #ifdef __NR_munlock | ||
2566 | {"munlock", __NR_munlock}, | ||
2567 | #endif | ||
2568 | #endif | ||
2569 | #ifdef SYS_munlockall | ||
2570 | #ifdef __NR_munlockall | ||
2571 | {"munlockall", __NR_munlockall}, | ||
2572 | #endif | ||
2573 | #endif | ||
2574 | #ifdef SYS_munmap | ||
2575 | #ifdef __NR_munmap | ||
2576 | {"munmap", __NR_munmap}, | ||
2577 | #endif | ||
2578 | #endif | ||
2579 | #ifdef SYS_name_to_handle_at | ||
2580 | #ifdef __NR_name_to_handle_at | ||
2581 | {"name_to_handle_at", __NR_name_to_handle_at}, | ||
2582 | #endif | ||
2583 | #endif | ||
2584 | #ifdef SYS_nanosleep | ||
2585 | #ifdef __NR_nanosleep | ||
2586 | {"nanosleep", __NR_nanosleep}, | ||
2587 | #endif | ||
2588 | #endif | ||
2589 | #ifdef SYS_newfstatat | ||
2590 | #ifdef __NR_newfstatat | ||
2591 | {"newfstatat", __NR_newfstatat}, | ||
2592 | #endif | ||
2593 | #endif | ||
2594 | #ifdef SYS_nfsservctl | ||
2595 | #ifdef __NR_nfsservctl | ||
2596 | {"nfsservctl", __NR_nfsservctl}, | ||
2597 | #endif | ||
2598 | #endif | ||
2599 | #ifdef SYS_open | ||
2600 | #ifdef __NR_open | ||
2601 | {"open", __NR_open}, | ||
2602 | #endif | ||
2603 | #endif | ||
2604 | #ifdef SYS_open_by_handle_at | ||
2605 | #ifdef __NR_open_by_handle_at | ||
2606 | {"open_by_handle_at", __NR_open_by_handle_at}, | ||
2607 | #endif | ||
2608 | #endif | ||
2609 | #ifdef SYS_openat | ||
2610 | #ifdef __NR_openat | ||
2611 | {"openat", __NR_openat}, | ||
2612 | #endif | ||
2613 | #endif | ||
2614 | #ifdef SYS_pause | ||
2615 | #ifdef __NR_pause | ||
2616 | {"pause", __NR_pause}, | ||
2617 | #endif | ||
2618 | #endif | ||
2619 | #ifdef SYS_perf_event_open | ||
2620 | #ifdef __NR_perf_event_open | ||
2621 | {"perf_event_open", __NR_perf_event_open}, | ||
2622 | #endif | ||
2623 | #endif | ||
2624 | #ifdef SYS_personality | ||
2625 | #ifdef __NR_personality | ||
2626 | {"personality", __NR_personality}, | ||
2627 | #endif | ||
2628 | #endif | ||
2629 | #ifdef SYS_pipe | ||
2630 | #ifdef __NR_pipe | ||
2631 | {"pipe", __NR_pipe}, | ||
2632 | #endif | ||
2633 | #endif | ||
2634 | #ifdef SYS_pipe2 | ||
2635 | #ifdef __NR_pipe2 | ||
2636 | {"pipe2", __NR_pipe2}, | ||
2637 | #endif | ||
2638 | #endif | ||
2639 | #ifdef SYS_pivot_root | ||
2640 | #ifdef __NR_pivot_root | ||
2641 | {"pivot_root", __NR_pivot_root}, | ||
2642 | #endif | ||
2643 | #endif | ||
2644 | #ifdef SYS_poll | ||
2645 | #ifdef __NR_poll | ||
2646 | {"poll", __NR_poll}, | ||
2647 | #endif | ||
2648 | #endif | ||
2649 | #ifdef SYS_ppoll | ||
2650 | #ifdef __NR_ppoll | ||
2651 | {"ppoll", __NR_ppoll}, | ||
2652 | #endif | ||
2653 | #endif | ||
2654 | #ifdef SYS_prctl | ||
2655 | #ifdef __NR_prctl | ||
2656 | {"prctl", __NR_prctl}, | ||
2657 | #endif | ||
2658 | #endif | ||
2659 | #ifdef SYS_pread64 | ||
2660 | #ifdef __NR_pread64 | ||
2661 | {"pread64", __NR_pread64}, | ||
2662 | #endif | ||
2663 | #endif | ||
2664 | #ifdef SYS_preadv | ||
2665 | #ifdef __NR_preadv | ||
2666 | {"preadv", __NR_preadv}, | ||
2667 | #endif | ||
2668 | #endif | ||
2669 | #ifdef SYS_prlimit64 | ||
2670 | #ifdef __NR_prlimit64 | ||
2671 | {"prlimit64", __NR_prlimit64}, | ||
2672 | #endif | ||
2673 | #endif | ||
2674 | #ifdef SYS_process_vm_readv | ||
2675 | #ifdef __NR_process_vm_readv | ||
2676 | {"process_vm_readv", __NR_process_vm_readv}, | ||
2677 | #endif | ||
2678 | #endif | ||
2679 | #ifdef SYS_process_vm_writev | ||
2680 | #ifdef __NR_process_vm_writev | ||
2681 | {"process_vm_writev", __NR_process_vm_writev}, | ||
2682 | #endif | ||
2683 | #endif | ||
2684 | #ifdef SYS_pselect6 | ||
2685 | #ifdef __NR_pselect6 | ||
2686 | {"pselect6", __NR_pselect6}, | ||
2687 | #endif | ||
2688 | #endif | ||
2689 | #ifdef SYS_ptrace | ||
2690 | #ifdef __NR_ptrace | ||
2691 | {"ptrace", __NR_ptrace}, | ||
2692 | #endif | ||
2693 | #endif | ||
2694 | #ifdef SYS_putpmsg | ||
2695 | #ifdef __NR_putpmsg | ||
2696 | {"putpmsg", __NR_putpmsg}, | ||
2697 | #endif | ||
2698 | #endif | ||
2699 | #ifdef SYS_pwrite64 | ||
2700 | #ifdef __NR_pwrite64 | ||
2701 | {"pwrite64", __NR_pwrite64}, | ||
2702 | #endif | ||
2703 | #endif | ||
2704 | #ifdef SYS_pwritev | ||
2705 | #ifdef __NR_pwritev | ||
2706 | {"pwritev", __NR_pwritev}, | ||
2707 | #endif | ||
2708 | #endif | ||
2709 | #ifdef SYS_query_module | ||
2710 | #ifdef __NR_query_module | ||
2711 | {"query_module", __NR_query_module}, | ||
2712 | #endif | ||
2713 | #endif | ||
2714 | #ifdef SYS_quotactl | ||
2715 | #ifdef __NR_quotactl | ||
2716 | {"quotactl", __NR_quotactl}, | ||
2717 | #endif | ||
2718 | #endif | ||
2719 | #ifdef SYS_read | ||
2720 | #ifdef __NR_read | ||
2721 | {"read", __NR_read}, | ||
2722 | #endif | ||
2723 | #endif | ||
2724 | #ifdef SYS_readahead | ||
2725 | #ifdef __NR_readahead | ||
2726 | {"readahead", __NR_readahead}, | ||
2727 | #endif | ||
2728 | #endif | ||
2729 | #ifdef SYS_readlink | ||
2730 | #ifdef __NR_readlink | ||
2731 | {"readlink", __NR_readlink}, | ||
2732 | #endif | ||
2733 | #endif | ||
2734 | #ifdef SYS_readlinkat | ||
2735 | #ifdef __NR_readlinkat | ||
2736 | {"readlinkat", __NR_readlinkat}, | ||
2737 | #endif | ||
2738 | #endif | ||
2739 | #ifdef SYS_readv | ||
2740 | #ifdef __NR_readv | ||
2741 | {"readv", __NR_readv}, | ||
2742 | #endif | ||
2743 | #endif | ||
2744 | #ifdef SYS_reboot | ||
2745 | #ifdef __NR_reboot | ||
2746 | {"reboot", __NR_reboot}, | ||
2747 | #endif | ||
2748 | #endif | ||
2749 | #ifdef SYS_recvfrom | ||
2750 | #ifdef __NR_recvfrom | ||
2751 | {"recvfrom", __NR_recvfrom}, | ||
2752 | #endif | ||
2753 | #endif | ||
2754 | #ifdef SYS_recvmmsg | ||
2755 | #ifdef __NR_recvmmsg | ||
2756 | {"recvmmsg", __NR_recvmmsg}, | ||
2757 | #endif | ||
2758 | #endif | ||
2759 | #ifdef SYS_recvmsg | ||
2760 | #ifdef __NR_recvmsg | ||
2761 | {"recvmsg", __NR_recvmsg}, | ||
2762 | #endif | ||
2763 | #endif | ||
2764 | #ifdef SYS_remap_file_pages | ||
2765 | #ifdef __NR_remap_file_pages | ||
2766 | {"remap_file_pages", __NR_remap_file_pages}, | ||
2767 | #endif | ||
2768 | #endif | ||
2769 | #ifdef SYS_removexattr | ||
2770 | #ifdef __NR_removexattr | ||
2771 | {"removexattr", __NR_removexattr}, | ||
2772 | #endif | ||
2773 | #endif | ||
2774 | #ifdef SYS_rename | ||
2775 | #ifdef __NR_rename | ||
2776 | {"rename", __NR_rename}, | ||
2777 | #endif | ||
2778 | #endif | ||
2779 | #ifdef SYS_renameat | ||
2780 | #ifdef __NR_renameat | ||
2781 | {"renameat", __NR_renameat}, | ||
2782 | #endif | ||
2783 | #endif | ||
2784 | #ifdef SYS_request_key | ||
2785 | #ifdef __NR_request_key | ||
2786 | {"request_key", __NR_request_key}, | ||
2787 | #endif | ||
2788 | #endif | ||
2789 | #ifdef SYS_restart_syscall | ||
2790 | #ifdef __NR_restart_syscall | ||
2791 | {"restart_syscall", __NR_restart_syscall}, | ||
2792 | #endif | ||
2793 | #endif | ||
2794 | #ifdef SYS_rmdir | ||
2795 | #ifdef __NR_rmdir | ||
2796 | {"rmdir", __NR_rmdir}, | ||
2797 | #endif | ||
2798 | #endif | ||
2799 | #ifdef SYS_rt_sigaction | ||
2800 | #ifdef __NR_rt_sigaction | ||
2801 | {"rt_sigaction", __NR_rt_sigaction}, | ||
2802 | #endif | ||
2803 | #endif | ||
2804 | #ifdef SYS_rt_sigpending | ||
2805 | #ifdef __NR_rt_sigpending | ||
2806 | {"rt_sigpending", __NR_rt_sigpending}, | ||
2807 | #endif | ||
2808 | #endif | ||
2809 | #ifdef SYS_rt_sigprocmask | ||
2810 | #ifdef __NR_rt_sigprocmask | ||
2811 | {"rt_sigprocmask", __NR_rt_sigprocmask}, | ||
2812 | #endif | ||
2813 | #endif | ||
2814 | #ifdef SYS_rt_sigqueueinfo | ||
2815 | #ifdef __NR_rt_sigqueueinfo | ||
2816 | {"rt_sigqueueinfo", __NR_rt_sigqueueinfo}, | ||
2817 | #endif | ||
2818 | #endif | ||
2819 | #ifdef SYS_rt_sigreturn | ||
2820 | #ifdef __NR_rt_sigreturn | ||
2821 | {"rt_sigreturn", __NR_rt_sigreturn}, | ||
2822 | #endif | ||
2823 | #endif | ||
2824 | #ifdef SYS_rt_sigsuspend | ||
2825 | #ifdef __NR_rt_sigsuspend | ||
2826 | {"rt_sigsuspend", __NR_rt_sigsuspend}, | ||
2827 | #endif | ||
2828 | #endif | ||
2829 | #ifdef SYS_rt_sigtimedwait | ||
2830 | #ifdef __NR_rt_sigtimedwait | ||
2831 | {"rt_sigtimedwait", __NR_rt_sigtimedwait}, | ||
2832 | #endif | ||
2833 | #endif | ||
2834 | #ifdef SYS_rt_tgsigqueueinfo | ||
2835 | #ifdef __NR_rt_tgsigqueueinfo | ||
2836 | {"rt_tgsigqueueinfo", __NR_rt_tgsigqueueinfo}, | ||
2837 | #endif | ||
2838 | #endif | ||
2839 | #ifdef SYS_sched_get_priority_max | ||
2840 | #ifdef __NR_sched_get_priority_max | ||
2841 | {"sched_get_priority_max", __NR_sched_get_priority_max}, | ||
2842 | #endif | ||
2843 | #endif | ||
2844 | #ifdef SYS_sched_get_priority_min | ||
2845 | #ifdef __NR_sched_get_priority_min | ||
2846 | {"sched_get_priority_min", __NR_sched_get_priority_min}, | ||
2847 | #endif | ||
2848 | #endif | ||
2849 | #ifdef SYS_sched_getaffinity | ||
2850 | #ifdef __NR_sched_getaffinity | ||
2851 | {"sched_getaffinity", __NR_sched_getaffinity}, | ||
2852 | #endif | ||
2853 | #endif | ||
2854 | #ifdef SYS_sched_getparam | ||
2855 | #ifdef __NR_sched_getparam | ||
2856 | {"sched_getparam", __NR_sched_getparam}, | ||
2857 | #endif | ||
2858 | #endif | ||
2859 | #ifdef SYS_sched_getscheduler | ||
2860 | #ifdef __NR_sched_getscheduler | ||
2861 | {"sched_getscheduler", __NR_sched_getscheduler}, | ||
2862 | #endif | ||
2863 | #endif | ||
2864 | #ifdef SYS_sched_rr_get_interval | ||
2865 | #ifdef __NR_sched_rr_get_interval | ||
2866 | {"sched_rr_get_interval", __NR_sched_rr_get_interval}, | ||
2867 | #endif | ||
2868 | #endif | ||
2869 | #ifdef SYS_sched_setaffinity | ||
2870 | #ifdef __NR_sched_setaffinity | ||
2871 | {"sched_setaffinity", __NR_sched_setaffinity}, | ||
2872 | #endif | ||
2873 | #endif | ||
2874 | #ifdef SYS_sched_setparam | ||
2875 | #ifdef __NR_sched_setparam | ||
2876 | {"sched_setparam", __NR_sched_setparam}, | ||
2877 | #endif | ||
2878 | #endif | ||
2879 | #ifdef SYS_sched_setscheduler | ||
2880 | #ifdef __NR_sched_setscheduler | ||
2881 | {"sched_setscheduler", __NR_sched_setscheduler}, | ||
2882 | #endif | ||
2883 | #endif | ||
2884 | #ifdef SYS_sched_yield | ||
2885 | #ifdef __NR_sched_yield | ||
2886 | {"sched_yield", __NR_sched_yield}, | ||
2887 | #endif | ||
2888 | #endif | ||
2889 | #ifdef SYS_security | ||
2890 | #ifdef __NR_security | ||
2891 | {"security", __NR_security}, | ||
2892 | #endif | ||
2893 | #endif | ||
2894 | #ifdef SYS_select | ||
2895 | #ifdef __NR_select | ||
2896 | {"select", __NR_select}, | ||
2897 | #endif | ||
2898 | #endif | ||
2899 | #ifdef SYS_semctl | ||
2900 | #ifdef __NR_semctl | ||
2901 | {"semctl", __NR_semctl}, | ||
2902 | #endif | ||
2903 | #endif | ||
2904 | #ifdef SYS_semget | ||
2905 | #ifdef __NR_semget | ||
2906 | {"semget", __NR_semget}, | ||
2907 | #endif | ||
2908 | #endif | ||
2909 | #ifdef SYS_semop | ||
2910 | #ifdef __NR_semop | ||
2911 | {"semop", __NR_semop}, | ||
2912 | #endif | ||
2913 | #endif | ||
2914 | #ifdef SYS_semtimedop | ||
2915 | #ifdef __NR_semtimedop | ||
2916 | {"semtimedop", __NR_semtimedop}, | ||
2917 | #endif | ||
2918 | #endif | ||
2919 | #ifdef SYS_sendfile | ||
2920 | #ifdef __NR_sendfile | ||
2921 | {"sendfile", __NR_sendfile}, | ||
2922 | #endif | ||
2923 | #endif | ||
2924 | #ifdef SYS_sendmmsg | ||
2925 | #ifdef __NR_sendmmsg | ||
2926 | {"sendmmsg", __NR_sendmmsg}, | ||
2927 | #endif | ||
2928 | #endif | ||
2929 | #ifdef SYS_sendmsg | ||
2930 | #ifdef __NR_sendmsg | ||
2931 | {"sendmsg", __NR_sendmsg}, | ||
2932 | #endif | ||
2933 | #endif | ||
2934 | #ifdef SYS_sendto | ||
2935 | #ifdef __NR_sendto | ||
2936 | {"sendto", __NR_sendto}, | ||
2937 | #endif | ||
2938 | #endif | ||
2939 | #ifdef SYS_set_mempolicy | ||
2940 | #ifdef __NR_set_mempolicy | ||
2941 | {"set_mempolicy", __NR_set_mempolicy}, | ||
2942 | #endif | ||
2943 | #endif | ||
2944 | #ifdef SYS_set_robust_list | ||
2945 | #ifdef __NR_set_robust_list | ||
2946 | {"set_robust_list", __NR_set_robust_list}, | ||
2947 | #endif | ||
2948 | #endif | ||
2949 | #ifdef SYS_set_thread_area | ||
2950 | #ifdef __NR_set_thread_area | ||
2951 | {"set_thread_area", __NR_set_thread_area}, | ||
2952 | #endif | ||
2953 | #endif | ||
2954 | #ifdef SYS_set_tid_address | ||
2955 | #ifdef __NR_set_tid_address | ||
2956 | {"set_tid_address", __NR_set_tid_address}, | ||
2957 | #endif | ||
2958 | #endif | ||
2959 | #ifdef SYS_setdomainname | ||
2960 | #ifdef __NR_setdomainname | ||
2961 | {"setdomainname", __NR_setdomainname}, | ||
2962 | #endif | ||
2963 | #endif | ||
2964 | #ifdef SYS_setfsgid | ||
2965 | #ifdef __NR_setfsgid | ||
2966 | {"setfsgid", __NR_setfsgid}, | ||
2967 | #endif | ||
2968 | #endif | ||
2969 | #ifdef SYS_setfsuid | ||
2970 | #ifdef __NR_setfsuid | ||
2971 | {"setfsuid", __NR_setfsuid}, | ||
2972 | #endif | ||
2973 | #endif | ||
2974 | #ifdef SYS_setgid | ||
2975 | #ifdef __NR_setgid | ||
2976 | {"setgid", __NR_setgid}, | ||
2977 | #endif | ||
2978 | #endif | ||
2979 | #ifdef SYS_setgroups | ||
2980 | #ifdef __NR_setgroups | ||
2981 | {"setgroups", __NR_setgroups}, | ||
2982 | #endif | ||
2983 | #endif | ||
2984 | #ifdef SYS_sethostname | ||
2985 | #ifdef __NR_sethostname | ||
2986 | {"sethostname", __NR_sethostname}, | ||
2987 | #endif | ||
2988 | #endif | ||
2989 | #ifdef SYS_setitimer | ||
2990 | #ifdef __NR_setitimer | ||
2991 | {"setitimer", __NR_setitimer}, | ||
2992 | #endif | ||
2993 | #endif | ||
2994 | #ifdef SYS_setns | ||
2995 | #ifdef __NR_setns | ||
2996 | {"setns", __NR_setns}, | ||
2997 | #endif | ||
2998 | #endif | ||
2999 | #ifdef SYS_setpgid | ||
3000 | #ifdef __NR_setpgid | ||
3001 | {"setpgid", __NR_setpgid}, | ||
3002 | #endif | ||
3003 | #endif | ||
3004 | #ifdef SYS_setpriority | ||
3005 | #ifdef __NR_setpriority | ||
3006 | {"setpriority", __NR_setpriority}, | ||
3007 | #endif | ||
3008 | #endif | ||
3009 | #ifdef SYS_setregid | ||
3010 | #ifdef __NR_setregid | ||
3011 | {"setregid", __NR_setregid}, | ||
3012 | #endif | ||
3013 | #endif | ||
3014 | #ifdef SYS_setresgid | ||
3015 | #ifdef __NR_setresgid | ||
3016 | {"setresgid", __NR_setresgid}, | ||
3017 | #endif | ||
3018 | #endif | ||
3019 | #ifdef SYS_setresuid | ||
3020 | #ifdef __NR_setresuid | ||
3021 | {"setresuid", __NR_setresuid}, | ||
3022 | #endif | ||
3023 | #endif | ||
3024 | #ifdef SYS_setreuid | ||
3025 | #ifdef __NR_setreuid | ||
3026 | {"setreuid", __NR_setreuid}, | ||
3027 | #endif | ||
3028 | #endif | ||
3029 | #ifdef SYS_setrlimit | ||
3030 | #ifdef __NR_setrlimit | ||
3031 | {"setrlimit", __NR_setrlimit}, | ||
3032 | #endif | ||
3033 | #endif | ||
3034 | #ifdef SYS_setsid | ||
3035 | #ifdef __NR_setsid | ||
3036 | {"setsid", __NR_setsid}, | ||
3037 | #endif | ||
3038 | #endif | ||
3039 | #ifdef SYS_setsockopt | ||
3040 | #ifdef __NR_setsockopt | ||
3041 | {"setsockopt", __NR_setsockopt}, | ||
3042 | #endif | ||
3043 | #endif | ||
3044 | #ifdef SYS_settimeofday | ||
3045 | #ifdef __NR_settimeofday | ||
3046 | {"settimeofday", __NR_settimeofday}, | ||
3047 | #endif | ||
3048 | #endif | ||
3049 | #ifdef SYS_setuid | ||
3050 | #ifdef __NR_setuid | ||
3051 | {"setuid", __NR_setuid}, | ||
3052 | #endif | ||
3053 | #endif | ||
3054 | #ifdef SYS_setxattr | ||
3055 | #ifdef __NR_setxattr | ||
3056 | {"setxattr", __NR_setxattr}, | ||
3057 | #endif | ||
3058 | #endif | ||
3059 | #ifdef SYS_shmat | ||
3060 | #ifdef __NR_shmat | ||
3061 | {"shmat", __NR_shmat}, | ||
3062 | #endif | ||
3063 | #endif | ||
3064 | #ifdef SYS_shmctl | ||
3065 | #ifdef __NR_shmctl | ||
3066 | {"shmctl", __NR_shmctl}, | ||
3067 | #endif | ||
3068 | #endif | ||
3069 | #ifdef SYS_shmdt | ||
3070 | #ifdef __NR_shmdt | ||
3071 | {"shmdt", __NR_shmdt}, | ||
3072 | #endif | ||
3073 | #endif | ||
3074 | #ifdef SYS_shmget | ||
3075 | #ifdef __NR_shmget | ||
3076 | {"shmget", __NR_shmget}, | ||
3077 | #endif | ||
3078 | #endif | ||
3079 | #ifdef SYS_shutdown | ||
3080 | #ifdef __NR_shutdown | ||
3081 | {"shutdown", __NR_shutdown}, | ||
3082 | #endif | ||
3083 | #endif | ||
3084 | #ifdef SYS_sigaltstack | ||
3085 | #ifdef __NR_sigaltstack | ||
3086 | {"sigaltstack", __NR_sigaltstack}, | ||
3087 | #endif | ||
3088 | #endif | ||
3089 | #ifdef SYS_signalfd | ||
3090 | #ifdef __NR_signalfd | ||
3091 | {"signalfd", __NR_signalfd}, | ||
3092 | #endif | ||
3093 | #endif | ||
3094 | #ifdef SYS_signalfd4 | ||
3095 | #ifdef __NR_signalfd4 | ||
3096 | {"signalfd4", __NR_signalfd4}, | ||
3097 | #endif | ||
3098 | #endif | ||
3099 | #ifdef SYS_socket | ||
3100 | #ifdef __NR_socket | ||
3101 | {"socket", __NR_socket}, | ||
3102 | #endif | ||
3103 | #endif | ||
3104 | #ifdef SYS_socketpair | ||
3105 | #ifdef __NR_socketpair | ||
3106 | {"socketpair", __NR_socketpair}, | ||
3107 | #endif | ||
3108 | #endif | ||
3109 | #ifdef SYS_splice | ||
3110 | #ifdef __NR_splice | ||
3111 | {"splice", __NR_splice}, | ||
3112 | #endif | ||
3113 | #endif | ||
3114 | #ifdef SYS_stat | ||
3115 | #ifdef __NR_stat | ||
3116 | {"stat", __NR_stat}, | ||
3117 | #endif | ||
3118 | #endif | ||
3119 | #ifdef SYS_statfs | ||
3120 | #ifdef __NR_statfs | ||
3121 | {"statfs", __NR_statfs}, | ||
3122 | #endif | ||
3123 | #endif | ||
3124 | #ifdef SYS_swapoff | ||
3125 | #ifdef __NR_swapoff | ||
3126 | {"swapoff", __NR_swapoff}, | ||
3127 | #endif | ||
3128 | #endif | ||
3129 | #ifdef SYS_swapon | ||
3130 | #ifdef __NR_swapon | ||
3131 | {"swapon", __NR_swapon}, | ||
3132 | #endif | ||
3133 | #endif | ||
3134 | #ifdef SYS_symlink | ||
3135 | #ifdef __NR_symlink | ||
3136 | {"symlink", __NR_symlink}, | ||
3137 | #endif | ||
3138 | #endif | ||
3139 | #ifdef SYS_symlinkat | ||
3140 | #ifdef __NR_symlinkat | ||
3141 | {"symlinkat", __NR_symlinkat}, | ||
3142 | #endif | ||
3143 | #endif | ||
3144 | #ifdef SYS_sync | ||
3145 | #ifdef __NR_sync | ||
3146 | {"sync", __NR_sync}, | ||
3147 | #endif | ||
3148 | #endif | ||
3149 | #ifdef SYS_sync_file_range | ||
3150 | #ifdef __NR_sync_file_range | ||
3151 | {"sync_file_range", __NR_sync_file_range}, | ||
3152 | #endif | ||
3153 | #endif | ||
3154 | #ifdef SYS_syncfs | ||
3155 | #ifdef __NR_syncfs | ||
3156 | {"syncfs", __NR_syncfs}, | ||
3157 | #endif | ||
3158 | #endif | ||
3159 | #ifdef SYS_sysfs | ||
3160 | #ifdef __NR_sysfs | ||
3161 | {"sysfs", __NR_sysfs}, | ||
3162 | #endif | ||
3163 | #endif | ||
3164 | #ifdef SYS_sysinfo | ||
3165 | #ifdef __NR_sysinfo | ||
3166 | {"sysinfo", __NR_sysinfo}, | ||
3167 | #endif | ||
3168 | #endif | ||
3169 | #ifdef SYS_syslog | ||
3170 | #ifdef __NR_syslog | ||
3171 | {"syslog", __NR_syslog}, | ||
3172 | #endif | ||
3173 | #endif | ||
3174 | #ifdef SYS_tee | ||
3175 | #ifdef __NR_tee | ||
3176 | {"tee", __NR_tee}, | ||
3177 | #endif | ||
3178 | #endif | ||
3179 | #ifdef SYS_tgkill | ||
3180 | #ifdef __NR_tgkill | ||
3181 | {"tgkill", __NR_tgkill}, | ||
3182 | #endif | ||
3183 | #endif | ||
3184 | #ifdef SYS_time | ||
3185 | #ifdef __NR_time | ||
3186 | {"time", __NR_time}, | ||
3187 | #endif | ||
3188 | #endif | ||
3189 | #ifdef SYS_timer_create | ||
3190 | #ifdef __NR_timer_create | ||
3191 | {"timer_create", __NR_timer_create}, | ||
3192 | #endif | ||
3193 | #endif | ||
3194 | #ifdef SYS_timer_delete | ||
3195 | #ifdef __NR_timer_delete | ||
3196 | {"timer_delete", __NR_timer_delete}, | ||
3197 | #endif | ||
3198 | #endif | ||
3199 | #ifdef SYS_timer_getoverrun | ||
3200 | #ifdef __NR_timer_getoverrun | ||
3201 | {"timer_getoverrun", __NR_timer_getoverrun}, | ||
3202 | #endif | ||
3203 | #endif | ||
3204 | #ifdef SYS_timer_gettime | ||
3205 | #ifdef __NR_timer_gettime | ||
3206 | {"timer_gettime", __NR_timer_gettime}, | ||
3207 | #endif | ||
3208 | #endif | ||
3209 | #ifdef SYS_timer_settime | ||
3210 | #ifdef __NR_timer_settime | ||
3211 | {"timer_settime", __NR_timer_settime}, | ||
3212 | #endif | ||
3213 | #endif | ||
3214 | #ifdef SYS_timerfd_create | ||
3215 | #ifdef __NR_timerfd_create | ||
3216 | {"timerfd_create", __NR_timerfd_create}, | ||
3217 | #endif | ||
3218 | #endif | ||
3219 | #ifdef SYS_timerfd_gettime | ||
3220 | #ifdef __NR_timerfd_gettime | ||
3221 | {"timerfd_gettime", __NR_timerfd_gettime}, | ||
3222 | #endif | ||
3223 | #endif | ||
3224 | #ifdef SYS_timerfd_settime | ||
3225 | #ifdef __NR_timerfd_settime | ||
3226 | {"timerfd_settime", __NR_timerfd_settime}, | ||
3227 | #endif | ||
3228 | #endif | ||
3229 | #ifdef SYS_times | ||
3230 | #ifdef __NR_times | ||
3231 | {"times", __NR_times}, | ||
3232 | #endif | ||
3233 | #endif | ||
3234 | #ifdef SYS_tkill | ||
3235 | #ifdef __NR_tkill | ||
3236 | {"tkill", __NR_tkill}, | ||
3237 | #endif | ||
3238 | #endif | ||
3239 | #ifdef SYS_truncate | ||
3240 | #ifdef __NR_truncate | ||
3241 | {"truncate", __NR_truncate}, | ||
3242 | #endif | ||
3243 | #endif | ||
3244 | #ifdef SYS_tuxcall | ||
3245 | #ifdef __NR_tuxcall | ||
3246 | {"tuxcall", __NR_tuxcall}, | ||
3247 | #endif | ||
3248 | #endif | ||
3249 | #ifdef SYS_umask | ||
3250 | #ifdef __NR_umask | ||
3251 | {"umask", __NR_umask}, | ||
3252 | #endif | ||
3253 | #endif | ||
3254 | #ifdef SYS_umount2 | ||
3255 | #ifdef __NR_umount2 | ||
3256 | {"umount2", __NR_umount2}, | ||
3257 | #endif | ||
3258 | #endif | ||
3259 | #ifdef SYS_uname | ||
3260 | #ifdef __NR_uname | ||
3261 | {"uname", __NR_uname}, | ||
3262 | #endif | ||
3263 | #endif | ||
3264 | #ifdef SYS_unlink | ||
3265 | #ifdef __NR_unlink | ||
3266 | {"unlink", __NR_unlink}, | ||
3267 | #endif | ||
3268 | #endif | ||
3269 | #ifdef SYS_unlinkat | ||
3270 | #ifdef __NR_unlinkat | ||
3271 | {"unlinkat", __NR_unlinkat}, | ||
3272 | #endif | ||
3273 | #endif | ||
3274 | #ifdef SYS_unshare | ||
3275 | #ifdef __NR_unshare | ||
3276 | {"unshare", __NR_unshare}, | ||
3277 | #endif | ||
3278 | #endif | ||
3279 | #ifdef SYS_uselib | ||
3280 | #ifdef __NR_uselib | ||
3281 | {"uselib", __NR_uselib}, | ||
3282 | #endif | ||
3283 | #endif | ||
3284 | #ifdef SYS_ustat | ||
3285 | #ifdef __NR_ustat | ||
3286 | {"ustat", __NR_ustat}, | ||
3287 | #endif | ||
3288 | #endif | ||
3289 | #ifdef SYS_utime | ||
3290 | #ifdef __NR_utime | ||
3291 | {"utime", __NR_utime}, | ||
3292 | #endif | ||
3293 | #endif | ||
3294 | #ifdef SYS_utimensat | ||
3295 | #ifdef __NR_utimensat | ||
3296 | {"utimensat", __NR_utimensat}, | ||
3297 | #endif | ||
3298 | #endif | ||
3299 | #ifdef SYS_utimes | ||
3300 | #ifdef __NR_utimes | ||
3301 | {"utimes", __NR_utimes}, | ||
3302 | #endif | ||
3303 | #endif | ||
3304 | #ifdef SYS_vfork | ||
3305 | #ifdef __NR_vfork | ||
3306 | {"vfork", __NR_vfork}, | ||
3307 | #endif | ||
3308 | #endif | ||
3309 | #ifdef SYS_vhangup | ||
3310 | #ifdef __NR_vhangup | ||
3311 | {"vhangup", __NR_vhangup}, | ||
3312 | #endif | ||
3313 | #endif | ||
3314 | #ifdef SYS_vmsplice | ||
3315 | #ifdef __NR_vmsplice | ||
3316 | {"vmsplice", __NR_vmsplice}, | ||
3317 | #endif | ||
3318 | #endif | ||
3319 | #ifdef SYS_vserver | ||
3320 | #ifdef __NR_vserver | ||
3321 | {"vserver", __NR_vserver}, | ||
3322 | #endif | ||
3323 | #endif | ||
3324 | #ifdef SYS_wait4 | ||
3325 | #ifdef __NR_wait4 | ||
3326 | {"wait4", __NR_wait4}, | ||
3327 | #endif | ||
3328 | #endif | ||
3329 | #ifdef SYS_waitid | ||
3330 | #ifdef __NR_waitid | ||
3331 | {"waitid", __NR_waitid}, | ||
3332 | #endif | ||
3333 | #endif | ||
3334 | #ifdef SYS_write | ||
3335 | #ifdef __NR_write | ||
3336 | {"write", __NR_write}, | ||
3337 | #endif | ||
3338 | #endif | ||
3339 | #ifdef SYS_writev | ||
3340 | #ifdef __NR_writev | ||
3341 | {"writev", __NR_writev}, | ||
3342 | #endif | ||
3343 | #endif | ||
3344 | #endif | ||
3345 | #if defined __x86_64__ && defined __ILP32__ | ||
3346 | #ifdef SYS_accept | ||
3347 | #ifdef __NR_accept | ||
3348 | {"accept", __NR_accept}, | ||
3349 | #endif | ||
3350 | #endif | ||
3351 | #ifdef SYS_accept4 | ||
3352 | #ifdef __NR_accept4 | ||
3353 | {"accept4", __NR_accept4}, | ||
3354 | #endif | ||
3355 | #endif | ||
3356 | #ifdef SYS_access | ||
3357 | #ifdef __NR_access | ||
3358 | {"access", __NR_access}, | ||
3359 | #endif | ||
3360 | #endif | ||
3361 | #ifdef SYS_acct | ||
3362 | #ifdef __NR_acct | ||
3363 | {"acct", __NR_acct}, | ||
3364 | #endif | ||
3365 | #endif | ||
3366 | #ifdef SYS_add_key | ||
3367 | #ifdef __NR_add_key | ||
3368 | {"add_key", __NR_add_key}, | ||
3369 | #endif | ||
3370 | #endif | ||
3371 | #ifdef SYS_adjtimex | ||
3372 | #ifdef __NR_adjtimex | ||
3373 | {"adjtimex", __NR_adjtimex}, | ||
3374 | #endif | ||
3375 | #endif | ||
3376 | #ifdef SYS_afs_syscall | ||
3377 | #ifdef __NR_afs_syscall | ||
3378 | {"afs_syscall", __NR_afs_syscall}, | ||
3379 | #endif | ||
3380 | #endif | ||
3381 | #ifdef SYS_alarm | ||
3382 | #ifdef __NR_alarm | ||
3383 | {"alarm", __NR_alarm}, | ||
3384 | #endif | ||
3385 | #endif | ||
3386 | #ifdef SYS_arch_prctl | ||
3387 | #ifdef __NR_arch_prctl | ||
3388 | {"arch_prctl", __NR_arch_prctl}, | ||
3389 | #endif | ||
3390 | #endif | ||
3391 | #ifdef SYS_bind | ||
3392 | #ifdef __NR_bind | ||
3393 | {"bind", __NR_bind}, | ||
3394 | #endif | ||
3395 | #endif | ||
3396 | #ifdef SYS_brk | ||
3397 | #ifdef __NR_brk | ||
3398 | {"brk", __NR_brk}, | ||
3399 | #endif | ||
3400 | #endif | ||
3401 | #ifdef SYS_capget | ||
3402 | #ifdef __NR_capget | ||
3403 | {"capget", __NR_capget}, | ||
3404 | #endif | ||
3405 | #endif | ||
3406 | #ifdef SYS_capset | ||
3407 | #ifdef __NR_capset | ||
3408 | {"capset", __NR_capset}, | ||
3409 | #endif | ||
3410 | #endif | ||
3411 | #ifdef SYS_chdir | ||
3412 | #ifdef __NR_chdir | ||
3413 | {"chdir", __NR_chdir}, | ||
3414 | #endif | ||
3415 | #endif | ||
3416 | #ifdef SYS_chmod | ||
3417 | #ifdef __NR_chmod | ||
3418 | {"chmod", __NR_chmod}, | ||
3419 | #endif | ||
3420 | #endif | ||
3421 | #ifdef SYS_chown | ||
3422 | #ifdef __NR_chown | ||
3423 | {"chown", __NR_chown}, | ||
3424 | #endif | ||
3425 | #endif | ||
3426 | #ifdef SYS_chroot | ||
3427 | #ifdef __NR_chroot | ||
3428 | {"chroot", __NR_chroot}, | ||
3429 | #endif | ||
3430 | #endif | ||
3431 | #ifdef SYS_clock_adjtime | ||
3432 | #ifdef __NR_clock_adjtime | ||
3433 | {"clock_adjtime", __NR_clock_adjtime}, | ||
3434 | #endif | ||
3435 | #endif | ||
3436 | #ifdef SYS_clock_getres | ||
3437 | #ifdef __NR_clock_getres | ||
3438 | {"clock_getres", __NR_clock_getres}, | ||
3439 | #endif | ||
3440 | #endif | ||
3441 | #ifdef SYS_clock_gettime | ||
3442 | #ifdef __NR_clock_gettime | ||
3443 | {"clock_gettime", __NR_clock_gettime}, | ||
3444 | #endif | ||
3445 | #endif | ||
3446 | #ifdef SYS_clock_nanosleep | ||
3447 | #ifdef __NR_clock_nanosleep | ||
3448 | {"clock_nanosleep", __NR_clock_nanosleep}, | ||
3449 | #endif | ||
3450 | #endif | ||
3451 | #ifdef SYS_clock_settime | ||
3452 | #ifdef __NR_clock_settime | ||
3453 | {"clock_settime", __NR_clock_settime}, | ||
3454 | #endif | ||
3455 | #endif | ||
3456 | #ifdef SYS_clone | ||
3457 | #ifdef __NR_clone | ||
3458 | {"clone", __NR_clone}, | ||
3459 | #endif | ||
3460 | #endif | ||
3461 | #ifdef SYS_close | ||
3462 | #ifdef __NR_close | ||
3463 | {"close", __NR_close}, | ||
3464 | #endif | ||
3465 | #endif | ||
3466 | #ifdef SYS_connect | ||
3467 | #ifdef __NR_connect | ||
3468 | {"connect", __NR_connect}, | ||
3469 | #endif | ||
3470 | #endif | ||
3471 | #ifdef SYS_creat | ||
3472 | #ifdef __NR_creat | ||
3473 | {"creat", __NR_creat}, | ||
3474 | #endif | ||
3475 | #endif | ||
3476 | #ifdef SYS_delete_module | ||
3477 | #ifdef __NR_delete_module | ||
3478 | {"delete_module", __NR_delete_module}, | ||
3479 | #endif | ||
3480 | #endif | ||
3481 | #ifdef SYS_dup | ||
3482 | #ifdef __NR_dup | ||
3483 | {"dup", __NR_dup}, | ||
3484 | #endif | ||
3485 | #endif | ||
3486 | #ifdef SYS_dup2 | ||
3487 | #ifdef __NR_dup2 | ||
3488 | {"dup2", __NR_dup2}, | ||
3489 | #endif | ||
3490 | #endif | ||
3491 | #ifdef SYS_dup3 | ||
3492 | #ifdef __NR_dup3 | ||
3493 | {"dup3", __NR_dup3}, | ||
3494 | #endif | ||
3495 | #endif | ||
3496 | #ifdef SYS_epoll_create | ||
3497 | #ifdef __NR_epoll_create | ||
3498 | {"epoll_create", __NR_epoll_create}, | ||
3499 | #endif | ||
3500 | #endif | ||
3501 | #ifdef SYS_epoll_create1 | ||
3502 | #ifdef __NR_epoll_create1 | ||
3503 | {"epoll_create1", __NR_epoll_create1}, | ||
3504 | #endif | ||
3505 | #endif | ||
3506 | #ifdef SYS_epoll_ctl | ||
3507 | #ifdef __NR_epoll_ctl | ||
3508 | {"epoll_ctl", __NR_epoll_ctl}, | ||
3509 | #endif | ||
3510 | #endif | ||
3511 | #ifdef SYS_epoll_pwait | ||
3512 | #ifdef __NR_epoll_pwait | ||
3513 | {"epoll_pwait", __NR_epoll_pwait}, | ||
3514 | #endif | ||
3515 | #endif | ||
3516 | #ifdef SYS_epoll_wait | ||
3517 | #ifdef __NR_epoll_wait | ||
3518 | {"epoll_wait", __NR_epoll_wait}, | ||
3519 | #endif | ||
3520 | #endif | ||
3521 | #ifdef SYS_eventfd | ||
3522 | #ifdef __NR_eventfd | ||
3523 | {"eventfd", __NR_eventfd}, | ||
3524 | #endif | ||
3525 | #endif | ||
3526 | #ifdef SYS_eventfd2 | ||
3527 | #ifdef __NR_eventfd2 | ||
3528 | {"eventfd2", __NR_eventfd2}, | ||
3529 | #endif | ||
3530 | #endif | ||
3531 | #ifdef SYS_execve | ||
3532 | #ifdef __NR_execve | ||
3533 | {"execve", __NR_execve}, | ||
3534 | #endif | ||
3535 | #endif | ||
3536 | #ifdef SYS_exit | ||
3537 | #ifdef __NR_exit | ||
3538 | {"exit", __NR_exit}, | ||
3539 | #endif | ||
3540 | #endif | ||
3541 | #ifdef SYS_exit_group | ||
3542 | #ifdef __NR_exit_group | ||
3543 | {"exit_group", __NR_exit_group}, | ||
3544 | #endif | ||
3545 | #endif | ||
3546 | #ifdef SYS_faccessat | ||
3547 | #ifdef __NR_faccessat | ||
3548 | {"faccessat", __NR_faccessat}, | ||
3549 | #endif | ||
3550 | #endif | ||
3551 | #ifdef SYS_fadvise64 | ||
3552 | #ifdef __NR_fadvise64 | ||
3553 | {"fadvise64", __NR_fadvise64}, | ||
3554 | #endif | ||
3555 | #endif | ||
3556 | #ifdef SYS_fallocate | ||
3557 | #ifdef __NR_fallocate | ||
3558 | {"fallocate", __NR_fallocate}, | ||
3559 | #endif | ||
3560 | #endif | ||
3561 | #ifdef SYS_fanotify_init | ||
3562 | #ifdef __NR_fanotify_init | ||
3563 | {"fanotify_init", __NR_fanotify_init}, | ||
3564 | #endif | ||
3565 | #endif | ||
3566 | #ifdef SYS_fanotify_mark | ||
3567 | #ifdef __NR_fanotify_mark | ||
3568 | {"fanotify_mark", __NR_fanotify_mark}, | ||
3569 | #endif | ||
3570 | #endif | ||
3571 | #ifdef SYS_fchdir | ||
3572 | #ifdef __NR_fchdir | ||
3573 | {"fchdir", __NR_fchdir}, | ||
3574 | #endif | ||
3575 | #endif | ||
3576 | #ifdef SYS_fchmod | ||
3577 | #ifdef __NR_fchmod | ||
3578 | {"fchmod", __NR_fchmod}, | ||
3579 | #endif | ||
3580 | #endif | ||
3581 | #ifdef SYS_fchmodat | ||
3582 | #ifdef __NR_fchmodat | ||
3583 | {"fchmodat", __NR_fchmodat}, | ||
3584 | #endif | ||
3585 | #endif | ||
3586 | #ifdef SYS_fchown | ||
3587 | #ifdef __NR_fchown | ||
3588 | {"fchown", __NR_fchown}, | ||
3589 | #endif | ||
3590 | #endif | ||
3591 | #ifdef SYS_fchownat | ||
3592 | #ifdef __NR_fchownat | ||
3593 | {"fchownat", __NR_fchownat}, | ||
3594 | #endif | ||
3595 | #endif | ||
3596 | #ifdef SYS_fcntl | ||
3597 | #ifdef __NR_fcntl | ||
3598 | {"fcntl", __NR_fcntl}, | ||
3599 | #endif | ||
3600 | #endif | ||
3601 | #ifdef SYS_fdatasync | ||
3602 | #ifdef __NR_fdatasync | ||
3603 | {"fdatasync", __NR_fdatasync}, | ||
3604 | #endif | ||
3605 | #endif | ||
3606 | #ifdef SYS_fgetxattr | ||
3607 | #ifdef __NR_fgetxattr | ||
3608 | {"fgetxattr", __NR_fgetxattr}, | ||
3609 | #endif | ||
3610 | #endif | ||
3611 | #ifdef SYS_finit_module | ||
3612 | #ifdef __NR_finit_module | ||
3613 | {"finit_module", __NR_finit_module}, | ||
3614 | #endif | ||
3615 | #endif | ||
3616 | #ifdef SYS_flistxattr | ||
3617 | #ifdef __NR_flistxattr | ||
3618 | {"flistxattr", __NR_flistxattr}, | ||
3619 | #endif | ||
3620 | #endif | ||
3621 | #ifdef SYS_flock | ||
3622 | #ifdef __NR_flock | ||
3623 | {"flock", __NR_flock}, | ||
3624 | #endif | ||
3625 | #endif | ||
3626 | #ifdef SYS_fork | ||
3627 | #ifdef __NR_fork | ||
3628 | {"fork", __NR_fork}, | ||
3629 | #endif | ||
3630 | #endif | ||
3631 | #ifdef SYS_fremovexattr | ||
3632 | #ifdef __NR_fremovexattr | ||
3633 | {"fremovexattr", __NR_fremovexattr}, | ||
3634 | #endif | ||
3635 | #endif | ||
3636 | #ifdef SYS_fsetxattr | ||
3637 | #ifdef __NR_fsetxattr | ||
3638 | {"fsetxattr", __NR_fsetxattr}, | ||
3639 | #endif | ||
3640 | #endif | ||
3641 | #ifdef SYS_fstat | ||
3642 | #ifdef __NR_fstat | ||
3643 | {"fstat", __NR_fstat}, | ||
3644 | #endif | ||
3645 | #endif | ||
3646 | #ifdef SYS_fstatfs | ||
3647 | #ifdef __NR_fstatfs | ||
3648 | {"fstatfs", __NR_fstatfs}, | ||
3649 | #endif | ||
3650 | #endif | ||
3651 | #ifdef SYS_fsync | ||
3652 | #ifdef __NR_fsync | ||
3653 | {"fsync", __NR_fsync}, | ||
3654 | #endif | ||
3655 | #endif | ||
3656 | #ifdef SYS_ftruncate | ||
3657 | #ifdef __NR_ftruncate | ||
3658 | {"ftruncate", __NR_ftruncate}, | ||
3659 | #endif | ||
3660 | #endif | ||
3661 | #ifdef SYS_futex | ||
3662 | #ifdef __NR_futex | ||
3663 | {"futex", __NR_futex}, | ||
3664 | #endif | ||
3665 | #endif | ||
3666 | #ifdef SYS_futimesat | ||
3667 | #ifdef __NR_futimesat | ||
3668 | {"futimesat", __NR_futimesat}, | ||
3669 | #endif | ||
3670 | #endif | ||
3671 | #ifdef SYS_get_mempolicy | ||
3672 | #ifdef __NR_get_mempolicy | ||
3673 | {"get_mempolicy", __NR_get_mempolicy}, | ||
3674 | #endif | ||
3675 | #endif | ||
3676 | #ifdef SYS_get_robust_list | ||
3677 | #ifdef __NR_get_robust_list | ||
3678 | {"get_robust_list", __NR_get_robust_list}, | ||
3679 | #endif | ||
3680 | #endif | ||
3681 | #ifdef SYS_getcpu | ||
3682 | #ifdef __NR_getcpu | ||
3683 | {"getcpu", __NR_getcpu}, | ||
3684 | #endif | ||
3685 | #endif | ||
3686 | #ifdef SYS_getcwd | ||
3687 | #ifdef __NR_getcwd | ||
3688 | {"getcwd", __NR_getcwd}, | ||
3689 | #endif | ||
3690 | #endif | ||
3691 | #ifdef SYS_getdents | ||
3692 | #ifdef __NR_getdents | ||
3693 | {"getdents", __NR_getdents}, | ||
3694 | #endif | ||
3695 | #endif | ||
3696 | #ifdef SYS_getdents64 | ||
3697 | #ifdef __NR_getdents64 | ||
3698 | {"getdents64", __NR_getdents64}, | ||
3699 | #endif | ||
3700 | #endif | ||
3701 | #ifdef SYS_getegid | ||
3702 | #ifdef __NR_getegid | ||
3703 | {"getegid", __NR_getegid}, | ||
3704 | #endif | ||
3705 | #endif | ||
3706 | #ifdef SYS_geteuid | ||
3707 | #ifdef __NR_geteuid | ||
3708 | {"geteuid", __NR_geteuid}, | ||
3709 | #endif | ||
3710 | #endif | ||
3711 | #ifdef SYS_getgid | ||
3712 | #ifdef __NR_getgid | ||
3713 | {"getgid", __NR_getgid}, | ||
3714 | #endif | ||
3715 | #endif | ||
3716 | #ifdef SYS_getgroups | ||
3717 | #ifdef __NR_getgroups | ||
3718 | {"getgroups", __NR_getgroups}, | ||
3719 | #endif | ||
3720 | #endif | ||
3721 | #ifdef SYS_getitimer | ||
3722 | #ifdef __NR_getitimer | ||
3723 | {"getitimer", __NR_getitimer}, | ||
3724 | #endif | ||
3725 | #endif | ||
3726 | #ifdef SYS_getpeername | ||
3727 | #ifdef __NR_getpeername | ||
3728 | {"getpeername", __NR_getpeername}, | ||
3729 | #endif | ||
3730 | #endif | ||
3731 | #ifdef SYS_getpgid | ||
3732 | #ifdef __NR_getpgid | ||
3733 | {"getpgid", __NR_getpgid}, | ||
3734 | #endif | ||
3735 | #endif | ||
3736 | #ifdef SYS_getpgrp | ||
3737 | #ifdef __NR_getpgrp | ||
3738 | {"getpgrp", __NR_getpgrp}, | ||
3739 | #endif | ||
3740 | #endif | ||
3741 | #ifdef SYS_getpid | ||
3742 | #ifdef __NR_getpid | ||
3743 | {"getpid", __NR_getpid}, | ||
3744 | #endif | ||
3745 | #endif | ||
3746 | #ifdef SYS_getpmsg | ||
3747 | #ifdef __NR_getpmsg | ||
3748 | {"getpmsg", __NR_getpmsg}, | ||
3749 | #endif | ||
3750 | #endif | ||
3751 | #ifdef SYS_getppid | ||
3752 | #ifdef __NR_getppid | ||
3753 | {"getppid", __NR_getppid}, | ||
3754 | #endif | ||
3755 | #endif | ||
3756 | #ifdef SYS_getpriority | ||
3757 | #ifdef __NR_getpriority | ||
3758 | {"getpriority", __NR_getpriority}, | ||
3759 | #endif | ||
3760 | #endif | ||
3761 | #ifdef SYS_getresgid | ||
3762 | #ifdef __NR_getresgid | ||
3763 | {"getresgid", __NR_getresgid}, | ||
3764 | #endif | ||
3765 | #endif | ||
3766 | #ifdef SYS_getresuid | ||
3767 | #ifdef __NR_getresuid | ||
3768 | {"getresuid", __NR_getresuid}, | ||
3769 | #endif | ||
3770 | #endif | ||
3771 | #ifdef SYS_getrlimit | ||
3772 | #ifdef __NR_getrlimit | ||
3773 | {"getrlimit", __NR_getrlimit}, | ||
3774 | #endif | ||
3775 | #endif | ||
3776 | #ifdef SYS_getrusage | ||
3777 | #ifdef __NR_getrusage | ||
3778 | {"getrusage", __NR_getrusage}, | ||
3779 | #endif | ||
3780 | #endif | ||
3781 | #ifdef SYS_getsid | ||
3782 | #ifdef __NR_getsid | ||
3783 | {"getsid", __NR_getsid}, | ||
3784 | #endif | ||
3785 | #endif | ||
3786 | #ifdef SYS_getsockname | ||
3787 | #ifdef __NR_getsockname | ||
3788 | {"getsockname", __NR_getsockname}, | ||
3789 | #endif | ||
3790 | #endif | ||
3791 | #ifdef SYS_getsockopt | ||
3792 | #ifdef __NR_getsockopt | ||
3793 | {"getsockopt", __NR_getsockopt}, | ||
3794 | #endif | ||
3795 | #endif | ||
3796 | #ifdef SYS_gettid | ||
3797 | #ifdef __NR_gettid | ||
3798 | {"gettid", __NR_gettid}, | ||
3799 | #endif | ||
3800 | #endif | ||
3801 | #ifdef SYS_gettimeofday | ||
3802 | #ifdef __NR_gettimeofday | ||
3803 | {"gettimeofday", __NR_gettimeofday}, | ||
3804 | #endif | ||
3805 | #endif | ||
3806 | #ifdef SYS_getuid | ||
3807 | #ifdef __NR_getuid | ||
3808 | {"getuid", __NR_getuid}, | ||
3809 | #endif | ||
3810 | #endif | ||
3811 | #ifdef SYS_getxattr | ||
3812 | #ifdef __NR_getxattr | ||
3813 | {"getxattr", __NR_getxattr}, | ||
3814 | #endif | ||
3815 | #endif | ||
3816 | #ifdef SYS_init_module | ||
3817 | #ifdef __NR_init_module | ||
3818 | {"init_module", __NR_init_module}, | ||
3819 | #endif | ||
3820 | #endif | ||
3821 | #ifdef SYS_inotify_add_watch | ||
3822 | #ifdef __NR_inotify_add_watch | ||
3823 | {"inotify_add_watch", __NR_inotify_add_watch}, | ||
3824 | #endif | ||
3825 | #endif | ||
3826 | #ifdef SYS_inotify_init | ||
3827 | #ifdef __NR_inotify_init | ||
3828 | {"inotify_init", __NR_inotify_init}, | ||
3829 | #endif | ||
3830 | #endif | ||
3831 | #ifdef SYS_inotify_init1 | ||
3832 | #ifdef __NR_inotify_init1 | ||
3833 | {"inotify_init1", __NR_inotify_init1}, | ||
3834 | #endif | ||
3835 | #endif | ||
3836 | #ifdef SYS_inotify_rm_watch | ||
3837 | #ifdef __NR_inotify_rm_watch | ||
3838 | {"inotify_rm_watch", __NR_inotify_rm_watch}, | ||
3839 | #endif | ||
3840 | #endif | ||
3841 | #ifdef SYS_io_cancel | ||
3842 | #ifdef __NR_io_cancel | ||
3843 | {"io_cancel", __NR_io_cancel}, | ||
3844 | #endif | ||
3845 | #endif | ||
3846 | #ifdef SYS_io_destroy | ||
3847 | #ifdef __NR_io_destroy | ||
3848 | {"io_destroy", __NR_io_destroy}, | ||
3849 | #endif | ||
3850 | #endif | ||
3851 | #ifdef SYS_io_getevents | ||
3852 | #ifdef __NR_io_getevents | ||
3853 | {"io_getevents", __NR_io_getevents}, | ||
3854 | #endif | ||
3855 | #endif | ||
3856 | #ifdef SYS_io_setup | ||
3857 | #ifdef __NR_io_setup | ||
3858 | {"io_setup", __NR_io_setup}, | ||
3859 | #endif | ||
3860 | #endif | ||
3861 | #ifdef SYS_io_submit | ||
3862 | #ifdef __NR_io_submit | ||
3863 | {"io_submit", __NR_io_submit}, | ||
3864 | #endif | ||
3865 | #endif | ||
3866 | #ifdef SYS_ioctl | ||
3867 | #ifdef __NR_ioctl | ||
3868 | {"ioctl", __NR_ioctl}, | ||
3869 | #endif | ||
3870 | #endif | ||
3871 | #ifdef SYS_ioperm | ||
3872 | #ifdef __NR_ioperm | ||
3873 | {"ioperm", __NR_ioperm}, | ||
3874 | #endif | ||
3875 | #endif | ||
3876 | #ifdef SYS_iopl | ||
3877 | #ifdef __NR_iopl | ||
3878 | {"iopl", __NR_iopl}, | ||
3879 | #endif | ||
3880 | #endif | ||
3881 | #ifdef SYS_ioprio_get | ||
3882 | #ifdef __NR_ioprio_get | ||
3883 | {"ioprio_get", __NR_ioprio_get}, | ||
3884 | #endif | ||
3885 | #endif | ||
3886 | #ifdef SYS_ioprio_set | ||
3887 | #ifdef __NR_ioprio_set | ||
3888 | {"ioprio_set", __NR_ioprio_set}, | ||
3889 | #endif | ||
3890 | #endif | ||
3891 | #ifdef SYS_kcmp | ||
3892 | #ifdef __NR_kcmp | ||
3893 | {"kcmp", __NR_kcmp}, | ||
3894 | #endif | ||
3895 | #endif | ||
3896 | #ifdef SYS_kexec_load | ||
3897 | #ifdef __NR_kexec_load | ||
3898 | {"kexec_load", __NR_kexec_load}, | ||
3899 | #endif | ||
3900 | #endif | ||
3901 | #ifdef SYS_keyctl | ||
3902 | #ifdef __NR_keyctl | ||
3903 | {"keyctl", __NR_keyctl}, | ||
3904 | #endif | ||
3905 | #endif | ||
3906 | #ifdef SYS_kill | ||
3907 | #ifdef __NR_kill | ||
3908 | {"kill", __NR_kill}, | ||
3909 | #endif | ||
3910 | #endif | ||
3911 | #ifdef SYS_lchown | ||
3912 | #ifdef __NR_lchown | ||
3913 | {"lchown", __NR_lchown}, | ||
3914 | #endif | ||
3915 | #endif | ||
3916 | #ifdef SYS_lgetxattr | ||
3917 | #ifdef __NR_lgetxattr | ||
3918 | {"lgetxattr", __NR_lgetxattr}, | ||
3919 | #endif | ||
3920 | #endif | ||
3921 | #ifdef SYS_link | ||
3922 | #ifdef __NR_link | ||
3923 | {"link", __NR_link}, | ||
3924 | #endif | ||
3925 | #endif | ||
3926 | #ifdef SYS_linkat | ||
3927 | #ifdef __NR_linkat | ||
3928 | {"linkat", __NR_linkat}, | ||
3929 | #endif | ||
3930 | #endif | ||
3931 | #ifdef SYS_listen | ||
3932 | #ifdef __NR_listen | ||
3933 | {"listen", __NR_listen}, | ||
3934 | #endif | ||
3935 | #endif | ||
3936 | #ifdef SYS_listxattr | ||
3937 | #ifdef __NR_listxattr | ||
3938 | {"listxattr", __NR_listxattr}, | ||
3939 | #endif | ||
3940 | #endif | ||
3941 | #ifdef SYS_llistxattr | ||
3942 | #ifdef __NR_llistxattr | ||
3943 | {"llistxattr", __NR_llistxattr}, | ||
3944 | #endif | ||
3945 | #endif | ||
3946 | #ifdef SYS_lookup_dcookie | ||
3947 | #ifdef __NR_lookup_dcookie | ||
3948 | {"lookup_dcookie", __NR_lookup_dcookie}, | ||
3949 | #endif | ||
3950 | #endif | ||
3951 | #ifdef SYS_lremovexattr | ||
3952 | #ifdef __NR_lremovexattr | ||
3953 | {"lremovexattr", __NR_lremovexattr}, | ||
3954 | #endif | ||
3955 | #endif | ||
3956 | #ifdef SYS_lseek | ||
3957 | #ifdef __NR_lseek | ||
3958 | {"lseek", __NR_lseek}, | ||
3959 | #endif | ||
3960 | #endif | ||
3961 | #ifdef SYS_lsetxattr | ||
3962 | #ifdef __NR_lsetxattr | ||
3963 | {"lsetxattr", __NR_lsetxattr}, | ||
3964 | #endif | ||
3965 | #endif | ||
3966 | #ifdef SYS_lstat | ||
3967 | #ifdef __NR_lstat | ||
3968 | {"lstat", __NR_lstat}, | ||
3969 | #endif | ||
3970 | #endif | ||
3971 | #ifdef SYS_madvise | ||
3972 | #ifdef __NR_madvise | ||
3973 | {"madvise", __NR_madvise}, | ||
3974 | #endif | ||
3975 | #endif | ||
3976 | #ifdef SYS_mbind | ||
3977 | #ifdef __NR_mbind | ||
3978 | {"mbind", __NR_mbind}, | ||
3979 | #endif | ||
3980 | #endif | ||
3981 | #ifdef SYS_migrate_pages | ||
3982 | #ifdef __NR_migrate_pages | ||
3983 | {"migrate_pages", __NR_migrate_pages}, | ||
3984 | #endif | ||
3985 | #endif | ||
3986 | #ifdef SYS_mincore | ||
3987 | #ifdef __NR_mincore | ||
3988 | {"mincore", __NR_mincore}, | ||
3989 | #endif | ||
3990 | #endif | ||
3991 | #ifdef SYS_mkdir | ||
3992 | #ifdef __NR_mkdir | ||
3993 | {"mkdir", __NR_mkdir}, | ||
3994 | #endif | ||
3995 | #endif | ||
3996 | #ifdef SYS_mkdirat | ||
3997 | #ifdef __NR_mkdirat | ||
3998 | {"mkdirat", __NR_mkdirat}, | ||
3999 | #endif | ||
4000 | #endif | ||
4001 | #ifdef SYS_mknod | ||
4002 | #ifdef __NR_mknod | ||
4003 | {"mknod", __NR_mknod}, | ||
4004 | #endif | ||
4005 | #endif | ||
4006 | #ifdef SYS_mknodat | ||
4007 | #ifdef __NR_mknodat | ||
4008 | {"mknodat", __NR_mknodat}, | ||
4009 | #endif | ||
4010 | #endif | ||
4011 | #ifdef SYS_mlock | ||
4012 | #ifdef __NR_mlock | ||
4013 | {"mlock", __NR_mlock}, | ||
4014 | #endif | ||
4015 | #endif | ||
4016 | #ifdef SYS_mlockall | ||
4017 | #ifdef __NR_mlockall | ||
4018 | {"mlockall", __NR_mlockall}, | ||
4019 | #endif | ||
4020 | #endif | ||
4021 | #ifdef SYS_mmap | ||
4022 | #ifdef __NR_mmap | ||
4023 | {"mmap", __NR_mmap}, | ||
4024 | #endif | ||
4025 | #endif | ||
4026 | #ifdef SYS_modify_ldt | ||
4027 | #ifdef __NR_modify_ldt | ||
4028 | {"modify_ldt", __NR_modify_ldt}, | ||
4029 | #endif | ||
4030 | #endif | ||
4031 | #ifdef SYS_mount | ||
4032 | #ifdef __NR_mount | ||
4033 | {"mount", __NR_mount}, | ||
4034 | #endif | ||
4035 | #endif | ||
4036 | #ifdef SYS_move_pages | ||
4037 | #ifdef __NR_move_pages | ||
4038 | {"move_pages", __NR_move_pages}, | ||
4039 | #endif | ||
4040 | #endif | ||
4041 | #ifdef SYS_mprotect | ||
4042 | #ifdef __NR_mprotect | ||
4043 | {"mprotect", __NR_mprotect}, | ||
4044 | #endif | ||
4045 | #endif | ||
4046 | #ifdef SYS_mq_getsetattr | ||
4047 | #ifdef __NR_mq_getsetattr | ||
4048 | {"mq_getsetattr", __NR_mq_getsetattr}, | ||
4049 | #endif | ||
4050 | #endif | ||
4051 | #ifdef SYS_mq_notify | ||
4052 | #ifdef __NR_mq_notify | ||
4053 | {"mq_notify", __NR_mq_notify}, | ||
4054 | #endif | ||
4055 | #endif | ||
4056 | #ifdef SYS_mq_open | ||
4057 | #ifdef __NR_mq_open | ||
4058 | {"mq_open", __NR_mq_open}, | ||
4059 | #endif | ||
4060 | #endif | ||
4061 | #ifdef SYS_mq_timedreceive | ||
4062 | #ifdef __NR_mq_timedreceive | ||
4063 | {"mq_timedreceive", __NR_mq_timedreceive}, | ||
4064 | #endif | ||
4065 | #endif | ||
4066 | #ifdef SYS_mq_timedsend | ||
4067 | #ifdef __NR_mq_timedsend | ||
4068 | {"mq_timedsend", __NR_mq_timedsend}, | ||
4069 | #endif | ||
4070 | #endif | ||
4071 | #ifdef SYS_mq_unlink | ||
4072 | #ifdef __NR_mq_unlink | ||
4073 | {"mq_unlink", __NR_mq_unlink}, | ||
4074 | #endif | ||
4075 | #endif | ||
4076 | #ifdef SYS_mremap | ||
4077 | #ifdef __NR_mremap | ||
4078 | {"mremap", __NR_mremap}, | ||
4079 | #endif | ||
4080 | #endif | ||
4081 | #ifdef SYS_msgctl | ||
4082 | #ifdef __NR_msgctl | ||
4083 | {"msgctl", __NR_msgctl}, | ||
4084 | #endif | ||
4085 | #endif | ||
4086 | #ifdef SYS_msgget | ||
4087 | #ifdef __NR_msgget | ||
4088 | {"msgget", __NR_msgget}, | ||
4089 | #endif | ||
4090 | #endif | ||
4091 | #ifdef SYS_msgrcv | ||
4092 | #ifdef __NR_msgrcv | ||
4093 | {"msgrcv", __NR_msgrcv}, | ||
4094 | #endif | ||
4095 | #endif | ||
4096 | #ifdef SYS_msgsnd | ||
4097 | #ifdef __NR_msgsnd | ||
4098 | {"msgsnd", __NR_msgsnd}, | ||
4099 | #endif | ||
4100 | #endif | ||
4101 | #ifdef SYS_msync | ||
4102 | #ifdef __NR_msync | ||
4103 | {"msync", __NR_msync}, | ||
4104 | #endif | ||
4105 | #endif | ||
4106 | #ifdef SYS_munlock | ||
4107 | #ifdef __NR_munlock | ||
4108 | {"munlock", __NR_munlock}, | ||
4109 | #endif | ||
4110 | #endif | ||
4111 | #ifdef SYS_munlockall | ||
4112 | #ifdef __NR_munlockall | ||
4113 | {"munlockall", __NR_munlockall}, | ||
4114 | #endif | ||
4115 | #endif | ||
4116 | #ifdef SYS_munmap | ||
4117 | #ifdef __NR_munmap | ||
4118 | {"munmap", __NR_munmap}, | ||
4119 | #endif | ||
4120 | #endif | ||
4121 | #ifdef SYS_name_to_handle_at | ||
4122 | #ifdef __NR_name_to_handle_at | ||
4123 | {"name_to_handle_at", __NR_name_to_handle_at}, | ||
4124 | #endif | ||
4125 | #endif | ||
4126 | #ifdef SYS_nanosleep | ||
4127 | #ifdef __NR_nanosleep | ||
4128 | {"nanosleep", __NR_nanosleep}, | ||
4129 | #endif | ||
4130 | #endif | ||
4131 | #ifdef SYS_newfstatat | ||
4132 | #ifdef __NR_newfstatat | ||
4133 | {"newfstatat", __NR_newfstatat}, | ||
4134 | #endif | ||
4135 | #endif | ||
4136 | #ifdef SYS_open | ||
4137 | #ifdef __NR_open | ||
4138 | {"open", __NR_open}, | ||
4139 | #endif | ||
4140 | #endif | ||
4141 | #ifdef SYS_open_by_handle_at | ||
4142 | #ifdef __NR_open_by_handle_at | ||
4143 | {"open_by_handle_at", __NR_open_by_handle_at}, | ||
4144 | #endif | ||
4145 | #endif | ||
4146 | #ifdef SYS_openat | ||
4147 | #ifdef __NR_openat | ||
4148 | {"openat", __NR_openat}, | ||
4149 | #endif | ||
4150 | #endif | ||
4151 | #ifdef SYS_pause | ||
4152 | #ifdef __NR_pause | ||
4153 | {"pause", __NR_pause}, | ||
4154 | #endif | ||
4155 | #endif | ||
4156 | #ifdef SYS_perf_event_open | ||
4157 | #ifdef __NR_perf_event_open | ||
4158 | {"perf_event_open", __NR_perf_event_open}, | ||
4159 | #endif | ||
4160 | #endif | ||
4161 | #ifdef SYS_personality | ||
4162 | #ifdef __NR_personality | ||
4163 | {"personality", __NR_personality}, | ||
4164 | #endif | ||
4165 | #endif | ||
4166 | #ifdef SYS_pipe | ||
4167 | #ifdef __NR_pipe | ||
4168 | {"pipe", __NR_pipe}, | ||
4169 | #endif | ||
4170 | #endif | ||
4171 | #ifdef SYS_pipe2 | ||
4172 | #ifdef __NR_pipe2 | ||
4173 | {"pipe2", __NR_pipe2}, | ||
4174 | #endif | ||
4175 | #endif | ||
4176 | #ifdef SYS_pivot_root | ||
4177 | #ifdef __NR_pivot_root | ||
4178 | {"pivot_root", __NR_pivot_root}, | ||
4179 | #endif | ||
4180 | #endif | ||
4181 | #ifdef SYS_poll | ||
4182 | #ifdef __NR_poll | ||
4183 | {"poll", __NR_poll}, | ||
4184 | #endif | ||
4185 | #endif | ||
4186 | #ifdef SYS_ppoll | ||
4187 | #ifdef __NR_ppoll | ||
4188 | {"ppoll", __NR_ppoll}, | ||
4189 | #endif | ||
4190 | #endif | ||
4191 | #ifdef SYS_prctl | ||
4192 | #ifdef __NR_prctl | ||
4193 | {"prctl", __NR_prctl}, | ||
4194 | #endif | ||
4195 | #endif | ||
4196 | #ifdef SYS_pread64 | ||
4197 | #ifdef __NR_pread64 | ||
4198 | {"pread64", __NR_pread64}, | ||
4199 | #endif | ||
4200 | #endif | ||
4201 | #ifdef SYS_preadv | ||
4202 | #ifdef __NR_preadv | ||
4203 | {"preadv", __NR_preadv}, | ||
4204 | #endif | ||
4205 | #endif | ||
4206 | #ifdef SYS_prlimit64 | ||
4207 | #ifdef __NR_prlimit64 | ||
4208 | {"prlimit64", __NR_prlimit64}, | ||
4209 | #endif | ||
4210 | #endif | ||
4211 | #ifdef SYS_process_vm_readv | ||
4212 | #ifdef __NR_process_vm_readv | ||
4213 | {"process_vm_readv", __NR_process_vm_readv}, | ||
4214 | #endif | ||
4215 | #endif | ||
4216 | #ifdef SYS_process_vm_writev | ||
4217 | #ifdef __NR_process_vm_writev | ||
4218 | {"process_vm_writev", __NR_process_vm_writev}, | ||
4219 | #endif | ||
4220 | #endif | ||
4221 | #ifdef SYS_pselect6 | ||
4222 | #ifdef __NR_pselect6 | ||
4223 | {"pselect6", __NR_pselect6}, | ||
4224 | #endif | ||
4225 | #endif | ||
4226 | #ifdef SYS_ptrace | ||
4227 | #ifdef __NR_ptrace | ||
4228 | {"ptrace", __NR_ptrace}, | ||
4229 | #endif | ||
4230 | #endif | ||
4231 | #ifdef SYS_putpmsg | ||
4232 | #ifdef __NR_putpmsg | ||
4233 | {"putpmsg", __NR_putpmsg}, | ||
4234 | #endif | ||
4235 | #endif | ||
4236 | #ifdef SYS_pwrite64 | ||
4237 | #ifdef __NR_pwrite64 | ||
4238 | {"pwrite64", __NR_pwrite64}, | ||
4239 | #endif | ||
4240 | #endif | ||
4241 | #ifdef SYS_pwritev | ||
4242 | #ifdef __NR_pwritev | ||
4243 | {"pwritev", __NR_pwritev}, | ||
4244 | #endif | ||
4245 | #endif | ||
4246 | #ifdef SYS_quotactl | ||
4247 | #ifdef __NR_quotactl | ||
4248 | {"quotactl", __NR_quotactl}, | ||
4249 | #endif | ||
4250 | #endif | ||
4251 | #ifdef SYS_read | ||
4252 | #ifdef __NR_read | ||
4253 | {"read", __NR_read}, | ||
4254 | #endif | ||
4255 | #endif | ||
4256 | #ifdef SYS_readahead | ||
4257 | #ifdef __NR_readahead | ||
4258 | {"readahead", __NR_readahead}, | ||
4259 | #endif | ||
4260 | #endif | ||
4261 | #ifdef SYS_readlink | ||
4262 | #ifdef __NR_readlink | ||
4263 | {"readlink", __NR_readlink}, | ||
4264 | #endif | ||
4265 | #endif | ||
4266 | #ifdef SYS_readlinkat | ||
4267 | #ifdef __NR_readlinkat | ||
4268 | {"readlinkat", __NR_readlinkat}, | ||
4269 | #endif | ||
4270 | #endif | ||
4271 | #ifdef SYS_readv | ||
4272 | #ifdef __NR_readv | ||
4273 | {"readv", __NR_readv}, | ||
4274 | #endif | ||
4275 | #endif | ||
4276 | #ifdef SYS_reboot | ||
4277 | #ifdef __NR_reboot | ||
4278 | {"reboot", __NR_reboot}, | ||
4279 | #endif | ||
4280 | #endif | ||
4281 | #ifdef SYS_recvfrom | ||
4282 | #ifdef __NR_recvfrom | ||
4283 | {"recvfrom", __NR_recvfrom}, | ||
4284 | #endif | ||
4285 | #endif | ||
4286 | #ifdef SYS_recvmmsg | ||
4287 | #ifdef __NR_recvmmsg | ||
4288 | {"recvmmsg", __NR_recvmmsg}, | ||
4289 | #endif | ||
4290 | #endif | ||
4291 | #ifdef SYS_recvmsg | ||
4292 | #ifdef __NR_recvmsg | ||
4293 | {"recvmsg", __NR_recvmsg}, | ||
4294 | #endif | ||
4295 | #endif | ||
4296 | #ifdef SYS_remap_file_pages | ||
4297 | #ifdef __NR_remap_file_pages | ||
4298 | {"remap_file_pages", __NR_remap_file_pages}, | ||
4299 | #endif | ||
4300 | #endif | ||
4301 | #ifdef SYS_removexattr | ||
4302 | #ifdef __NR_removexattr | ||
4303 | {"removexattr", __NR_removexattr}, | ||
4304 | #endif | ||
4305 | #endif | ||
4306 | #ifdef SYS_rename | ||
4307 | #ifdef __NR_rename | ||
4308 | {"rename", __NR_rename}, | ||
4309 | #endif | ||
4310 | #endif | ||
4311 | #ifdef SYS_renameat | ||
4312 | #ifdef __NR_renameat | ||
4313 | {"renameat", __NR_renameat}, | ||
4314 | #endif | ||
4315 | #endif | ||
4316 | #ifdef SYS_request_key | ||
4317 | #ifdef __NR_request_key | ||
4318 | {"request_key", __NR_request_key}, | ||
4319 | #endif | ||
4320 | #endif | ||
4321 | #ifdef SYS_restart_syscall | ||
4322 | #ifdef __NR_restart_syscall | ||
4323 | {"restart_syscall", __NR_restart_syscall}, | ||
4324 | #endif | ||
4325 | #endif | ||
4326 | #ifdef SYS_rmdir | ||
4327 | #ifdef __NR_rmdir | ||
4328 | {"rmdir", __NR_rmdir}, | ||
4329 | #endif | ||
4330 | #endif | ||
4331 | #ifdef SYS_rt_sigaction | ||
4332 | #ifdef __NR_rt_sigaction | ||
4333 | {"rt_sigaction", __NR_rt_sigaction}, | ||
4334 | #endif | ||
4335 | #endif | ||
4336 | #ifdef SYS_rt_sigpending | ||
4337 | #ifdef __NR_rt_sigpending | ||
4338 | {"rt_sigpending", __NR_rt_sigpending}, | ||
4339 | #endif | ||
4340 | #endif | ||
4341 | #ifdef SYS_rt_sigprocmask | ||
4342 | #ifdef __NR_rt_sigprocmask | ||
4343 | {"rt_sigprocmask", __NR_rt_sigprocmask}, | ||
4344 | #endif | ||
4345 | #endif | ||
4346 | #ifdef SYS_rt_sigqueueinfo | ||
4347 | #ifdef __NR_rt_sigqueueinfo | ||
4348 | {"rt_sigqueueinfo", __NR_rt_sigqueueinfo}, | ||
4349 | #endif | ||
4350 | #endif | ||
4351 | #ifdef SYS_rt_sigreturn | ||
4352 | #ifdef __NR_rt_sigreturn | ||
4353 | {"rt_sigreturn", __NR_rt_sigreturn}, | ||
4354 | #endif | ||
4355 | #endif | ||
4356 | #ifdef SYS_rt_sigsuspend | ||
4357 | #ifdef __NR_rt_sigsuspend | ||
4358 | {"rt_sigsuspend", __NR_rt_sigsuspend}, | ||
4359 | #endif | ||
4360 | #endif | ||
4361 | #ifdef SYS_rt_sigtimedwait | ||
4362 | #ifdef __NR_rt_sigtimedwait | ||
4363 | {"rt_sigtimedwait", __NR_rt_sigtimedwait}, | ||
4364 | #endif | ||
4365 | #endif | ||
4366 | #ifdef SYS_rt_tgsigqueueinfo | ||
4367 | #ifdef __NR_rt_tgsigqueueinfo | ||
4368 | {"rt_tgsigqueueinfo", __NR_rt_tgsigqueueinfo}, | ||
4369 | #endif | ||
4370 | #endif | ||
4371 | #ifdef SYS_sched_get_priority_max | ||
4372 | #ifdef __NR_sched_get_priority_max | ||
4373 | {"sched_get_priority_max", __NR_sched_get_priority_max}, | ||
4374 | #endif | ||
4375 | #endif | ||
4376 | #ifdef SYS_sched_get_priority_min | ||
4377 | #ifdef __NR_sched_get_priority_min | ||
4378 | {"sched_get_priority_min", __NR_sched_get_priority_min}, | ||
4379 | #endif | ||
4380 | #endif | ||
4381 | #ifdef SYS_sched_getaffinity | ||
4382 | #ifdef __NR_sched_getaffinity | ||
4383 | {"sched_getaffinity", __NR_sched_getaffinity}, | ||
4384 | #endif | ||
4385 | #endif | ||
4386 | #ifdef SYS_sched_getparam | ||
4387 | #ifdef __NR_sched_getparam | ||
4388 | {"sched_getparam", __NR_sched_getparam}, | ||
4389 | #endif | ||
4390 | #endif | ||
4391 | #ifdef SYS_sched_getscheduler | ||
4392 | #ifdef __NR_sched_getscheduler | ||
4393 | {"sched_getscheduler", __NR_sched_getscheduler}, | ||
4394 | #endif | ||
4395 | #endif | ||
4396 | #ifdef SYS_sched_rr_get_interval | ||
4397 | #ifdef __NR_sched_rr_get_interval | ||
4398 | {"sched_rr_get_interval", __NR_sched_rr_get_interval}, | ||
4399 | #endif | ||
4400 | #endif | ||
4401 | #ifdef SYS_sched_setaffinity | ||
4402 | #ifdef __NR_sched_setaffinity | ||
4403 | {"sched_setaffinity", __NR_sched_setaffinity}, | ||
4404 | #endif | ||
4405 | #endif | ||
4406 | #ifdef SYS_sched_setparam | ||
4407 | #ifdef __NR_sched_setparam | ||
4408 | {"sched_setparam", __NR_sched_setparam}, | ||
4409 | #endif | ||
4410 | #endif | ||
4411 | #ifdef SYS_sched_setscheduler | ||
4412 | #ifdef __NR_sched_setscheduler | ||
4413 | {"sched_setscheduler", __NR_sched_setscheduler}, | ||
4414 | #endif | ||
4415 | #endif | ||
4416 | #ifdef SYS_sched_yield | ||
4417 | #ifdef __NR_sched_yield | ||
4418 | {"sched_yield", __NR_sched_yield}, | ||
4419 | #endif | ||
4420 | #endif | ||
4421 | #ifdef SYS_security | ||
4422 | #ifdef __NR_security | ||
4423 | {"security", __NR_security}, | ||
4424 | #endif | ||
4425 | #endif | ||
4426 | #ifdef SYS_select | ||
4427 | #ifdef __NR_select | ||
4428 | {"select", __NR_select}, | ||
4429 | #endif | ||
4430 | #endif | ||
4431 | #ifdef SYS_semctl | ||
4432 | #ifdef __NR_semctl | ||
4433 | {"semctl", __NR_semctl}, | ||
4434 | #endif | ||
4435 | #endif | ||
4436 | #ifdef SYS_semget | ||
4437 | #ifdef __NR_semget | ||
4438 | {"semget", __NR_semget}, | ||
4439 | #endif | ||
4440 | #endif | ||
4441 | #ifdef SYS_semop | ||
4442 | #ifdef __NR_semop | ||
4443 | {"semop", __NR_semop}, | ||
4444 | #endif | ||
4445 | #endif | ||
4446 | #ifdef SYS_semtimedop | ||
4447 | #ifdef __NR_semtimedop | ||
4448 | {"semtimedop", __NR_semtimedop}, | ||
4449 | #endif | ||
4450 | #endif | ||
4451 | #ifdef SYS_sendfile | ||
4452 | #ifdef __NR_sendfile | ||
4453 | {"sendfile", __NR_sendfile}, | ||
4454 | #endif | ||
4455 | #endif | ||
4456 | #ifdef SYS_sendmmsg | ||
4457 | #ifdef __NR_sendmmsg | ||
4458 | {"sendmmsg", __NR_sendmmsg}, | ||
4459 | #endif | ||
4460 | #endif | ||
4461 | #ifdef SYS_sendmsg | ||
4462 | #ifdef __NR_sendmsg | ||
4463 | {"sendmsg", __NR_sendmsg}, | ||
4464 | #endif | ||
4465 | #endif | ||
4466 | #ifdef SYS_sendto | ||
4467 | #ifdef __NR_sendto | ||
4468 | {"sendto", __NR_sendto}, | ||
4469 | #endif | ||
4470 | #endif | ||
4471 | #ifdef SYS_set_mempolicy | ||
4472 | #ifdef __NR_set_mempolicy | ||
4473 | {"set_mempolicy", __NR_set_mempolicy}, | ||
4474 | #endif | ||
4475 | #endif | ||
4476 | #ifdef SYS_set_robust_list | ||
4477 | #ifdef __NR_set_robust_list | ||
4478 | {"set_robust_list", __NR_set_robust_list}, | ||
4479 | #endif | ||
4480 | #endif | ||
4481 | #ifdef SYS_set_tid_address | ||
4482 | #ifdef __NR_set_tid_address | ||
4483 | {"set_tid_address", __NR_set_tid_address}, | ||
4484 | #endif | ||
4485 | #endif | ||
4486 | #ifdef SYS_setdomainname | ||
4487 | #ifdef __NR_setdomainname | ||
4488 | {"setdomainname", __NR_setdomainname}, | ||
4489 | #endif | ||
4490 | #endif | ||
4491 | #ifdef SYS_setfsgid | ||
4492 | #ifdef __NR_setfsgid | ||
4493 | {"setfsgid", __NR_setfsgid}, | ||
4494 | #endif | ||
4495 | #endif | ||
4496 | #ifdef SYS_setfsuid | ||
4497 | #ifdef __NR_setfsuid | ||
4498 | {"setfsuid", __NR_setfsuid}, | ||
4499 | #endif | ||
4500 | #endif | ||
4501 | #ifdef SYS_setgid | ||
4502 | #ifdef __NR_setgid | ||
4503 | {"setgid", __NR_setgid}, | ||
4504 | #endif | ||
4505 | #endif | ||
4506 | #ifdef SYS_setgroups | ||
4507 | #ifdef __NR_setgroups | ||
4508 | {"setgroups", __NR_setgroups}, | ||
4509 | #endif | ||
4510 | #endif | ||
4511 | #ifdef SYS_sethostname | ||
4512 | #ifdef __NR_sethostname | ||
4513 | {"sethostname", __NR_sethostname}, | ||
4514 | #endif | ||
4515 | #endif | ||
4516 | #ifdef SYS_setitimer | ||
4517 | #ifdef __NR_setitimer | ||
4518 | {"setitimer", __NR_setitimer}, | ||
4519 | #endif | ||
4520 | #endif | ||
4521 | #ifdef SYS_setns | ||
4522 | #ifdef __NR_setns | ||
4523 | {"setns", __NR_setns}, | ||
4524 | #endif | ||
4525 | #endif | ||
4526 | #ifdef SYS_setpgid | ||
4527 | #ifdef __NR_setpgid | ||
4528 | {"setpgid", __NR_setpgid}, | ||
4529 | #endif | ||
4530 | #endif | ||
4531 | #ifdef SYS_setpriority | ||
4532 | #ifdef __NR_setpriority | ||
4533 | {"setpriority", __NR_setpriority}, | ||
4534 | #endif | ||
4535 | #endif | ||
4536 | #ifdef SYS_setregid | ||
4537 | #ifdef __NR_setregid | ||
4538 | {"setregid", __NR_setregid}, | ||
4539 | #endif | ||
4540 | #endif | ||
4541 | #ifdef SYS_setresgid | ||
4542 | #ifdef __NR_setresgid | ||
4543 | {"setresgid", __NR_setresgid}, | ||
4544 | #endif | ||
4545 | #endif | ||
4546 | #ifdef SYS_setresuid | ||
4547 | #ifdef __NR_setresuid | ||
4548 | {"setresuid", __NR_setresuid}, | ||
4549 | #endif | ||
4550 | #endif | ||
4551 | #ifdef SYS_setreuid | ||
4552 | #ifdef __NR_setreuid | ||
4553 | {"setreuid", __NR_setreuid}, | ||
4554 | #endif | ||
4555 | #endif | ||
4556 | #ifdef SYS_setrlimit | ||
4557 | #ifdef __NR_setrlimit | ||
4558 | {"setrlimit", __NR_setrlimit}, | ||
4559 | #endif | ||
4560 | #endif | ||
4561 | #ifdef SYS_setsid | ||
4562 | #ifdef __NR_setsid | ||
4563 | {"setsid", __NR_setsid}, | ||
4564 | #endif | ||
4565 | #endif | ||
4566 | #ifdef SYS_setsockopt | ||
4567 | #ifdef __NR_setsockopt | ||
4568 | {"setsockopt", __NR_setsockopt}, | ||
4569 | #endif | ||
4570 | #endif | ||
4571 | #ifdef SYS_settimeofday | ||
4572 | #ifdef __NR_settimeofday | ||
4573 | {"settimeofday", __NR_settimeofday}, | ||
4574 | #endif | ||
4575 | #endif | ||
4576 | #ifdef SYS_setuid | ||
4577 | #ifdef __NR_setuid | ||
4578 | {"setuid", __NR_setuid}, | ||
4579 | #endif | ||
4580 | #endif | ||
4581 | #ifdef SYS_setxattr | ||
4582 | #ifdef __NR_setxattr | ||
4583 | {"setxattr", __NR_setxattr}, | ||
4584 | #endif | ||
4585 | #endif | ||
4586 | #ifdef SYS_shmat | ||
4587 | #ifdef __NR_shmat | ||
4588 | {"shmat", __NR_shmat}, | ||
4589 | #endif | ||
4590 | #endif | ||
4591 | #ifdef SYS_shmctl | ||
4592 | #ifdef __NR_shmctl | ||
4593 | {"shmctl", __NR_shmctl}, | ||
4594 | #endif | ||
4595 | #endif | ||
4596 | #ifdef SYS_shmdt | ||
4597 | #ifdef __NR_shmdt | ||
4598 | {"shmdt", __NR_shmdt}, | ||
4599 | #endif | ||
4600 | #endif | ||
4601 | #ifdef SYS_shmget | ||
4602 | #ifdef __NR_shmget | ||
4603 | {"shmget", __NR_shmget}, | ||
4604 | #endif | ||
4605 | #endif | ||
4606 | #ifdef SYS_shutdown | ||
4607 | #ifdef __NR_shutdown | ||
4608 | {"shutdown", __NR_shutdown}, | ||
4609 | #endif | ||
4610 | #endif | ||
4611 | #ifdef SYS_sigaltstack | ||
4612 | #ifdef __NR_sigaltstack | ||
4613 | {"sigaltstack", __NR_sigaltstack}, | ||
4614 | #endif | ||
4615 | #endif | ||
4616 | #ifdef SYS_signalfd | ||
4617 | #ifdef __NR_signalfd | ||
4618 | {"signalfd", __NR_signalfd}, | ||
4619 | #endif | ||
4620 | #endif | ||
4621 | #ifdef SYS_signalfd4 | ||
4622 | #ifdef __NR_signalfd4 | ||
4623 | {"signalfd4", __NR_signalfd4}, | ||
4624 | #endif | ||
4625 | #endif | ||
4626 | #ifdef SYS_socket | ||
4627 | #ifdef __NR_socket | ||
4628 | {"socket", __NR_socket}, | ||
4629 | #endif | ||
4630 | #endif | ||
4631 | #ifdef SYS_socketpair | ||
4632 | #ifdef __NR_socketpair | ||
4633 | {"socketpair", __NR_socketpair}, | ||
4634 | #endif | ||
4635 | #endif | ||
4636 | #ifdef SYS_splice | ||
4637 | #ifdef __NR_splice | ||
4638 | {"splice", __NR_splice}, | ||
4639 | #endif | ||
4640 | #endif | ||
4641 | #ifdef SYS_stat | ||
4642 | #ifdef __NR_stat | ||
4643 | {"stat", __NR_stat}, | ||
4644 | #endif | ||
4645 | #endif | ||
4646 | #ifdef SYS_statfs | ||
4647 | #ifdef __NR_statfs | ||
4648 | {"statfs", __NR_statfs}, | ||
4649 | #endif | ||
4650 | #endif | ||
4651 | #ifdef SYS_swapoff | ||
4652 | #ifdef __NR_swapoff | ||
4653 | {"swapoff", __NR_swapoff}, | ||
4654 | #endif | ||
4655 | #endif | ||
4656 | #ifdef SYS_swapon | ||
4657 | #ifdef __NR_swapon | ||
4658 | {"swapon", __NR_swapon}, | ||
4659 | #endif | ||
4660 | #endif | ||
4661 | #ifdef SYS_symlink | ||
4662 | #ifdef __NR_symlink | ||
4663 | {"symlink", __NR_symlink}, | ||
4664 | #endif | ||
4665 | #endif | ||
4666 | #ifdef SYS_symlinkat | ||
4667 | #ifdef __NR_symlinkat | ||
4668 | {"symlinkat", __NR_symlinkat}, | ||
4669 | #endif | ||
4670 | #endif | ||
4671 | #ifdef SYS_sync | ||
4672 | #ifdef __NR_sync | ||
4673 | {"sync", __NR_sync}, | ||
4674 | #endif | ||
4675 | #endif | ||
4676 | #ifdef SYS_sync_file_range | ||
4677 | #ifdef __NR_sync_file_range | ||
4678 | {"sync_file_range", __NR_sync_file_range}, | ||
4679 | #endif | ||
4680 | #endif | ||
4681 | #ifdef SYS_syncfs | ||
4682 | #ifdef __NR_syncfs | ||
4683 | {"syncfs", __NR_syncfs}, | ||
4684 | #endif | ||
4685 | #endif | ||
4686 | #ifdef SYS_sysfs | ||
4687 | #ifdef __NR_sysfs | ||
4688 | {"sysfs", __NR_sysfs}, | ||
4689 | #endif | ||
4690 | #endif | ||
4691 | #ifdef SYS_sysinfo | ||
4692 | #ifdef __NR_sysinfo | ||
4693 | {"sysinfo", __NR_sysinfo}, | ||
4694 | #endif | ||
4695 | #endif | ||
4696 | #ifdef SYS_syslog | ||
4697 | #ifdef __NR_syslog | ||
4698 | {"syslog", __NR_syslog}, | ||
4699 | #endif | ||
4700 | #endif | ||
4701 | #ifdef SYS_tee | ||
4702 | #ifdef __NR_tee | ||
4703 | {"tee", __NR_tee}, | ||
4704 | #endif | ||
4705 | #endif | ||
4706 | #ifdef SYS_tgkill | ||
4707 | #ifdef __NR_tgkill | ||
4708 | {"tgkill", __NR_tgkill}, | ||
4709 | #endif | ||
4710 | #endif | ||
4711 | #ifdef SYS_time | ||
4712 | #ifdef __NR_time | ||
4713 | {"time", __NR_time}, | ||
4714 | #endif | ||
4715 | #endif | ||
4716 | #ifdef SYS_timer_create | ||
4717 | #ifdef __NR_timer_create | ||
4718 | {"timer_create", __NR_timer_create}, | ||
4719 | #endif | ||
4720 | #endif | ||
4721 | #ifdef SYS_timer_delete | ||
4722 | #ifdef __NR_timer_delete | ||
4723 | {"timer_delete", __NR_timer_delete}, | ||
4724 | #endif | ||
4725 | #endif | ||
4726 | #ifdef SYS_timer_getoverrun | ||
4727 | #ifdef __NR_timer_getoverrun | ||
4728 | {"timer_getoverrun", __NR_timer_getoverrun}, | ||
4729 | #endif | ||
4730 | #endif | ||
4731 | #ifdef SYS_timer_gettime | ||
4732 | #ifdef __NR_timer_gettime | ||
4733 | {"timer_gettime", __NR_timer_gettime}, | ||
4734 | #endif | ||
4735 | #endif | ||
4736 | #ifdef SYS_timer_settime | ||
4737 | #ifdef __NR_timer_settime | ||
4738 | {"timer_settime", __NR_timer_settime}, | ||
4739 | #endif | ||
4740 | #endif | ||
4741 | #ifdef SYS_timerfd_create | ||
4742 | #ifdef __NR_timerfd_create | ||
4743 | {"timerfd_create", __NR_timerfd_create}, | ||
4744 | #endif | ||
4745 | #endif | ||
4746 | #ifdef SYS_timerfd_gettime | ||
4747 | #ifdef __NR_timerfd_gettime | ||
4748 | {"timerfd_gettime", __NR_timerfd_gettime}, | ||
4749 | #endif | ||
4750 | #endif | ||
4751 | #ifdef SYS_timerfd_settime | ||
4752 | #ifdef __NR_timerfd_settime | ||
4753 | {"timerfd_settime", __NR_timerfd_settime}, | ||
4754 | #endif | ||
4755 | #endif | ||
4756 | #ifdef SYS_times | ||
4757 | #ifdef __NR_times | ||
4758 | {"times", __NR_times}, | ||
4759 | #endif | ||
4760 | #endif | ||
4761 | #ifdef SYS_tkill | ||
4762 | #ifdef __NR_tkill | ||
4763 | {"tkill", __NR_tkill}, | ||
4764 | #endif | ||
4765 | #endif | ||
4766 | #ifdef SYS_truncate | ||
4767 | #ifdef __NR_truncate | ||
4768 | {"truncate", __NR_truncate}, | ||
4769 | #endif | ||
4770 | #endif | ||
4771 | #ifdef SYS_tuxcall | ||
4772 | #ifdef __NR_tuxcall | ||
4773 | {"tuxcall", __NR_tuxcall}, | ||
4774 | #endif | ||
4775 | #endif | ||
4776 | #ifdef SYS_umask | ||
4777 | #ifdef __NR_umask | ||
4778 | {"umask", __NR_umask}, | ||
4779 | #endif | ||
4780 | #endif | ||
4781 | #ifdef SYS_umount2 | ||
4782 | #ifdef __NR_umount2 | ||
4783 | {"umount2", __NR_umount2}, | ||
4784 | #endif | ||
4785 | #endif | ||
4786 | #ifdef SYS_uname | ||
4787 | #ifdef __NR_uname | ||
4788 | {"uname", __NR_uname}, | ||
4789 | #endif | ||
4790 | #endif | ||
4791 | #ifdef SYS_unlink | ||
4792 | #ifdef __NR_unlink | ||
4793 | {"unlink", __NR_unlink}, | ||
4794 | #endif | ||
4795 | #endif | ||
4796 | #ifdef SYS_unlinkat | ||
4797 | #ifdef __NR_unlinkat | ||
4798 | {"unlinkat", __NR_unlinkat}, | ||
4799 | #endif | ||
4800 | #endif | ||
4801 | #ifdef SYS_unshare | ||
4802 | #ifdef __NR_unshare | ||
4803 | {"unshare", __NR_unshare}, | ||
4804 | #endif | ||
4805 | #endif | ||
4806 | #ifdef SYS_ustat | ||
4807 | #ifdef __NR_ustat | ||
4808 | {"ustat", __NR_ustat}, | ||
4809 | #endif | ||
4810 | #endif | ||
4811 | #ifdef SYS_utime | ||
4812 | #ifdef __NR_utime | ||
4813 | {"utime", __NR_utime}, | ||
4814 | #endif | ||
4815 | #endif | ||
4816 | #ifdef SYS_utimensat | ||
4817 | #ifdef __NR_utimensat | ||
4818 | {"utimensat", __NR_utimensat}, | ||
4819 | #endif | ||
4820 | #endif | ||
4821 | #ifdef SYS_utimes | ||
4822 | #ifdef __NR_utimes | ||
4823 | {"utimes", __NR_utimes}, | ||
4824 | #endif | ||
4825 | #endif | ||
4826 | #ifdef SYS_vfork | ||
4827 | #ifdef __NR_vfork | ||
4828 | {"vfork", __NR_vfork}, | ||
4829 | #endif | ||
4830 | #endif | ||
4831 | #ifdef SYS_vhangup | ||
4832 | #ifdef __NR_vhangup | ||
4833 | {"vhangup", __NR_vhangup}, | ||
4834 | #endif | ||
4835 | #endif | ||
4836 | #ifdef SYS_vmsplice | ||
4837 | #ifdef __NR_vmsplice | ||
4838 | {"vmsplice", __NR_vmsplice}, | ||
4839 | #endif | ||
4840 | #endif | ||
4841 | #ifdef SYS_wait4 | ||
4842 | #ifdef __NR_wait4 | ||
4843 | {"wait4", __NR_wait4}, | ||
4844 | #endif | ||
4845 | #endif | ||
4846 | #ifdef SYS_waitid | ||
4847 | #ifdef __NR_waitid | ||
4848 | {"waitid", __NR_waitid}, | ||
4849 | #endif | ||
4850 | #endif | ||
4851 | #ifdef SYS_write | ||
4852 | #ifdef __NR_write | ||
4853 | {"write", __NR_write}, | ||
4854 | #endif | ||
4855 | #endif | ||
4856 | #ifdef SYS_writev | ||
4857 | #ifdef __NR_writev | ||
4858 | {"writev", __NR_writev}, | ||
4859 | #endif | ||
4860 | #endif | ||
4861 | #endif | ||
4862 | |||
4863 | // | ||
4864 | // end of generated code | ||
4865 | // | ||
4866 | }; // end of syslist | ||
4867 | |||
4868 | const char *syscall_find_nr(int nr) { | ||
4869 | int i; | ||
4870 | int elems = sizeof(syslist) / sizeof(syslist[0]); | ||
4871 | for (i = 0; i < elems; i++) { | ||
4872 | if (nr == syslist[i].nr) | ||
4873 | return syslist[i].name; | ||
4874 | } | ||
4875 | |||
4876 | return "unknown"; | ||
4877 | } | ||
4878 | |||
4879 | // return -1 if error, or syscall number | ||
4880 | static int syscall_find_name(const char *name) { | ||
4881 | int i; | ||
4882 | int elems = sizeof(syslist) / sizeof(syslist[0]); | ||
4883 | for (i = 0; i < elems; i++) { | ||
4884 | if (strcmp(name, syslist[i].name) == 0) | ||
4885 | return syslist[i].nr; | ||
4886 | } | ||
4887 | |||
4888 | return -1; | ||
4889 | } | ||
4890 | |||
4891 | // return 1 if error, 0 if OK | ||
4892 | int syscall_check_list(const char *slist, void (*callback)(int)) { | ||
4893 | // don't allow empty lists | ||
4894 | if (slist == NULL || *slist == '\0') { | ||
4895 | fprintf(stderr, "Error: empty syscall lists are not allowed\n"); | ||
4896 | return -1; | ||
4897 | } | ||
4898 | |||
4899 | // work on a copy of the string | ||
4900 | char *str = strdup(slist); | ||
4901 | if (!str) | ||
4902 | errExit("strdup"); | ||
4903 | |||
4904 | char *ptr = str; | ||
4905 | char *start = str; | ||
4906 | while (*ptr != '\0') { | ||
4907 | if (islower(*ptr) || isdigit(*ptr) || *ptr == '_') | ||
4908 | ; | ||
4909 | else if (*ptr == ',') { | ||
4910 | *ptr = '\0'; | ||
4911 | int nr = syscall_find_name(start); | ||
4912 | if (nr == -1) | ||
4913 | fprintf(stderr, "Warning: syscall %s not found\n", start); | ||
4914 | else if (callback != NULL) | ||
4915 | callback(nr); | ||
4916 | |||
4917 | start = ptr + 1; | ||
4918 | } | ||
4919 | ptr++; | ||
4920 | } | ||
4921 | if (*start != '\0') { | ||
4922 | int nr = syscall_find_name(start); | ||
4923 | if (nr == -1) | ||
4924 | fprintf(stderr, "Warning: syscall %s not found\n", start); | ||
4925 | else if (callback != NULL) | ||
4926 | callback(nr); | ||
4927 | } | ||
4928 | |||
4929 | free(str); | ||
4930 | return 0; | ||
4931 | } | ||
4932 | |||
4933 | void syscall_print(void) { | ||
4934 | int i; | ||
4935 | int elems = sizeof(syslist) / sizeof(syslist[0]); | ||
4936 | for (i = 0; i < elems; i++) { | ||
4937 | printf("%d\t- %s\n", syslist[i].nr, syslist[i].name); | ||
4938 | } | ||
4939 | printf("\n"); | ||
4940 | } | ||
4941 | |||
4942 | #endif // HAVE_SECCOMP | ||
diff --git a/src/firejail/usage.c b/src/firejail/usage.c new file mode 100644 index 000000000..71ae203ff --- /dev/null +++ b/src/firejail/usage.c | |||
@@ -0,0 +1,312 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | |||
22 | void usage(void) { | ||
23 | printf("firejail - version %s\n\n", VERSION); | ||
24 | printf("Firejail is a SUID sandbox program that reduces the risk of security breaches by\n"); | ||
25 | printf("restricting the running environment of untrusted applications using Linux\n"); | ||
26 | printf("namespaces. It includes a sandbox profile for Mozilla Firefox.\n\n"); | ||
27 | printf("\n"); | ||
28 | printf("Usage: firejail [options] [program and arguments]\n\n"); | ||
29 | printf("\n"); | ||
30 | printf("Without any options, the sandbox consists of a filesystem chroot build from the\n"); | ||
31 | printf("current system directories mounted read-only, and new PID and IPC\n"); | ||
32 | printf("namespaces. If no program is specified as an argument, /bin/bash is started by\n"); | ||
33 | printf("default in the sandbox.\n\n"); | ||
34 | printf("\n"); | ||
35 | printf("Options:\n\n"); | ||
36 | printf("\t-- - signal the end of options and disables further option processing.\n\n"); | ||
37 | printf("\t--bandwidth=name - set bandwidth limits for the sandbox identified\n"); | ||
38 | printf("\t\tby name, see Traffic Shaping section for more details.\n\n"); | ||
39 | printf("\t--bandwidth=pid - set bandwidth limits for the sandbox identified\n"); | ||
40 | printf("\t\tby PID, see Traffic Shaping section for more details.\n\n"); | ||
41 | #ifdef HAVE_BIND | ||
42 | printf("\t--bind=dirname1,dirname2 - mount-bind dirname1 on top of dirname2.\n\n"); | ||
43 | printf("\t--bind=filename1,dirname2 - mount-bind filename1 on top of filename2.\n\n"); | ||
44 | #endif | ||
45 | printf("\t--blacklist=dirname_or_filename - blacklist directory or file.\n\n"); | ||
46 | printf("\t-c - execute command and exit.\n\n"); | ||
47 | printf("\t--caps - enable default Linux capabilities filter. The filter disables\n"); | ||
48 | printf("\t\tCAP_SYS_MODULE, CAP_SYS_RAWIO, CAP_SYS_BOOT, CAP_SYS_NICE,\n"); | ||
49 | printf("\t\tCAP_SYS_TTY_CONFIG, CAP_SYSLOG, CAP_MKNOD, CAP_SYS_ADMIN.\n\n"); | ||
50 | printf("\t--caps.drop=all - drop all capabilities.\n\n"); | ||
51 | printf("\t--caps.drop=capability,capability,capability - blacklist Linux\n"); | ||
52 | printf("\t\tcapabilities filter.\n\n"); | ||
53 | printf("\t--caps.keep=capability,capability,capability - whitelist Linux\n"); | ||
54 | printf("\t\tcapabilities filter.\n\n"); | ||
55 | printf("\t--caps.print=name - print the caps filter for the sandbox identified\n"); | ||
56 | printf("\t\tby name.\n\n"); | ||
57 | printf("\t--caps.print=pid - print the caps filter for the sandbox identified\n"); | ||
58 | printf("\t\tby PID.\n\n"); | ||
59 | printf("\t--cgroup=tasks-file - place the sandbox in the specified control group.\n"); | ||
60 | printf("\t\ttasks-file is the full path of cgroup tasks file.\n"); | ||
61 | printf("\t\tExample: --cgroup=/sys/fs/cgroup/g1/tasks\n\n"); | ||
62 | #ifdef HAVE_CHROOT | ||
63 | printf("\t--chroot=dirname - chroot into dirname directory.\n\n"); | ||
64 | #endif | ||
65 | printf("\t--cpu=cpu-number,cpu-number - set cpu affinity.\n"); | ||
66 | printf("\t\tExample: cpu=0,1,2\n\n"); | ||
67 | printf("\t--csh - use /bin/csh as default shell.\n\n"); | ||
68 | printf("\t--debug - print sandbox debug messages.\n\n"); | ||
69 | printf("\t--debug-syscalls - print all recognized system calls in the current\n"); | ||
70 | printf("\t\tFirejail software build and exit.\n\n"); | ||
71 | printf("\t--debug-caps - print all recognized capabilities in the current\n"); | ||
72 | printf("\t\tFirejail software build and exit.\n\n"); | ||
73 | printf("\t--defaultgw=address - use this address as default gateway in the new\n"); | ||
74 | printf("\t\tnetwork namespace.\n\n"); | ||
75 | printf("\t--dns=address - set a DNS server for the sandbox. Up to three DNS\n"); | ||
76 | printf("\t\tservers can be defined.\n\n"); | ||
77 | printf("\t--dns.print=name - print DNS configuration for the sandbox identified\n"); | ||
78 | printf("\t\tby name.\n\n"); | ||
79 | printf("\t--dns.print=pid - print DNS configuration of the sandbox identified.\n"); | ||
80 | printf("\t\tby PID.\n\n"); | ||
81 | printf("\t--help, -? - this help screen.\n\n"); | ||
82 | printf("\t--ip=address - set interface IP address.\n\n"); | ||
83 | printf("\t--ip=none - no IP address and no default gateway address are configured\n"); | ||
84 | printf("\t\tin the new network namespace. Use this option in case you intend\n"); | ||
85 | printf("\t\tto start an external DHCP client in the sandbox.\n\n"); | ||
86 | printf("\t--iprange=address,address - configure an IP address in this range\n\n"); | ||
87 | printf("\t--ipc-namespace - enable a new IPC namespace if the sandbox was started\n"); | ||
88 | printf("\t\tas a regular user. IPC namespace is enabled by default only if\n"); | ||
89 | printf("\t\tthe sandbox is started as root.\n\n"); | ||
90 | printf("\t--join=name - join the sandbox identified by name.\n\n"); | ||
91 | printf("\t--join=pid - join the sandbox identified by PID.\n\n"); | ||
92 | printf("\t--list - list all sandboxes.\n\n"); | ||
93 | printf("\t--mac=xx:xx:xx:xx:xx:xx - set interface MAC address.\n\n"); | ||
94 | printf("\t--name=name - set sandbox hostname.\n\n"); | ||
95 | printf("\t--net=bridgename - enable network namespaces and connect to this bridge\n"); | ||
96 | printf("\t\tdevice. Unless specified with option --ip and --defaultgw, an\n"); | ||
97 | printf("\t\tIP address and a default gateway will be assigned automatically\n"); | ||
98 | printf("\t\tto the sandbox. The IP address is checked using ARP before\n"); | ||
99 | printf("\t\tassignment. The IP address assigned as default gateway is the\n"); | ||
100 | printf("\t\tbridge device IP address. Up to four --net devices can\n"); | ||
101 | printf("\t\tbe defined. Mixing bridge and macvlan devices is allowed.\n\n"); | ||
102 | printf("\t--net=ethernet_interface - enable network namespaces and connect\n"); | ||
103 | printf("\t\tto this ethernet_interface using the standard Linux macvlan\n"); | ||
104 | printf("\t\tdriver. Unless specified with option --ip and --defaultgw, an\n"); | ||
105 | printf("\t\tIP address and a default gateway will be assigned automatically\n"); | ||
106 | printf("\t\tto the sandbox. The IP address is checked using ARP before\n"); | ||
107 | printf("\t\tassignment. The IP address assigned as default gateway is the\n"); | ||
108 | printf("\t\tdefault gateway of the host. Up to four --net devices can\n"); | ||
109 | printf("\t\tbe defined. Mixing bridge and macvlan devices is allowed.\n\n"); | ||
110 | printf("\t--net=none - enable a new, unconnected network namespace.\n\n"); | ||
111 | |||
112 | printf("\t--netfilter - enable the default client network filter in the new\n"); | ||
113 | printf("\t\tnetwork namespace:\n\n"); | ||
114 | printf("\t\t*filter\n"); | ||
115 | printf("\t\t:INPUT DROP [0:0]\n"); | ||
116 | printf("\t\t:FORWARD DROP [0:0]\n"); | ||
117 | printf("\t\t:OUTPUT ACCEPT [0:0]\n"); | ||
118 | printf("\t\t-A INPUT -i lo -j ACCEPT\n"); | ||
119 | printf("\t\t-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); | ||
120 | printf("\t\t-A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT\n"); | ||
121 | printf("\t\t-A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT\n"); | ||
122 | printf("\t\t-A INPUT -p icmp --icmp-type echo-request -j ACCEPT \n"); | ||
123 | printf("\t\tCOMMIT\n\n"); | ||
124 | printf("\t--netfilter=filename - enable the network filter specified by\n"); | ||
125 | printf("\t\tfilename in the new network namespace. The filter file format\n"); | ||
126 | printf("\t\tis the format of iptables-save and iptable-restore commands.\n\n"); | ||
127 | |||
128 | printf("\t--netstats - monitor network statistics for sandboxes creating a new\n"); | ||
129 | printf("\t\tnetwork namespace.\n\n"); | ||
130 | printf("\t--nogroups - disable supplementary groups. Without this option,\n"); | ||
131 | printf("\t\tsupplementary groups are enabled for the user starting the\n"); | ||
132 | printf("\t\tsandbox. For root user supplementary groups are always\n"); | ||
133 | printf("\t\tdisabled.\n\n"); | ||
134 | |||
135 | printf("\t--noroot - install a user namespace with a single user - the current\n"); | ||
136 | printf("\t\tuser. root user does not exist in the new namespace. This option\n"); | ||
137 | printf("\t\tis not supported for --chroot and --overlay configurations.\n\n"); | ||
138 | |||
139 | printf("\t--output=logfile - stdout logging and log rotation. Copy stdout to\n"); | ||
140 | printf("\t\tlogfile, and keep the size of the file under 500KB using log\n"); | ||
141 | printf("\t\trotation. Five files with prefixes .1 to .5 are used in\n"); | ||
142 | printf("\t\trotation.\n\n"); | ||
143 | printf("\t--overlay - mount a filesystem overlay on top of the current filesystem.\n"); | ||
144 | printf("\t\t(OverlayFS support is required in Linux kernel for this option\n"); | ||
145 | printf("\t\tto work)\n\n"); | ||
146 | |||
147 | printf("\t--private - mount new /root and /home/user directories in temporary\n"); | ||
148 | printf("\t\tfilesystems. All modifications are discarded when the sandbox is\n"); | ||
149 | printf("\t\tclosed.\n\n"); | ||
150 | printf("\t--private=directory - use directory as user home.\n\n"); | ||
151 | printf("\t--private.keep=file,directory - build a new user home in a temporary\n"); | ||
152 | printf("\t\tfilesystem, and copy the files and directories in the list in\n"); | ||
153 | printf("\t\tthe new home. All modifications are discarded when the sandbox\n"); | ||
154 | printf("\t\tis closed.\n\n"); | ||
155 | printf("\t--private-dev - create a new /dev directory. Only null, full, zero, tty,\n"); | ||
156 | printf("\t\tpst, ptms, random, urandom and shm devices are available.\n\n"); | ||
157 | |||
158 | printf("\t--profile=filename - use a custom profile.\n\n"); | ||
159 | printf("\t--read-only=dirname_or_filename - set directory or file read-only.\n\n"); | ||
160 | printf("\t--rlimit-fsize=number - set the maximum file size that can be created\n"); | ||
161 | printf("\t\tby a process.\n\n"); | ||
162 | printf("\t--rlimit-nofile=number - set the maximum number of files that can be\n"); | ||
163 | printf("\t\topened by a process.\n\n"); | ||
164 | printf("\t--rlimit-nproc=number - set the maximum number of processes that can be\n"); | ||
165 | printf("\t\tcreated for the real user ID of the calling process.\n\n"); | ||
166 | printf("\t--rlimit-sigpending=number - set the maximum number of pending signals\n"); | ||
167 | printf("\t\tfor a process.\n\n"); | ||
168 | |||
169 | printf("\t--scan - ARP-scan all the networks from inside a network namespace.\n"); | ||
170 | printf("\t\tThis makes it possible to detect macvlan kernel device drivers\n"); | ||
171 | printf("\t\trunning on the current host.\n\n"); | ||
172 | |||
173 | #ifdef HAVE_SECCOMP | ||
174 | printf("\t--seccomp - enable seccomp filter and blacklist the syscalls in the\n"); | ||
175 | printf("\t\tlist. The default list is as follows: mount, umount2,\n"); | ||
176 | printf("\t\tptrace, kexec_load, open_by_handle_at, init_module,\n"); | ||
177 | printf("\t\tfinit_module, delete_module, iopl, ioperm, swapon, swapoff,\n"); | ||
178 | printf("\t\tmknode, syslog, process_vm_readv and process_vm_writev\n"); | ||
179 | printf("\t\tsysfs,_sysctl, adjtimex, clock_adjtime, lookup_dcookie,\n"); | ||
180 | printf("\t\tperf_event_open, fanotify_init and kcmp.\n\n"); | ||
181 | |||
182 | printf("\t--seccomp=syscall,syscall,syscall - enable seccomp filter, blacklist the\n"); | ||
183 | printf("\t\tdefault syscall list and the syscalls specified by the command.\n\n"); | ||
184 | |||
185 | printf("\t--seccomp.drop=syscall,syscall,syscall - enable seccomp filter, and\n"); | ||
186 | printf("\t\tblacklist the syscalls specified by the command.\n\n"); | ||
187 | |||
188 | printf("\t--seccomp.keep=syscall,syscall,syscall - enable seccomp filter, and\n"); | ||
189 | printf("\t\twhitelist the syscalls specified by the command.\n\n"); | ||
190 | |||
191 | printf("\t--seccomp.print=name - print the seccomp filter for the sandbox\n"); | ||
192 | printf("\t\tidentified by name.\n\n"); | ||
193 | printf("\t--seccomp.print=pid - print the seccomp filter for the sandbox\n"); | ||
194 | printf("\t\tidentified by PID.\n\n"); | ||
195 | #endif | ||
196 | |||
197 | printf("\t--shell=none - run the program directly without a user shell.\n\n"); | ||
198 | printf("\t--shell=program - set default user shell.\n\n"); | ||
199 | printf("\t--shutdown=name - shutdown the sandbox identified by name.\n\n"); | ||
200 | printf("\t--shutdown=pid - shutdown the sandbox identified by PID.\n\n"); | ||
201 | printf("\t--tmpfs=dirname - mount a tmpfs filesystem on directory dirname.\n\n"); | ||
202 | printf("\t--top - monitor the most CPU-intensive sandboxes.\n\n"); | ||
203 | printf("\t--trace - trace open, access and connect system calls.\n\n"); | ||
204 | printf("\t--tree - print a tree of all sandboxed processes.\n\n"); | ||
205 | printf("\t--version - print program version and exit.\n\n"); | ||
206 | printf("\t--zsh - use /usr/bin/zsh as default shell.\n\n"); | ||
207 | printf("\n"); | ||
208 | printf("\n"); | ||
209 | |||
210 | |||
211 | printf("Traffic Shaping\n\n"); | ||
212 | |||
213 | printf("Network bandwidth is an expensive resource shared among all sandboxes\n"); | ||
214 | printf("running on a system. Traffic shaping allows the user to increase network\n"); | ||
215 | printf("performance by controlling the amount of data that flows into and out of the\n"); | ||
216 | printf("sandboxes. Firejail implements a simple rate-limiting shaper based on Linux\n"); | ||
217 | printf("command tc. The shaper works at sandbox level, and can be used only for\n"); | ||
218 | printf("sandboxes configured with new network namespaces.\n\n"); | ||
219 | |||
220 | printf("Set rate-limits:\n"); | ||
221 | printf("\tfirejail --bandwidth={name|pid} set network-name down-speed up-speed\n\n"); | ||
222 | printf("Clear rate-limits:\n"); | ||
223 | printf("\tfirejail --bandwidth={name|pid} clear network-name\n\n"); | ||
224 | printf("Status:\n"); | ||
225 | printf("\tfirejail --bandwidth={name|pid} status\n\n"); | ||
226 | printf("where:\n"); | ||
227 | printf("\tname - sandbox name\n"); | ||
228 | printf("\tpid - sandbox pid\n"); | ||
229 | printf("\tnetwork-name - network name as used by --net option\n"); | ||
230 | printf("\tdown-speed - download speed in KB/s (decimal kilobyte per second)\n"); | ||
231 | printf("\tup-speed - upload speed in KB/s (decimal kilobyte per second)\n"); | ||
232 | printf("\n"); | ||
233 | printf("Example:\n"); | ||
234 | printf("\t$ firejail --name=mybrowser --net=eth0 firefox &\n"); | ||
235 | printf("\t$ firejail --bandwidth=mybrowser set eth0 80 20\n"); | ||
236 | printf("\t$ firejail --bandwidth=mybrowser status\n"); | ||
237 | printf("\t$ firejail --bandwidth=mybrowser clear eth0\n"); | ||
238 | printf("\n"); | ||
239 | printf("\n"); | ||
240 | |||
241 | |||
242 | |||
243 | printf("Monitoring\n\n"); | ||
244 | |||
245 | printf("Option --list prints a list of all sandboxes. The format for each entry is as\n"); | ||
246 | printf("follows:\n\n"); | ||
247 | printf("\tPID:USER:Command\n\n"); | ||
248 | |||
249 | printf("Option --tree prints the tree of processes running in the sandbox. The format\n"); | ||
250 | printf("for each process entry is as follows:\n\n"); | ||
251 | printf("\tPID:USER:Command\n\n"); | ||
252 | |||
253 | printf("Option --top is similar to the UNIX top command, however it applies only to\n"); | ||
254 | printf("sandboxes. Listed below are the available fields (columns) in alphabetical\n"); | ||
255 | printf("order:\n\n"); | ||
256 | printf("\tCommand - command used to start the sandbox.\n"); | ||
257 | printf("\tCPU%% - CPU usage, the sandbox share of the elapsed CPU time since the\n"); | ||
258 | printf("\t last screen update\n"); | ||
259 | printf("\tPID - Unique process ID for the task controlling the sandbox.\n"); | ||
260 | printf("\tPrcs - number of processes running in sandbox, including the controlling\n"); | ||
261 | printf("\t process.\n"); | ||
262 | printf("\tRES - Resident Memory Size (KiB), sandbox non-swapped physical memory.\n"); | ||
263 | printf("\t It is a sum of the RES values for all processes running in the\n"); | ||
264 | printf("\t sandbox.\n"); | ||
265 | printf("\tSHR - Shared Memory Size (KiB), it reflects memory shared with other\n"); | ||
266 | printf("\t processes. It is a sum of the SHR values for all processes running\n"); | ||
267 | printf("\t in the sandbox, including the controlling process.\n"); | ||
268 | printf("\tUptime - sandbox running time in hours:minutes:seconds format.\n"); | ||
269 | printf("\tUser - The owner of the sandbox.\n"); | ||
270 | printf("\n"); | ||
271 | printf("\n"); | ||
272 | printf("Profile files\n\n"); | ||
273 | printf("Several command line configuration options can be passed to the program using\n"); | ||
274 | printf("profile files. Default Firejail profile files are stored in /etc/firejail\n"); | ||
275 | printf("directory, user profile files are stored in ~/.config/firejail directory. See\n"); | ||
276 | printf("man 5 firejail-profile for more information.\n\n"); | ||
277 | printf("\n"); | ||
278 | printf("Restricted shell\n\n"); | ||
279 | printf("To configure a restricted shell, replace /bin/bash with /usr/bin/firejail i\n"); | ||
280 | printf("/etc/password file for each user that needs to be restricted.\n"); | ||
281 | printf("Alternatively, you can specify /usr/bin/firejail in adduser command:\n\n"); | ||
282 | printf(" adduser --shell /usr/bin/firejail username\n\n"); | ||
283 | printf("Arguments to be passed to firejail executable upon login are declared in\n"); | ||
284 | printf("/etc/firejail/login.users file.\n\n"); | ||
285 | printf("\n"); | ||
286 | printf("Examples:\n\n"); | ||
287 | printf(" $ firejail\n"); | ||
288 | printf(" start a regular /bin/bash session in sandbox\n"); | ||
289 | printf(" $ firejail firefox\n"); | ||
290 | printf(" start Mozilla Firefox\n"); | ||
291 | printf(" $ firejail --seccomp firefox\n"); | ||
292 | printf(" start Mozilla Firefox in a seccomp sandbox\n"); | ||
293 | printf(" $ firejail --caps firefox\n"); | ||
294 | printf(" start Mozilla Firefox in a Linux capabilities sandbox\n"); | ||
295 | printf(" $ firejail --debug firefox\n"); | ||
296 | printf(" debug Firefox sandbox\n"); | ||
297 | printf(" $ firejail --private\n"); | ||
298 | printf(" start a /bin/bash session with a new tmpfs home directory\n"); | ||
299 | printf(" $ firejail --net=br0 ip=10.10.20.10\n"); | ||
300 | printf(" start a /bin/bash session in a new network namespace; the session is\n"); | ||
301 | printf(" connected to the main network using br0 bridge device, an IP address\n"); | ||
302 | printf(" of 10.10.20.10 is assigned to the sandbox\n"); | ||
303 | printf(" $ firejail --net=br0 --net=br1 --net=br2\n"); | ||
304 | printf(" start a /bin/bash session in a new network namespace and connect it\n"); | ||
305 | printf(" to br0, br1, and br2 host bridge devices\n"); | ||
306 | printf(" $ firejail --list\n"); | ||
307 | printf(" list all running sandboxes\n"); | ||
308 | printf("\n"); | ||
309 | printf("License GPL version 2 or later\n"); | ||
310 | printf("Homepage: http://firejail.sourceforge.net\n"); | ||
311 | printf("\n"); | ||
312 | } | ||
diff --git a/src/firejail/util.c b/src/firejail/util.c new file mode 100644 index 000000000..2c50caf17 --- /dev/null +++ b/src/firejail/util.c | |||
@@ -0,0 +1,480 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/stat.h> | ||
22 | #include <fcntl.h> | ||
23 | #include <syslog.h> | ||
24 | #include <errno.h> | ||
25 | #include <dirent.h> | ||
26 | #include <grp.h> | ||
27 | |||
28 | #define MAX_GROUPS 1024 | ||
29 | // drop privileges | ||
30 | // - for root group or if nogroups is set, supplementary groups are not configured | ||
31 | void drop_privs(int nogroups) { | ||
32 | gid_t gid = getgid(); | ||
33 | |||
34 | // configure supplementary groups | ||
35 | if (gid == 0 || nogroups) { | ||
36 | if (setgroups(0, NULL) < 0) | ||
37 | errExit("setgroups"); | ||
38 | if (arg_debug) | ||
39 | printf("Username %s, no supplementary groups\n", cfg.username); | ||
40 | } | ||
41 | else { | ||
42 | assert(cfg.username); | ||
43 | gid_t groups[MAX_GROUPS]; | ||
44 | int ngroups = MAX_GROUPS; | ||
45 | int rv = getgrouplist(cfg.username, gid, groups, &ngroups); | ||
46 | |||
47 | if (arg_debug && rv) { | ||
48 | printf("Username %s, groups ", cfg.username); | ||
49 | int i; | ||
50 | for (i = 0; i < ngroups; i++) | ||
51 | printf("%u, ", groups[i]); | ||
52 | printf("\n"); | ||
53 | } | ||
54 | |||
55 | if (rv == -1) { | ||
56 | fprintf(stderr, "Warning: cannot extract supplementary group list, dropping them\n"); | ||
57 | if (setgroups(0, NULL) < 0) | ||
58 | errExit("setgroups"); | ||
59 | } | ||
60 | else { | ||
61 | rv = setgroups(ngroups, groups); | ||
62 | if (rv) { | ||
63 | fprintf(stderr, "Warning: cannot set supplementary group list, dropping them\n"); | ||
64 | if (setgroups(0, NULL) < 0) | ||
65 | errExit("setgroups"); | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | |||
70 | // set uid/gid | ||
71 | if (setgid(getgid()) < 0) | ||
72 | errExit("setgid/getgid"); | ||
73 | if (setuid(getuid()) < 0) | ||
74 | errExit("setuid/getuid"); | ||
75 | } | ||
76 | |||
77 | |||
78 | void logsignal(int s) { | ||
79 | if (!arg_debug) | ||
80 | return; | ||
81 | |||
82 | openlog("firejail", LOG_NDELAY | LOG_PID, LOG_USER); | ||
83 | syslog(LOG_INFO, "Signal %d caught", s); | ||
84 | closelog(); | ||
85 | } | ||
86 | |||
87 | |||
88 | void logmsg(const char *msg) { | ||
89 | if (!arg_debug) | ||
90 | return; | ||
91 | |||
92 | openlog("firejail", LOG_NDELAY | LOG_PID, LOG_USER); | ||
93 | syslog(LOG_INFO, "%s\n", msg); | ||
94 | closelog(); | ||
95 | } | ||
96 | |||
97 | |||
98 | void logargs(int argc, char **argv) { | ||
99 | if (!arg_debug) | ||
100 | return; | ||
101 | |||
102 | int i; | ||
103 | int len = 0; | ||
104 | |||
105 | // calculate message length | ||
106 | for (i = 0; i < argc; i++) | ||
107 | len += strlen(argv[i]) + 1; // + ' ' | ||
108 | |||
109 | // build message | ||
110 | char msg[len + 1]; | ||
111 | char *ptr = msg; | ||
112 | for (i = 0; i < argc; i++) { | ||
113 | sprintf(ptr, "%s ", argv[i]); | ||
114 | ptr += strlen(ptr); | ||
115 | } | ||
116 | |||
117 | // log message | ||
118 | logmsg(msg); | ||
119 | } | ||
120 | |||
121 | |||
122 | void logerr(const char *msg) { | ||
123 | if (!arg_debug) | ||
124 | return; | ||
125 | |||
126 | openlog("firejail", LOG_NDELAY | LOG_PID, LOG_USER); | ||
127 | syslog(LOG_ERR, "%s\n", msg); | ||
128 | closelog(); | ||
129 | } | ||
130 | |||
131 | |||
132 | // return -1 if error, 0 if no error | ||
133 | int copy_file(const char *srcname, const char *destname) { | ||
134 | assert(srcname); | ||
135 | assert(destname); | ||
136 | |||
137 | // open source | ||
138 | int src = open(srcname, O_RDONLY); | ||
139 | if (src < 0) { | ||
140 | fprintf(stderr, "Warning: cannot open %s, file not copied\n", srcname); | ||
141 | return -1; | ||
142 | } | ||
143 | |||
144 | // open destination | ||
145 | int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | ||
146 | if (dst < 0) { | ||
147 | fprintf(stderr, "Warning: cannot open %s, file not copied\n", destname); | ||
148 | close(src); | ||
149 | return -1; | ||
150 | } | ||
151 | |||
152 | // copy | ||
153 | ssize_t len; | ||
154 | static const int BUFLEN = 1024; | ||
155 | unsigned char buf[BUFLEN]; | ||
156 | while ((len = read(src, buf, BUFLEN)) > 0) { | ||
157 | int done = 0; | ||
158 | while (done != len) { | ||
159 | int rv = write(dst, buf + done, len - done); | ||
160 | if (rv == -1) { | ||
161 | close(src); | ||
162 | close(dst); | ||
163 | return -1; | ||
164 | } | ||
165 | |||
166 | done += rv; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | close(src); | ||
171 | close(dst); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | |||
176 | char *get_link(const char *fname) { | ||
177 | assert(fname); | ||
178 | struct stat sb; | ||
179 | char *linkname; | ||
180 | ssize_t r; | ||
181 | |||
182 | if (lstat(fname, &sb) == -1) | ||
183 | return NULL; | ||
184 | |||
185 | linkname = malloc(sb.st_size + 1); | ||
186 | if (linkname == NULL) | ||
187 | return NULL; | ||
188 | memset(linkname, 0, sb.st_size + 1); | ||
189 | |||
190 | r = readlink(fname, linkname, sb.st_size + 1); | ||
191 | if (r < 0) { | ||
192 | free(linkname); | ||
193 | return NULL; | ||
194 | } | ||
195 | return linkname; | ||
196 | } | ||
197 | |||
198 | |||
199 | // return 1 if the file is a directory | ||
200 | int is_dir(const char *fname) { | ||
201 | assert(fname); | ||
202 | if (*fname == '\0') | ||
203 | return 0; | ||
204 | |||
205 | // if fname doesn't end in '/', add one | ||
206 | int rv; | ||
207 | struct stat s; | ||
208 | if (fname[strlen(fname) - 1] == '/') | ||
209 | rv = stat(fname, &s); | ||
210 | else { | ||
211 | char *tmp; | ||
212 | if (asprintf(&tmp, "%s/", fname) == -1) { | ||
213 | fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__); | ||
214 | errExit("asprintf"); | ||
215 | } | ||
216 | rv = stat(tmp, &s); | ||
217 | free(tmp); | ||
218 | } | ||
219 | |||
220 | if (rv == -1) | ||
221 | return 0; | ||
222 | |||
223 | if (S_ISDIR(s.st_mode)) | ||
224 | return 1; | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | // return 1 if the file is a link | ||
230 | int is_link(const char *fname) { | ||
231 | assert(fname); | ||
232 | if (*fname == '\0') | ||
233 | return 0; | ||
234 | |||
235 | struct stat s; | ||
236 | if (lstat(fname, &s) == 0) { | ||
237 | if (S_ISLNK(s.st_mode)) | ||
238 | return 1; | ||
239 | } | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | |||
245 | // remove multiple spaces and return allocated memory | ||
246 | char *line_remove_spaces(const char *buf) { | ||
247 | assert(buf); | ||
248 | if (strlen(buf) == 0) | ||
249 | return NULL; | ||
250 | |||
251 | // allocate memory for the new string | ||
252 | char *rv = malloc(strlen(buf) + 1); | ||
253 | if (rv == NULL) | ||
254 | errExit("malloc"); | ||
255 | |||
256 | // remove space at start of line | ||
257 | const char *ptr1 = buf; | ||
258 | while (*ptr1 == ' ' || *ptr1 == '\t') | ||
259 | ptr1++; | ||
260 | |||
261 | // copy data and remove additional spaces | ||
262 | char *ptr2 = rv; | ||
263 | int state = 0; | ||
264 | while (*ptr1 != '\0') { | ||
265 | if (*ptr1 == '\n' || *ptr1 == '\r') | ||
266 | break; | ||
267 | |||
268 | if (state == 0) { | ||
269 | if (*ptr1 != ' ' && *ptr1 != '\t') | ||
270 | *ptr2++ = *ptr1++; | ||
271 | else { | ||
272 | *ptr2++ = ' '; | ||
273 | ptr1++; | ||
274 | state = 1; | ||
275 | } | ||
276 | } | ||
277 | else { // state == 1 | ||
278 | while (*ptr1 == ' ' || *ptr1 == '\t') | ||
279 | ptr1++; | ||
280 | state = 0; | ||
281 | } | ||
282 | } | ||
283 | |||
284 | // strip last blank character if any | ||
285 | if (*(ptr2 - 1) == ' ') | ||
286 | --ptr2; | ||
287 | *ptr2 = '\0'; | ||
288 | // if (arg_debug) | ||
289 | // printf("Processing line #%s#\n", rv); | ||
290 | |||
291 | return rv; | ||
292 | } | ||
293 | |||
294 | |||
295 | char *split_comma(char *str) { | ||
296 | if (str == NULL || *str == '\0') | ||
297 | return NULL; | ||
298 | char *ptr = strchr(str, ','); | ||
299 | if (!ptr) | ||
300 | return NULL; | ||
301 | *ptr = '\0'; | ||
302 | ptr++; | ||
303 | if (*ptr == '\0') | ||
304 | return NULL; | ||
305 | return ptr; | ||
306 | } | ||
307 | |||
308 | |||
309 | int not_unsigned(const char *str) { | ||
310 | int rv = 0; | ||
311 | const char *ptr = str; | ||
312 | while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') { | ||
313 | if (!isdigit(*ptr)) { | ||
314 | rv = 1; | ||
315 | break; | ||
316 | } | ||
317 | ptr++; | ||
318 | } | ||
319 | |||
320 | return rv; | ||
321 | } | ||
322 | |||
323 | |||
324 | #define BUFLEN 4096 | ||
325 | // find the first child for this parent; return 1 if error | ||
326 | int find_child(pid_t parent, pid_t *child) { | ||
327 | *child = 0; // use it to flag a found child | ||
328 | |||
329 | DIR *dir; | ||
330 | if (!(dir = opendir("/proc"))) { | ||
331 | // sleep 2 seconds and try again | ||
332 | sleep(2); | ||
333 | if (!(dir = opendir("/proc"))) { | ||
334 | fprintf(stderr, "Error: cannot open /proc directory\n"); | ||
335 | exit(1); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | struct dirent *entry; | ||
340 | char *end; | ||
341 | while (*child == 0 && (entry = readdir(dir))) { | ||
342 | pid_t pid = strtol(entry->d_name, &end, 10); | ||
343 | if (end == entry->d_name || *end) | ||
344 | continue; | ||
345 | if (pid == parent) | ||
346 | continue; | ||
347 | |||
348 | // open stat file | ||
349 | char *file; | ||
350 | if (asprintf(&file, "/proc/%u/status", pid) == -1) { | ||
351 | perror("asprintf"); | ||
352 | exit(1); | ||
353 | } | ||
354 | FILE *fp = fopen(file, "r"); | ||
355 | if (!fp) { | ||
356 | free(file); | ||
357 | continue; | ||
358 | } | ||
359 | |||
360 | // look for firejail executable name | ||
361 | char buf[BUFLEN]; | ||
362 | while (fgets(buf, BUFLEN - 1, fp)) { | ||
363 | if (strncmp(buf, "PPid:", 5) == 0) { | ||
364 | char *ptr = buf + 5; | ||
365 | while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\t')) { | ||
366 | ptr++; | ||
367 | } | ||
368 | if (*ptr == '\0') { | ||
369 | fprintf(stderr, "Error: cannot read /proc file\n"); | ||
370 | exit(1); | ||
371 | } | ||
372 | if (parent == atoi(ptr)) | ||
373 | *child = pid; | ||
374 | break; // stop reading the file | ||
375 | } | ||
376 | } | ||
377 | fclose(fp); | ||
378 | free(file); | ||
379 | } | ||
380 | closedir(dir); | ||
381 | |||
382 | return (*child)? 0:1; // 0 = found, 1 = not found | ||
383 | } | ||
384 | |||
385 | |||
386 | |||
387 | void extract_command_name(const char *str) { | ||
388 | assert(str); | ||
389 | cfg.command_name = strdup(str); | ||
390 | if (!cfg.command_name) | ||
391 | errExit("strdup"); | ||
392 | |||
393 | // restrict the command name to the first word | ||
394 | char *ptr = cfg.command_name; | ||
395 | while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') | ||
396 | ptr++; | ||
397 | *ptr = '\0'; | ||
398 | |||
399 | // remove the path: /usr/bin/firefox becomes firefox | ||
400 | ptr = strrchr(cfg.command_name, '/'); | ||
401 | if (ptr) { | ||
402 | ptr++; | ||
403 | if (*ptr == '\0') { | ||
404 | fprintf(stderr, "Error: invalid command name\n"); | ||
405 | exit(1); | ||
406 | } | ||
407 | |||
408 | char *tmp = strdup(ptr); | ||
409 | if (!tmp) | ||
410 | errExit("strdup"); | ||
411 | free(cfg.command_name); | ||
412 | cfg.command_name = tmp; | ||
413 | } | ||
414 | } | ||
415 | |||
416 | |||
417 | void update_map(char *mapping, char *map_file) { | ||
418 | int fd, j; | ||
419 | size_t map_len; /* Length of 'mapping' */ | ||
420 | |||
421 | /* Replace commas in mapping string with newlines */ | ||
422 | |||
423 | map_len = strlen(mapping); | ||
424 | for (j = 0; j < map_len; j++) | ||
425 | if (mapping[j] == ',') | ||
426 | mapping[j] = '\n'; | ||
427 | |||
428 | fd = open(map_file, O_RDWR); | ||
429 | if (fd == -1) { | ||
430 | fprintf(stderr, "Error: cannot open %s: %s\n", map_file, strerror(errno)); | ||
431 | exit(EXIT_FAILURE); | ||
432 | } | ||
433 | |||
434 | if (write(fd, mapping, map_len) != map_len) { | ||
435 | fprintf(stderr, "Error: cannot write to %s: %s\n", map_file, strerror(errno)); | ||
436 | exit(EXIT_FAILURE); | ||
437 | } | ||
438 | |||
439 | close(fd); | ||
440 | } | ||
441 | |||
442 | |||
443 | void wait_for_other(int fd) { | ||
444 | //**************************** | ||
445 | // wait for the parent to be initialized | ||
446 | //**************************** | ||
447 | char childstr[BUFLEN + 1]; | ||
448 | int newfd = dup(fd); | ||
449 | if (newfd == -1) | ||
450 | errExit("dup"); | ||
451 | FILE* stream; | ||
452 | stream = fdopen(newfd, "r"); | ||
453 | *childstr = '\0'; | ||
454 | if (fgets(childstr, BUFLEN, stream)) { | ||
455 | // remove \n) | ||
456 | char *ptr = childstr; | ||
457 | while(*ptr !='\0' && *ptr != '\n') | ||
458 | ptr++; | ||
459 | if (*ptr == '\0') | ||
460 | errExit("fgets"); | ||
461 | *ptr = '\0'; | ||
462 | } | ||
463 | else { | ||
464 | fprintf(stderr, "Error: cannot establish communication with the parent, exiting...\n"); | ||
465 | exit(1); | ||
466 | } | ||
467 | fclose(stream); | ||
468 | } | ||
469 | |||
470 | |||
471 | void notify_other(int fd) { | ||
472 | FILE* stream; | ||
473 | int newfd = dup(fd); | ||
474 | if (newfd == -1) | ||
475 | errExit("dup"); | ||
476 | stream = fdopen(newfd, "w"); | ||
477 | fprintf(stream, "%u\n", getpid()); | ||
478 | fflush(stream); | ||
479 | fclose(stream); | ||
480 | } | ||
diff --git a/src/firejail/veth.c b/src/firejail/veth.c new file mode 100644 index 000000000..ecc31f18d --- /dev/null +++ b/src/firejail/veth.c | |||
@@ -0,0 +1,191 @@ | |||
1 | /* code based on iproute2 ip/iplink.c, modified to be included in firejail project | ||
2 | * | ||
3 | * Original source code: | ||
4 | * | ||
5 | * Information: | ||
6 | * http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2 | ||
7 | * | ||
8 | * Download: | ||
9 | * http://www.kernel.org/pub/linux/utils/net/iproute2/ | ||
10 | * | ||
11 | * Repository: | ||
12 | * git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git | ||
13 | * | ||
14 | * License: GPL v2 | ||
15 | * | ||
16 | * Original copyright header | ||
17 | * | ||
18 | * iplink.c "ip link". | ||
19 | * | ||
20 | * This program is free software; you can redistribute it and/or | ||
21 | * modify it under the terms of the GNU General Public License | ||
22 | * as published by the Free Software Foundation; either version | ||
23 | * 2 of the License, or (at your option) any later version. | ||
24 | * | ||
25 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> | ||
26 | * | ||
27 | */ | ||
28 | /* | ||
29 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
30 | * | ||
31 | * This file is part of firejail project | ||
32 | * | ||
33 | * This program is free software; you can redistribute it and/or modify | ||
34 | * it under the terms of the GNU General Public License as published by | ||
35 | * the Free Software Foundation; either version 2 of the License, or | ||
36 | * (at your option) any later version. | ||
37 | * | ||
38 | * This program is distributed in the hope that it will be useful, | ||
39 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
40 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
41 | * GNU General Public License for more details. | ||
42 | * | ||
43 | * You should have received a copy of the GNU General Public License along | ||
44 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
45 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
46 | */ | ||
47 | |||
48 | #include "firejail.h" | ||
49 | #include "../include/libnetlink.h" | ||
50 | #include <linux/veth.h> | ||
51 | |||
52 | struct iplink_req | ||
53 | { | ||
54 | struct nlmsghdr n; | ||
55 | struct ifinfomsg i; | ||
56 | char buf[1024]; | ||
57 | }; | ||
58 | |||
59 | static struct rtnl_handle rth = { .fd = -1 }; | ||
60 | |||
61 | int net_create_veth(const char *dev, const char *nsdev, unsigned pid) { | ||
62 | int len; | ||
63 | struct iplink_req req; | ||
64 | |||
65 | if (arg_debug) | ||
66 | printf("create veth %s/%s/%u\n", dev, nsdev, pid); | ||
67 | assert(dev); | ||
68 | assert(nsdev); | ||
69 | assert(pid); | ||
70 | |||
71 | if (rtnl_open(&rth, 0) < 0) { | ||
72 | fprintf(stderr, "cannot open netlink\n"); | ||
73 | exit(1); | ||
74 | } | ||
75 | |||
76 | memset(&req, 0, sizeof(req)); | ||
77 | |||
78 | req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); | ||
79 | req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL; | ||
80 | req.n.nlmsg_type = RTM_NEWLINK; | ||
81 | req.i.ifi_family = 0; | ||
82 | |||
83 | if (dev) { | ||
84 | len = strlen(dev) + 1; | ||
85 | addattr_l(&req.n, sizeof(req), IFLA_IFNAME, dev, len); | ||
86 | } | ||
87 | |||
88 | struct rtattr *linkinfo = NLMSG_TAIL(&req.n); | ||
89 | addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0); | ||
90 | addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, "veth", strlen("veth")); | ||
91 | |||
92 | struct rtattr * data = NLMSG_TAIL(&req.n); | ||
93 | addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0); | ||
94 | |||
95 | struct rtattr * peerdata = NLMSG_TAIL(&req.n); | ||
96 | addattr_l (&req.n, sizeof(req), VETH_INFO_PEER, NULL, 0); | ||
97 | req.n.nlmsg_len += sizeof(struct ifinfomsg); | ||
98 | |||
99 | // place the link in the child namespace | ||
100 | addattr_l (&req.n, sizeof(req), IFLA_NET_NS_PID, &pid, 4); | ||
101 | |||
102 | if (nsdev) { | ||
103 | int len = strlen(nsdev) + 1; | ||
104 | addattr_l(&req.n, sizeof(req), IFLA_IFNAME, nsdev, len); | ||
105 | } | ||
106 | peerdata->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)peerdata; | ||
107 | |||
108 | data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; | ||
109 | linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo; | ||
110 | |||
111 | // send message | ||
112 | if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) | ||
113 | exit(2); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | |||
119 | int net_create_macvlan(const char *dev, const char *parent, unsigned pid) { | ||
120 | int len; | ||
121 | struct iplink_req req; | ||
122 | if (arg_debug) | ||
123 | printf("create macvlan %s, parent %s\n", dev, parent); | ||
124 | assert(dev); | ||
125 | assert(parent); | ||
126 | |||
127 | if (rtnl_open(&rth, 0) < 0) { | ||
128 | fprintf(stderr, "cannot open netlink\n"); | ||
129 | exit(1); | ||
130 | } | ||
131 | |||
132 | memset(&req, 0, sizeof(req)); | ||
133 | |||
134 | req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); | ||
135 | req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL; | ||
136 | req.n.nlmsg_type = RTM_NEWLINK; | ||
137 | req.i.ifi_family = 0; | ||
138 | |||
139 | // we start with the parent | ||
140 | int parent_ifindex = 2; | ||
141 | addattr_l(&req.n, sizeof(req), IFLA_LINK, &parent_ifindex, 4); | ||
142 | |||
143 | // add new interface name | ||
144 | len = strlen(dev) + 1; | ||
145 | addattr_l(&req.n, sizeof(req), IFLA_IFNAME, dev, len); | ||
146 | |||
147 | // place the interface in child namespace | ||
148 | addattr_l (&req.n, sizeof(req), IFLA_NET_NS_PID, &pid, 4); | ||
149 | |||
150 | |||
151 | // add link info for the new interface | ||
152 | struct rtattr *linkinfo = NLMSG_TAIL(&req.n); | ||
153 | addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0); | ||
154 | addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, "macvlan", strlen("macvlan")); | ||
155 | |||
156 | // set macvlan bridge mode | ||
157 | struct rtattr * data = NLMSG_TAIL(&req.n); | ||
158 | addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0); | ||
159 | int macvlan_type = MACVLAN_MODE_BRIDGE; | ||
160 | addattr_l (&req.n, sizeof(req), IFLA_INFO_KIND, &macvlan_type, 4); | ||
161 | |||
162 | data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; | ||
163 | // req.n.nlmsg_len += sizeof(struct ifinfomsg); | ||
164 | |||
165 | |||
166 | data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; | ||
167 | linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo; | ||
168 | |||
169 | // send message | ||
170 | if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) | ||
171 | exit(2); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | int main(int argc, char **argv) { | ||
178 | printf("Hello\n"); | ||
179 | |||
180 | |||
181 | char *dev = argv[3]; | ||
182 | char *nsdev = argv[8]; | ||
183 | unsigned pid; | ||
184 | sscanf(argv[10], "%u", &pid); | ||
185 | |||
186 | |||
187 | net_create_veth(dev, nsdev, pid); | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | */ \ No newline at end of file | ||
diff --git a/src/firemon/Makefile.in b/src/firemon/Makefile.in new file mode 100644 index 000000000..425289695 --- /dev/null +++ b/src/firemon/Makefile.in | |||
@@ -0,0 +1,24 @@ | |||
1 | all: firemon | ||
2 | |||
3 | PREFIX=@prefix@ | ||
4 | VERSION=@PACKAGE_VERSION@ | ||
5 | NAME=@PACKAGE_NAME@ | ||
6 | |||
7 | H_FILE_LIST = $(wildcard *.[h]) | ||
8 | C_FILE_LIST = $(wildcard *.c) | ||
9 | OBJS = $(C_FILE_LIST:.c=.o) | ||
10 | BINOBJS = $(foreach file, $(OBJS), $file) | ||
11 | CFLAGS += -ggdb -O2 -DVERSION='"$(VERSION)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security | ||
12 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now | ||
13 | |||
14 | %.o : %.c $(H_FILE_LIST) | ||
15 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ | ||
16 | |||
17 | firemon: $(OBJS) ../lib/common.o ../lib/pid.o | ||
18 | $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o ../lib/pid.o $(LIBS) | ||
19 | |||
20 | clean:; rm -f *.o firemon | ||
21 | |||
22 | distclean: clean | ||
23 | rm -fr Makefile | ||
24 | |||
diff --git a/src/firemon/arp.c b/src/firemon/arp.c new file mode 100644 index 000000000..71beb0630 --- /dev/null +++ b/src/firemon/arp.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | #define MAXBUF 4096 | ||
22 | |||
23 | static void print_arp(const char *fname) { | ||
24 | FILE *fp = fopen(fname, "r"); | ||
25 | if (!fp) | ||
26 | return; | ||
27 | |||
28 | printf(" ARP Table:\n"); | ||
29 | char buf[MAXBUF]; | ||
30 | while (fgets(buf, MAXBUF, fp)) { | ||
31 | // remove blanks, \n | ||
32 | char *ptr = buf; | ||
33 | while (*ptr == ' ' || *ptr == '\t') | ||
34 | ptr++; | ||
35 | char *start = ptr; | ||
36 | if (*start == '\0') | ||
37 | continue; | ||
38 | ptr = strchr(ptr, '\n'); | ||
39 | if (ptr) | ||
40 | *ptr = '\0'; | ||
41 | |||
42 | // remove table header | ||
43 | //IP address HW type Flags HW address Mask Device | ||
44 | if (strncmp(start, "IP address", 10) == 0) | ||
45 | continue; | ||
46 | |||
47 | // extract data | ||
48 | char ip[64]; | ||
49 | char type[64]; | ||
50 | char flags[64]; | ||
51 | char mac[64]; | ||
52 | char mask[64]; | ||
53 | char device[64]; | ||
54 | int rv = sscanf(start, "%s %s %s %s %s %s\n", ip, type, flags, mac, mask, device); | ||
55 | if (rv != 6) | ||
56 | continue; | ||
57 | |||
58 | // destination ip | ||
59 | unsigned a, b, c, d; | ||
60 | if (sscanf(ip, "%u.%u.%u.%u", &a, &b, &c, &d) != 4 || a > 255 || b > 255 || c > 255 || d > 255) | ||
61 | continue; | ||
62 | uint32_t destip = a * 0x1000000 + b * 0x10000 + c * 0x100 + d; | ||
63 | if (strcmp(flags, "0x0") == 0) | ||
64 | printf(" %d.%d.%d.%d dev %s FAILED\n", | ||
65 | PRINT_IP(destip), device); | ||
66 | else | ||
67 | printf(" %d.%d.%d.%d dev %s lladdr %s REACHABLE\n", | ||
68 | PRINT_IP(destip), device, mac); | ||
69 | } | ||
70 | |||
71 | fclose(fp); | ||
72 | |||
73 | } | ||
74 | |||
75 | void arp(pid_t pid) { | ||
76 | if (getuid() == 0) | ||
77 | firemon_drop_privs(); | ||
78 | |||
79 | pid_read(pid); | ||
80 | |||
81 | // print processes | ||
82 | int i; | ||
83 | for (i = 0; i < max_pids; i++) { | ||
84 | if (pids[i].level == 1) { | ||
85 | pid_print_list(i, 0); | ||
86 | int child = find_child(i); | ||
87 | if (child != -1) { | ||
88 | char *fname; | ||
89 | if (asprintf(&fname, "/proc/%d/net/arp", child) == -1) | ||
90 | errExit("asprintf"); | ||
91 | print_arp(fname); | ||
92 | free(fname); | ||
93 | printf("\n"); | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | |||
99 | |||
diff --git a/src/firemon/caps.c b/src/firemon/caps.c new file mode 100644 index 000000000..4ae9ab28d --- /dev/null +++ b/src/firemon/caps.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | #define MAXBUF 4098 | ||
22 | |||
23 | static void print_caps(int pid) { | ||
24 | char *file; | ||
25 | if (asprintf(&file, "/proc/%d/status", pid) == -1) { | ||
26 | errExit("asprintf"); | ||
27 | exit(1); | ||
28 | } | ||
29 | |||
30 | FILE *fp = fopen(file, "r"); | ||
31 | if (!fp) { | ||
32 | printf(" Error: cannot open %s\n", file); | ||
33 | free(file); | ||
34 | return; | ||
35 | } | ||
36 | |||
37 | char buf[MAXBUF]; | ||
38 | while (fgets(buf, MAXBUF, fp)) { | ||
39 | if (strncmp(buf, "CapBnd:", 7) == 0) { | ||
40 | printf(" %s", buf); | ||
41 | fflush(0); | ||
42 | free(file); | ||
43 | fclose(fp); | ||
44 | return; | ||
45 | } | ||
46 | } | ||
47 | fclose(fp); | ||
48 | free(file); | ||
49 | } | ||
50 | |||
51 | void caps(pid_t pid) { | ||
52 | if (getuid() == 0) | ||
53 | firemon_drop_privs(); | ||
54 | |||
55 | pid_read(pid); // include all processes | ||
56 | |||
57 | // print processes | ||
58 | int i; | ||
59 | for (i = 0; i < max_pids; i++) { | ||
60 | if (pids[i].level == 1) { | ||
61 | pid_print_list(i, 0); | ||
62 | int child = find_child(i); | ||
63 | if (child != -1) | ||
64 | print_caps(child); | ||
65 | } | ||
66 | } | ||
67 | printf("\n"); | ||
68 | } | ||
69 | |||
diff --git a/src/firemon/cgroup.c b/src/firemon/cgroup.c new file mode 100644 index 000000000..214aefaf9 --- /dev/null +++ b/src/firemon/cgroup.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | #define MAXBUF 4098 | ||
22 | |||
23 | static void print_cgroup(int pid) { | ||
24 | char *file; | ||
25 | if (asprintf(&file, "/proc/%d/cgroup", pid) == -1) { | ||
26 | errExit("asprintf"); | ||
27 | exit(1); | ||
28 | } | ||
29 | |||
30 | FILE *fp = fopen(file, "r"); | ||
31 | if (!fp) { | ||
32 | printf(" Error: cannot open %s\n", file); | ||
33 | free(file); | ||
34 | return; | ||
35 | } | ||
36 | |||
37 | char buf[MAXBUF]; | ||
38 | if (fgets(buf, MAXBUF, fp)) { | ||
39 | printf(" %s", buf); | ||
40 | fflush(0); | ||
41 | } | ||
42 | |||
43 | fclose(fp); | ||
44 | free(file); | ||
45 | } | ||
46 | |||
47 | void cgroup(pid_t pid) { | ||
48 | if (getuid() == 0) | ||
49 | firemon_drop_privs(); | ||
50 | |||
51 | pid_read(pid); | ||
52 | |||
53 | // print processes | ||
54 | int i; | ||
55 | for (i = 0; i < max_pids; i++) { | ||
56 | if (pids[i].level == 1) { | ||
57 | pid_print_list(i, 0); | ||
58 | int child = find_child(i); | ||
59 | if (child != -1) | ||
60 | print_cgroup(child); | ||
61 | } | ||
62 | } | ||
63 | } | ||
64 | |||
diff --git a/src/firemon/cpu.c b/src/firemon/cpu.c new file mode 100644 index 000000000..d5d20d1b8 --- /dev/null +++ b/src/firemon/cpu.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | #define MAXBUF 4098 | ||
22 | |||
23 | static void print_cpu(int pid) { | ||
24 | char *file; | ||
25 | if (asprintf(&file, "/proc/%d/status", pid) == -1) { | ||
26 | errExit("asprintf"); | ||
27 | exit(1); | ||
28 | } | ||
29 | |||
30 | FILE *fp = fopen(file, "r"); | ||
31 | if (!fp) { | ||
32 | printf(" Error: cannot open %s\n", file); | ||
33 | free(file); | ||
34 | return; | ||
35 | } | ||
36 | |||
37 | char buf[MAXBUF]; | ||
38 | while (fgets(buf, MAXBUF, fp)) { | ||
39 | if (strncmp(buf, "Cpus_allowed_list:", 18) == 0) { | ||
40 | printf(" %s", buf); | ||
41 | fflush(0); | ||
42 | free(file); | ||
43 | fclose(fp); | ||
44 | return; | ||
45 | } | ||
46 | } | ||
47 | fclose(fp); | ||
48 | free(file); | ||
49 | } | ||
50 | |||
51 | void cpu(pid_t pid) { | ||
52 | if (getuid() == 0) | ||
53 | firemon_drop_privs(); | ||
54 | |||
55 | pid_read(pid); | ||
56 | |||
57 | // print processes | ||
58 | int i; | ||
59 | for (i = 0; i < max_pids; i++) { | ||
60 | if (pids[i].level == 1) { | ||
61 | pid_print_list(i, 0); | ||
62 | int child = find_child(i); | ||
63 | if (child != -1) | ||
64 | print_cpu(child); | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
diff --git a/src/firemon/firemon.c b/src/firemon/firemon.c new file mode 100644 index 000000000..d77d11a7a --- /dev/null +++ b/src/firemon/firemon.c | |||
@@ -0,0 +1,222 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | #include <signal.h> | ||
22 | #include <termios.h> | ||
23 | #include <sys/ioctl.h> | ||
24 | #include <sys/prctl.h> | ||
25 | #include <grp.h> | ||
26 | |||
27 | |||
28 | static int arg_route = 0; | ||
29 | static int arg_arp = 0; | ||
30 | static int arg_tree = 0; | ||
31 | static int arg_interface = 0; | ||
32 | static int arg_seccomp = 0; | ||
33 | static int arg_caps = 0; | ||
34 | static int arg_cpu = 0; | ||
35 | static int arg_cgroup = 0; | ||
36 | int arg_nowrap = 0; | ||
37 | |||
38 | static struct termios tlocal; // startup terminal setting | ||
39 | static struct termios twait; // no wait on key press | ||
40 | static int terminal_set = 0; | ||
41 | |||
42 | static void my_handler(int s){ | ||
43 | if (terminal_set) | ||
44 | tcsetattr(0, TCSANOW, &tlocal); | ||
45 | exit(0); | ||
46 | } | ||
47 | |||
48 | // find the first child process for the specified pid | ||
49 | // return -1 if not found | ||
50 | int find_child(int id) { | ||
51 | int i; | ||
52 | for (i = 0; i < max_pids; i++) { | ||
53 | if (pids[i].level == 2 && pids[i].parent == id) | ||
54 | return i; | ||
55 | } | ||
56 | |||
57 | return -1; | ||
58 | } | ||
59 | |||
60 | // drop privileges | ||
61 | void firemon_drop_privs(void) { | ||
62 | // drop privileges | ||
63 | if (setgroups(0, NULL) < 0) | ||
64 | errExit("setgroups"); | ||
65 | if (setgid(getgid()) < 0) | ||
66 | errExit("setgid/getgid"); | ||
67 | if (setuid(getuid()) < 0) | ||
68 | errExit("setuid/getuid"); | ||
69 | } | ||
70 | |||
71 | // sleep and wait for a key to be pressed | ||
72 | void firemon_sleep(int st) { | ||
73 | if (terminal_set == 0) { | ||
74 | tcgetattr(0, &twait); // get current terminal attirbutes; 0 is the file descriptor for stdin | ||
75 | memcpy(&tlocal, &twait, sizeof(tlocal)); | ||
76 | twait.c_lflag &= ~ICANON; // disable canonical mode | ||
77 | twait.c_lflag &= ~ECHO; // no echo | ||
78 | twait.c_cc[VMIN] = 1; // wait until at least one keystroke available | ||
79 | twait.c_cc[VTIME] = 0; // no timeout | ||
80 | terminal_set = 1; | ||
81 | } | ||
82 | tcsetattr(0, TCSANOW, &twait); | ||
83 | |||
84 | |||
85 | fd_set fds; | ||
86 | FD_ZERO(&fds); | ||
87 | FD_SET(0,&fds); | ||
88 | int maxfd = 1; | ||
89 | |||
90 | struct timeval ts; | ||
91 | ts.tv_sec = st; | ||
92 | ts.tv_usec = 0; | ||
93 | |||
94 | int ready = select(maxfd, &fds, (fd_set *) 0, (fd_set *) 0, &ts); | ||
95 | (void) ready; | ||
96 | if( FD_ISSET(0, &fds)) { | ||
97 | getchar(); | ||
98 | tcsetattr(0, TCSANOW, &tlocal); | ||
99 | printf("\n"); | ||
100 | exit(0); | ||
101 | } | ||
102 | tcsetattr(0, TCSANOW, &tlocal); | ||
103 | } | ||
104 | |||
105 | |||
106 | int main(int argc, char **argv) { | ||
107 | unsigned pid = 0; | ||
108 | int i; | ||
109 | |||
110 | // handle CTRL-C | ||
111 | signal (SIGINT, my_handler); | ||
112 | signal (SIGTERM, my_handler); | ||
113 | |||
114 | for (i = 1; i < argc; i++) { | ||
115 | // default options | ||
116 | if (strcmp(argv[i], "--help") == 0 || | ||
117 | strcmp(argv[i], "-?") == 0) { | ||
118 | usage(); | ||
119 | return 0; | ||
120 | } | ||
121 | else if (strcmp(argv[i], "--version") == 0) { | ||
122 | printf("firemon version %s\n\n", VERSION); | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | // options without a pid argument | ||
127 | else if (strcmp(argv[i], "--top") == 0) { | ||
128 | top(); // never to return | ||
129 | } | ||
130 | else if (strcmp(argv[i], "--list") == 0) { | ||
131 | list(); | ||
132 | return 0; | ||
133 | } | ||
134 | else if (strcmp(argv[i], "--netstats") == 0) { | ||
135 | netstats(); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | |||
140 | // cumulative options with or without a pid argument | ||
141 | else if (strcmp(argv[i], "--cgroup") == 0) { | ||
142 | arg_cgroup = 1; | ||
143 | } | ||
144 | else if (strcmp(argv[i], "--cpu") == 0) { | ||
145 | arg_cpu = 1; | ||
146 | } | ||
147 | else if (strcmp(argv[i], "--seccomp") == 0) { | ||
148 | arg_seccomp = 1; | ||
149 | } | ||
150 | else if (strcmp(argv[i], "--caps") == 0) { | ||
151 | arg_caps = 1; | ||
152 | } | ||
153 | else if (strcmp(argv[i], "--tree") == 0) { | ||
154 | arg_tree = 1; | ||
155 | } | ||
156 | else if (strcmp(argv[i], "--interface") == 0) { | ||
157 | arg_interface = 1; | ||
158 | } | ||
159 | else if (strcmp(argv[i], "--route") == 0) { | ||
160 | arg_route = 1; | ||
161 | } | ||
162 | else if (strcmp(argv[i], "--arp") == 0) { | ||
163 | arg_arp = 1; | ||
164 | } | ||
165 | |||
166 | else if (strncmp(argv[i], "--name=", 7) == 0) { | ||
167 | char *name = argv[i] + 7; | ||
168 | if (name2pid(name, (pid_t *) &pid)) { | ||
169 | fprintf(stderr, "Error: cannot find sandbox %s\n", name); | ||
170 | return 1; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | // etc | ||
175 | else if (strcmp(argv[i], "--nowrap") == 0) | ||
176 | arg_nowrap = 1; | ||
177 | |||
178 | // invalid option | ||
179 | else if (*argv[i] == '-') { | ||
180 | fprintf(stderr, "Error: invalid option\n"); | ||
181 | return 1; | ||
182 | } | ||
183 | |||
184 | // PID argument | ||
185 | else { | ||
186 | // this should be a pid number | ||
187 | char *ptr = argv[i]; | ||
188 | while (*ptr != '\0') { | ||
189 | if (!isdigit(*ptr)) { | ||
190 | fprintf(stderr, "Error: not a valid PID number\n"); | ||
191 | exit(1); | ||
192 | } | ||
193 | ptr++; | ||
194 | } | ||
195 | |||
196 | sscanf(argv[i], "%u", &pid); | ||
197 | break; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | if (arg_tree) | ||
202 | tree((pid_t) pid); | ||
203 | if (arg_interface) | ||
204 | interface((pid_t) pid); | ||
205 | if (arg_route) | ||
206 | route((pid_t) pid); | ||
207 | if (arg_arp) | ||
208 | arp((pid_t) pid); | ||
209 | if (arg_seccomp) | ||
210 | seccomp((pid_t) pid); | ||
211 | if (arg_caps) | ||
212 | caps((pid_t) pid); | ||
213 | if (arg_cpu) | ||
214 | cpu((pid_t) pid); | ||
215 | if (arg_cgroup) | ||
216 | cgroup((pid_t) pid); | ||
217 | |||
218 | if (!arg_route && !arg_arp && !arg_interface && !arg_tree && !arg_caps && !arg_seccomp) | ||
219 | procevent((pid_t) pid); // never to return | ||
220 | |||
221 | return 0; | ||
222 | } | ||
diff --git a/src/firemon/firemon.h b/src/firemon/firemon.h new file mode 100644 index 000000000..59b1f352c --- /dev/null +++ b/src/firemon/firemon.h | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #ifndef FIREMON_H | ||
21 | #define FIREMON_H | ||
22 | #define _GNU_SOURCE | ||
23 | #include <stdlib.h> | ||
24 | #include <stdio.h> | ||
25 | #include <ctype.h> | ||
26 | #include <string.h> | ||
27 | #include <errno.h> | ||
28 | #include <stdint.h> | ||
29 | #include "../include/pid.h" | ||
30 | #include "../include/common.h" | ||
31 | |||
32 | // clear screen | ||
33 | static inline void firemon_clrscr(void) { | ||
34 | printf("\033[2J\033[1;1H"); | ||
35 | fflush(0); | ||
36 | } | ||
37 | |||
38 | // firemon.c | ||
39 | extern int arg_nowrap; | ||
40 | int find_child(int id); | ||
41 | void firemon_drop_privs(void); | ||
42 | void firemon_sleep(int st); | ||
43 | |||
44 | |||
45 | // procevent.c | ||
46 | void procevent(pid_t pid); | ||
47 | |||
48 | // usage.c | ||
49 | void usage(void); | ||
50 | |||
51 | // top.c | ||
52 | void top(void); | ||
53 | |||
54 | // list.c | ||
55 | void list(void); | ||
56 | |||
57 | // interface.c | ||
58 | void interface(pid_t pid); | ||
59 | |||
60 | // arp.c | ||
61 | void arp(pid_t pid); | ||
62 | |||
63 | // route.c | ||
64 | void route(pid_t pid); | ||
65 | |||
66 | // caps.c | ||
67 | void caps(pid_t pid); | ||
68 | |||
69 | // seccomp.c | ||
70 | void seccomp(pid_t pid); | ||
71 | |||
72 | // cpu.c | ||
73 | void cpu(pid_t pid); | ||
74 | |||
75 | // cgroup.c | ||
76 | void cgroup(pid_t pid); | ||
77 | |||
78 | // tree.c | ||
79 | void tree(pid_t pid); | ||
80 | |||
81 | // netstats.c | ||
82 | void netstats(void); | ||
83 | |||
84 | #endif | ||
diff --git a/src/firemon/interface.c b/src/firemon/interface.c new file mode 100644 index 000000000..52a9c33cd --- /dev/null +++ b/src/firemon/interface.c | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | #include <sys/types.h> | ||
22 | #include <sys/wait.h> | ||
23 | #include <netdb.h> | ||
24 | #include <arpa/inet.h> | ||
25 | #include <ifaddrs.h> | ||
26 | #include <net/if.h> | ||
27 | #include <linux/connector.h> | ||
28 | #include <linux/netlink.h> | ||
29 | #include <linux/if_link.h> | ||
30 | #include <linux/sockios.h> | ||
31 | #include <sys/ioctl.h> | ||
32 | |||
33 | //#include <net/route.h> | ||
34 | //#include <linux/if_bridge.h> | ||
35 | |||
36 | // print IP addresses for all interfaces | ||
37 | static void net_ifprint(void) { | ||
38 | uint32_t ip; | ||
39 | uint32_t mask; | ||
40 | struct ifaddrs *ifaddr, *ifa; | ||
41 | |||
42 | int fd; | ||
43 | if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { | ||
44 | fprintf(stderr, "Error: cannot open AF_INET socket\n"); | ||
45 | exit(1); | ||
46 | } | ||
47 | |||
48 | if (getifaddrs(&ifaddr) == -1) | ||
49 | errExit("getifaddrs"); | ||
50 | |||
51 | // walk through the linked list | ||
52 | printf(" Link status:\n"); | ||
53 | for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { | ||
54 | if (ifa->ifa_addr == NULL) | ||
55 | continue; | ||
56 | |||
57 | if (ifa->ifa_addr->sa_family == AF_PACKET) { | ||
58 | if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP) { | ||
59 | if (ifa->ifa_data != NULL) { | ||
60 | struct rtnl_link_stats *stats = ifa->ifa_data; | ||
61 | |||
62 | // extract mac address | ||
63 | struct ifreq ifr; | ||
64 | memset(&ifr, 0, sizeof(ifr)); | ||
65 | strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ); | ||
66 | int rv = ioctl (fd, SIOCGIFHWADDR, &ifr); | ||
67 | |||
68 | if (rv == 0) | ||
69 | printf(" %s UP, %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
70 | ifa->ifa_name, PRINT_MAC((unsigned char *) &ifr.ifr_hwaddr.sa_data)); | ||
71 | else | ||
72 | printf(" %s UP\n", ifa->ifa_name); | ||
73 | |||
74 | printf(" tx/rx: %u/%u packets, %u/%u bytes\n", | ||
75 | stats->tx_packets, stats->rx_packets, | ||
76 | stats->tx_bytes, stats->rx_bytes); | ||
77 | } | ||
78 | } | ||
79 | else | ||
80 | printf(" %s DOWN\n", ifa->ifa_name); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | |||
85 | // walk through the linked list | ||
86 | printf(" IPv4 status:\n"); | ||
87 | for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { | ||
88 | if (ifa->ifa_addr == NULL) | ||
89 | continue; | ||
90 | |||
91 | if (ifa->ifa_addr->sa_family == AF_INET) { | ||
92 | struct sockaddr_in *si = (struct sockaddr_in *) ifa->ifa_netmask; | ||
93 | mask = ntohl(si->sin_addr.s_addr); | ||
94 | si = (struct sockaddr_in *) ifa->ifa_addr; | ||
95 | ip = ntohl(si->sin_addr.s_addr); | ||
96 | |||
97 | char *status; | ||
98 | if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP) | ||
99 | status = "UP"; | ||
100 | else | ||
101 | status = "DOWN"; | ||
102 | |||
103 | printf(" %s %s, %d.%d.%d.%d/%u\n", | ||
104 | ifa->ifa_name, status, PRINT_IP(ip), mask2bits(mask)); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | |||
109 | // walk through the linked list | ||
110 | printf(" IPv6 status:\n"); | ||
111 | for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { | ||
112 | if (ifa->ifa_addr == NULL) | ||
113 | continue; | ||
114 | |||
115 | if (ifa->ifa_addr->sa_family == AF_INET6) { | ||
116 | char host[NI_MAXHOST]; | ||
117 | int s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), | ||
118 | host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); | ||
119 | if (s == 0) { | ||
120 | char *ptr; | ||
121 | if ((ptr = strchr(host, '%')) != NULL) | ||
122 | *ptr = '\0'; | ||
123 | char *status; | ||
124 | if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP) | ||
125 | status = "UP"; | ||
126 | else | ||
127 | status = "DOWN"; | ||
128 | |||
129 | printf(" %s %s, %s\n", ifa->ifa_name, status, host); | ||
130 | } | ||
131 | } | ||
132 | } | ||
133 | |||
134 | freeifaddrs(ifaddr); | ||
135 | close(fd); | ||
136 | } | ||
137 | |||
138 | static void print_sandbox(pid_t pid) { | ||
139 | pid_t child = fork(); | ||
140 | if (child == -1) | ||
141 | return; | ||
142 | |||
143 | if (child == 0) { | ||
144 | int rv = join_namespace(pid, "net"); | ||
145 | if (rv) | ||
146 | return; | ||
147 | net_ifprint(); | ||
148 | printf("\n"); | ||
149 | exit(0); | ||
150 | } | ||
151 | |||
152 | // wait for the child to finish | ||
153 | waitpid(child, NULL, 0); | ||
154 | } | ||
155 | |||
156 | void interface(pid_t pid) { | ||
157 | if (getuid() != 0) { | ||
158 | fprintf(stderr, "Error: you need to be root to run this command\n"); | ||
159 | exit(1); | ||
160 | } | ||
161 | |||
162 | pid_read(pid); // a pid of 0 will include all processes | ||
163 | |||
164 | // print processes | ||
165 | int i; | ||
166 | for (i = 0; i < max_pids; i++) { | ||
167 | if (pids[i].level == 1) { | ||
168 | pid_print_list(i, 0); | ||
169 | int child = find_child(i); | ||
170 | if (child != -1) { | ||
171 | print_sandbox(child); | ||
172 | } | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | |||
diff --git a/src/firemon/list.c b/src/firemon/list.c new file mode 100644 index 000000000..6a997bde1 --- /dev/null +++ b/src/firemon/list.c | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | |||
22 | void list(void) { | ||
23 | if (getuid() == 0) | ||
24 | firemon_drop_privs(); | ||
25 | |||
26 | pid_read(0); // include all processes | ||
27 | |||
28 | // print processes | ||
29 | int i; | ||
30 | for (i = 0; i < max_pids; i++) { | ||
31 | if (pids[i].level == 1) | ||
32 | pid_print_list(i, 0); | ||
33 | } | ||
34 | } | ||
35 | |||
diff --git a/src/firemon/netstats.c b/src/firemon/netstats.c new file mode 100644 index 000000000..6c4a767f1 --- /dev/null +++ b/src/firemon/netstats.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | #include <termios.h> | ||
22 | #include <sys/ioctl.h> | ||
23 | #include <sys/types.h> | ||
24 | #include <sys/stat.h> | ||
25 | #include <unistd.h> | ||
26 | |||
27 | #define MAXBUF 4096 | ||
28 | |||
29 | static char *get_header(void) { | ||
30 | char *rv; | ||
31 | if (asprintf(&rv, "%-5.5s %-9.9s %-10.10s %-10.10s %s", | ||
32 | "PID", "User", "RX(KB/s)", "TX(KB/s)", "Command") == -1) | ||
33 | errExit("asprintf"); | ||
34 | |||
35 | return rv; | ||
36 | } | ||
37 | |||
38 | void get_stats(int parent) { | ||
39 | // find the first child | ||
40 | int child = -1; | ||
41 | for (child = parent + 1; child < max_pids; child++) { | ||
42 | if (pids[child].parent == parent) | ||
43 | break; | ||
44 | } | ||
45 | |||
46 | if (child == -1) | ||
47 | goto errexit; | ||
48 | |||
49 | // open /proc/child/net/dev file and read rx and tx | ||
50 | char *fname; | ||
51 | if (asprintf(&fname, "/proc/%d/net/dev", child) == -1) | ||
52 | errExit("asprintf"); | ||
53 | FILE *fp = fopen(fname, "r"); | ||
54 | if (!fp) { | ||
55 | free(fname); | ||
56 | goto errexit; | ||
57 | } | ||
58 | |||
59 | char buf[MAXBUF]; | ||
60 | long long unsigned rx = 0; | ||
61 | long long unsigned tx = 0; | ||
62 | while (fgets(buf, MAXBUF, fp)) { | ||
63 | if (strncmp(buf, "Inter", 5) == 0) | ||
64 | continue; | ||
65 | if (strncmp(buf, " face", 5) == 0) | ||
66 | continue; | ||
67 | |||
68 | char *ptr = buf; | ||
69 | while (*ptr != '\0' && *ptr != ':') { | ||
70 | ptr++; | ||
71 | } | ||
72 | |||
73 | if (*ptr == '\0') { | ||
74 | fclose(fp); | ||
75 | free(fname); | ||
76 | goto errexit; | ||
77 | } | ||
78 | ptr++; | ||
79 | |||
80 | long long unsigned rxval; | ||
81 | long long unsigned txval; | ||
82 | unsigned a, b, c, d, e, f, g; | ||
83 | sscanf(ptr, "%llu %u %u %u %u %u %u %u %llu", | ||
84 | &rxval, &a, &b, &c, &d, &e, &f, &g, &txval); | ||
85 | rx += rxval; | ||
86 | tx += txval; | ||
87 | } | ||
88 | |||
89 | // store data | ||
90 | pids[parent].rx_delta = rx - pids[parent].rx; | ||
91 | pids[parent].rx = rx; | ||
92 | pids[parent].tx_delta = tx - pids[parent].tx; | ||
93 | pids[parent].tx = tx; | ||
94 | |||
95 | |||
96 | free(fname); | ||
97 | fclose(fp); | ||
98 | return; | ||
99 | |||
100 | errexit: | ||
101 | pids[parent].rx = 0; | ||
102 | pids[parent].tx = 0; | ||
103 | pids[parent].rx_delta = 0; | ||
104 | pids[parent].tx_delta = 0; | ||
105 | } | ||
106 | |||
107 | |||
108 | static void print_proc(int index, int itv, int col) { | ||
109 | // command | ||
110 | char *cmd = pid_proc_cmdline(index); | ||
111 | char *ptrcmd; | ||
112 | if (cmd == NULL) { | ||
113 | if (pids[index].zombie) | ||
114 | ptrcmd = "(zombie)"; | ||
115 | else | ||
116 | ptrcmd = ""; | ||
117 | } | ||
118 | else | ||
119 | ptrcmd = cmd; | ||
120 | // if the command doesn't have a --net= option, don't print | ||
121 | if (strstr(ptrcmd, "--net=") == NULL) { | ||
122 | if (cmd) | ||
123 | free(cmd); | ||
124 | return; | ||
125 | } | ||
126 | |||
127 | // pid | ||
128 | char pidstr[10]; | ||
129 | snprintf(pidstr, 10, "%u", index); | ||
130 | |||
131 | // user | ||
132 | char *user = pid_get_user_name(pids[index].uid); | ||
133 | char *ptruser; | ||
134 | if (user) | ||
135 | ptruser = user; | ||
136 | else | ||
137 | ptruser = ""; | ||
138 | |||
139 | |||
140 | float rx_kbps = ((float) pids[index].rx_delta / 1000) / itv; | ||
141 | char ptrrx[15]; | ||
142 | sprintf(ptrrx, "%.03f", rx_kbps); | ||
143 | |||
144 | float tx_kbps = ((float) pids[index].tx_delta / 1000) / itv; | ||
145 | char ptrtx[15]; | ||
146 | sprintf(ptrtx, "%.03f", tx_kbps); | ||
147 | |||
148 | char buf[1024 + 1]; | ||
149 | snprintf(buf, 1024, "%-5.5s %-9.9s %-10.10s %-10.10s %s", | ||
150 | pidstr, ptruser, ptrrx, ptrtx, ptrcmd); | ||
151 | if (col < 1024) | ||
152 | buf[col] = '\0'; | ||
153 | printf("%s\n", buf); | ||
154 | |||
155 | if (cmd) | ||
156 | free(cmd); | ||
157 | if (user) | ||
158 | free(user); | ||
159 | |||
160 | } | ||
161 | |||
162 | void netstats(void) { | ||
163 | if (getuid() == 0) | ||
164 | firemon_drop_privs(); | ||
165 | |||
166 | pid_read(0); // include all processes | ||
167 | |||
168 | printf("Displaying network statistics only for sandboxes using a new network namespace.\n"); | ||
169 | |||
170 | // print processes | ||
171 | while (1) { | ||
172 | // set pid table | ||
173 | int i; | ||
174 | int itv = 5; // 5 second interval | ||
175 | pid_read(0); // todo: preserve the last calculation if any, so we don't have to do get_stats() | ||
176 | |||
177 | // start rx/tx measurements | ||
178 | for (i = 0; i < max_pids; i++) { | ||
179 | if (pids[i].level == 1) | ||
180 | get_stats(i); | ||
181 | } | ||
182 | |||
183 | // wait 5 seconds | ||
184 | firemon_sleep(itv); | ||
185 | |||
186 | // grab screen size | ||
187 | struct winsize sz; | ||
188 | int row = 24; | ||
189 | int col = 80; | ||
190 | if (!ioctl(0, TIOCGWINSZ, &sz)) { | ||
191 | col = sz.ws_col; | ||
192 | row = sz.ws_row; | ||
193 | } | ||
194 | |||
195 | // start printing | ||
196 | firemon_clrscr(); | ||
197 | char *header = get_header(); | ||
198 | if (strlen(header) > col) | ||
199 | header[col] = '\0'; | ||
200 | printf("%s\n", header); | ||
201 | if (row > 0) | ||
202 | row--; | ||
203 | free(header); | ||
204 | |||
205 | // start rx/tx measurements | ||
206 | for (i = 0; i < max_pids; i++) { | ||
207 | if (pids[i].level == 1) { | ||
208 | get_stats(i); | ||
209 | print_proc(i, itv, col); | ||
210 | } | ||
211 | } | ||
212 | } | ||
213 | } | ||
214 | |||
diff --git a/src/firemon/procevent.c b/src/firemon/procevent.c new file mode 100644 index 000000000..d2b5f7bbf --- /dev/null +++ b/src/firemon/procevent.c | |||
@@ -0,0 +1,377 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | #include <sys/socket.h> | ||
22 | #include <linux/connector.h> | ||
23 | #include <linux/netlink.h> | ||
24 | #include <linux/cn_proc.h> | ||
25 | #include <sys/types.h> | ||
26 | #include <sys/stat.h> | ||
27 | #include <unistd.h> | ||
28 | #include <arpa/inet.h> | ||
29 | #include <time.h> | ||
30 | #define PIDS_BUFLEN 4096 | ||
31 | #define SERVER_PORT 889 // 889-899 is left unassigned by IANA | ||
32 | |||
33 | static int pid_is_firejail(pid_t pid) { | ||
34 | uid_t rv = 0; | ||
35 | |||
36 | // open stat file | ||
37 | char *file; | ||
38 | if (asprintf(&file, "/proc/%u/status", pid) == -1) { | ||
39 | perror("asprintf"); | ||
40 | exit(1); | ||
41 | } | ||
42 | FILE *fp = fopen(file, "r"); | ||
43 | if (!fp) { | ||
44 | free(file); | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | // look for firejail executable name | ||
49 | char buf[PIDS_BUFLEN]; | ||
50 | while (fgets(buf, PIDS_BUFLEN - 1, fp)) { | ||
51 | if (strncmp(buf, "Name:", 5) == 0) { | ||
52 | char *ptr = buf + 5; | ||
53 | while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\t')) { | ||
54 | ptr++; | ||
55 | } | ||
56 | if (*ptr == '\0') | ||
57 | goto doexit; | ||
58 | if (strncmp(ptr, "firejail", 8) == 0) | ||
59 | rv = 1; | ||
60 | // if (strncmp(ptr, "lxc-execute", 11) == 0) | ||
61 | // rv = 1; | ||
62 | break; | ||
63 | } | ||
64 | } | ||
65 | doexit: | ||
66 | fclose(fp); | ||
67 | free(file); | ||
68 | return rv; | ||
69 | } | ||
70 | |||
71 | |||
72 | static int procevent_netlink_setup(void) { | ||
73 | // open socket for process event connector | ||
74 | int sock; | ||
75 | if ((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR)) < 0) { | ||
76 | fprintf(stderr, "Error: cannot open netlink socket\n"); | ||
77 | exit(1); | ||
78 | } | ||
79 | |||
80 | // bind socket | ||
81 | struct sockaddr_nl addr; | ||
82 | memset(&addr, 0, sizeof(addr)); | ||
83 | addr.nl_pid = getpid(); | ||
84 | addr.nl_family = AF_NETLINK; | ||
85 | addr.nl_groups = CN_IDX_PROC; | ||
86 | if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { | ||
87 | fprintf(stderr, "Error: cannot bind to netlink socket\n"); | ||
88 | exit(1); | ||
89 | } | ||
90 | |||
91 | // send monitoring message | ||
92 | struct nlmsghdr nlmsghdr; | ||
93 | memset(&nlmsghdr, 0, sizeof(nlmsghdr)); | ||
94 | nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct cn_msg) + sizeof(enum proc_cn_mcast_op)); | ||
95 | nlmsghdr.nlmsg_pid = getpid(); | ||
96 | nlmsghdr.nlmsg_type = NLMSG_DONE; | ||
97 | |||
98 | struct cn_msg cn_msg; | ||
99 | memset(&cn_msg, 0, sizeof(cn_msg)); | ||
100 | cn_msg.id.idx = CN_IDX_PROC; | ||
101 | cn_msg.id.val = CN_VAL_PROC; | ||
102 | cn_msg.len = sizeof(enum proc_cn_mcast_op); | ||
103 | |||
104 | struct iovec iov[3]; | ||
105 | iov[0].iov_base = &nlmsghdr; | ||
106 | iov[0].iov_len = sizeof(nlmsghdr); | ||
107 | iov[1].iov_base = &cn_msg; | ||
108 | iov[1].iov_len = sizeof(cn_msg); | ||
109 | |||
110 | enum proc_cn_mcast_op op = PROC_CN_MCAST_LISTEN; | ||
111 | iov[2].iov_base = &op; | ||
112 | iov[2].iov_len = sizeof(op); | ||
113 | |||
114 | if (writev(sock, iov, 3) == -1) { | ||
115 | fprintf(stderr, "Error: cannot write to netlink socket\n"); | ||
116 | exit(1); | ||
117 | } | ||
118 | |||
119 | return sock; | ||
120 | } | ||
121 | |||
122 | |||
123 | static int procevent_monitor(const int sock, pid_t mypid) { | ||
124 | ssize_t len; | ||
125 | struct nlmsghdr *nlmsghdr; | ||
126 | |||
127 | // timeout in order to re-enable firejail module trace | ||
128 | struct timeval tv; | ||
129 | tv.tv_sec = 30; | ||
130 | tv.tv_usec = 0; | ||
131 | |||
132 | while (1) { | ||
133 | #define BUFFSIZE 4096 | ||
134 | char __attribute__ ((aligned(NLMSG_ALIGNTO)))buf[BUFFSIZE]; | ||
135 | |||
136 | fd_set readfds; | ||
137 | int max; | ||
138 | FD_ZERO(&readfds); | ||
139 | FD_SET(sock, &readfds); | ||
140 | max = sock; | ||
141 | max++; | ||
142 | |||
143 | int rv = select(max, &readfds, NULL, NULL, &tv); | ||
144 | if (rv == -1) { | ||
145 | fprintf(stderr, "recv: %s\n", strerror(errno)); | ||
146 | return -1; | ||
147 | } | ||
148 | |||
149 | // timeout | ||
150 | if (rv == 0) { | ||
151 | tv.tv_sec = 30; | ||
152 | tv.tv_usec = 0; | ||
153 | continue; | ||
154 | } | ||
155 | |||
156 | |||
157 | if ((len = recv(sock, buf, sizeof(buf), 0)) == 0) { | ||
158 | return 0; | ||
159 | } | ||
160 | if (len == -1) { | ||
161 | if (errno == EINTR) { | ||
162 | return 0; | ||
163 | } else { | ||
164 | fprintf(stderr,"recv: %s\n", strerror(errno)); | ||
165 | return -1; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | for (nlmsghdr = (struct nlmsghdr *)buf; | ||
170 | NLMSG_OK (nlmsghdr, len); | ||
171 | nlmsghdr = NLMSG_NEXT (nlmsghdr, len)) { | ||
172 | |||
173 | struct cn_msg *cn_msg; | ||
174 | struct proc_event *proc_ev; | ||
175 | struct tm tm; | ||
176 | time_t now; | ||
177 | |||
178 | if ((nlmsghdr->nlmsg_type == NLMSG_ERROR) || | ||
179 | (nlmsghdr->nlmsg_type == NLMSG_NOOP)) | ||
180 | continue; | ||
181 | |||
182 | cn_msg = NLMSG_DATA(nlmsghdr); | ||
183 | if ((cn_msg->id.idx != CN_IDX_PROC) || | ||
184 | (cn_msg->id.val != CN_VAL_PROC)) | ||
185 | continue; | ||
186 | |||
187 | (void)time(&now); | ||
188 | (void)localtime_r(&now, &tm); | ||
189 | char line[PIDS_BUFLEN]; | ||
190 | char *lineptr = line; | ||
191 | sprintf(lineptr, "%2.2d:%2.2d:%2.2d", tm.tm_hour, tm.tm_min, tm.tm_sec); | ||
192 | lineptr += strlen(lineptr); | ||
193 | |||
194 | proc_ev = (struct proc_event *)cn_msg->data; | ||
195 | pid_t pid = 0; | ||
196 | pid_t child = 0; | ||
197 | int remove_pid = 0; | ||
198 | switch (proc_ev->what) { | ||
199 | case PROC_EVENT_FORK: | ||
200 | if (proc_ev->event_data.fork.child_pid != | ||
201 | proc_ev->event_data.fork.child_tgid) | ||
202 | continue; // this is a thread, not a process | ||
203 | pid = proc_ev->event_data.fork.parent_tgid; | ||
204 | if (pids[pid].level > 0) { | ||
205 | child = proc_ev->event_data.fork.child_tgid; | ||
206 | child %= max_pids; | ||
207 | pids[child].level = pids[pid].level + 1; | ||
208 | pids[child].uid = pid_get_uid(child); | ||
209 | } | ||
210 | sprintf(lineptr, " fork"); | ||
211 | break; | ||
212 | case PROC_EVENT_EXEC: | ||
213 | pid = proc_ev->event_data.exec.process_tgid; | ||
214 | sprintf(lineptr, " exec"); | ||
215 | break; | ||
216 | |||
217 | case PROC_EVENT_EXIT: | ||
218 | if (proc_ev->event_data.exit.process_pid != | ||
219 | proc_ev->event_data.exit.process_tgid) | ||
220 | continue; // this is a thread, not a process | ||
221 | |||
222 | pid = proc_ev->event_data.exit.process_tgid; | ||
223 | remove_pid = 1; | ||
224 | sprintf(lineptr, " exit"); | ||
225 | break; | ||
226 | |||
227 | case PROC_EVENT_UID: | ||
228 | pid = proc_ev->event_data.id.process_tgid; | ||
229 | sprintf(lineptr, " uid "); | ||
230 | break; | ||
231 | |||
232 | case PROC_EVENT_GID: | ||
233 | pid = proc_ev->event_data.id.process_tgid; | ||
234 | sprintf(lineptr, " gid "); | ||
235 | break; | ||
236 | |||
237 | case PROC_EVENT_SID: | ||
238 | pid = proc_ev->event_data.sid.process_tgid; | ||
239 | sprintf(lineptr, " sid "); | ||
240 | break; | ||
241 | |||
242 | default: | ||
243 | sprintf(lineptr, "\n"); | ||
244 | continue; | ||
245 | } | ||
246 | |||
247 | int add_new = 0; | ||
248 | if (pids[pid].level < 0) // not a firejail process | ||
249 | continue; | ||
250 | else if (pids[pid].level == 0) { // new porcess, do we track it? | ||
251 | if (pid_is_firejail(pid) && mypid == 0) { | ||
252 | pids[pid].level = 1; | ||
253 | add_new = 1; | ||
254 | } | ||
255 | else { | ||
256 | pids[pid].level = -1; | ||
257 | continue; | ||
258 | } | ||
259 | } | ||
260 | |||
261 | lineptr += strlen(lineptr); | ||
262 | sprintf(lineptr, " %u", pid); | ||
263 | lineptr += strlen(lineptr); | ||
264 | |||
265 | char *user = pids[pid].user; | ||
266 | if (!user) | ||
267 | user = pid_get_user_name(pids[pid].uid); | ||
268 | if (user) { | ||
269 | pids[pid].user = user; | ||
270 | sprintf(lineptr, " (%s)", user); | ||
271 | lineptr += strlen(lineptr); | ||
272 | } | ||
273 | |||
274 | |||
275 | int sandbox_closed = 0; // exit sandbox flag | ||
276 | char *cmd = pids[pid].cmd; | ||
277 | if (!cmd) { | ||
278 | cmd = pid_proc_cmdline(pid); | ||
279 | } | ||
280 | if (add_new) { | ||
281 | if (!cmd) | ||
282 | sprintf(lineptr, " NEW SANDBOX\n"); | ||
283 | else | ||
284 | sprintf(lineptr, " NEW SANDBOX: %s\n", cmd); | ||
285 | lineptr += strlen(lineptr); | ||
286 | } | ||
287 | else if (proc_ev->what == PROC_EVENT_EXIT && pids[pid].level == 1) { | ||
288 | sprintf(lineptr, " EXIT SANDBOX\n"); | ||
289 | lineptr += strlen(lineptr); | ||
290 | if (mypid == pid) | ||
291 | sandbox_closed = 1; | ||
292 | } | ||
293 | else { | ||
294 | if (!cmd) { | ||
295 | cmd = pid_proc_cmdline(pid); | ||
296 | } | ||
297 | if (cmd == NULL) | ||
298 | sprintf(lineptr, "\n"); | ||
299 | else { | ||
300 | sprintf(lineptr, " %s\n", cmd); | ||
301 | free(cmd); | ||
302 | } | ||
303 | lineptr += strlen(lineptr); | ||
304 | } | ||
305 | (void) lineptr; | ||
306 | |||
307 | // print the event | ||
308 | printf("%s", line); | ||
309 | fflush(0); | ||
310 | |||
311 | // unflag pid for exit events | ||
312 | if (remove_pid) { | ||
313 | if (pids[pid].user) | ||
314 | free(pids[pid].user); | ||
315 | if (pids[pid].cmd) | ||
316 | free(pids[pid].cmd); | ||
317 | memset(&pids[pid], 0, sizeof(Process)); | ||
318 | } | ||
319 | |||
320 | // print forked child | ||
321 | if (child) { | ||
322 | cmd = pid_proc_cmdline(child); | ||
323 | if (cmd) { | ||
324 | printf("\tchild %u %s\n", child, cmd); | ||
325 | free(cmd); | ||
326 | } | ||
327 | else | ||
328 | printf("\tchild %u\n", child); | ||
329 | } | ||
330 | |||
331 | // on uid events the uid is changing | ||
332 | if (proc_ev->what == PROC_EVENT_UID) { | ||
333 | if (pids[pid].user) | ||
334 | free(pids[pid].user); | ||
335 | pids[pid].user = 0; | ||
336 | pids[pid].uid = pid_get_uid(pid); | ||
337 | } | ||
338 | |||
339 | if (sandbox_closed) | ||
340 | exit(0); | ||
341 | } | ||
342 | } | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | static void procevent_print_pids(void) { | ||
347 | // print files | ||
348 | int i; | ||
349 | for (i = 0; i < max_pids; i++) { | ||
350 | if (pids[i].level == 1) | ||
351 | pid_print_tree(i, 0, 1); | ||
352 | } | ||
353 | printf("\n"); | ||
354 | } | ||
355 | |||
356 | void procevent(pid_t pid) { | ||
357 | // need to be root for this | ||
358 | if (getuid() != 0) { | ||
359 | fprintf(stderr, "Error: you need to be root to get process events\n"); | ||
360 | exit(1); | ||
361 | } | ||
362 | |||
363 | // read and print sandboxed processes | ||
364 | pid_read(pid); | ||
365 | procevent_print_pids(); | ||
366 | |||
367 | // monitor using netlink | ||
368 | int sock = procevent_netlink_setup(); | ||
369 | if (sock < 0) { | ||
370 | fprintf(stderr, "Error: cannot open netlink socket\n"); | ||
371 | exit(1); | ||
372 | } | ||
373 | |||
374 | procevent_monitor(sock, pid); // it will never return from here | ||
375 | assert(0); | ||
376 | close(sock); // quiet static analyzers | ||
377 | } | ||
diff --git a/src/firemon/route.c b/src/firemon/route.c new file mode 100644 index 000000000..7f559c7b5 --- /dev/null +++ b/src/firemon/route.c | |||
@@ -0,0 +1,213 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | #include <assert.h> | ||
22 | #include <arpa/inet.h> | ||
23 | #define MAXBUF 4096 | ||
24 | |||
25 | typedef struct iflist_t { | ||
26 | struct iflist_t *next; | ||
27 | uint32_t ip; | ||
28 | } IfList; | ||
29 | static IfList *ifs = NULL; | ||
30 | static char last_start[MAXBUF + 1]; | ||
31 | |||
32 | static IfList *list_find(uint32_t ip, uint32_t mask) { | ||
33 | IfList *ptr = ifs; | ||
34 | while (ptr) { | ||
35 | if ((ptr->ip & mask) == (ip & mask)) | ||
36 | return ptr; | ||
37 | ptr = ptr->next; | ||
38 | } | ||
39 | |||
40 | return NULL; | ||
41 | } | ||
42 | |||
43 | static void extract_if(const char *fname) { | ||
44 | // clear interface list | ||
45 | while (ifs) { | ||
46 | IfList *tmp = ifs->next; | ||
47 | free(ifs); | ||
48 | ifs = tmp; | ||
49 | } | ||
50 | assert(ifs == NULL); | ||
51 | |||
52 | FILE *fp = fopen(fname, "r"); | ||
53 | if (!fp) | ||
54 | return; | ||
55 | |||
56 | char buf[MAXBUF]; | ||
57 | int state = 0; // 0 -wait for Local | ||
58 | // | ||
59 | while (fgets(buf, MAXBUF, fp)) { | ||
60 | // remove blanks, \n | ||
61 | char *ptr = buf; | ||
62 | while (*ptr == ' ' || *ptr == '\t') | ||
63 | ptr++; | ||
64 | char *start = ptr; | ||
65 | if (*start == '\0') | ||
66 | continue; | ||
67 | ptr = strchr(ptr, '\n'); | ||
68 | if (ptr) | ||
69 | *ptr = '\0'; | ||
70 | |||
71 | if (state == 0) { | ||
72 | if (strncmp(buf, "Local:", 6) == 0) { | ||
73 | state = 1; | ||
74 | continue; | ||
75 | } | ||
76 | } | ||
77 | else if (state == 1) { | ||
78 | // remove broadcast addresses | ||
79 | if (strstr(start,"BROADCAST")) | ||
80 | continue; | ||
81 | else if (*start == '+') | ||
82 | continue; | ||
83 | else if (*start == '|') { | ||
84 | memset(last_start, 0, MAXBUF + 1); | ||
85 | strncpy(last_start, start, MAXBUF); | ||
86 | continue; | ||
87 | } | ||
88 | else if (strstr(buf, "LOCAL")) { | ||
89 | // printf("%s %s\n", last_start, start); | ||
90 | unsigned mbits; | ||
91 | sscanf(start, "/%u", &mbits); | ||
92 | if (mbits != 32) | ||
93 | continue; | ||
94 | |||
95 | unsigned a, b, c, d; | ||
96 | if (sscanf(last_start, "|-- %u.%u.%u.%u", &a, &b, &c, &d) != 4 || a > 255 || b > 255 || c > 255 || d > 255) | ||
97 | continue; | ||
98 | |||
99 | IfList *newif = malloc(sizeof(IfList)); | ||
100 | if (!newif) | ||
101 | errExit("malloc"); | ||
102 | newif->ip = a * 0x1000000 + b * 0x10000 + c * 0x100 + d; | ||
103 | newif->next = ifs; | ||
104 | ifs = newif; | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | |||
109 | fclose(fp); | ||
110 | |||
111 | |||
112 | } | ||
113 | |||
114 | static void print_route(const char *fname) { | ||
115 | FILE *fp = fopen(fname, "r"); | ||
116 | if (!fp) | ||
117 | return; | ||
118 | |||
119 | printf(" Route table:\n"); | ||
120 | char buf[MAXBUF]; | ||
121 | while (fgets(buf, MAXBUF, fp)) { | ||
122 | // remove blanks, \n | ||
123 | char *ptr = buf; | ||
124 | while (*ptr == ' ' || *ptr == '\t') | ||
125 | ptr++; | ||
126 | char *start = ptr; | ||
127 | if (*start == '\0') | ||
128 | continue; | ||
129 | ptr = strchr(ptr, '\n'); | ||
130 | if (ptr) | ||
131 | *ptr = '\0'; | ||
132 | |||
133 | // remove table header | ||
134 | //Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT | ||
135 | if (strncmp(start, "Iface", 5) == 0) | ||
136 | continue; | ||
137 | |||
138 | // extract data | ||
139 | char ifname[64]; | ||
140 | char destination[64]; | ||
141 | char gateway[64]; | ||
142 | char flags[64]; | ||
143 | char refcnt[64]; | ||
144 | char use[64]; | ||
145 | char metric[64]; | ||
146 | char mask[64]; | ||
147 | int rv = sscanf(start, "%s %s %s %s %s %s %s %s\n", ifname, destination, gateway, flags, refcnt, use, metric, mask); | ||
148 | if (rv != 8) | ||
149 | continue; | ||
150 | |||
151 | // destination ip | ||
152 | uint32_t destip; | ||
153 | sscanf(destination, "%x", &destip); | ||
154 | destip = ntohl(destip); | ||
155 | uint32_t destmask; | ||
156 | sscanf(mask, "%x", &destmask); | ||
157 | destmask = ntohl(destmask); | ||
158 | uint32_t gw; | ||
159 | sscanf(gateway, "%x", &gw); | ||
160 | gw = ntohl(gw); | ||
161 | |||
162 | // printf("#%s# #%s# #%s# #%s# #%s# #%s# #%s# #%s#\n", ifname, destination, gateway, flags, refcnt, use, metric, mask); | ||
163 | if (gw != 0) | ||
164 | printf(" %u.%u.%u.%u/%u via %u.%u.%u.%u, dev %s, metric %s\n", | ||
165 | PRINT_IP(destip), mask2bits(destmask), | ||
166 | PRINT_IP(gw), | ||
167 | ifname, | ||
168 | metric); | ||
169 | else { // this is an interface | ||
170 | IfList *ifentry = list_find(destip, destmask); | ||
171 | if (ifentry) { | ||
172 | printf(" %u.%u.%u.%u/%u, dev %s, scope link src %d.%d.%d.%d\n", | ||
173 | PRINT_IP(destip), mask2bits(destmask), | ||
174 | ifname, | ||
175 | PRINT_IP(ifentry->ip)); | ||
176 | } | ||
177 | } | ||
178 | } | ||
179 | |||
180 | fclose(fp); | ||
181 | |||
182 | } | ||
183 | |||
184 | void route(pid_t pid) { | ||
185 | if (getuid() == 0) | ||
186 | firemon_drop_privs(); | ||
187 | |||
188 | pid_read(pid); | ||
189 | |||
190 | // print processes | ||
191 | int i; | ||
192 | for (i = 0; i < max_pids; i++) { | ||
193 | if (pids[i].level == 1) { | ||
194 | pid_print_list(i, 0); | ||
195 | int child = find_child(i); | ||
196 | if (child != -1) { | ||
197 | char *fname; | ||
198 | if (asprintf(&fname, "/proc/%d/net/fib_trie", child) == -1) | ||
199 | errExit("asprintf"); | ||
200 | extract_if(fname); | ||
201 | free(fname); | ||
202 | |||
203 | if (asprintf(&fname, "/proc/%d/net/route", child) == -1) | ||
204 | errExit("asprintf"); | ||
205 | print_route(fname); | ||
206 | free(fname); | ||
207 | printf("\n"); | ||
208 | } | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | |||
213 | |||
diff --git a/src/firemon/seccomp.c b/src/firemon/seccomp.c new file mode 100644 index 000000000..4ffc93f2e --- /dev/null +++ b/src/firemon/seccomp.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | |||
22 | #define MAXBUF 4098 | ||
23 | static void print_seccomp(int pid) { | ||
24 | char *file; | ||
25 | if (asprintf(&file, "/proc/%d/status", pid) == -1) { | ||
26 | errExit("asprintf"); | ||
27 | exit(1); | ||
28 | } | ||
29 | |||
30 | FILE *fp = fopen(file, "r"); | ||
31 | if (!fp) { | ||
32 | printf(" Error: cannot open %s\n", file); | ||
33 | free(file); | ||
34 | return; | ||
35 | } | ||
36 | |||
37 | char buf[MAXBUF]; | ||
38 | while (fgets(buf, MAXBUF, fp)) { | ||
39 | if (strncmp(buf, "Seccomp:", 8) == 0) { | ||
40 | printf(" %s", buf); | ||
41 | fflush(0); | ||
42 | fclose(fp); | ||
43 | free(file); | ||
44 | return; | ||
45 | } | ||
46 | } | ||
47 | fclose(fp); | ||
48 | free(file); | ||
49 | } | ||
50 | |||
51 | void seccomp(pid_t pid) { | ||
52 | if (getuid() == 0) | ||
53 | firemon_drop_privs(); | ||
54 | |||
55 | pid_read(pid); // include all processes | ||
56 | |||
57 | // print processes | ||
58 | int i; | ||
59 | for (i = 0; i < max_pids; i++) { | ||
60 | if (pids[i].level == 1) { | ||
61 | pid_print_list(i, 0); | ||
62 | int child = find_child(i); | ||
63 | if (child != -1) | ||
64 | print_seccomp(child); | ||
65 | } | ||
66 | } | ||
67 | printf("\n"); | ||
68 | } | ||
69 | |||
diff --git a/src/firemon/top.c b/src/firemon/top.c new file mode 100644 index 000000000..1eb753694 --- /dev/null +++ b/src/firemon/top.c | |||
@@ -0,0 +1,297 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | #include <termios.h> | ||
22 | #include <sys/ioctl.h> | ||
23 | #include <sys/types.h> | ||
24 | #include <sys/stat.h> | ||
25 | #include <unistd.h> | ||
26 | |||
27 | static unsigned pgs_rss = 0; | ||
28 | static unsigned pgs_shared = 0; | ||
29 | static unsigned clocktick = 0; | ||
30 | static unsigned long long sysuptime = 0; | ||
31 | |||
32 | static char *get_header(void) { | ||
33 | char *rv; | ||
34 | if (asprintf(&rv, "%-5.5s %-9.9s %-8.8s %-8.8s %-5.5s %-4.4s %-9.9s %s", | ||
35 | "PID", "User", "RES(KiB)", "SHR(KiB)", "CPU%", "Prcs", "Uptime", "Command") == -1) | ||
36 | errExit("asprintf"); | ||
37 | |||
38 | return rv; | ||
39 | } | ||
40 | |||
41 | |||
42 | // recursivity!!! | ||
43 | static char *print_top(unsigned index, unsigned parent, unsigned *utime, unsigned *stime, unsigned itv, float *cpu, int *cnt) { | ||
44 | char *rv = NULL; | ||
45 | |||
46 | char procdir[20]; | ||
47 | snprintf(procdir, 20, "/proc/%u", index); | ||
48 | struct stat s; | ||
49 | if (stat(procdir, &s) == -1) | ||
50 | return NULL; | ||
51 | |||
52 | if (pids[index].level == 1) { | ||
53 | pgs_rss = 0; | ||
54 | pgs_shared = 0; | ||
55 | *utime = 0; | ||
56 | *stime = 0; | ||
57 | *cnt = 0; | ||
58 | } | ||
59 | |||
60 | (*cnt)++; | ||
61 | pid_getmem(index, &pgs_rss, &pgs_shared); | ||
62 | unsigned utmp; | ||
63 | unsigned stmp; | ||
64 | pid_get_cpu_time(index, &utmp, &stmp); | ||
65 | *utime += utmp; | ||
66 | *stime += stmp; | ||
67 | |||
68 | |||
69 | int i; | ||
70 | for (i = index + 1; i < max_pids; i++) { | ||
71 | if (pids[i].parent == index) | ||
72 | print_top(i, index, utime, stime, itv, cpu, cnt); | ||
73 | } | ||
74 | |||
75 | if (pids[index].level == 1) { | ||
76 | // pid | ||
77 | char pidstr[10]; | ||
78 | snprintf(pidstr, 10, "%u", index); | ||
79 | |||
80 | // command | ||
81 | char *cmd = pid_proc_cmdline(index); | ||
82 | char *ptrcmd; | ||
83 | if (cmd == NULL) { | ||
84 | if (pids[index].zombie) | ||
85 | ptrcmd = "(zombie)"; | ||
86 | else | ||
87 | ptrcmd = ""; | ||
88 | } | ||
89 | else | ||
90 | ptrcmd = cmd; | ||
91 | |||
92 | // user | ||
93 | char *user = pid_get_user_name(pids[index].uid); | ||
94 | char *ptruser; | ||
95 | if (user) | ||
96 | ptruser = user; | ||
97 | else | ||
98 | ptruser = ""; | ||
99 | |||
100 | // memory | ||
101 | int pgsz = getpagesize(); | ||
102 | char rss[10]; | ||
103 | snprintf(rss, 10, "%u", pgs_rss * pgsz / 1024); | ||
104 | char shared[10]; | ||
105 | snprintf(shared, 10, "%u", pgs_shared * pgsz / 1024); | ||
106 | |||
107 | // uptime | ||
108 | unsigned long long uptime = pid_get_start_time(index); | ||
109 | if (clocktick == 0) | ||
110 | clocktick = sysconf(_SC_CLK_TCK); | ||
111 | uptime /= clocktick; | ||
112 | uptime = sysuptime - uptime; | ||
113 | unsigned sec = uptime % 60; | ||
114 | uptime -= sec; | ||
115 | uptime /= 60; | ||
116 | unsigned min = uptime % 60; | ||
117 | uptime -= min; | ||
118 | uptime /= 60; | ||
119 | unsigned hour = uptime; | ||
120 | char uptime_str[50]; | ||
121 | snprintf(uptime_str, 50, "%02u:%02u:%02u", hour, min, sec); | ||
122 | |||
123 | // cpu | ||
124 | itv *= clocktick; | ||
125 | float ud = (float) (*utime - pids[index].utime) / itv * 100; | ||
126 | float sd = (float) (*stime - pids[index].stime) / itv * 100; | ||
127 | float cd = ud + sd; | ||
128 | *cpu = cd; | ||
129 | char cpu_str[10]; | ||
130 | snprintf(cpu_str, 10, "%2.1f", cd); | ||
131 | |||
132 | // process count | ||
133 | char prcs_str[10]; | ||
134 | snprintf(prcs_str, 10, "%d", *cnt); | ||
135 | |||
136 | if (asprintf(&rv, "%-5.5s %-9.9s %-8.8s %-8.8s %-5.5s %-4.4s %-9.9s %s", | ||
137 | pidstr, ptruser, rss, shared, cpu_str, prcs_str, uptime_str, ptrcmd) == -1) | ||
138 | errExit("asprintf"); | ||
139 | |||
140 | if (cmd) | ||
141 | free(cmd); | ||
142 | if (user) | ||
143 | free(user); | ||
144 | |||
145 | } | ||
146 | |||
147 | return rv; | ||
148 | } | ||
149 | |||
150 | |||
151 | typedef struct node_t { | ||
152 | struct node_t *next; | ||
153 | char *line; | ||
154 | float cpu; | ||
155 | } Node; | ||
156 | |||
157 | static Node *head = NULL; | ||
158 | |||
159 | static void head_clear(void) { | ||
160 | Node *ptr = head; | ||
161 | while (ptr) { | ||
162 | if (ptr->line) | ||
163 | free(ptr->line); | ||
164 | Node *next = ptr->next; | ||
165 | free(ptr); | ||
166 | ptr = next; | ||
167 | } | ||
168 | |||
169 | head = NULL; | ||
170 | } | ||
171 | |||
172 | static void head_add(float cpu, char *line) { | ||
173 | // allocate a new node structure | ||
174 | Node *node = malloc(sizeof(Node)); | ||
175 | if (!node) | ||
176 | errExit("malloc"); | ||
177 | node->line = line; | ||
178 | node->cpu = cpu; | ||
179 | node->next = NULL; | ||
180 | |||
181 | // insert in first list position | ||
182 | if (head == NULL || head->cpu < cpu) { | ||
183 | node->next = head; | ||
184 | head = node; | ||
185 | return; | ||
186 | } | ||
187 | |||
188 | // insert in the right place | ||
189 | Node *ptr = head; | ||
190 | while (1) { | ||
191 | // last position | ||
192 | Node *current = ptr->next; | ||
193 | if (current == NULL) { | ||
194 | ptr->next = node; | ||
195 | return; | ||
196 | } | ||
197 | |||
198 | // current position | ||
199 | if (current->cpu < cpu) { | ||
200 | ptr->next = node; | ||
201 | node->next = current; | ||
202 | return; | ||
203 | } | ||
204 | |||
205 | ptr = current; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | void head_print(int col, int row) { | ||
210 | Node *ptr = head; | ||
211 | int current = 0; | ||
212 | while (ptr) { | ||
213 | if (current >= row) | ||
214 | break; | ||
215 | |||
216 | if (strlen(ptr->line) > col) | ||
217 | ptr->line[col] = '\0'; | ||
218 | |||
219 | if (ptr->next == NULL || current == (row - 1)) { | ||
220 | printf("%s", ptr->line); | ||
221 | fflush(0); | ||
222 | } | ||
223 | else | ||
224 | printf("%s\n", ptr->line); | ||
225 | |||
226 | ptr = ptr->next; | ||
227 | current++; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | void top(void) { | ||
232 | if (getuid() == 0) | ||
233 | firemon_drop_privs(); | ||
234 | |||
235 | while (1) { | ||
236 | // clear linked list | ||
237 | head_clear(); | ||
238 | |||
239 | // set pid table | ||
240 | int i; | ||
241 | int itv = 5; // 5 second interval | ||
242 | pid_read(0); | ||
243 | |||
244 | // start cpu measurements | ||
245 | unsigned utime = 0; | ||
246 | unsigned stime = 0; | ||
247 | for (i = 0; i < max_pids; i++) { | ||
248 | if (pids[i].level == 1) | ||
249 | pid_store_cpu(i, 0, &utime, &stime); | ||
250 | } | ||
251 | |||
252 | // wait 5 seconds | ||
253 | firemon_sleep(itv); | ||
254 | |||
255 | // grab screen size | ||
256 | struct winsize sz; | ||
257 | int row = 24; | ||
258 | int col = 80; | ||
259 | if (!ioctl(0, TIOCGWINSZ, &sz)) { | ||
260 | col = sz.ws_col; | ||
261 | row = sz.ws_row; | ||
262 | } | ||
263 | |||
264 | // start printing | ||
265 | firemon_clrscr(); | ||
266 | char *header = get_header(); | ||
267 | if (strlen(header) > col) | ||
268 | header[col] = '\0'; | ||
269 | printf("%s\n", header); | ||
270 | if (row > 0) | ||
271 | row--; | ||
272 | free(header); | ||
273 | |||
274 | // find system uptime | ||
275 | FILE *fp = fopen("/proc/uptime", "r"); | ||
276 | if (fp) { | ||
277 | float f; | ||
278 | int rv = fscanf(fp, "%f", &f); | ||
279 | (void) rv; | ||
280 | sysuptime = (unsigned long long) f; | ||
281 | fclose(fp); | ||
282 | } | ||
283 | |||
284 | // print processes | ||
285 | for (i = 0; i < max_pids; i++) { | ||
286 | if (pids[i].level == 1) { | ||
287 | float cpu = 0; | ||
288 | int cnt = 0; // process count | ||
289 | char *line = print_top(i, 0, &utime, &stime, itv, &cpu, &cnt); | ||
290 | if (line) | ||
291 | head_add(cpu, line); | ||
292 | } | ||
293 | } | ||
294 | head_print(col, row); | ||
295 | } | ||
296 | } | ||
297 | |||
diff --git a/src/firemon/tree.c b/src/firemon/tree.c new file mode 100644 index 000000000..97e0e1f13 --- /dev/null +++ b/src/firemon/tree.c | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | |||
22 | void tree(pid_t pid) { | ||
23 | if (getuid() == 0) | ||
24 | firemon_drop_privs(); | ||
25 | |||
26 | pid_read(pid); // include all processes | ||
27 | |||
28 | // print processes | ||
29 | int i; | ||
30 | for (i = 0; i < max_pids; i++) { | ||
31 | if (pids[i].level == 1) | ||
32 | pid_print_tree(i, 0, arg_nowrap); | ||
33 | } | ||
34 | printf("\n"); | ||
35 | } | ||
36 | |||
diff --git a/src/firemon/usage.c b/src/firemon/usage.c new file mode 100644 index 000000000..52788807a --- /dev/null +++ b/src/firemon/usage.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | |||
22 | void usage(void) { | ||
23 | printf("firemon - version %s\n", VERSION); | ||
24 | printf("Usage: firemon [OPTIONS] [PID]\n\n"); | ||
25 | printf("Monitor processes started in a Firejail sandbox. Without any PID specified,\n"); | ||
26 | printf("all processes started by Firejail are monitored. Descendants of these processes\n"); | ||
27 | printf("are also being monitored.\n\n"); | ||
28 | printf("Options:\n"); | ||
29 | printf("\t--arp - print ARP table for each sandbox.\n\n"); | ||
30 | printf("\t--caps - print capabilities configuration for each sandbox.\n\n"); | ||
31 | printf("\t--cgroup - print control group information for each sandbox.\n\n"); | ||
32 | printf("\t--cpu - print CPU affinity for each sandbox.\n\n"); | ||
33 | printf("\t--help, -? - this help screen.\n\n"); | ||
34 | printf("\t--interface - print network interface information for each sandbox.\n\n"); | ||
35 | printf("\t--list - list all sandboxes.\n\n"); | ||
36 | printf("\t--name=name - print information only about named sandbox.\n\n"); | ||
37 | printf("\t--netstats - monitor network statistics for sandboxes creating a new\n"); | ||
38 | printf("\t\tnetwork namespace.\n\n"); | ||
39 | printf("\t--route - print route table for each sandbox.\n\n"); | ||
40 | printf("\t--seccomp - print seccomp configuration for each sandbox.\n\n"); | ||
41 | printf("\t--tree - print a tree of all sandboxed processes.\n\n"); | ||
42 | printf("\t--top - monitor the most CPU-intensive sandboxes.\n\n"); | ||
43 | printf("\t--version - print program version and exit.\n\n"); | ||
44 | |||
45 | printf("Without any options, firemon monitors all fork, exec, id change, and exit events\n"); | ||
46 | printf("in the sandbox. Monitoring a specific PID is also supported.\n\n"); | ||
47 | |||
48 | printf("Option --list prints a list of all sandboxes. The format for each entry is as\n"); | ||
49 | printf("follows:\n\n"); | ||
50 | printf("\tPID:USER:Command\n\n"); | ||
51 | |||
52 | printf("Option --tree prints the tree of processes running in the sandbox. The format\n"); | ||
53 | printf("for each process entry is as follows:\n\n"); | ||
54 | printf("\tPID:USER:Command\n\n"); | ||
55 | |||
56 | printf("Option --top is similar to the UNIX top command, however it applies only to\n"); | ||
57 | printf("sandboxes. Listed below are the available fields (columns) in alphabetical\n"); | ||
58 | printf("order:\n\n"); | ||
59 | printf("\tCommand - command used to start the sandbox.\n"); | ||
60 | printf("\tCPU%% - CPU usage, the sandbox share of the elapsed CPU time since the\n"); | ||
61 | printf("\t last screen update\n"); | ||
62 | printf("\tPID - Unique process ID for the task controlling the sandbox.\n"); | ||
63 | printf("\tPrcs - number of processes running in sandbox, including the controlling\n"); | ||
64 | printf("\t process.\n"); | ||
65 | printf("\tRES - Resident Memory Size (KiB), sandbox non-swapped physical memory.\n"); | ||
66 | printf("\t It is a sum of the RES values for all processes running in the\n"); | ||
67 | printf("\t sandbox.\n"); | ||
68 | printf("\tSHR - Shared Memory Size (KiB), it reflects memory shared with other\n"); | ||
69 | printf("\t processes. It is a sum of the SHR values for all processes running\n"); | ||
70 | printf("\t in the sandbox, including the controlling process.\n"); | ||
71 | printf("\tUptime - sandbox running time in hours:minutes:seconds format.\n"); | ||
72 | printf("\tUser - The owner of the sandbox.\n"); | ||
73 | printf("\n"); | ||
74 | printf("License GPL version 2 or later\n"); | ||
75 | printf("Homepage: http://firejail.sourceforge.net\n"); | ||
76 | printf("\n"); | ||
77 | } | ||
diff --git a/src/fshaper/fshaper.sh b/src/fshaper/fshaper.sh new file mode 100755 index 000000000..4045fd5a4 --- /dev/null +++ b/src/fshaper/fshaper.sh | |||
@@ -0,0 +1,69 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | usage() { | ||
4 | echo "Usage:" | ||
5 | echo " fshaper.sh --status" | ||
6 | echo " fshaper.sh --clear device" | ||
7 | echo " fshaper.sh --set device download-speed upload-speed" | ||
8 | } | ||
9 | |||
10 | if [ "$1" = "--status" ]; then | ||
11 | /sbin/tc -s qdisc ls | ||
12 | /sbin/tc -s class ls | ||
13 | exit | ||
14 | fi | ||
15 | |||
16 | if [ "$1" = "--clear" ]; then | ||
17 | if [ $# -ne 2 ]; then | ||
18 | echo "Error: invalid command" | ||
19 | usage | ||
20 | exit | ||
21 | fi | ||
22 | |||
23 | DEV=$2 | ||
24 | echo "Removing bandwith limits" | ||
25 | /sbin/tc qdisc del dev $DEV root 2> /dev/null > /dev/null | ||
26 | /sbin/tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null | ||
27 | exit | ||
28 | |||
29 | fi | ||
30 | |||
31 | if [ "$1" = "--set" ]; then | ||
32 | DEV=$2 | ||
33 | echo "Removing bandwith limit" | ||
34 | /sbin/tc qdisc del dev $DEV ingress #2> /dev/null > /dev/null | ||
35 | |||
36 | if [ $# -ne 4 ]; then | ||
37 | echo "Error: missing parameters" | ||
38 | usage | ||
39 | exit | ||
40 | fi | ||
41 | |||
42 | DEV=$2 | ||
43 | echo "Configuring interface $DEV " | ||
44 | |||
45 | IN=$3 | ||
46 | IN=$((${IN} * 8)) | ||
47 | echo "Download speed ${IN}kbps" | ||
48 | |||
49 | OUT=$4 | ||
50 | OUT=$((${OUT} * 8)) | ||
51 | echo "Upload speed ${OUT}kbps" | ||
52 | |||
53 | echo "cleaning limits" | ||
54 | /sbin/tc qdisc del dev $DEV root 2> /dev/null > /dev/null | ||
55 | /sbin/tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null | ||
56 | |||
57 | echo "configuring tc ingress" | ||
58 | /sbin/tc qdisc add dev $DEV handle ffff: ingress #2> /dev/null > /dev/null | ||
59 | /sbin/tc filter add dev $DEV parent ffff: protocol ip prio 50 u32 match ip src \ | ||
60 | 0.0.0.0/0 police rate ${IN}kbit burst 10k drop flowid :1 #2> /dev/null > /dev/null | ||
61 | |||
62 | echo "configuring tc egress" | ||
63 | /sbin/tc qdisc add dev $DEV root tbf rate ${OUT}kbit latency 25ms burst 10k #2> /dev/null > /dev/null | ||
64 | exit | ||
65 | fi | ||
66 | |||
67 | echo "Error: missing parameters" | ||
68 | usage | ||
69 | exit 1 | ||
diff --git a/src/ftee/Makefile.in b/src/ftee/Makefile.in new file mode 100644 index 000000000..6911f0a3c --- /dev/null +++ b/src/ftee/Makefile.in | |||
@@ -0,0 +1,24 @@ | |||
1 | all: ftee | ||
2 | |||
3 | PREFIX=@prefix@ | ||
4 | VERSION=@PACKAGE_VERSION@ | ||
5 | NAME=@PACKAGE_NAME@ | ||
6 | |||
7 | H_FILE_LIST = $(wildcard *.[h]) | ||
8 | C_FILE_LIST = $(wildcard *.c) | ||
9 | OBJS = $(C_FILE_LIST:.c=.o) | ||
10 | BINOBJS = $(foreach file, $(OBJS), $file) | ||
11 | CFLAGS += -ggdb -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(PREFIX)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security | ||
12 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread | ||
13 | |||
14 | %.o : %.c $(H_FILE_LIST) | ||
15 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ | ||
16 | |||
17 | ftee: $(OBJS) | ||
18 | $(CC) $(LDFLAGS) -o $@ $(OBJS) | ||
19 | |||
20 | clean:; rm -f *.o ftee | ||
21 | |||
22 | distclean: clean | ||
23 | rm -fr Makefile | ||
24 | |||
diff --git a/src/ftee/ftee.h b/src/ftee/ftee.h new file mode 100644 index 000000000..a28cc5bb5 --- /dev/null +++ b/src/ftee/ftee.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #ifndef FTEE_H | ||
21 | #define FTEE_H | ||
22 | #include "../include/common.h" | ||
23 | |||
24 | #endif \ No newline at end of file | ||
diff --git a/src/ftee/main.c b/src/ftee/main.c new file mode 100644 index 000000000..4dca3cf48 --- /dev/null +++ b/src/ftee/main.c | |||
@@ -0,0 +1,228 @@ | |||
1 | #include "ftee.h" | ||
2 | #include <errno.h> | ||
3 | #include <sys/types.h> | ||
4 | #include <sys/stat.h> | ||
5 | #include <unistd.h> | ||
6 | #define MAXBUF 512 | ||
7 | |||
8 | static unsigned char buf[MAXBUF]; | ||
9 | |||
10 | static FILE *out_fp = NULL; | ||
11 | static int out_cnt = 0; | ||
12 | static int out_max = 500 * 1024; | ||
13 | |||
14 | static void log_close(void) { | ||
15 | if (out_fp) { | ||
16 | fclose(out_fp); | ||
17 | out_fp = NULL; | ||
18 | } | ||
19 | } | ||
20 | |||
21 | static void log_rotate(const char *fname) { | ||
22 | struct stat s; | ||
23 | int index = strlen(fname); | ||
24 | char *name1 = malloc(index + 2 + 1); | ||
25 | char *name2 = malloc(index + 2 + 1); | ||
26 | if (!name1 || !name2) | ||
27 | errExit("malloc"); | ||
28 | strcpy(name1, fname); | ||
29 | strcpy(name2, fname); | ||
30 | fflush(0); | ||
31 | |||
32 | // delete filename.5 | ||
33 | sprintf(name1 + index, ".5"); | ||
34 | if (stat(name1, &s) == 0) { | ||
35 | int rv = unlink(name1); | ||
36 | if (rv == -1) | ||
37 | perror("unlink"); | ||
38 | } | ||
39 | |||
40 | // move files 1 to 4 down one position | ||
41 | sprintf(name2 + index, ".4"); | ||
42 | if (stat(name2, &s) == 0) { | ||
43 | int rv = rename(name2, name1); | ||
44 | if (rv == -1) | ||
45 | perror("rename"); | ||
46 | } | ||
47 | |||
48 | sprintf(name1 + index, ".3"); | ||
49 | if (stat(name1, &s) == 0) { | ||
50 | int rv = rename(name1, name2); | ||
51 | if (rv == -1) | ||
52 | perror("rename"); | ||
53 | } | ||
54 | |||
55 | sprintf(name2 + index, ".2"); | ||
56 | if (stat(name2, &s) == 0) { | ||
57 | /* coverity[toctou] */ | ||
58 | int rv = rename(name2, name1); | ||
59 | if (rv == -1) | ||
60 | perror("rename"); | ||
61 | } | ||
62 | |||
63 | sprintf(name1 + index, ".1"); | ||
64 | if (stat(name1, &s) == 0) { | ||
65 | int rv = rename(name1, name2); | ||
66 | if (rv == -1) | ||
67 | perror("rename"); | ||
68 | } | ||
69 | |||
70 | // move the first file | ||
71 | if (out_fp) | ||
72 | fclose(out_fp); | ||
73 | |||
74 | out_fp = NULL; | ||
75 | if (stat(fname, &s) == 0) { | ||
76 | int rv = rename(fname, name1); | ||
77 | if (rv == -1) | ||
78 | perror("rename"); | ||
79 | } | ||
80 | |||
81 | free(name1); | ||
82 | free(name2); | ||
83 | } | ||
84 | |||
85 | static void log_write(const unsigned char *str, int len, const char *fname) { | ||
86 | assert(fname); | ||
87 | |||
88 | if (out_fp == NULL) { | ||
89 | out_fp = fopen(fname, "w"); | ||
90 | if (!out_fp) { | ||
91 | fprintf(stderr, "Error: cannot open log file %s\n", fname); | ||
92 | exit(1); | ||
93 | } | ||
94 | out_cnt = 0; | ||
95 | } | ||
96 | |||
97 | // rotate files | ||
98 | out_cnt += len; | ||
99 | if (out_cnt >= out_max) { | ||
100 | log_rotate(fname); | ||
101 | |||
102 | // reopen the first file | ||
103 | if (out_fp) | ||
104 | fclose(out_fp); | ||
105 | out_fp = fopen(fname, "w"); | ||
106 | if (!out_fp) { | ||
107 | fprintf(stderr, "Error: cannot open log file %s\n", fname); | ||
108 | exit(1); | ||
109 | } | ||
110 | out_cnt = len; | ||
111 | } | ||
112 | |||
113 | fwrite(str, len, 1, out_fp); | ||
114 | fflush(0); | ||
115 | } | ||
116 | |||
117 | |||
118 | // return 1 if the file is a directory | ||
119 | static int is_dir(const char *fname) { | ||
120 | assert(fname); | ||
121 | if (*fname == '\0') | ||
122 | return 0; | ||
123 | |||
124 | // if fname doesn't end in '/', add one | ||
125 | int rv; | ||
126 | struct stat s; | ||
127 | if (fname[strlen(fname) - 1] == '/') | ||
128 | rv = stat(fname, &s); | ||
129 | else { | ||
130 | char *tmp; | ||
131 | if (asprintf(&tmp, "%s/", fname) == -1) { | ||
132 | fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__); | ||
133 | exit(1); | ||
134 | } | ||
135 | rv = stat(tmp, &s); | ||
136 | free(tmp); | ||
137 | } | ||
138 | |||
139 | if (rv == -1) | ||
140 | return 0; | ||
141 | |||
142 | if (S_ISDIR(s.st_mode)) | ||
143 | return 1; | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | // return 1 if the file is a link | ||
149 | static int is_link(const char *fname) { | ||
150 | assert(fname); | ||
151 | if (*fname == '\0') | ||
152 | return 0; | ||
153 | |||
154 | struct stat s; | ||
155 | if (lstat(fname, &s) == 0) { | ||
156 | if (S_ISLNK(s.st_mode)) | ||
157 | return 1; | ||
158 | } | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | |||
164 | |||
165 | |||
166 | |||
167 | static void usage(void) { | ||
168 | printf("Usage: ftee filename\n"); | ||
169 | } | ||
170 | |||
171 | int main(int argc, char **argv) { | ||
172 | if (argc < 2) { | ||
173 | fprintf(stderr, "Error: please provide a filename to store the program output\n"); | ||
174 | usage(); | ||
175 | exit(1); | ||
176 | } | ||
177 | char *fname = argv[1]; | ||
178 | |||
179 | |||
180 | // do not accept directories, links, and files with ".." | ||
181 | if (strstr(fname, "..") || is_link(fname) || is_dir(fname)) { | ||
182 | fprintf(stderr, "Error: invalid output file. Links, directories and files with \"..\" are not allowed.\n"); | ||
183 | exit(1); | ||
184 | } | ||
185 | |||
186 | struct stat s; | ||
187 | if (stat(fname, &s) == 0) { | ||
188 | // check permissions | ||
189 | if (s.st_uid != getuid() || s.st_gid != getgid()) { | ||
190 | fprintf(stderr, "Error: the output file needs to be owned by the current user.\n"); | ||
191 | exit(1); | ||
192 | } | ||
193 | |||
194 | // check hard links | ||
195 | if (s.st_nlink != 1) { | ||
196 | fprintf(stderr, "Error: no hard links allowed.\n"); | ||
197 | exit(1); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | // check if we can append to this file | ||
202 | /* coverity[toctou] */ | ||
203 | FILE *fp = fopen(fname, "a"); | ||
204 | if (!fp) { | ||
205 | fprintf(stderr, "Error: cannot open output file %s\n", fname); | ||
206 | exit(1); | ||
207 | } | ||
208 | fclose(fp); | ||
209 | |||
210 | |||
211 | // preserve the last log file | ||
212 | log_rotate(fname); | ||
213 | |||
214 | setvbuf (stdout, NULL, _IONBF, 0); | ||
215 | while(1) { | ||
216 | int n = read(0, buf, sizeof(buf)); | ||
217 | if (n < 0 && errno == EINTR) | ||
218 | continue; | ||
219 | if (n <= 0) | ||
220 | break; | ||
221 | |||
222 | fwrite(buf, n, 1, stdout); | ||
223 | log_write(buf, n, fname); | ||
224 | } | ||
225 | |||
226 | log_close(); | ||
227 | return 0; | ||
228 | } | ||
diff --git a/src/include/common.h b/src/include/common.h new file mode 100644 index 000000000..7ce1e9290 --- /dev/null +++ b/src/include/common.h | |||
@@ -0,0 +1,115 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef COMMON_H | ||
22 | #define COMMON_H | ||
23 | #define _GNU_SOURCE | ||
24 | #include <stdio.h> | ||
25 | #include <sys/types.h> | ||
26 | #include <unistd.h> | ||
27 | #include <stdlib.h> | ||
28 | #include <stdint.h> | ||
29 | #include <stddef.h> | ||
30 | #include <string.h> | ||
31 | #include <ctype.h> | ||
32 | #include <assert.h> | ||
33 | |||
34 | #define errExit(msg) do { char msgout[500]; sprintf(msgout, "Error %s:%s(%d)", msg, __FUNCTION__, __LINE__); perror(msgout); exit(1);} while (0) | ||
35 | |||
36 | // macro to print ip addresses in a printf statement | ||
37 | #define PRINT_IP(A) \ | ||
38 | ((int) (((A) >> 24) & 0xFF)), ((int) (((A) >> 16) & 0xFF)), ((int) (((A) >> 8) & 0xFF)), ((int) ( (A) & 0xFF)) | ||
39 | |||
40 | // macro to print a mac addresses in a printf statement | ||
41 | #define PRINT_MAC(A) \ | ||
42 | ((unsigned) (*(A)) & 0xff), ((unsigned) (*((A) + 1) & 0xff)), ((unsigned) (*((A) + 2) & 0xff)), \ | ||
43 | ((unsigned) (*((A) + 3)) & 0xff), ((unsigned) (*((A) + 4) & 0xff)), ((unsigned) (*((A) + 5)) & 0xff) | ||
44 | |||
45 | // the number of bits in a network mask | ||
46 | static inline uint8_t mask2bits(uint32_t mask) { | ||
47 | uint32_t tmp = 0x80000000; | ||
48 | int i; | ||
49 | uint8_t rv = 0; | ||
50 | |||
51 | for (i = 0; i < 32; i++, tmp >>= 1) { | ||
52 | if (tmp & mask) | ||
53 | rv++; | ||
54 | else | ||
55 | break; | ||
56 | } | ||
57 | return rv; | ||
58 | } | ||
59 | |||
60 | // read an IPv4 address and convert it to uint32_t | ||
61 | static inline int atoip(const char *str, uint32_t *ip) { | ||
62 | unsigned a, b, c, d; | ||
63 | |||
64 | if (sscanf(str, "%u.%u.%u.%u", &a, &b, &c, &d) != 4 || a > 255 || b > 255 || c > 255 || d > 255) | ||
65 | return 1; | ||
66 | |||
67 | *ip = a * 0x1000000 + b * 0x10000 + c * 0x100 + d; | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | // verify an ip address is in the network range given by ifip and mask | ||
72 | static inline char *in_netrange(uint32_t ip, uint32_t ifip, uint32_t ifmask) { | ||
73 | if ((ip & ifmask) != (ifip & ifmask)) | ||
74 | return "Error: the IP address is not in the interface range\n"; | ||
75 | else if ((ip & ifmask) == ip) | ||
76 | return "Error: the IP address is a network address\n"; | ||
77 | else if ((ip | ~ifmask) == ip) | ||
78 | return "Error: the IP address is a network address\n"; | ||
79 | return NULL; | ||
80 | } | ||
81 | |||
82 | // read a mac address | ||
83 | static inline int atomac(char *str, unsigned char macAddr[6]) { | ||
84 | unsigned mac[6]; | ||
85 | |||
86 | if (sscanf(str, "%2x:%2x:%2x:%2x:%2x:%2x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) != 6) | ||
87 | return 1; | ||
88 | |||
89 | int i; | ||
90 | for (i = 0; i < 6; i++) { | ||
91 | if (mac[i] > 0xff) | ||
92 | return 1; | ||
93 | |||
94 | macAddr[i] = (unsigned char) mac[i]; | ||
95 | } | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | // check a mac address is configured | ||
101 | static inline int mac_not_zero(const unsigned char mac[6]) { | ||
102 | int i; | ||
103 | for (i = 0; i < 6; i++) { | ||
104 | if (mac[i] != 0) | ||
105 | return 1; | ||
106 | } | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | int join_namespace(pid_t pid, char *type); | ||
112 | int name2pid(const char *name, pid_t *pid); | ||
113 | char *pid_proc_comm(const pid_t pid); | ||
114 | char *pid_proc_cmdline(const pid_t pid); | ||
115 | #endif | ||
diff --git a/src/include/libnetlink.h b/src/include/libnetlink.h new file mode 100644 index 000000000..e9cd6b186 --- /dev/null +++ b/src/include/libnetlink.h | |||
@@ -0,0 +1,163 @@ | |||
1 | /* file extracted from iproute2 software package | ||
2 | * | ||
3 | * Original source code: | ||
4 | * | ||
5 | * Information: | ||
6 | * http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2 | ||
7 | * | ||
8 | * Download: | ||
9 | * http://www.kernel.org/pub/linux/utils/net/iproute2/ | ||
10 | * | ||
11 | * Repository: | ||
12 | * git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git | ||
13 | * | ||
14 | * License: GPL v2 | ||
15 | */ | ||
16 | |||
17 | |||
18 | #ifndef __LIBNETLINK_H__ | ||
19 | #define __LIBNETLINK_H__ 1 | ||
20 | |||
21 | #define _GNU_SOURCE | ||
22 | #include <stdio.h> | ||
23 | #include <stdlib.h> | ||
24 | #include <stdint.h> | ||
25 | #include <string.h> | ||
26 | #include <asm/types.h> | ||
27 | #include <linux/netlink.h> | ||
28 | #include <linux/rtnetlink.h> | ||
29 | #include <linux/if_link.h> | ||
30 | #include <linux/if_addr.h> | ||
31 | #include <linux/neighbour.h> | ||
32 | |||
33 | struct rtnl_handle | ||
34 | { | ||
35 | int fd; | ||
36 | struct sockaddr_nl local; | ||
37 | struct sockaddr_nl peer; | ||
38 | __u32 seq; | ||
39 | __u32 dump; | ||
40 | }; | ||
41 | |||
42 | extern int rcvbuf; | ||
43 | |||
44 | extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions); | ||
45 | extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol); | ||
46 | extern void rtnl_close(struct rtnl_handle *rth); | ||
47 | extern int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type); | ||
48 | extern int rtnl_wilddump_req_filter(struct rtnl_handle *rth, int fam, int type, | ||
49 | __u32 filt_mask); | ||
50 | extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len); | ||
51 | |||
52 | typedef int (*rtnl_filter_t)(const struct sockaddr_nl *, | ||
53 | struct nlmsghdr *n, void *); | ||
54 | |||
55 | struct rtnl_dump_filter_arg | ||
56 | { | ||
57 | rtnl_filter_t filter; | ||
58 | void *arg1; | ||
59 | }; | ||
60 | |||
61 | extern int rtnl_dump_filter_l(struct rtnl_handle *rth, | ||
62 | const struct rtnl_dump_filter_arg *arg); | ||
63 | extern int rtnl_dump_filter(struct rtnl_handle *rth, rtnl_filter_t filter, | ||
64 | void *arg); | ||
65 | extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, | ||
66 | unsigned groups, struct nlmsghdr *answer); | ||
67 | extern int rtnl_send(struct rtnl_handle *rth, const void *buf, int); | ||
68 | extern int rtnl_send_check(struct rtnl_handle *rth, const void *buf, int); | ||
69 | |||
70 | extern int addattr(struct nlmsghdr *n, int maxlen, int type); | ||
71 | extern int addattr8(struct nlmsghdr *n, int maxlen, int type, __u8 data); | ||
72 | extern int addattr16(struct nlmsghdr *n, int maxlen, int type, __u16 data); | ||
73 | extern int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data); | ||
74 | extern int addattr64(struct nlmsghdr *n, int maxlen, int type, __u64 data); | ||
75 | extern int addattrstrz(struct nlmsghdr *n, int maxlen, int type, const char *data); | ||
76 | |||
77 | extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen); | ||
78 | extern int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len); | ||
79 | extern struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type); | ||
80 | extern int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest); | ||
81 | extern struct rtattr *addattr_nest_compat(struct nlmsghdr *n, int maxlen, int type, const void *data, int len); | ||
82 | extern int addattr_nest_compat_end(struct nlmsghdr *n, struct rtattr *nest); | ||
83 | extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data); | ||
84 | extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, const void *data, int alen); | ||
85 | |||
86 | extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len); | ||
87 | extern int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta, | ||
88 | int len, unsigned short flags); | ||
89 | extern int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len); | ||
90 | extern int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rta, int len); | ||
91 | |||
92 | #define parse_rtattr_nested(tb, max, rta) \ | ||
93 | (parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))) | ||
94 | |||
95 | #define parse_rtattr_nested_compat(tb, max, rta, data, len) \ | ||
96 | ({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \ | ||
97 | __parse_rtattr_nested_compat(tb, max, rta, len); }) | ||
98 | |||
99 | static inline __u8 rta_getattr_u8(const struct rtattr *rta) | ||
100 | { | ||
101 | return *(__u8 *)RTA_DATA(rta); | ||
102 | } | ||
103 | static inline __u16 rta_getattr_u16(const struct rtattr *rta) | ||
104 | { | ||
105 | return *(__u16 *)RTA_DATA(rta); | ||
106 | } | ||
107 | static inline __u32 rta_getattr_u32(const struct rtattr *rta) | ||
108 | { | ||
109 | return *(__u32 *)RTA_DATA(rta); | ||
110 | } | ||
111 | static inline __u64 rta_getattr_u64(const struct rtattr *rta) | ||
112 | { | ||
113 | __u64 tmp; | ||
114 | memcpy(&tmp, RTA_DATA(rta), sizeof(__u64)); | ||
115 | return tmp; | ||
116 | } | ||
117 | static inline const char *rta_getattr_str(const struct rtattr *rta) | ||
118 | { | ||
119 | return (const char *)RTA_DATA(rta); | ||
120 | } | ||
121 | |||
122 | extern int rtnl_listen(struct rtnl_handle *, rtnl_filter_t handler, | ||
123 | void *jarg); | ||
124 | extern int rtnl_from_file(FILE *, rtnl_filter_t handler, | ||
125 | void *jarg); | ||
126 | |||
127 | #define NLMSG_TAIL(nmsg) \ | ||
128 | ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) | ||
129 | |||
130 | #ifndef IFA_RTA | ||
131 | #define IFA_RTA(r) \ | ||
132 | ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)))) | ||
133 | #endif | ||
134 | #ifndef IFA_PAYLOAD | ||
135 | #define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg)) | ||
136 | #endif | ||
137 | |||
138 | #ifndef IFLA_RTA | ||
139 | #define IFLA_RTA(r) \ | ||
140 | ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) | ||
141 | #endif | ||
142 | #ifndef IFLA_PAYLOAD | ||
143 | #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) | ||
144 | #endif | ||
145 | |||
146 | #ifndef NDA_RTA | ||
147 | #define NDA_RTA(r) \ | ||
148 | ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) | ||
149 | #endif | ||
150 | #ifndef NDA_PAYLOAD | ||
151 | #define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg)) | ||
152 | #endif | ||
153 | |||
154 | #ifndef NDTA_RTA | ||
155 | #define NDTA_RTA(r) \ | ||
156 | ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndtmsg)))) | ||
157 | #endif | ||
158 | #ifndef NDTA_PAYLOAD | ||
159 | #define NDTA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndtmsg)) | ||
160 | #endif | ||
161 | |||
162 | #endif /* __LIBNETLINK_H__ */ | ||
163 | |||
diff --git a/src/include/pid.h b/src/include/pid.h new file mode 100644 index 000000000..aaadaa542 --- /dev/null +++ b/src/include/pid.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #ifndef PID_H | ||
21 | #define PID_H | ||
22 | extern int max_pids; | ||
23 | |||
24 | |||
25 | #define _GNU_SOURCE | ||
26 | #include <stdio.h> | ||
27 | #include <sys/types.h> | ||
28 | #include <unistd.h> | ||
29 | typedef struct { | ||
30 | short level; // -1 not a firejail process, 0 not investigated yet, 1 firejail process, > 1 firejail child | ||
31 | unsigned char zombie; | ||
32 | pid_t parent; | ||
33 | uid_t uid; | ||
34 | char *user; | ||
35 | char *cmd; | ||
36 | unsigned utime; | ||
37 | unsigned stime; | ||
38 | unsigned long long rx; // network rx, bytes | ||
39 | unsigned long long tx; // networking tx, bytes | ||
40 | unsigned rx_delta; | ||
41 | unsigned tx_delta; | ||
42 | } Process; | ||
43 | //extern Process pids[max_pids]; | ||
44 | extern Process *pids; | ||
45 | |||
46 | // pid functions | ||
47 | void pid_getmem(unsigned pid, unsigned *rss, unsigned *shared); | ||
48 | void pid_get_cpu_time(unsigned pid, unsigned *utime, unsigned *stime); | ||
49 | unsigned long long pid_get_start_time(unsigned pid); | ||
50 | uid_t pid_get_uid(pid_t pid); | ||
51 | char *pid_get_user_name(uid_t uid); | ||
52 | // print functions | ||
53 | void pid_print_tree(unsigned index, unsigned parent, int nowrap); | ||
54 | void pid_print_list(unsigned index, int nowrap); | ||
55 | void pid_store_cpu(unsigned index, unsigned parent, unsigned *utime, unsigned *stime); | ||
56 | void pid_read(pid_t mon_pid); | ||
57 | |||
58 | #endif | ||
diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in new file mode 100644 index 000000000..6e6be1910 --- /dev/null +++ b/src/lib/Makefile.in | |||
@@ -0,0 +1,20 @@ | |||
1 | PREFIX=@prefix@ | ||
2 | VERSION=@PACKAGE_VERSION@ | ||
3 | NAME=@PACKAGE_NAME@ | ||
4 | |||
5 | H_FILE_LIST = $(wildcard *.[h]) | ||
6 | C_FILE_LIST = $(wildcard *.c) | ||
7 | OBJS = $(C_FILE_LIST:.c=.o) | ||
8 | BINOBJS = $(foreach file, $(OBJS), $file) | ||
9 | CFLAGS += -ggdb -O2 -DVERSION='"$(VERSION)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security | ||
10 | LDFLAGS:=-pic -Wl,-z,relro -Wl,-z,now | ||
11 | |||
12 | all: $(OBJS) | ||
13 | |||
14 | %.o : %.c $(H_FILE_LIST) | ||
15 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ | ||
16 | |||
17 | clean:; rm -f $(OBJS) | ||
18 | |||
19 | distclean: clean | ||
20 | rm -fr Makefile | ||
diff --git a/src/lib/common.c b/src/lib/common.c new file mode 100644 index 000000000..6d928abbb --- /dev/null +++ b/src/lib/common.c | |||
@@ -0,0 +1,192 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #define _GNU_SOURCE | ||
21 | #include <stdio.h> | ||
22 | #include <sys/types.h> | ||
23 | #include <sys/stat.h> | ||
24 | #include <sys/wait.h> | ||
25 | #include <fcntl.h> | ||
26 | #include <sys/syscall.h> | ||
27 | #include <errno.h> | ||
28 | #include <unistd.h> | ||
29 | #include <sys/prctl.h> | ||
30 | #include <signal.h> | ||
31 | #include <dirent.h> | ||
32 | #include <string.h> | ||
33 | #include "../include/common.h" | ||
34 | |||
35 | int join_namespace(pid_t pid, char *type) { | ||
36 | char *path; | ||
37 | if (asprintf(&path, "/proc/%u/ns/%s", pid, type) == -1) | ||
38 | errExit("asprintf"); | ||
39 | |||
40 | int fd = open(path, O_RDONLY); | ||
41 | if (fd < 0) { | ||
42 | free(path); | ||
43 | fprintf(stderr, "Error: cannot open /proc/%u/ns/%s.\n", pid, type); | ||
44 | return -1; | ||
45 | } | ||
46 | |||
47 | if (syscall(__NR_setns, fd, 0) < 0) { | ||
48 | free(path); | ||
49 | fprintf(stderr, "Error: cannot join namespace %s.\n", type); | ||
50 | close(fd); | ||
51 | return -1; | ||
52 | } | ||
53 | |||
54 | close(fd); | ||
55 | free(path); | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | // return 1 if error | ||
60 | int name2pid(const char *name, pid_t *pid) { | ||
61 | pid_t parent = getpid(); | ||
62 | |||
63 | DIR *dir; | ||
64 | if (!(dir = opendir("/proc"))) { | ||
65 | // sleep 2 seconds and try again | ||
66 | sleep(2); | ||
67 | if (!(dir = opendir("/proc"))) { | ||
68 | fprintf(stderr, "Error: cannot open /proc directory\n"); | ||
69 | exit(1); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | struct dirent *entry; | ||
74 | char *end; | ||
75 | while ((entry = readdir(dir))) { | ||
76 | pid_t newpid = strtol(entry->d_name, &end, 10); | ||
77 | if (end == entry->d_name || *end) | ||
78 | continue; | ||
79 | if (newpid == parent) | ||
80 | continue; | ||
81 | |||
82 | // check if this is a firejail executable | ||
83 | char *comm = pid_proc_comm(newpid); | ||
84 | if (comm) { | ||
85 | // remove \n | ||
86 | char *ptr = strchr(comm, '\n'); | ||
87 | if (ptr) | ||
88 | *ptr = '\0'; | ||
89 | if (strcmp(comm, "firejail")) { | ||
90 | free(comm); | ||
91 | continue; | ||
92 | } | ||
93 | free(comm); | ||
94 | } | ||
95 | |||
96 | char *cmd = pid_proc_cmdline(newpid); | ||
97 | if (cmd) { | ||
98 | // mark the end of the name | ||
99 | char *ptr = strstr(cmd, "--name="); | ||
100 | char *start = ptr; | ||
101 | if (!ptr) { | ||
102 | free(cmd); | ||
103 | continue; | ||
104 | } | ||
105 | while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') | ||
106 | ptr++; | ||
107 | *ptr = '\0'; | ||
108 | int rv = strcmp(start + 7, name); | ||
109 | if (rv == 0) { | ||
110 | free(cmd); | ||
111 | *pid = newpid; | ||
112 | closedir(dir); | ||
113 | return 0; | ||
114 | } | ||
115 | free(cmd); | ||
116 | } | ||
117 | } | ||
118 | closedir(dir); | ||
119 | return 1; | ||
120 | } | ||
121 | |||
122 | #define BUFLEN 4096 | ||
123 | char *pid_proc_comm(const pid_t pid) { | ||
124 | // open /proc/pid/cmdline file | ||
125 | char *fname; | ||
126 | int fd; | ||
127 | if (asprintf(&fname, "/proc/%d//comm", pid) == -1) | ||
128 | return NULL; | ||
129 | if ((fd = open(fname, O_RDONLY)) < 0) { | ||
130 | free(fname); | ||
131 | return NULL; | ||
132 | } | ||
133 | free(fname); | ||
134 | |||
135 | // read file | ||
136 | unsigned char buffer[BUFLEN]; | ||
137 | ssize_t len; | ||
138 | if ((len = read(fd, buffer, sizeof(buffer) - 1)) <= 0) { | ||
139 | close(fd); | ||
140 | return NULL; | ||
141 | } | ||
142 | buffer[len] = '\0'; | ||
143 | close(fd); | ||
144 | |||
145 | // return a malloc copy of the command line | ||
146 | char *rv = strdup((char *) buffer); | ||
147 | if (strlen(rv) == 0) { | ||
148 | free(rv); | ||
149 | return NULL; | ||
150 | } | ||
151 | return rv; | ||
152 | } | ||
153 | |||
154 | char *pid_proc_cmdline(const pid_t pid) { | ||
155 | // open /proc/pid/cmdline file | ||
156 | char *fname; | ||
157 | int fd; | ||
158 | if (asprintf(&fname, "/proc/%d/cmdline", pid) == -1) | ||
159 | return NULL; | ||
160 | if ((fd = open(fname, O_RDONLY)) < 0) { | ||
161 | free(fname); | ||
162 | return NULL; | ||
163 | } | ||
164 | free(fname); | ||
165 | |||
166 | // read file | ||
167 | unsigned char buffer[BUFLEN]; | ||
168 | ssize_t len; | ||
169 | if ((len = read(fd, buffer, sizeof(buffer) - 1)) <= 0) { | ||
170 | close(fd); | ||
171 | return NULL; | ||
172 | } | ||
173 | buffer[len] = '\0'; | ||
174 | close(fd); | ||
175 | |||
176 | // clean data | ||
177 | int i; | ||
178 | for (i = 0; i < len; i++) { | ||
179 | if (buffer[i] == '\0') | ||
180 | buffer[i] = ' '; | ||
181 | if (buffer[i] >= 0x80) // execv in progress!!! | ||
182 | return NULL; | ||
183 | } | ||
184 | |||
185 | // return a malloc copy of the command line | ||
186 | char *rv = strdup((char *) buffer); | ||
187 | if (strlen(rv) == 0) { | ||
188 | free(rv); | ||
189 | return NULL; | ||
190 | } | ||
191 | return rv; | ||
192 | } | ||
diff --git a/src/lib/libnetlink.c b/src/lib/libnetlink.c new file mode 100644 index 000000000..264632a01 --- /dev/null +++ b/src/lib/libnetlink.c | |||
@@ -0,0 +1,803 @@ | |||
1 | /* file extracted from iproute2 software package | ||
2 | * | ||
3 | * Original source code: | ||
4 | * | ||
5 | * Information: | ||
6 | * http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2 | ||
7 | * | ||
8 | * Download: | ||
9 | * http://www.kernel.org/pub/linux/utils/net/iproute2/ | ||
10 | * | ||
11 | * Repository: | ||
12 | * git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git | ||
13 | * | ||
14 | * License: GPL v2 | ||
15 | * | ||
16 | * Original copyright header | ||
17 | * | ||
18 | * libnetlink.c RTnetlink service routines. | ||
19 | * | ||
20 | * This program is free software; you can redistribute it and/or | ||
21 | * modify it under the terms of the GNU General Public License | ||
22 | * as published by the Free Software Foundation; either version | ||
23 | * 2 of the License, or (at your option) any later version. | ||
24 | * | ||
25 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include <stdio.h> | ||
30 | #include <stdlib.h> | ||
31 | #include <unistd.h> | ||
32 | #include <syslog.h> | ||
33 | #include <fcntl.h> | ||
34 | #include <net/if_arp.h> | ||
35 | #include <sys/socket.h> | ||
36 | #include <netinet/in.h> | ||
37 | #include <string.h> | ||
38 | #include <errno.h> | ||
39 | #include <time.h> | ||
40 | #include <sys/uio.h> | ||
41 | |||
42 | #include "../include/libnetlink.h" | ||
43 | |||
44 | int rcvbuf = 1024 * 1024; | ||
45 | |||
46 | void rtnl_close(struct rtnl_handle *rth) | ||
47 | { | ||
48 | if (rth->fd >= 0) { | ||
49 | close(rth->fd); | ||
50 | rth->fd = -1; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, | ||
55 | int protocol) | ||
56 | { | ||
57 | socklen_t addr_len; | ||
58 | int sndbuf = 32768; | ||
59 | |||
60 | memset(rth, 0, sizeof(*rth)); | ||
61 | |||
62 | rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, protocol); | ||
63 | if (rth->fd < 0) { | ||
64 | perror("Cannot open netlink socket"); | ||
65 | return -1; | ||
66 | } | ||
67 | |||
68 | if (setsockopt(rth->fd,SOL_SOCKET,SO_SNDBUF,&sndbuf,sizeof(sndbuf)) < 0) { | ||
69 | perror("SO_SNDBUF"); | ||
70 | return -1; | ||
71 | } | ||
72 | |||
73 | if (setsockopt(rth->fd,SOL_SOCKET,SO_RCVBUF,&rcvbuf,sizeof(rcvbuf)) < 0) { | ||
74 | perror("SO_RCVBUF"); | ||
75 | return -1; | ||
76 | } | ||
77 | |||
78 | memset(&rth->local, 0, sizeof(rth->local)); | ||
79 | rth->local.nl_family = AF_NETLINK; | ||
80 | rth->local.nl_groups = subscriptions; | ||
81 | |||
82 | if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) { | ||
83 | perror("Cannot bind netlink socket"); | ||
84 | return -1; | ||
85 | } | ||
86 | addr_len = sizeof(rth->local); | ||
87 | if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) { | ||
88 | perror("Cannot getsockname"); | ||
89 | return -1; | ||
90 | } | ||
91 | if (addr_len != sizeof(rth->local)) { | ||
92 | fprintf(stderr, "Wrong address length %d\n", addr_len); | ||
93 | return -1; | ||
94 | } | ||
95 | if (rth->local.nl_family != AF_NETLINK) { | ||
96 | fprintf(stderr, "Wrong address family %d\n", rth->local.nl_family); | ||
97 | return -1; | ||
98 | } | ||
99 | rth->seq = time(NULL); | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions) | ||
104 | { | ||
105 | return rtnl_open_byproto(rth, subscriptions, NETLINK_ROUTE); | ||
106 | } | ||
107 | |||
108 | int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) | ||
109 | { | ||
110 | return rtnl_wilddump_req_filter(rth, family, type, RTEXT_FILTER_VF); | ||
111 | } | ||
112 | |||
113 | int rtnl_wilddump_req_filter(struct rtnl_handle *rth, int family, int type, | ||
114 | __u32 filt_mask) | ||
115 | { | ||
116 | struct { | ||
117 | struct nlmsghdr nlh; | ||
118 | struct ifinfomsg ifm; | ||
119 | /* attribute has to be NLMSG aligned */ | ||
120 | struct rtattr ext_req __attribute__ ((aligned(NLMSG_ALIGNTO))); | ||
121 | __u32 ext_filter_mask; | ||
122 | } req; | ||
123 | |||
124 | memset(&req, 0, sizeof(req)); | ||
125 | req.nlh.nlmsg_len = sizeof(req); | ||
126 | req.nlh.nlmsg_type = type; | ||
127 | req.nlh.nlmsg_flags = NLM_F_DUMP|NLM_F_REQUEST; | ||
128 | req.nlh.nlmsg_pid = 0; | ||
129 | req.nlh.nlmsg_seq = rth->dump = ++rth->seq; | ||
130 | req.ifm.ifi_family = family; | ||
131 | |||
132 | req.ext_req.rta_type = IFLA_EXT_MASK; | ||
133 | req.ext_req.rta_len = RTA_LENGTH(sizeof(__u32)); | ||
134 | req.ext_filter_mask = filt_mask; | ||
135 | |||
136 | return send(rth->fd, (void*)&req, sizeof(req), 0); | ||
137 | } | ||
138 | |||
139 | int rtnl_send(struct rtnl_handle *rth, const void *buf, int len) | ||
140 | { | ||
141 | return send(rth->fd, buf, len, 0); | ||
142 | } | ||
143 | |||
144 | int rtnl_send_check(struct rtnl_handle *rth, const void *buf, int len) | ||
145 | { | ||
146 | struct nlmsghdr *h; | ||
147 | int status; | ||
148 | char resp[1024]; | ||
149 | |||
150 | status = send(rth->fd, buf, len, 0); | ||
151 | if (status < 0) | ||
152 | return status; | ||
153 | |||
154 | /* Check for immediate errors */ | ||
155 | status = recv(rth->fd, resp, sizeof(resp), MSG_DONTWAIT|MSG_PEEK); | ||
156 | if (status < 0) { | ||
157 | if (errno == EAGAIN) | ||
158 | return 0; | ||
159 | return -1; | ||
160 | } | ||
161 | |||
162 | for (h = (struct nlmsghdr *)resp; NLMSG_OK(h, status); | ||
163 | h = NLMSG_NEXT(h, status)) { | ||
164 | if (h->nlmsg_type == NLMSG_ERROR) { | ||
165 | struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); | ||
166 | if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) | ||
167 | fprintf(stderr, "ERROR truncated\n"); | ||
168 | else | ||
169 | errno = -err->error; | ||
170 | return -1; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) | ||
178 | { | ||
179 | struct nlmsghdr nlh; | ||
180 | struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK }; | ||
181 | struct iovec iov[2] = { | ||
182 | { .iov_base = &nlh, .iov_len = sizeof(nlh) }, | ||
183 | { .iov_base = req, .iov_len = len } | ||
184 | }; | ||
185 | struct msghdr msg = { | ||
186 | .msg_name = &nladdr, | ||
187 | .msg_namelen = sizeof(nladdr), | ||
188 | .msg_iov = iov, | ||
189 | .msg_iovlen = 2, | ||
190 | }; | ||
191 | |||
192 | nlh.nlmsg_len = NLMSG_LENGTH(len); | ||
193 | nlh.nlmsg_type = type; | ||
194 | nlh.nlmsg_flags = NLM_F_DUMP|NLM_F_REQUEST; | ||
195 | nlh.nlmsg_pid = 0; | ||
196 | nlh.nlmsg_seq = rth->dump = ++rth->seq; | ||
197 | |||
198 | return sendmsg(rth->fd, &msg, 0); | ||
199 | } | ||
200 | |||
201 | int rtnl_dump_filter_l(struct rtnl_handle *rth, | ||
202 | const struct rtnl_dump_filter_arg *arg) | ||
203 | { | ||
204 | struct sockaddr_nl nladdr; | ||
205 | struct iovec iov; | ||
206 | struct msghdr msg = { | ||
207 | .msg_name = &nladdr, | ||
208 | .msg_namelen = sizeof(nladdr), | ||
209 | .msg_iov = &iov, | ||
210 | .msg_iovlen = 1, | ||
211 | }; | ||
212 | char buf[16384]; | ||
213 | int dump_intr = 0; | ||
214 | |||
215 | iov.iov_base = buf; | ||
216 | while (1) { | ||
217 | int status; | ||
218 | const struct rtnl_dump_filter_arg *a; | ||
219 | int found_done = 0; | ||
220 | int msglen = 0; | ||
221 | |||
222 | iov.iov_len = sizeof(buf); | ||
223 | status = recvmsg(rth->fd, &msg, 0); | ||
224 | |||
225 | if (status < 0) { | ||
226 | if (errno == EINTR || errno == EAGAIN) | ||
227 | continue; | ||
228 | fprintf(stderr, "netlink receive error %s (%d)\n", | ||
229 | strerror(errno), errno); | ||
230 | return -1; | ||
231 | } | ||
232 | |||
233 | if (status == 0) { | ||
234 | fprintf(stderr, "EOF on netlink\n"); | ||
235 | return -1; | ||
236 | } | ||
237 | |||
238 | for (a = arg; a->filter; a++) { | ||
239 | struct nlmsghdr *h = (struct nlmsghdr*)buf; | ||
240 | msglen = status; | ||
241 | |||
242 | while (NLMSG_OK(h, msglen)) { | ||
243 | int err; | ||
244 | |||
245 | if (nladdr.nl_pid != 0 || | ||
246 | h->nlmsg_pid != rth->local.nl_pid || | ||
247 | h->nlmsg_seq != rth->dump) | ||
248 | goto skip_it; | ||
249 | |||
250 | if (h->nlmsg_flags & NLM_F_DUMP_INTR) | ||
251 | dump_intr = 1; | ||
252 | |||
253 | if (h->nlmsg_type == NLMSG_DONE) { | ||
254 | found_done = 1; | ||
255 | break; /* process next filter */ | ||
256 | } | ||
257 | if (h->nlmsg_type == NLMSG_ERROR) { | ||
258 | struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); | ||
259 | if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { | ||
260 | fprintf(stderr, | ||
261 | "ERROR truncated\n"); | ||
262 | } else { | ||
263 | errno = -err->error; | ||
264 | perror("RTNETLINK answers"); | ||
265 | } | ||
266 | return -1; | ||
267 | } | ||
268 | err = a->filter(&nladdr, h, a->arg1); | ||
269 | if (err < 0) | ||
270 | return err; | ||
271 | |||
272 | skip_it: | ||
273 | h = NLMSG_NEXT(h, msglen); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | if (found_done) { | ||
278 | if (dump_intr) | ||
279 | fprintf(stderr, | ||
280 | "Dump was interrupted and may be inconsistent.\n"); | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | if (msg.msg_flags & MSG_TRUNC) { | ||
285 | fprintf(stderr, "Message truncated\n"); | ||
286 | continue; | ||
287 | } | ||
288 | if (msglen) { | ||
289 | fprintf(stderr, "!!!Remnant of size %d\n", msglen); | ||
290 | exit(1); | ||
291 | } | ||
292 | } | ||
293 | } | ||
294 | |||
295 | int rtnl_dump_filter(struct rtnl_handle *rth, | ||
296 | rtnl_filter_t filter, | ||
297 | void *arg1) | ||
298 | { | ||
299 | const struct rtnl_dump_filter_arg a[2] = { | ||
300 | { .filter = filter, .arg1 = arg1, }, | ||
301 | { .filter = NULL, .arg1 = NULL, }, | ||
302 | }; | ||
303 | |||
304 | return rtnl_dump_filter_l(rth, a); | ||
305 | } | ||
306 | |||
307 | int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, | ||
308 | unsigned groups, struct nlmsghdr *answer) | ||
309 | { | ||
310 | int status; | ||
311 | unsigned seq; | ||
312 | struct nlmsghdr *h; | ||
313 | struct sockaddr_nl nladdr; | ||
314 | struct iovec iov = { | ||
315 | .iov_base = (void*) n, | ||
316 | .iov_len = n->nlmsg_len | ||
317 | }; | ||
318 | struct msghdr msg = { | ||
319 | .msg_name = &nladdr, | ||
320 | .msg_namelen = sizeof(nladdr), | ||
321 | .msg_iov = &iov, | ||
322 | .msg_iovlen = 1, | ||
323 | }; | ||
324 | char buf[16384]; | ||
325 | |||
326 | memset(&nladdr, 0, sizeof(nladdr)); | ||
327 | nladdr.nl_family = AF_NETLINK; | ||
328 | nladdr.nl_pid = peer; | ||
329 | nladdr.nl_groups = groups; | ||
330 | |||
331 | n->nlmsg_seq = seq = ++rtnl->seq; | ||
332 | |||
333 | if (answer == NULL) | ||
334 | n->nlmsg_flags |= NLM_F_ACK; | ||
335 | |||
336 | status = sendmsg(rtnl->fd, &msg, 0); | ||
337 | |||
338 | if (status < 0) { | ||
339 | perror("Cannot talk to rtnetlink"); | ||
340 | return -1; | ||
341 | } | ||
342 | |||
343 | memset(buf,0,sizeof(buf)); | ||
344 | |||
345 | iov.iov_base = buf; | ||
346 | |||
347 | while (1) { | ||
348 | iov.iov_len = sizeof(buf); | ||
349 | status = recvmsg(rtnl->fd, &msg, 0); | ||
350 | |||
351 | if (status < 0) { | ||
352 | if (errno == EINTR || errno == EAGAIN) | ||
353 | continue; | ||
354 | fprintf(stderr, "netlink receive error %s (%d)\n", | ||
355 | strerror(errno), errno); | ||
356 | return -1; | ||
357 | } | ||
358 | if (status == 0) { | ||
359 | fprintf(stderr, "EOF on netlink\n"); | ||
360 | return -1; | ||
361 | } | ||
362 | if (msg.msg_namelen != sizeof(nladdr)) { | ||
363 | fprintf(stderr, "sender address length == %d\n", msg.msg_namelen); | ||
364 | exit(1); | ||
365 | } | ||
366 | for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) { | ||
367 | int len = h->nlmsg_len; | ||
368 | int l = len - sizeof(*h); | ||
369 | |||
370 | if (l < 0 || len>status) { | ||
371 | if (msg.msg_flags & MSG_TRUNC) { | ||
372 | fprintf(stderr, "Truncated message\n"); | ||
373 | return -1; | ||
374 | } | ||
375 | fprintf(stderr, "!!!malformed message: len=%d\n", len); | ||
376 | exit(1); | ||
377 | } | ||
378 | |||
379 | if (nladdr.nl_pid != peer || | ||
380 | h->nlmsg_pid != rtnl->local.nl_pid || | ||
381 | h->nlmsg_seq != seq) { | ||
382 | /* Don't forget to skip that message. */ | ||
383 | status -= NLMSG_ALIGN(len); | ||
384 | h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); | ||
385 | continue; | ||
386 | } | ||
387 | |||
388 | if (h->nlmsg_type == NLMSG_ERROR) { | ||
389 | struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); | ||
390 | if (l < sizeof(struct nlmsgerr)) { | ||
391 | fprintf(stderr, "ERROR truncated\n"); | ||
392 | } else { | ||
393 | if (!err->error) { | ||
394 | if (answer) | ||
395 | memcpy(answer, h, h->nlmsg_len); | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | fprintf(stderr, "RTNETLINK answers: %s\n", strerror(-err->error)); | ||
400 | errno = -err->error; | ||
401 | } | ||
402 | return -1; | ||
403 | } | ||
404 | if (answer) { | ||
405 | memcpy(answer, h, h->nlmsg_len); | ||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | fprintf(stderr, "Unexpected reply!!!\n"); | ||
410 | |||
411 | status -= NLMSG_ALIGN(len); | ||
412 | h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); | ||
413 | } | ||
414 | if (msg.msg_flags & MSG_TRUNC) { | ||
415 | fprintf(stderr, "Message truncated\n"); | ||
416 | continue; | ||
417 | } | ||
418 | if (status) { | ||
419 | fprintf(stderr, "!!!Remnant of size %d\n", status); | ||
420 | exit(1); | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | |||
425 | int rtnl_listen(struct rtnl_handle *rtnl, | ||
426 | rtnl_filter_t handler, | ||
427 | void *jarg) | ||
428 | { | ||
429 | int status; | ||
430 | struct nlmsghdr *h; | ||
431 | struct sockaddr_nl nladdr; | ||
432 | struct iovec iov; | ||
433 | struct msghdr msg = { | ||
434 | .msg_name = &nladdr, | ||
435 | .msg_namelen = sizeof(nladdr), | ||
436 | .msg_iov = &iov, | ||
437 | .msg_iovlen = 1, | ||
438 | }; | ||
439 | char buf[8192]; | ||
440 | |||
441 | memset(&nladdr, 0, sizeof(nladdr)); | ||
442 | nladdr.nl_family = AF_NETLINK; | ||
443 | nladdr.nl_pid = 0; | ||
444 | nladdr.nl_groups = 0; | ||
445 | |||
446 | iov.iov_base = buf; | ||
447 | while (1) { | ||
448 | iov.iov_len = sizeof(buf); | ||
449 | status = recvmsg(rtnl->fd, &msg, 0); | ||
450 | |||
451 | if (status < 0) { | ||
452 | if (errno == EINTR || errno == EAGAIN) | ||
453 | continue; | ||
454 | fprintf(stderr, "netlink receive error %s (%d)\n", | ||
455 | strerror(errno), errno); | ||
456 | if (errno == ENOBUFS) | ||
457 | continue; | ||
458 | return -1; | ||
459 | } | ||
460 | if (status == 0) { | ||
461 | fprintf(stderr, "EOF on netlink\n"); | ||
462 | return -1; | ||
463 | } | ||
464 | if (msg.msg_namelen != sizeof(nladdr)) { | ||
465 | fprintf(stderr, "Sender address length == %d\n", msg.msg_namelen); | ||
466 | exit(1); | ||
467 | } | ||
468 | for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) { | ||
469 | int err; | ||
470 | int len = h->nlmsg_len; | ||
471 | int l = len - sizeof(*h); | ||
472 | |||
473 | if (l<0 || len>status) { | ||
474 | if (msg.msg_flags & MSG_TRUNC) { | ||
475 | fprintf(stderr, "Truncated message\n"); | ||
476 | return -1; | ||
477 | } | ||
478 | fprintf(stderr, "!!!malformed message: len=%d\n", len); | ||
479 | exit(1); | ||
480 | } | ||
481 | |||
482 | err = handler(&nladdr, h, jarg); | ||
483 | if (err < 0) | ||
484 | return err; | ||
485 | |||
486 | status -= NLMSG_ALIGN(len); | ||
487 | h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); | ||
488 | } | ||
489 | if (msg.msg_flags & MSG_TRUNC) { | ||
490 | fprintf(stderr, "Message truncated\n"); | ||
491 | continue; | ||
492 | } | ||
493 | if (status) { | ||
494 | fprintf(stderr, "!!!Remnant of size %d\n", status); | ||
495 | exit(1); | ||
496 | } | ||
497 | } | ||
498 | } | ||
499 | |||
500 | int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler, | ||
501 | void *jarg) | ||
502 | { | ||
503 | int status; | ||
504 | struct sockaddr_nl nladdr; | ||
505 | char buf[8192]; | ||
506 | struct nlmsghdr *h = (void*)buf; | ||
507 | |||
508 | memset(&nladdr, 0, sizeof(nladdr)); | ||
509 | nladdr.nl_family = AF_NETLINK; | ||
510 | nladdr.nl_pid = 0; | ||
511 | nladdr.nl_groups = 0; | ||
512 | |||
513 | while (1) { | ||
514 | int err, len; | ||
515 | int l; | ||
516 | |||
517 | status = fread(&buf, 1, sizeof(*h), rtnl); | ||
518 | |||
519 | if (status < 0) { | ||
520 | if (errno == EINTR) | ||
521 | continue; | ||
522 | perror("rtnl_from_file: fread"); | ||
523 | return -1; | ||
524 | } | ||
525 | if (status == 0) | ||
526 | return 0; | ||
527 | |||
528 | len = h->nlmsg_len; | ||
529 | l = len - sizeof(*h); | ||
530 | |||
531 | if (l<0 || len>sizeof(buf)) { | ||
532 | fprintf(stderr, "!!!malformed message: len=%d @%lu\n", | ||
533 | len, ftell(rtnl)); | ||
534 | return -1; | ||
535 | } | ||
536 | |||
537 | status = fread(NLMSG_DATA(h), 1, NLMSG_ALIGN(l), rtnl); | ||
538 | |||
539 | if (status < 0) { | ||
540 | perror("rtnl_from_file: fread"); | ||
541 | return -1; | ||
542 | } | ||
543 | if (status < l) { | ||
544 | fprintf(stderr, "rtnl-from_file: truncated message\n"); | ||
545 | return -1; | ||
546 | } | ||
547 | |||
548 | err = handler(&nladdr, h, jarg); | ||
549 | if (err < 0) | ||
550 | return err; | ||
551 | } | ||
552 | } | ||
553 | |||
554 | int addattr(struct nlmsghdr *n, int maxlen, int type) | ||
555 | { | ||
556 | return addattr_l(n, maxlen, type, NULL, 0); | ||
557 | } | ||
558 | |||
559 | int addattr8(struct nlmsghdr *n, int maxlen, int type, __u8 data) | ||
560 | { | ||
561 | return addattr_l(n, maxlen, type, &data, sizeof(__u8)); | ||
562 | } | ||
563 | |||
564 | int addattr16(struct nlmsghdr *n, int maxlen, int type, __u16 data) | ||
565 | { | ||
566 | return addattr_l(n, maxlen, type, &data, sizeof(__u16)); | ||
567 | } | ||
568 | |||
569 | int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data) | ||
570 | { | ||
571 | return addattr_l(n, maxlen, type, &data, sizeof(__u32)); | ||
572 | } | ||
573 | |||
574 | int addattr64(struct nlmsghdr *n, int maxlen, int type, __u64 data) | ||
575 | { | ||
576 | return addattr_l(n, maxlen, type, &data, sizeof(__u64)); | ||
577 | } | ||
578 | |||
579 | int addattrstrz(struct nlmsghdr *n, int maxlen, int type, const char *str) | ||
580 | { | ||
581 | return addattr_l(n, maxlen, type, str, strlen(str)+1); | ||
582 | } | ||
583 | |||
584 | |||
585 | |||
586 | int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, | ||
587 | int alen) | ||
588 | { | ||
589 | |||
590 | #if 0 | ||
591 | printf("%d: %s\n", __LINE__, __FUNCTION__); | ||
592 | printf("\ttype %d - ", type); | ||
593 | if (type == IFLA_LINK) { | ||
594 | printf("IFLA_LINK\n"); | ||
595 | int i; | ||
596 | printf("\tdata - "); | ||
597 | for (i = 0; i < alen; i++) | ||
598 | printf("%02x, ", *((unsigned char *)data + i)); | ||
599 | printf("\n"); | ||
600 | } | ||
601 | else if (type == IFLA_IFNAME) { | ||
602 | printf("IFLA_IFNAME\n"); | ||
603 | printf("\tdata - #%s#\n", data); | ||
604 | } | ||
605 | else if (type == IFLA_LINKINFO) printf("IFLA_LINKINFO\n"); | ||
606 | else if (type == IFLA_ADDRESS) { | ||
607 | printf("IFLA_ADDRESS or IFLA_INFO_KIND\n"); | ||
608 | int i; | ||
609 | printf("\tdata - "); | ||
610 | for (i = 0; i < alen; i++) | ||
611 | printf("%02x, ", *((unsigned char *)data + i)); | ||
612 | printf("\n"); | ||
613 | } | ||
614 | else if (type == IFLA_BROADCAST) printf("IFLA_BROADCAST or IFLA_INFO_DATA\n"); | ||
615 | |||
616 | printf("\tdata length: %d\n", alen); | ||
617 | #endif | ||
618 | |||
619 | int len = RTA_LENGTH(alen); | ||
620 | struct rtattr *rta; | ||
621 | |||
622 | if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) { | ||
623 | fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen); | ||
624 | return -1; | ||
625 | } | ||
626 | rta = NLMSG_TAIL(n); | ||
627 | rta->rta_type = type; | ||
628 | rta->rta_len = len; | ||
629 | memcpy(RTA_DATA(rta), data, alen); | ||
630 | n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); | ||
631 | return 0; | ||
632 | } | ||
633 | |||
634 | #if 0 | ||
635 | int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, | ||
636 | int alen) | ||
637 | { | ||
638 | printf("%s: adding type %d, length %d ", __FUNCTION__, type, alen); | ||
639 | if (type == IFLA_INFO_KIND) { | ||
640 | if (alen) | ||
641 | printf("(IFLA_INFO_KIND %s)\n", (char *)data); | ||
642 | else | ||
643 | printf("(VETH_INFO_PEER)\n"); | ||
644 | } | ||
645 | else if (type == IFLA_IFNAME) { | ||
646 | printf("(IFLA_IFNAME %s)\n", (char *) data); | ||
647 | } | ||
648 | else if (type == IFLA_NET_NS_PID) { | ||
649 | printf("(IFLA_NET_NS_PID %u)\n", *((unsigned *) data)); | ||
650 | } | ||
651 | else if (type == IFLA_LINKINFO) | ||
652 | printf("(IFLA_LINKINFO)\n"); | ||
653 | else if (type == IFLA_INFO_DATA) | ||
654 | printf("(IFLA_INFO_DATA)\n"); | ||
655 | else | ||
656 | printf("\n"); | ||
657 | |||
658 | int len = RTA_LENGTH(alen); | ||
659 | struct rtattr *rta; | ||
660 | |||
661 | if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) { | ||
662 | fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen); | ||
663 | return -1; | ||
664 | } | ||
665 | rta = NLMSG_TAIL(n); | ||
666 | rta->rta_type = type; | ||
667 | rta->rta_len = len; | ||
668 | memcpy(RTA_DATA(rta), data, alen); | ||
669 | n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); | ||
670 | return 0; | ||
671 | } | ||
672 | #endif | ||
673 | |||
674 | int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len) | ||
675 | { | ||
676 | if (NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len) > maxlen) { | ||
677 | fprintf(stderr, "addraw_l ERROR: message exceeded bound of %d\n",maxlen); | ||
678 | return -1; | ||
679 | } | ||
680 | |||
681 | memcpy(NLMSG_TAIL(n), data, len); | ||
682 | memset((void *) NLMSG_TAIL(n) + len, 0, NLMSG_ALIGN(len) - len); | ||
683 | n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len); | ||
684 | return 0; | ||
685 | } | ||
686 | |||
687 | struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type) | ||
688 | { | ||
689 | struct rtattr *nest = NLMSG_TAIL(n); | ||
690 | |||
691 | addattr_l(n, maxlen, type, NULL, 0); | ||
692 | return nest; | ||
693 | } | ||
694 | |||
695 | int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest) | ||
696 | { | ||
697 | nest->rta_len = (void *)NLMSG_TAIL(n) - (void *)nest; | ||
698 | return n->nlmsg_len; | ||
699 | } | ||
700 | |||
701 | struct rtattr *addattr_nest_compat(struct nlmsghdr *n, int maxlen, int type, | ||
702 | const void *data, int len) | ||
703 | { | ||
704 | struct rtattr *start = NLMSG_TAIL(n); | ||
705 | |||
706 | addattr_l(n, maxlen, type, data, len); | ||
707 | addattr_nest(n, maxlen, type); | ||
708 | return start; | ||
709 | } | ||
710 | |||
711 | int addattr_nest_compat_end(struct nlmsghdr *n, struct rtattr *start) | ||
712 | { | ||
713 | struct rtattr *nest = (void *)start + NLMSG_ALIGN(start->rta_len); | ||
714 | |||
715 | start->rta_len = (void *)NLMSG_TAIL(n) - (void *)start; | ||
716 | addattr_nest_end(n, nest); | ||
717 | return n->nlmsg_len; | ||
718 | } | ||
719 | |||
720 | int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data) | ||
721 | { | ||
722 | int len = RTA_LENGTH(4); | ||
723 | struct rtattr *subrta; | ||
724 | |||
725 | if (RTA_ALIGN(rta->rta_len) + len > maxlen) { | ||
726 | fprintf(stderr,"rta_addattr32: Error! max allowed bound %d exceeded\n",maxlen); | ||
727 | return -1; | ||
728 | } | ||
729 | subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); | ||
730 | subrta->rta_type = type; | ||
731 | subrta->rta_len = len; | ||
732 | memcpy(RTA_DATA(subrta), &data, 4); | ||
733 | rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len; | ||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | int rta_addattr_l(struct rtattr *rta, int maxlen, int type, | ||
738 | const void *data, int alen) | ||
739 | { | ||
740 | struct rtattr *subrta; | ||
741 | int len = RTA_LENGTH(alen); | ||
742 | |||
743 | if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) { | ||
744 | fprintf(stderr,"rta_addattr_l: Error! max allowed bound %d exceeded\n",maxlen); | ||
745 | return -1; | ||
746 | } | ||
747 | subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); | ||
748 | subrta->rta_type = type; | ||
749 | subrta->rta_len = len; | ||
750 | memcpy(RTA_DATA(subrta), data, alen); | ||
751 | rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len); | ||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) | ||
756 | { | ||
757 | return parse_rtattr_flags(tb, max, rta, len, 0); | ||
758 | } | ||
759 | |||
760 | int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta, | ||
761 | int len, unsigned short flags) | ||
762 | { | ||
763 | unsigned short type; | ||
764 | |||
765 | memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); | ||
766 | while (RTA_OK(rta, len)) { | ||
767 | type = rta->rta_type & ~flags; | ||
768 | if ((type <= max) && (!tb[type])) | ||
769 | tb[type] = rta; | ||
770 | rta = RTA_NEXT(rta,len); | ||
771 | } | ||
772 | if (len) | ||
773 | fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len); | ||
774 | return 0; | ||
775 | } | ||
776 | |||
777 | int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len) | ||
778 | { | ||
779 | int i = 0; | ||
780 | |||
781 | memset(tb, 0, sizeof(struct rtattr *) * max); | ||
782 | while (RTA_OK(rta, len)) { | ||
783 | if (rta->rta_type <= max && i < max) | ||
784 | tb[i++] = rta; | ||
785 | rta = RTA_NEXT(rta,len); | ||
786 | } | ||
787 | if (len) | ||
788 | fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len); | ||
789 | return i; | ||
790 | } | ||
791 | |||
792 | int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rta, | ||
793 | int len) | ||
794 | { | ||
795 | if (RTA_PAYLOAD(rta) < len) | ||
796 | return -1; | ||
797 | if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) { | ||
798 | rta = RTA_DATA(rta) + RTA_ALIGN(len); | ||
799 | return parse_rtattr_nested(tb, max, rta); | ||
800 | } | ||
801 | memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); | ||
802 | return 0; | ||
803 | } | ||
diff --git a/src/lib/pid.c b/src/lib/pid.c new file mode 100644 index 000000000..a0261ead2 --- /dev/null +++ b/src/lib/pid.c | |||
@@ -0,0 +1,392 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "../include/common.h" | ||
21 | #include "../include/pid.h" | ||
22 | #include <string.h> | ||
23 | #include <sys/types.h> | ||
24 | #include <pwd.h> | ||
25 | #include <sys/ioctl.h> | ||
26 | #include <dirent.h> | ||
27 | |||
28 | #define PIDS_BUFLEN 4096 | ||
29 | //Process pids[max_pids]; | ||
30 | Process *pids = NULL; | ||
31 | int max_pids=32769; | ||
32 | #define PIDS_BUFLEN 4096 | ||
33 | |||
34 | // get the memory associated with this pid | ||
35 | void pid_getmem(unsigned pid, unsigned *rss, unsigned *shared) { | ||
36 | // open stat file | ||
37 | char *file; | ||
38 | if (asprintf(&file, "/proc/%u/statm", pid) == -1) { | ||
39 | perror("asprintf"); | ||
40 | exit(1); | ||
41 | } | ||
42 | FILE *fp = fopen(file, "r"); | ||
43 | if (!fp) { | ||
44 | free(file); | ||
45 | return; | ||
46 | } | ||
47 | free(file); | ||
48 | |||
49 | unsigned a, b, c; | ||
50 | if (3 != fscanf(fp, "%u %u %u", &a, &b, &c)) { | ||
51 | fclose(fp); | ||
52 | return; | ||
53 | } | ||
54 | *rss += b; | ||
55 | *shared += c; | ||
56 | fclose(fp); | ||
57 | } | ||
58 | |||
59 | |||
60 | void pid_get_cpu_time(unsigned pid, unsigned *utime, unsigned *stime) { | ||
61 | // open stat file | ||
62 | char *file; | ||
63 | if (asprintf(&file, "/proc/%u/stat", pid) == -1) { | ||
64 | perror("asprintf"); | ||
65 | exit(1); | ||
66 | } | ||
67 | FILE *fp = fopen(file, "r"); | ||
68 | if (!fp) { | ||
69 | free(file); | ||
70 | return; | ||
71 | } | ||
72 | free(file); | ||
73 | |||
74 | char line[PIDS_BUFLEN]; | ||
75 | if (fgets(line, PIDS_BUFLEN - 1, fp)) { | ||
76 | char *ptr = line; | ||
77 | // jump 13 fields | ||
78 | int i; | ||
79 | for (i = 0; i < 13; i++) { | ||
80 | while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') | ||
81 | ptr++; | ||
82 | if (*ptr == '\0') | ||
83 | goto myexit; | ||
84 | ptr++; | ||
85 | } | ||
86 | if (2 != sscanf(ptr, "%u %u", utime, stime)) | ||
87 | goto myexit; | ||
88 | } | ||
89 | |||
90 | myexit: | ||
91 | fclose(fp); | ||
92 | } | ||
93 | |||
94 | unsigned long long pid_get_start_time(unsigned pid) { | ||
95 | // open stat file | ||
96 | char *file; | ||
97 | if (asprintf(&file, "/proc/%u/stat", pid) == -1) { | ||
98 | perror("asprintf"); | ||
99 | exit(1); | ||
100 | } | ||
101 | FILE *fp = fopen(file, "r"); | ||
102 | if (!fp) { | ||
103 | free(file); | ||
104 | return 0; | ||
105 | } | ||
106 | free(file); | ||
107 | |||
108 | char line[PIDS_BUFLEN]; | ||
109 | unsigned long long retval = 0; | ||
110 | if (fgets(line, PIDS_BUFLEN - 1, fp)) { | ||
111 | char *ptr = line; | ||
112 | // jump 21 fields | ||
113 | int i; | ||
114 | for (i = 0; i < 21; i++) { | ||
115 | while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') | ||
116 | ptr++; | ||
117 | if (*ptr == '\0') | ||
118 | goto myexit; | ||
119 | ptr++; | ||
120 | } | ||
121 | if (1 != sscanf(ptr, "%llu", &retval)) | ||
122 | goto myexit; | ||
123 | } | ||
124 | |||
125 | myexit: | ||
126 | fclose(fp); | ||
127 | return retval; | ||
128 | } | ||
129 | |||
130 | char *pid_get_user_name(uid_t uid) { | ||
131 | struct passwd *pw = getpwuid(uid); | ||
132 | if (pw) | ||
133 | return strdup(pw->pw_name); | ||
134 | return NULL; | ||
135 | } | ||
136 | |||
137 | uid_t pid_get_uid(pid_t pid) { | ||
138 | uid_t rv = 0; | ||
139 | |||
140 | // open stat file | ||
141 | char *file; | ||
142 | if (asprintf(&file, "/proc/%u/status", pid) == -1) { | ||
143 | perror("asprintf"); | ||
144 | exit(1); | ||
145 | } | ||
146 | FILE *fp = fopen(file, "r"); | ||
147 | if (!fp) { | ||
148 | free(file); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | // look for firejail executable name | ||
153 | char buf[PIDS_BUFLEN]; | ||
154 | while (fgets(buf, PIDS_BUFLEN - 1, fp)) { | ||
155 | if (strncmp(buf, "Uid:", 4) == 0) { | ||
156 | char *ptr = buf + 5; | ||
157 | while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\t')) { | ||
158 | ptr++; | ||
159 | } | ||
160 | if (*ptr == '\0') | ||
161 | goto doexit; | ||
162 | |||
163 | rv = atoi(ptr); | ||
164 | break; // break regardless! | ||
165 | } | ||
166 | } | ||
167 | doexit: | ||
168 | fclose(fp); | ||
169 | free(file); | ||
170 | return rv; | ||
171 | } | ||
172 | |||
173 | static void print_elem(unsigned index, int nowrap) { | ||
174 | // get terminal size | ||
175 | struct winsize sz; | ||
176 | int col = 0; | ||
177 | if (isatty(STDIN_FILENO)) { | ||
178 | if (!ioctl(0, TIOCGWINSZ, &sz)) | ||
179 | col = sz.ws_col; | ||
180 | } | ||
181 | |||
182 | // indent | ||
183 | char indent[(pids[index].level - 1) * 2 + 1]; | ||
184 | memset(indent, ' ', sizeof(indent)); | ||
185 | indent[(pids[index].level - 1) * 2] = '\0'; | ||
186 | |||
187 | // get data | ||
188 | uid_t uid = pids[index].uid; | ||
189 | char *cmd = pid_proc_cmdline(index); | ||
190 | char *user = pid_get_user_name(uid); | ||
191 | char *allocated = user; | ||
192 | if (user ==NULL) | ||
193 | user = ""; | ||
194 | if (cmd) { | ||
195 | if (col < 4 || nowrap) | ||
196 | printf("%s%u:%s:%s\n", indent, index, user, cmd); | ||
197 | else { | ||
198 | char *out; | ||
199 | if (asprintf(&out, "%s%u:%s:%s\n", indent, index, user, cmd) == -1) | ||
200 | errExit("asprintf"); | ||
201 | int len = strlen(out); | ||
202 | if (len > col) { | ||
203 | out[col] = '\0'; | ||
204 | out[col - 1] = '\n'; | ||
205 | } | ||
206 | printf("%s", out); | ||
207 | free(out); | ||
208 | } | ||
209 | |||
210 | free(cmd); | ||
211 | } | ||
212 | else { | ||
213 | if (pids[index].zombie) | ||
214 | printf("%s%u: (zombie)\n", indent, index); | ||
215 | else | ||
216 | printf("%s%u:\n", indent, index); | ||
217 | } | ||
218 | if (allocated) | ||
219 | free(allocated); | ||
220 | } | ||
221 | |||
222 | // recursivity!!! | ||
223 | void pid_print_tree(unsigned index, unsigned parent, int nowrap) { | ||
224 | print_elem(index, nowrap); | ||
225 | |||
226 | int i; | ||
227 | for (i = index + 1; i < max_pids; i++) { | ||
228 | if (pids[i].parent == index) | ||
229 | pid_print_tree(i, index, nowrap); | ||
230 | } | ||
231 | |||
232 | for (i = 0; i < index; i++) { | ||
233 | if (pids[i].parent == index) | ||
234 | pid_print_tree(i, index, nowrap); | ||
235 | } | ||
236 | } | ||
237 | |||
238 | void pid_print_list(unsigned index, int nowrap) { | ||
239 | print_elem(index, nowrap); | ||
240 | } | ||
241 | |||
242 | // recursivity!!! | ||
243 | void pid_store_cpu(unsigned index, unsigned parent, unsigned *utime, unsigned *stime) { | ||
244 | if (pids[index].level == 1) { | ||
245 | *utime = 0; | ||
246 | *stime = 0; | ||
247 | } | ||
248 | |||
249 | unsigned utmp = 0; | ||
250 | unsigned stmp = 0; | ||
251 | pid_get_cpu_time(index, &utmp, &stmp); | ||
252 | *utime += utmp; | ||
253 | *stime += stmp; | ||
254 | |||
255 | int i; | ||
256 | for (i = index + 1; i < max_pids; i++) { | ||
257 | if (pids[i].parent == index) | ||
258 | pid_store_cpu(i, index, utime, stime); | ||
259 | } | ||
260 | |||
261 | if (pids[index].level == 1) { | ||
262 | pids[index].utime = *utime; | ||
263 | pids[index].stime = *stime; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | // mon_pid: pid of sandbox to be monitored, 0 if all sandboxes are included | ||
268 | void pid_read(pid_t mon_pid) { | ||
269 | if (pids == NULL) { | ||
270 | FILE *fp = fopen("/proc/sys/kernel/pid_max", "r"); | ||
271 | if (fp) { | ||
272 | int val; | ||
273 | if (fscanf(fp, "%d", &val) == 1) { | ||
274 | if (val >= max_pids) | ||
275 | max_pids = val + 1; | ||
276 | } | ||
277 | fclose(fp); | ||
278 | } | ||
279 | pids = malloc(sizeof(Process) * max_pids); | ||
280 | if (pids == NULL) | ||
281 | errExit("malloc"); | ||
282 | } | ||
283 | memset(pids, 0, sizeof(Process) * max_pids); | ||
284 | pid_t mypid = getpid(); | ||
285 | |||
286 | DIR *dir; | ||
287 | if (!(dir = opendir("/proc"))) { | ||
288 | // sleep 2 seconds and try again | ||
289 | sleep(2); | ||
290 | if (!(dir = opendir("/proc"))) { | ||
291 | fprintf(stderr, "Error: cannot open /proc directory\n"); | ||
292 | exit(1); | ||
293 | } | ||
294 | } | ||
295 | |||
296 | pid_t child = -1; | ||
297 | struct dirent *entry; | ||
298 | char *end; | ||
299 | while (child < 0 && (entry = readdir(dir))) { | ||
300 | pid_t pid = strtol(entry->d_name, &end, 10); | ||
301 | pid %= max_pids; | ||
302 | if (end == entry->d_name || *end) | ||
303 | continue; | ||
304 | if (pid == mypid) | ||
305 | continue; | ||
306 | |||
307 | // open stat file | ||
308 | char *file; | ||
309 | if (asprintf(&file, "/proc/%u/status", pid) == -1) { | ||
310 | perror("asprintf"); | ||
311 | exit(1); | ||
312 | } | ||
313 | FILE *fp = fopen(file, "r"); | ||
314 | if (!fp) { | ||
315 | free(file); | ||
316 | continue; | ||
317 | } | ||
318 | |||
319 | // look for firejail executable name | ||
320 | char buf[PIDS_BUFLEN]; | ||
321 | while (fgets(buf, PIDS_BUFLEN - 1, fp)) { | ||
322 | if (strncmp(buf, "Name:", 5) == 0) { | ||
323 | char *ptr = buf + 5; | ||
324 | while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\t')) { | ||
325 | ptr++; | ||
326 | } | ||
327 | if (*ptr == '\0') { | ||
328 | fprintf(stderr, "Error: cannot read /proc file\n"); | ||
329 | exit(1); | ||
330 | } | ||
331 | |||
332 | if (mon_pid == 0 && strncmp(ptr, "firejail", 8) == 0) { | ||
333 | pids[pid].level = 1; | ||
334 | } | ||
335 | else if (mon_pid == pid && strncmp(ptr, "firejail", 8) == 0) { | ||
336 | pids[pid].level = 1; | ||
337 | } | ||
338 | // else if (mon_pid == 0 && strncmp(ptr, "lxc-execute", 11) == 0) { | ||
339 | // pids[pid].level = 1; | ||
340 | // } | ||
341 | // else if (mon_pid == pid && strncmp(ptr, "lxc-execute", 11) == 0) { | ||
342 | // pids[pid].level = 1; | ||
343 | // } | ||
344 | else | ||
345 | pids[pid].level = -1; | ||
346 | } | ||
347 | if (strncmp(buf, "State:", 6) == 0) { | ||
348 | if (strstr(buf, "(zombie)")) | ||
349 | pids[pid].zombie = 1; | ||
350 | } | ||
351 | else if (strncmp(buf, "PPid:", 5) == 0) { | ||
352 | char *ptr = buf + 5; | ||
353 | while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\t')) { | ||
354 | ptr++; | ||
355 | } | ||
356 | if (*ptr == '\0') { | ||
357 | fprintf(stderr, "Error: cannot read /proc file\n"); | ||
358 | exit(1); | ||
359 | } | ||
360 | unsigned parent = atoi(ptr); | ||
361 | parent %= max_pids; | ||
362 | if (pids[parent].level > 0) { | ||
363 | pids[pid].level = pids[parent].level + 1; | ||
364 | } | ||
365 | pids[pid].parent = parent; | ||
366 | } | ||
367 | else if (strncmp(buf, "Uid:", 4) == 0) { | ||
368 | char *ptr = buf + 5; | ||
369 | while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\t')) { | ||
370 | ptr++; | ||
371 | } | ||
372 | if (*ptr == '\0') { | ||
373 | fprintf(stderr, "Error: cannot read /proc file\n"); | ||
374 | exit(1); | ||
375 | } | ||
376 | pids[pid].uid = atoi(ptr); | ||
377 | break; | ||
378 | } | ||
379 | } | ||
380 | fclose(fp); | ||
381 | free(file); | ||
382 | } | ||
383 | closedir(dir); | ||
384 | |||
385 | pid_t pid; | ||
386 | for (pid = 0; pid < max_pids; pid++) { | ||
387 | int parent = pids[pid].parent; | ||
388 | if (pids[parent].level > 0) { | ||
389 | pids[pid].level = pids[parent].level + 1; | ||
390 | } | ||
391 | } | ||
392 | } | ||
diff --git a/src/libtrace/Makefile.in b/src/libtrace/Makefile.in new file mode 100644 index 000000000..8848fc08c --- /dev/null +++ b/src/libtrace/Makefile.in | |||
@@ -0,0 +1,25 @@ | |||
1 | PREFIX=@prefix@ | ||
2 | VERSION=@PACKAGE_VERSION@ | ||
3 | NAME=@PACKAGE_NAME@ | ||
4 | |||
5 | H_FILE_LIST = $(wildcard *.[h]) | ||
6 | C_FILE_LIST = $(wildcard *.c) | ||
7 | OBJS = $(C_FILE_LIST:.c=.o) | ||
8 | BINOBJS = $(foreach file, $(OBJS), $file) | ||
9 | CFLAGS += -ggdb -O2 -DVERSION='"$(VERSION)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security | ||
10 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now | ||
11 | |||
12 | all: libtrace.so | ||
13 | |||
14 | %.o : %.c $(H_FILE_LIST) | ||
15 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ | ||
16 | |||
17 | # gcc -shared -fPIC -ldl traceopen.c -o traceopen.so | ||
18 | libtrace.so: $(OBJS) | ||
19 | $(CC) $(LDFLAGS) -shared -fPIC -z relro -o $@ $(OBJS) -ldl | ||
20 | |||
21 | |||
22 | clean:; rm -f $(OBJS) libtrace.so | ||
23 | |||
24 | distclean: clean | ||
25 | rm -fr Makefile | ||
diff --git a/src/libtrace/libtrace.c b/src/libtrace/libtrace.c new file mode 100644 index 000000000..a785ec698 --- /dev/null +++ b/src/libtrace/libtrace.c | |||
@@ -0,0 +1,609 @@ | |||
1 | #define _GNU_SOURCE | ||
2 | #include <stdio.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <string.h> | ||
5 | #include <dlfcn.h> | ||
6 | #include <sys/types.h> | ||
7 | #include <unistd.h> | ||
8 | #include <sys/socket.h> | ||
9 | #include <netinet/in.h> | ||
10 | #include <arpa/inet.h> | ||
11 | #include <sys/un.h> | ||
12 | #include <sys/stat.h> | ||
13 | |||
14 | // break recursivity on fopen call | ||
15 | typedef FILE *(*orig_fopen_t)(const char *pathname, const char *mode); | ||
16 | static orig_fopen_t orig_fopen = NULL; | ||
17 | typedef FILE *(*orig_fopen64_t)(const char *pathname, const char *mode); | ||
18 | static orig_fopen64_t orig_fopen64 = NULL; | ||
19 | |||
20 | // | ||
21 | // pid | ||
22 | // | ||
23 | static pid_t mypid = 0; | ||
24 | static inline pid_t pid(void) { | ||
25 | if (!mypid) | ||
26 | mypid = getpid(); | ||
27 | return mypid; | ||
28 | } | ||
29 | |||
30 | // | ||
31 | // process name | ||
32 | // | ||
33 | #define MAXNAME 16 | ||
34 | static char myname[MAXNAME]; | ||
35 | static int nameinit = 0; | ||
36 | static char *name(void) { | ||
37 | if (!nameinit) { | ||
38 | // initialize the name of the process based on /proc/PID/comm | ||
39 | memset(myname, 0, MAXNAME); | ||
40 | |||
41 | pid_t p = pid(); | ||
42 | char *fname; | ||
43 | if (asprintf(&fname, "/proc/%u/comm", p) == -1) | ||
44 | return "unknown"; | ||
45 | |||
46 | // read file | ||
47 | if (!orig_fopen) | ||
48 | orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen"); | ||
49 | FILE *fp = orig_fopen(fname, "r"); | ||
50 | if (!fp) | ||
51 | return "unknown"; | ||
52 | if (fgets(myname, MAXNAME, fp) == NULL) { | ||
53 | fclose(fp); | ||
54 | free(fname); | ||
55 | return "unknown"; | ||
56 | } | ||
57 | |||
58 | // clean '\n' | ||
59 | char *ptr = strchr(myname, '\n'); | ||
60 | if (ptr) | ||
61 | *ptr = '\0'; | ||
62 | |||
63 | fclose(fp); | ||
64 | free(fname); | ||
65 | nameinit = 1; | ||
66 | } | ||
67 | |||
68 | return myname; | ||
69 | } | ||
70 | |||
71 | // | ||
72 | // network | ||
73 | // | ||
74 | typedef struct { | ||
75 | int val; | ||
76 | char *name; | ||
77 | } XTable; | ||
78 | |||
79 | static XTable socket_type[] = { | ||
80 | #ifdef SOCK_STREAM | ||
81 | { SOCK_STREAM, "SOCK_STREAM" }, | ||
82 | #endif | ||
83 | #ifdef SOCK_DGRAM | ||
84 | { SOCK_DGRAM, "SOCK_DGRAM" }, | ||
85 | #endif | ||
86 | #ifdef SOCK_RAW | ||
87 | { SOCK_RAW, "SOCK_RAW" }, | ||
88 | #endif | ||
89 | #ifdef SOCK_RDM | ||
90 | { SOCK_RDM, "SOCK_RDM" }, | ||
91 | #endif | ||
92 | #ifdef SOCK_SEQPACKET | ||
93 | { SOCK_SEQPACKET, "SOCK_SEQPACKET" }, | ||
94 | #endif | ||
95 | #ifdef SOCK_DCCP | ||
96 | { SOCK_DCCP, "SOCK_DCCP" }, | ||
97 | #endif | ||
98 | { 0, NULL} // NULL terminated | ||
99 | }; | ||
100 | |||
101 | static XTable socket_domain[] = { | ||
102 | #ifdef AF_INET | ||
103 | { AF_INET, "AF_INET" }, | ||
104 | #endif | ||
105 | #ifdef AF_INET6 | ||
106 | { AF_INET6, "AF_INET6" }, | ||
107 | #endif | ||
108 | #ifdef AF_LOCAL | ||
109 | { AF_LOCAL, "AF_LOCAL" }, | ||
110 | #endif | ||
111 | #ifdef AF_PACKET | ||
112 | { AF_PACKET, "AF_PACKET" }, | ||
113 | #endif | ||
114 | #ifdef AF_IPX | ||
115 | { AF_IPX, "AF_IPX" }, | ||
116 | #endif | ||
117 | #ifdef AF_NETLINK | ||
118 | { AF_NETLINK, "AF_NETLINK" }, | ||
119 | #endif | ||
120 | #ifdef AF_X25 | ||
121 | { AF_X25, "AF_X25" }, | ||
122 | #endif | ||
123 | #ifdef AF_AX25 | ||
124 | { AF_AX25, "AF_AX25" }, | ||
125 | #endif | ||
126 | #ifdef AF_ATMPVC | ||
127 | { AF_ATMPVC, "AF_ATMPVC" }, | ||
128 | #endif | ||
129 | #ifdef AF_APPLETALK | ||
130 | { AF_APPLETALK, "AF_APPLETALK" }, | ||
131 | #endif | ||
132 | { 0, NULL} // NULL terminated | ||
133 | }; | ||
134 | |||
135 | static XTable socket_protocol[] = { | ||
136 | #ifdef IPPROTO_IP | ||
137 | { IPPROTO_IP, "IPPROTO_IP" }, | ||
138 | #endif | ||
139 | #ifdef IPPROTO_ICMP | ||
140 | { IPPROTO_ICMP, "IPPROTO_ICMP" }, | ||
141 | #endif | ||
142 | #ifdef IPPROTO_IGMP | ||
143 | { IPPROTO_IGMP, "IPPROTO_IGMP" }, | ||
144 | #endif | ||
145 | #ifdef IPPROTO_IPIP | ||
146 | { IPPROTO_IPIP, "IPPROTO_IPIP" }, | ||
147 | #endif | ||
148 | #ifdef IPPROTO_TCP | ||
149 | { IPPROTO_TCP, "IPPROTO_TCP" }, | ||
150 | #endif | ||
151 | #ifdef IPPROTO_EGP | ||
152 | { IPPROTO_EGP, "IPPROTO_EGP" }, | ||
153 | #endif | ||
154 | #ifdef IPPROTO_PUP | ||
155 | { IPPROTO_PUP, "IPPROTO_PUP" }, | ||
156 | #endif | ||
157 | #ifdef IPPROTO_UDP | ||
158 | { IPPROTO_UDP, "IPPROTO_UDP" }, | ||
159 | #endif | ||
160 | #ifdef IPPROTO_IDP | ||
161 | { IPPROTO_IDP, "IPPROTO_IDP" }, | ||
162 | #endif | ||
163 | #ifdef IPPROTO_DCCP | ||
164 | { IPPROTO_DCCP, "IPPROTO_DCCP" }, | ||
165 | #endif | ||
166 | #ifdef IPPROTO_RSVP | ||
167 | { IPPROTO_RSVP, "IPPROTO_RSVP" }, | ||
168 | #endif | ||
169 | #ifdef IPPROTO_GRE | ||
170 | { IPPROTO_GRE, "IPPROTO_GRE" }, | ||
171 | #endif | ||
172 | #ifdef IPPROTO_IPV6 | ||
173 | { IPPROTO_IPV6, "IPPROTO_IPV6" }, | ||
174 | #endif | ||
175 | #ifdef IPPROTO_ESP | ||
176 | { IPPROTO_ESP, "IPPROTO_ESP" }, | ||
177 | #endif | ||
178 | #ifdef IPPROTO_AH | ||
179 | { IPPROTO_AH, "IPPROTO_AH" }, | ||
180 | #endif | ||
181 | #ifdef IPPROTO_BEETPH | ||
182 | { IPPROTO_BEETPH, "IPPROTO_BEETPH" }, | ||
183 | #endif | ||
184 | #ifdef IPPROTO_PIM | ||
185 | { IPPROTO_PIM, "IPPROTO_PIM" }, | ||
186 | #endif | ||
187 | #ifdef IPPROTO_COMP | ||
188 | { IPPROTO_COMP, "IPPROTO_COMP" }, | ||
189 | #endif | ||
190 | #ifdef IPPROTO_SCTP | ||
191 | { IPPROTO_SCTP, "IPPROTO_SCTP" }, | ||
192 | #endif | ||
193 | #ifdef IPPROTO_UDPLITE | ||
194 | { IPPROTO_UDPLITE, "IPPROTO_UDPLITE" }, | ||
195 | #endif | ||
196 | #ifdef IPPROTO_RAW | ||
197 | { IPPROTO_RAW, "IPPROTO_RAW" }, | ||
198 | #endif | ||
199 | { 0, NULL} // NULL terminated | ||
200 | }; | ||
201 | |||
202 | static char *translate(XTable *table, int val) { | ||
203 | while (table->name != NULL) { | ||
204 | if (val == table->val) | ||
205 | return table->name; | ||
206 | table++; | ||
207 | } | ||
208 | |||
209 | return NULL; | ||
210 | } | ||
211 | |||
212 | static void print_sockaddr(const char *call, const struct sockaddr *addr) { | ||
213 | if (addr->sa_family == AF_INET) { | ||
214 | struct sockaddr_in *a = (struct sockaddr_in *) addr; | ||
215 | printf("%u:%s:%s %s:%u\n", pid(), name(), call, inet_ntoa(a->sin_addr), ntohs(a->sin_port)); | ||
216 | } | ||
217 | else if (addr->sa_family == AF_INET6) { | ||
218 | struct sockaddr_in6 *a = (struct sockaddr_in6 *) addr; | ||
219 | char str[INET6_ADDRSTRLEN]; | ||
220 | inet_ntop(AF_INET6, &(a->sin6_addr), str, INET6_ADDRSTRLEN); | ||
221 | printf("%u:%s:%s %s\n", pid(), name(), call, str); | ||
222 | } | ||
223 | else if (addr->sa_family == AF_UNIX) { | ||
224 | struct sockaddr_un *a = (struct sockaddr_un *) addr; | ||
225 | if (a->sun_path[0]) | ||
226 | printf("%u:%s:%s %s\n", pid(), name(), call, a->sun_path); | ||
227 | else | ||
228 | printf("%u:%s:%s @%s\n", pid(), name(), call, a->sun_path + 1); | ||
229 | } | ||
230 | else { | ||
231 | printf("%u:%s:%s family %d\n", pid(), name(), call, addr->sa_family); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | // | ||
236 | // syscalls | ||
237 | // | ||
238 | |||
239 | // open | ||
240 | typedef int (*orig_open_t)(const char *pathname, int flags, mode_t mode); | ||
241 | static orig_open_t orig_open = NULL; | ||
242 | int open(const char *pathname, int flags, mode_t mode) { | ||
243 | if (!orig_open) | ||
244 | orig_open = (orig_open_t)dlsym(RTLD_NEXT, "open"); | ||
245 | |||
246 | int rv = orig_open(pathname, flags, mode); | ||
247 | printf("%u:%s:open %s\n", pid(), name(), pathname); | ||
248 | return rv; | ||
249 | } | ||
250 | |||
251 | typedef int (*orig_open64_t)(const char *pathname, int flags, mode_t mode); | ||
252 | static orig_open64_t orig_open64 = NULL; | ||
253 | int open64(const char *pathname, int flags, mode_t mode) { | ||
254 | if (!orig_open64) | ||
255 | orig_open64 = (orig_open64_t)dlsym(RTLD_NEXT, "open64"); | ||
256 | |||
257 | int rv = orig_open64(pathname, flags, mode); | ||
258 | printf("%u:%s:open64 %s\n", pid(), name(), pathname); | ||
259 | return rv; | ||
260 | } | ||
261 | |||
262 | // openat | ||
263 | typedef int (*orig_openat_t)(int dirfd, const char *pathname, int flags, mode_t mode); | ||
264 | static orig_openat_t orig_openat = NULL; | ||
265 | int openat(int dirfd, const char *pathname, int flags, mode_t mode) { | ||
266 | if (!orig_openat) | ||
267 | orig_openat = (orig_openat_t)dlsym(RTLD_NEXT, "openat"); | ||
268 | |||
269 | int rv = orig_openat(dirfd, pathname, flags, mode); | ||
270 | printf("%u:%s:openat %s\n", pid(), name(), pathname); | ||
271 | return rv; | ||
272 | } | ||
273 | |||
274 | typedef int (*orig_openat64_t)(int dirfd, const char *pathname, int flags, mode_t mode); | ||
275 | static orig_openat64_t orig_openat64 = NULL; | ||
276 | int openat64(int dirfd, const char *pathname, int flags, mode_t mode) { | ||
277 | if (!orig_openat64) | ||
278 | orig_openat64 = (orig_openat64_t)dlsym(RTLD_NEXT, "openat64"); | ||
279 | |||
280 | int rv = orig_openat64(dirfd, pathname, flags, mode); | ||
281 | printf("%u:%s:openat64 %s\n", pid(), name(), pathname); | ||
282 | return rv; | ||
283 | } | ||
284 | |||
285 | |||
286 | // fopen | ||
287 | FILE *fopen(const char *pathname, const char *mode) { | ||
288 | if (!orig_fopen) | ||
289 | orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen"); | ||
290 | |||
291 | FILE *rv = orig_fopen(pathname, mode); | ||
292 | printf("%u:%s:fopen %s\n", pid(), name(), pathname); | ||
293 | return rv; | ||
294 | } | ||
295 | |||
296 | FILE *fopen64(const char *pathname, const char *mode) { | ||
297 | if (!orig_fopen64) | ||
298 | orig_fopen64 = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen64"); | ||
299 | |||
300 | FILE *rv = orig_fopen64(pathname, mode); | ||
301 | printf("%u:%s:fopen64 %s\n", pid(), name(), pathname); | ||
302 | return rv; | ||
303 | } | ||
304 | |||
305 | |||
306 | // freopen | ||
307 | typedef FILE *(*orig_freopen_t)(const char *pathname, const char *mode, FILE *stream); | ||
308 | static orig_freopen_t orig_freopen = NULL; | ||
309 | FILE *freopen(const char *pathname, const char *mode, FILE *stream) { | ||
310 | if (!orig_freopen) | ||
311 | orig_freopen = (orig_freopen_t)dlsym(RTLD_NEXT, "freopen"); | ||
312 | |||
313 | FILE *rv = orig_freopen(pathname, mode, stream); | ||
314 | printf("%u:%s:freopen %s\n", pid(), name(), pathname); | ||
315 | return rv; | ||
316 | } | ||
317 | |||
318 | typedef FILE *(*orig_freopen64_t)(const char *pathname, const char *mode, FILE *stream); | ||
319 | static orig_freopen64_t orig_freopen64 = NULL; | ||
320 | FILE *freopen64(const char *pathname, const char *mode, FILE *stream) { | ||
321 | if (!orig_freopen64) | ||
322 | orig_freopen64 = (orig_freopen64_t)dlsym(RTLD_NEXT, "freopen64"); | ||
323 | |||
324 | FILE *rv = orig_freopen64(pathname, mode, stream); | ||
325 | printf("%u:%s:freopen64 %s\n", pid(), name(), pathname); | ||
326 | return rv; | ||
327 | } | ||
328 | |||
329 | // unlink | ||
330 | typedef int (*orig_unlink_t)(const char *pathname); | ||
331 | static orig_unlink_t orig_unlink = NULL; | ||
332 | int unlink(const char *pathname) { | ||
333 | if (!orig_unlink) | ||
334 | orig_unlink = (orig_unlink_t)dlsym(RTLD_NEXT, "unlink"); | ||
335 | |||
336 | int rv = orig_unlink(pathname); | ||
337 | printf("%u:%s:unlink %s\n", pid(), name(), pathname); | ||
338 | return rv; | ||
339 | } | ||
340 | |||
341 | typedef int (*orig_unlinkat_t)(int dirfd, const char *pathname, int flags); | ||
342 | static orig_unlinkat_t orig_unlinkat = NULL; | ||
343 | int unlinkat(int dirfd, const char *pathname, int flags) { | ||
344 | if (!orig_unlinkat) | ||
345 | orig_unlinkat = (orig_unlinkat_t)dlsym(RTLD_NEXT, "unlinkat"); | ||
346 | |||
347 | int rv = orig_unlinkat(dirfd, pathname, flags); | ||
348 | printf("%u:%s:unlinkat %s\n", pid(), name(), pathname); | ||
349 | return rv; | ||
350 | } | ||
351 | |||
352 | // mkdir/mkdirat/rmdir | ||
353 | typedef int (*orig_mkdir_t)(const char *pathname, mode_t mode); | ||
354 | static orig_mkdir_t orig_mkdir = NULL; | ||
355 | int mkdir(const char *pathname, mode_t mode) { | ||
356 | if (!orig_mkdir) | ||
357 | orig_mkdir = (orig_mkdir_t)dlsym(RTLD_NEXT, "mkdir"); | ||
358 | |||
359 | int rv = orig_mkdir(pathname, mode); | ||
360 | printf("%u:%s:mkdir %s\n", pid(), name(), pathname); | ||
361 | return rv; | ||
362 | } | ||
363 | |||
364 | typedef int (*orig_mkdirat_t)(int dirfd, const char *pathname, mode_t mode); | ||
365 | static orig_mkdirat_t orig_mkdirat = NULL; | ||
366 | int mkdirat(int dirfd, const char *pathname, mode_t mode) { | ||
367 | if (!orig_mkdirat) | ||
368 | orig_mkdirat = (orig_mkdirat_t)dlsym(RTLD_NEXT, "mkdirat"); | ||
369 | |||
370 | int rv = orig_mkdirat(dirfd, pathname, mode); | ||
371 | printf("%u:%s:mkdirat %s\n", pid(), name(), pathname); | ||
372 | return rv; | ||
373 | } | ||
374 | |||
375 | typedef int (*orig_rmdir_t)(const char *pathname); | ||
376 | static orig_rmdir_t orig_rmdir = NULL; | ||
377 | int rmdir(const char *pathname) { | ||
378 | if (!orig_rmdir) | ||
379 | orig_rmdir = (orig_rmdir_t)dlsym(RTLD_NEXT, "rmdir"); | ||
380 | |||
381 | int rv = orig_rmdir(pathname); | ||
382 | printf("%u:%s:rmdir %s\n", pid(), name(), pathname); | ||
383 | return rv; | ||
384 | } | ||
385 | |||
386 | // stat | ||
387 | typedef int (*orig_stat_t)(const char *pathname, struct stat *buf); | ||
388 | static orig_stat_t orig_stat = NULL; | ||
389 | int stat(const char *pathname, struct stat *buf) { | ||
390 | if (!orig_stat) | ||
391 | orig_stat = (orig_stat_t)dlsym(RTLD_NEXT, "stat"); | ||
392 | |||
393 | int rv = orig_stat(pathname, buf); | ||
394 | printf("%u:%s:stat %s\n", pid(), name(), pathname); | ||
395 | return rv; | ||
396 | } | ||
397 | |||
398 | typedef int (*orig_stat64_t)(const char *pathname, struct stat64 *buf); | ||
399 | static orig_stat64_t orig_stat64 = NULL; | ||
400 | int stat64(const char *pathname, struct stat64 *buf) { | ||
401 | if (!orig_stat) | ||
402 | orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat"); | ||
403 | |||
404 | int rv = orig_stat64(pathname, buf); | ||
405 | printf("%u:%s:stat %s\n", pid(), name(), pathname); | ||
406 | return rv; | ||
407 | } | ||
408 | |||
409 | |||
410 | // access | ||
411 | typedef int (*orig_access_t)(const char *pathname, int mode); | ||
412 | static orig_access_t orig_access = NULL; | ||
413 | int access(const char *pathname, int mode) { | ||
414 | if (!orig_access) | ||
415 | orig_access = (orig_access_t)dlsym(RTLD_NEXT, "access"); | ||
416 | |||
417 | int rv = orig_access(pathname, mode); | ||
418 | printf("%u:%s:access %s\n", pid(), name(), pathname); | ||
419 | return rv; | ||
420 | } | ||
421 | |||
422 | |||
423 | // connect | ||
424 | typedef int (*orig_connect_t)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); | ||
425 | static orig_connect_t orig_connect = NULL; | ||
426 | int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { | ||
427 | if (!orig_connect) | ||
428 | orig_connect = (orig_connect_t)dlsym(RTLD_NEXT, "connect"); | ||
429 | |||
430 | int rv = orig_connect(sockfd, addr, addrlen); | ||
431 | print_sockaddr("connect", addr); | ||
432 | |||
433 | return rv; | ||
434 | } | ||
435 | |||
436 | // socket | ||
437 | typedef int (*orig_socket_t)(int domain, int type, int protocol); | ||
438 | static orig_socket_t orig_socket = NULL; | ||
439 | static char buf[1024]; | ||
440 | int socket(int domain, int type, int protocol) { | ||
441 | if (!orig_socket) | ||
442 | orig_socket = (orig_socket_t)dlsym(RTLD_NEXT, "socket"); | ||
443 | |||
444 | int rv = orig_socket(domain, type, protocol); | ||
445 | char *ptr = buf; | ||
446 | ptr += sprintf(ptr, "%u:%s:socket ", pid(), name()); | ||
447 | char *str = translate(socket_domain, domain); | ||
448 | if (str == NULL) | ||
449 | ptr += sprintf(ptr, "%d ", domain); | ||
450 | else | ||
451 | ptr += sprintf(ptr, "%s ", str); | ||
452 | |||
453 | int t = type; // glibc uses higher bits for various other purposes | ||
454 | #ifdef SOCK_CLOEXEC | ||
455 | t &= ~SOCK_CLOEXEC; | ||
456 | #endif | ||
457 | #ifdef SOCK_NONBLOCK | ||
458 | t &= ~SOCK_NONBLOCK; | ||
459 | #endif | ||
460 | str = translate(socket_type, t); | ||
461 | if (str == NULL) | ||
462 | ptr += sprintf(ptr, "%d ", type); | ||
463 | else | ||
464 | ptr += sprintf(ptr, "%s ", str); | ||
465 | |||
466 | str = translate(socket_protocol, protocol); | ||
467 | if (str == NULL) | ||
468 | ptr += sprintf(ptr, "%d", protocol); | ||
469 | else | ||
470 | ptr += sprintf(ptr, "%s", str); | ||
471 | |||
472 | printf("%s\n", buf); | ||
473 | return rv; | ||
474 | } | ||
475 | |||
476 | // bind | ||
477 | typedef int (*orig_bind_t)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); | ||
478 | static orig_bind_t orig_bind = NULL; | ||
479 | int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { | ||
480 | if (!orig_bind) | ||
481 | orig_bind = (orig_bind_t)dlsym(RTLD_NEXT, "bind"); | ||
482 | |||
483 | int rv = orig_bind(sockfd, addr, addrlen); | ||
484 | print_sockaddr("bind", addr); | ||
485 | |||
486 | return rv; | ||
487 | } | ||
488 | |||
489 | #if 0 //todo: fix compilation problems | ||
490 | typedef int (*orig_accept_t)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); | ||
491 | static orig_accept_t orig_accept = NULL; | ||
492 | int accept(int sockfd, struct sockaddr *addr, socklen_t addrlen) { | ||
493 | if (!orig_accept) | ||
494 | orig_accept = (orig_accept_t)dlsym(RTLD_NEXT, "accept"); | ||
495 | |||
496 | int rv = orig_accept(sockfd, addr, addrlen); | ||
497 | print_sockaddr("accept", addr); | ||
498 | |||
499 | return rv; | ||
500 | } | ||
501 | #endif | ||
502 | |||
503 | typedef int (*orig_system_t)(const char *command); | ||
504 | static orig_system_t orig_system = NULL; | ||
505 | int system(const char *command) { | ||
506 | if (!orig_system) | ||
507 | orig_system = (orig_system_t)dlsym(RTLD_NEXT, "system"); | ||
508 | |||
509 | int rv = orig_system(command); | ||
510 | printf("%u:%s:system %s\n", pid(), name(), command); | ||
511 | |||
512 | return rv; | ||
513 | } | ||
514 | |||
515 | typedef int (*orig_setuid_t)(uid_t uid); | ||
516 | static orig_setuid_t orig_setuid = NULL; | ||
517 | int setuid(uid_t uid) { | ||
518 | if (!orig_setuid) | ||
519 | orig_setuid = (orig_setuid_t)dlsym(RTLD_NEXT, "setuid"); | ||
520 | |||
521 | int rv = orig_setuid(uid); | ||
522 | printf("%u:%s:setuid %d\n", pid(), name(), uid); | ||
523 | |||
524 | return rv; | ||
525 | } | ||
526 | |||
527 | typedef int (*orig_setgid_t)(gid_t gid); | ||
528 | static orig_setgid_t orig_setgid = NULL; | ||
529 | int setgid(gid_t gid) { | ||
530 | if (!orig_setgid) | ||
531 | orig_setgid = (orig_setgid_t)dlsym(RTLD_NEXT, "setgid"); | ||
532 | |||
533 | int rv = orig_setgid(gid); | ||
534 | printf("%u:%s:setgid %d\n", pid(), name(), gid); | ||
535 | |||
536 | return rv; | ||
537 | } | ||
538 | |||
539 | typedef int (*orig_setfsuid_t)(uid_t uid); | ||
540 | static orig_setfsuid_t orig_setfsuid = NULL; | ||
541 | int setfsuid(uid_t uid) { | ||
542 | if (!orig_setfsuid) | ||
543 | orig_setfsuid = (orig_setfsuid_t)dlsym(RTLD_NEXT, "setfsuid"); | ||
544 | |||
545 | int rv = orig_setfsuid(uid); | ||
546 | printf("%u:%s:setfsuid %d\n", pid(), name(), uid); | ||
547 | |||
548 | return rv; | ||
549 | } | ||
550 | |||
551 | typedef int (*orig_setfsgid_t)(gid_t gid); | ||
552 | static orig_setfsgid_t orig_setfsgid = NULL; | ||
553 | int setfsgid(gid_t gid) { | ||
554 | if (!orig_setfsgid) | ||
555 | orig_setfsgid = (orig_setfsgid_t)dlsym(RTLD_NEXT, "setfsgid"); | ||
556 | |||
557 | int rv = orig_setfsgid(gid); | ||
558 | printf("%u:%s:setfsgid %d\n", pid(), name(), gid); | ||
559 | |||
560 | return rv; | ||
561 | } | ||
562 | |||
563 | typedef int (*orig_setreuid_t)(uid_t ruid, uid_t euid); | ||
564 | static orig_setreuid_t orig_setreuid = NULL; | ||
565 | int setreuid(uid_t ruid, uid_t euid) { | ||
566 | if (!orig_setreuid) | ||
567 | orig_setreuid = (orig_setreuid_t)dlsym(RTLD_NEXT, "setreuid"); | ||
568 | |||
569 | int rv = orig_setreuid(ruid, euid); | ||
570 | printf("%u:%s:setreuid %d %d\n", pid(), name(), ruid, euid); | ||
571 | |||
572 | return rv; | ||
573 | } | ||
574 | |||
575 | typedef int (*orig_setregid_t)(gid_t rgid, gid_t egid); | ||
576 | static orig_setregid_t orig_setregid = NULL; | ||
577 | int setregid(gid_t rgid, gid_t egid) { | ||
578 | if (!orig_setregid) | ||
579 | orig_setregid = (orig_setregid_t)dlsym(RTLD_NEXT, "setregid"); | ||
580 | |||
581 | int rv = orig_setregid(rgid, egid); | ||
582 | printf("%u:%s:setregid %d %d\n", pid(), name(), rgid, egid); | ||
583 | |||
584 | return rv; | ||
585 | } | ||
586 | |||
587 | typedef int (*orig_setresuid_t)(uid_t ruid, uid_t euid, uid_t suid); | ||
588 | static orig_setresuid_t orig_setresuid = NULL; | ||
589 | int setresuid(uid_t ruid, uid_t euid, uid_t suid) { | ||
590 | if (!orig_setresuid) | ||
591 | orig_setresuid = (orig_setresuid_t)dlsym(RTLD_NEXT, "setresuid"); | ||
592 | |||
593 | int rv = orig_setresuid(ruid, euid, suid); | ||
594 | printf("%u:%s:setresuid %d %d %d\n", pid(), name(), ruid, euid, suid); | ||
595 | |||
596 | return rv; | ||
597 | } | ||
598 | |||
599 | typedef int (*orig_setresgid_t)(gid_t rgid, gid_t egid, gid_t sgid); | ||
600 | static orig_setresgid_t orig_setresgid = NULL; | ||
601 | int setresgid(gid_t rgid, gid_t egid, gid_t sgid) { | ||
602 | if (!orig_setresgid) | ||
603 | orig_setresgid = (orig_setresgid_t)dlsym(RTLD_NEXT, "setresgid"); | ||
604 | |||
605 | int rv = orig_setresgid(rgid, egid, sgid); | ||
606 | printf("%u:%s:setresgid %d %d %d\n", pid(), name(), rgid, egid, sgid); | ||
607 | |||
608 | return rv; | ||
609 | } \ No newline at end of file | ||
diff --git a/src/man/firejail-login.txt b/src/man/firejail-login.txt new file mode 100644 index 000000000..6613dc044 --- /dev/null +++ b/src/man/firejail-login.txt | |||
@@ -0,0 +1,36 @@ | |||
1 | .TH man 5 "MONTH YEAR" "VERSION" "firejail login.users man page" | ||
2 | .SH NAME | ||
3 | login.users \- Login file syntax for Firejail | ||
4 | |||
5 | .SH DESCRIPTION | ||
6 | /etc/firejail/login.users file describes additional arguments passed to firejail executable | ||
7 | upon user logging into a Firejail restircted shell. Each user entry in the file consists of | ||
8 | a user name followed by the arguments passed to firejail. The format is as follows: | ||
9 | |||
10 | user_name: arguments | ||
11 | |||
12 | Example: | ||
13 | |||
14 | netblue:--debug --net=none | ||
15 | |||
16 | .SH RESTRICTED SHELL | ||
17 | To configure a restricted shell, replace /bin/bash with /usr/bin/firejail in | ||
18 | /etc/password file for each user that needs to be restricted. Alternatively, | ||
19 | you can specify /usr/bin/firejail in adduser command: | ||
20 | |||
21 | adduser \-\-shell /usr/bin/firejail username | ||
22 | |||
23 | .SH FILES | ||
24 | /etc/firejail/login.users | ||
25 | |||
26 | .SH LICENSE | ||
27 | Firejail is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. | ||
28 | .PP | ||
29 | Homepage: http://firejail.sourceforge.net | ||
30 | .SH SEE ALSO | ||
31 | \&\flfirejail\fR\|(1), | ||
32 | \&\flfiremon\fR\|(1), | ||
33 | \&\flfirejail-profile\fR\|(5) | ||
34 | |||
35 | |||
36 | |||
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt new file mode 100644 index 000000000..46da19ecd --- /dev/null +++ b/src/man/firejail-profile.txt | |||
@@ -0,0 +1,181 @@ | |||
1 | .TH man 5 "MONTH YEAR" "VERSION" "firejail profiles man page" | ||
2 | .SH NAME | ||
3 | profile \- Profile file syntax for Firejail | ||
4 | |||
5 | .SH USAGE | ||
6 | .TP | ||
7 | firejail \-\-profile=filename.profile | ||
8 | |||
9 | .SH DESCRIPTION | ||
10 | Several Firejail command line configuration options can be passed to the program using | ||
11 | profile files. Default Firejail profile files are stored in /etc/firejail | ||
12 | directory and ~/.config/firejail directory. | ||
13 | |||
14 | .SH Scripting | ||
15 | Include and comment support: | ||
16 | |||
17 | .TP | ||
18 | \f\include other.profile | ||
19 | Include other.profile file. | ||
20 | .TP | ||
21 | # this is a comment | ||
22 | |||
23 | .SH Filesystem | ||
24 | These profile entries define a chroot filesystem built on top of the existing | ||
25 | host filesystem. Each line describes a file element that is removed from | ||
26 | the filesystem (\fBblacklist\fR), a read-only file or directory (\fBread-only\fR), | ||
27 | a tmpfs mounted on top of an existing directory (\fBtmpfs\fR), | ||
28 | or mount-bind a directory or file on top of another directory or file (\fBbind\fR). | ||
29 | Use \fBprivate\fR to set private mode. | ||
30 | File globbing is supported, and PATH and HOME directories are searched. | ||
31 | Examples: | ||
32 | .TP | ||
33 | \f\blacklist /usr/bin | ||
34 | Remove /usr/bin directory. | ||
35 | .TP | ||
36 | \f\blacklist /etc/password | ||
37 | Remove /etc/password file. | ||
38 | .TP | ||
39 | \f\read-only /etc/password | ||
40 | Read-only /etc/password file. | ||
41 | .TP | ||
42 | tmpfs /etc | ||
43 | Mount an empty tmpfs filesystem on top of /etc directory. | ||
44 | .TP | ||
45 | bind /root/config/ssh,/etc/ssh | ||
46 | Mount-bind /root/config/ssh on /etc/ssh. | ||
47 | .TP | ||
48 | \f\blacklist /usr/bin/gcc* | ||
49 | Remove all gcc files in /usr/bin (file globbing). | ||
50 | .TP | ||
51 | \f\blacklist ${PATH}/ifconfig | ||
52 | Remove ifconfig command from the regular path directories. | ||
53 | .TP | ||
54 | \f\blacklist ${HOME}/.ssh | ||
55 | Remove .ssh directory from user home directory. | ||
56 | .TP | ||
57 | \f\private | ||
58 | Mount new /root and /home/user directories in temporary | ||
59 | filesystems. All modifications are discarded when the sandbox is | ||
60 | closed. | ||
61 | .TP | ||
62 | \f\private directory | ||
63 | Use directory as user home. | ||
64 | .TP | ||
65 | \f\private.keep file,directory | ||
66 | Build a new user home in a temporary | ||
67 | filesystem, and copy the files and directories in the list in the | ||
68 | new home. All modifications are discarded when the sandbox is | ||
69 | closed. | ||
70 | .TP | ||
71 | \f\private-dev | ||
72 | Create a new /dev directory. Only null, full, zero, tty, pts, ptmx, random, urandom and shm devices are available. | ||
73 | |||
74 | .SH Filters | ||
75 | \fBcaps\fR and \fBseccomp\fR enable Linux capabilities and seccomp filters. Examples: | ||
76 | |||
77 | .TP | ||
78 | caps | ||
79 | Enable default Linux capabilities filter. | ||
80 | .TP | ||
81 | caps.drop all | ||
82 | Blacklist all Linux capabilities. | ||
83 | .TP | ||
84 | caps.drop capability,capability,capability | ||
85 | Blacklist Linux capabilities filter. | ||
86 | .TP | ||
87 | caps.drop capability,capability,capability | ||
88 | Whitelist Linux capabilities filter. | ||
89 | .TP | ||
90 | \f\seccomp | ||
91 | Enable default seccomp filter. | ||
92 | .TP | ||
93 | \f\seccomp syscall,syscall,syscall | ||
94 | Enable seccomp filter and blacklist the system calls in the list on top of default seccomp filter. | ||
95 | .TP | ||
96 | \f\seccomp.drop syscall,syscall,syscall | ||
97 | Enable seccomp filter and blacklist the system calls in the list. | ||
98 | .TP | ||
99 | \f\seccomp.keep syscall,syscall,syscall | ||
100 | Enable seccomp filter and whitelist the system calls in the list. | ||
101 | |||
102 | |||
103 | .SH User Namespace | ||
104 | Use \fBnoroot\fR to enable an user namespace. The namespace has only one user, the current user. | ||
105 | There is no root account defined in the namespace. | ||
106 | |||
107 | .TP | ||
108 | noroot | ||
109 | Enable an user namespace without root user defined. | ||
110 | |||
111 | |||
112 | .SH Resource limits | ||
113 | These profile entries define the limits on system resources (rlimits) for the processes inside the sandbox. | ||
114 | The limits can be modified inside the sandbox using the regular \fBulimt\fR command. Examples: | ||
115 | |||
116 | .TP | ||
117 | \f\rlimit-fsize 1024 | ||
118 | Set the maximum file size that can be created by a process to 1024 bytes. | ||
119 | .TP | ||
120 | \f\rlimit-nproc 1000 | ||
121 | Set the maximum number of processes that can be created for the real user ID of the calling process to 1000. | ||
122 | .TP | ||
123 | \f\rlimit-nofile 500 | ||
124 | Set the maximum number of files that can be opened by a process to 500. | ||
125 | .TP | ||
126 | \f\rlimit-sigpending 200 | ||
127 | Set the maximum number of processes that can be created for the real user ID of the calling process to 200. | ||
128 | |||
129 | .SH CPU Affinity | ||
130 | Set the CPU cores available for this sandbox. Examples: | ||
131 | |||
132 | .TP | ||
133 | cpu 1,2,3 | ||
134 | Use only CPU cores 0, 1 and 2. | ||
135 | |||
136 | .SH Control Groups | ||
137 | Place the sandbox in an existing control group specified by the full path of the task file. Example: | ||
138 | |||
139 | .TP | ||
140 | cgroup /sys/fs/cgroup/g1/tasks | ||
141 | The sandbox is placed in g1 control group. | ||
142 | |||
143 | .SH User Environment | ||
144 | |||
145 | .TP | ||
146 | nogroups | ||
147 | Disable supplementary user groups | ||
148 | .TP | ||
149 | shell none | ||
150 | Run the program directly, without a shell. | ||
151 | |||
152 | .SH Networking | ||
153 | Networking features available in profile files. | ||
154 | |||
155 | .TP | ||
156 | netfilter | ||
157 | If a new network namespace is created, enabled default network filter. | ||
158 | |||
159 | .TP | ||
160 | netfilter filename | ||
161 | If a new network namespace is created, enabled the network filter in filename. | ||
162 | |||
163 | .TP | ||
164 | dns address | ||
165 | Set a DNS server for the sandbox. Up to three DNS servers can be defined. | ||
166 | |||
167 | |||
168 | .SH FILES | ||
169 | /etc/firejail/filename.profile, $HOME/.config/firejail/filename.profile | ||
170 | |||
171 | .SH LICENSE | ||
172 | Firejail is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. | ||
173 | .PP | ||
174 | Homepage: http://firejail.sourceforge.net | ||
175 | .SH SEE ALSO | ||
176 | \&\flfirejail\fR\|(1), | ||
177 | \&\flfiremon\fR\|(1), | ||
178 | \&\flfirejail-login\fR\|(5) | ||
179 | |||
180 | |||
181 | |||
diff --git a/src/man/firejail.txt b/src/man/firejail.txt new file mode 100644 index 000000000..51f21975e --- /dev/null +++ b/src/man/firejail.txt | |||
@@ -0,0 +1,1196 @@ | |||
1 | .TH man 1 "MONTH YEAR" "VERSION" "firejail man page" | ||
2 | .SH NAME | ||
3 | Firejail \- Linux namespaces sandbox program | ||
4 | .SH SYNOPSIS | ||
5 | Start a sandbox: | ||
6 | .PP | ||
7 | .RS | ||
8 | firejail [OPTIONS] [program and arguments] | ||
9 | .RE | ||
10 | .PP | ||
11 | Network traffic shaping for an existing sandbox: | ||
12 | .PP | ||
13 | .RS | ||
14 | firejail \-\-bandwidth={<name>|<PID>} bandwidth-command | ||
15 | .RE | ||
16 | .PP | ||
17 | Monitoring: | ||
18 | .PP | ||
19 | .RS | ||
20 | firejail {\-\-list | \-\-netstats | \-\-top | \-\-tree} | ||
21 | .RE | ||
22 | .PP | ||
23 | Miscellaneous: | ||
24 | .PP | ||
25 | .RS | ||
26 | firejail {\-? | \-\-debug-caps | \-\-debug-syscalls | \-\-help | | ||
27 | .br | ||
28 | \-\-version} | ||
29 | .RE | ||
30 | .SH DESCRIPTION | ||
31 | Firejail is a SUID sandbox program that reduces the risk of security breaches by | ||
32 | restricting the running environment of untrusted applications using Linux | ||
33 | namespaces, seccomp-bpf and Linux capabilities. | ||
34 | It allows a process and all its descendants to have their own private view of the | ||
35 | globally shared kernel resources, such as the network stack, process table, mount table. | ||
36 | Firejail can work in a SELinux or AppArmor environment, | ||
37 | and it is integrated with Linux Control Groups. | ||
38 | .PP | ||
39 | Written in C with virtually no dependencies, the software runs on any Linux computer with a 3.x kernel version | ||
40 | or newer. | ||
41 | It can sandbox any type of processes: servers, graphical applications, and even user login sessions. | ||
42 | The software includes sandbox profiles for a number of more common | ||
43 | Linux programs, such as Mozilla Firefox, Chromium, VLC, Transmission etc. | ||
44 | .SH USAGE | ||
45 | Without any options, the sandbox consists of a chroot filesystem build in a new mount namespace, | ||
46 | and new PID and UTS namespaces. IPC, network and user namespaces can be added using the command line options. | ||
47 | The default Firejail filesystem is based on the host filesystem with the main directories mounted read-only. | ||
48 | Only /home, /tmp and /var directories are writable. | ||
49 | .PP | ||
50 | If no program is specified as an argument, /bin/bash is started by default. | ||
51 | Examples: | ||
52 | .PP | ||
53 | $ firejail [OPTIONS] # starting a /bin/bash shell | ||
54 | .PP | ||
55 | $ firejail [OPTIONS] firefox # starting Mozilla Firefox | ||
56 | .PP | ||
57 | Multiple commands can be run in sandbox using regular bash logic operators: | ||
58 | .PP | ||
59 | $ sudo firejail [OPTIONS] "/etc/init.d/nginx start && sleep inf" | ||
60 | .PP | ||
61 | In the previous example, "sleep inf" command is required in order to keep the session open for the daemon program. | ||
62 | |||
63 | .SH OPTIONS | ||
64 | .TP | ||
65 | \fB\-\- | ||
66 | Signal the end of options and disables further option processing. | ||
67 | .TP | ||
68 | \fB\-\-bandwidth=name | ||
69 | Set bandwidth limits for the sandbox identified by name, see TRAFFIC SHAPING section for more details. | ||
70 | .TP | ||
71 | \fB\-\-bandwidth=pid | ||
72 | Set bandwidth limits for the sandbox identified by PID, see TRAFFIC SHAPING section for more details. | ||
73 | .TP | ||
74 | \fB\-\-bind=dirname1,dirname2 | ||
75 | Mount-bind dirname1 on top of dirname2. This option is only available when running the sandbox as root. | ||
76 | .br | ||
77 | |||
78 | .br | ||
79 | Example: | ||
80 | .br | ||
81 | # firejail \-\-bind=/config/www,/var/www | ||
82 | .TP | ||
83 | \fB\-\-bind=filename1,filename2 | ||
84 | Mount-bind filename1 on top of filename2. This option is only available when running as root. | ||
85 | .br | ||
86 | |||
87 | .br | ||
88 | Example: | ||
89 | .br | ||
90 | # firejail \-\-bind=/config/etc/passwd,/etc/passwd | ||
91 | .TP | ||
92 | \fB\-\-blacklist=dirname_or_filename | ||
93 | Blacklist directory or file. | ||
94 | .br | ||
95 | |||
96 | .br | ||
97 | Example: | ||
98 | .br | ||
99 | $ firejail \-\-blacklist=/sbin \-\-blacklist=/usr/sbin | ||
100 | .TP | ||
101 | \fB\-c | ||
102 | Execute command and exit. | ||
103 | .TP | ||
104 | \fB\-\-caps | ||
105 | Linux capabilities is a kernel feature designed to split up the root privilege into a set of distinct privileges. | ||
106 | These privileges can be enabled or disabled independently, thus restricting what a process running | ||
107 | as root can do in the system. | ||
108 | |||
109 | By default root programs run with all capabilities enabled. \-\-caps option disables the following capabilities: | ||
110 | CAP_SYS_MODULE, CAP_SYS_RAWIO, | ||
111 | CAP_SYS_BOOT, CAP_SYS_NICE, CAP_SYS_TTY_CONFIG, CAP_SYSLOG, CAP_MKNOD, CAP_SYS_ADMIN. | ||
112 | The filter is applied to all processes started in the sandbox. | ||
113 | .br | ||
114 | |||
115 | .br | ||
116 | Example: | ||
117 | .br | ||
118 | $ sudo firejail \-\-caps "/etc/init.d/nginx start && sleep inf" | ||
119 | |||
120 | .TP | ||
121 | \fB\-\-caps.drop=all | ||
122 | Drop all capabilities for the processes running in the sandbox. This option is recommended for running GUI programs | ||
123 | or any other program that doesn't require root privileges. It is a must-have option for sandboxing untrusted programs | ||
124 | installed from unofficial sources - such as games, Java programs, etc. | ||
125 | .br | ||
126 | |||
127 | .br | ||
128 | Example: | ||
129 | .br | ||
130 | $ firejail \-\-caps.drop=all warzone2100 | ||
131 | |||
132 | .TP | ||
133 | \fB\-\-caps.drop=capability,capability,capability | ||
134 | Define a custom blacklist Linux capabilities filter. | ||
135 | .br | ||
136 | |||
137 | .br | ||
138 | Example: | ||
139 | .br | ||
140 | $ firejail \-\-caps.keep=net_broadcast,net_admin,net_raw | ||
141 | |||
142 | .TP | ||
143 | \fB\-\-caps.keep=capability,capability,capability | ||
144 | Define a custom whitelist Linux capabilities filter. | ||
145 | .br | ||
146 | |||
147 | .br | ||
148 | Example: | ||
149 | .br | ||
150 | $ sudo firejail \-\-caps.keep=chown,net_bind_service,setgid,\\ | ||
151 | setuid "/etc/init.d/nginx start && sleep inf" | ||
152 | |||
153 | .TP | ||
154 | \fB\-\-caps.print=name | ||
155 | Print the caps filter for the sandbox identified by name. | ||
156 | .br | ||
157 | |||
158 | .br | ||
159 | Example: | ||
160 | .br | ||
161 | $ firejail \-\-name=mygame \-\-caps.drop=all warzone2100 & | ||
162 | .br | ||
163 | [...] | ||
164 | .br | ||
165 | $ firejail \-\-caps.print=mygame | ||
166 | |||
167 | .TP | ||
168 | \fB\-\-caps.print=pid | ||
169 | Print the caps filter for a sandbox identified by PID. | ||
170 | .br | ||
171 | |||
172 | .br | ||
173 | Example: | ||
174 | .br | ||
175 | $ firejail \-\-list | ||
176 | .br | ||
177 | 3272:netblue:firejail \-\-private firefox | ||
178 | .br | ||
179 | $ firejail \-\-caps.print=3272 | ||
180 | |||
181 | .TP | ||
182 | \fB\-\-cgroup=tasks-file | ||
183 | Place the sandbox in the specified control group. tasks-file is the full path of cgroup tasks file. | ||
184 | .br | ||
185 | |||
186 | .br | ||
187 | Example: | ||
188 | .br | ||
189 | # firejail \-\-cgroup=/sys/fs/cgroup/g1/tasks | ||
190 | |||
191 | .TP | ||
192 | \fB\-\-chroot=dirname | ||
193 | Chroot the sandbox into a root filesystem. If the sandbox is started as a | ||
194 | regular user, default seccomp and capabilities filters are eanbled. | ||
195 | .br | ||
196 | |||
197 | .br | ||
198 | Example: | ||
199 | .br | ||
200 | $ firejail \-\-chroot=/media/ubuntu warzone2100 | ||
201 | |||
202 | .TP | ||
203 | \fB\-\-cpu=cpu-number,cpu-number,cpu-number | ||
204 | Set CPU affinity. | ||
205 | .br | ||
206 | |||
207 | .br | ||
208 | Example: | ||
209 | .br | ||
210 | $ firejail \-\-cpu=0,1 handbrake | ||
211 | |||
212 | .TP | ||
213 | \fB\-\-csh | ||
214 | Use /bin/csh as default user shell. | ||
215 | .br | ||
216 | |||
217 | .br | ||
218 | Example: | ||
219 | .br | ||
220 | $ firejail \-\-csh | ||
221 | .TP | ||
222 | \fB\-\-debug\fR | ||
223 | Print debug messages. | ||
224 | .br | ||
225 | |||
226 | .br | ||
227 | Example: | ||
228 | .br | ||
229 | $ firejail \-\-debug firefox | ||
230 | .TP | ||
231 | \fB\-\-debug-syscalls | ||
232 | Print all recognized system calls in the current Firejail software build and exit. | ||
233 | .br | ||
234 | |||
235 | .br | ||
236 | Example: | ||
237 | .br | ||
238 | $ firejail \-\-debug-syscalls | ||
239 | .TP | ||
240 | \fB\-\-debug-caps | ||
241 | Print all recognized capabilities in the current Firejail software build and exit. | ||
242 | .br | ||
243 | |||
244 | .br | ||
245 | Example: | ||
246 | .br | ||
247 | $ firejail \-\-debug-caps | ||
248 | .TP | ||
249 | \fB\-\-defaultgw=address | ||
250 | Use this address as default gateway in the new network namespace. | ||
251 | .br | ||
252 | |||
253 | .br | ||
254 | Example: | ||
255 | .br | ||
256 | $ firejail \-\-net=eth0 \-\-defaultgw=10.10.20.1 firefox | ||
257 | |||
258 | .TP | ||
259 | \fB\-\-dns=address | ||
260 | Set a DNS server for the sandbox. Up to three DNS servers can be defined. | ||
261 | Use this option if you don't trust the DNS setup on your network. | ||
262 | .br | ||
263 | |||
264 | .br | ||
265 | Example: | ||
266 | .br | ||
267 | $ firejail \-\-dns=8.8.8.8 \-\-dns=8.8.4.4 firefox | ||
268 | |||
269 | .TP | ||
270 | \fB\-\-dns.print=name | ||
271 | Print DNS configuration for a sandbox identified by name. | ||
272 | .br | ||
273 | |||
274 | .br | ||
275 | Example: | ||
276 | .br | ||
277 | $ firejail \-\-name=mygame \-\-caps.drop=all warzone2100 & | ||
278 | .br | ||
279 | [...] | ||
280 | .br | ||
281 | $ firejail \-\-dns.print=mygame | ||
282 | |||
283 | .TP | ||
284 | \fB\-\-dns.print=pid | ||
285 | Print DNS configuration for a sandbox identified by PID. | ||
286 | .br | ||
287 | |||
288 | .br | ||
289 | Example: | ||
290 | .br | ||
291 | $ firejail \-\-list | ||
292 | .br | ||
293 | 3272:netblue:firejail \-\-private firefox | ||
294 | .br | ||
295 | $ firejail \-\-dns.print=3272 | ||
296 | |||
297 | .TP | ||
298 | \fB\-?\fR, \fB\-\-help\fR | ||
299 | Print options end exit. | ||
300 | .TP | ||
301 | \fB\-\-ip=address | ||
302 | Assign IP addresses to the last network interface defined by a \-\-net option. A | ||
303 | default gateway is assigned by default. | ||
304 | .br | ||
305 | |||
306 | .br | ||
307 | Example: | ||
308 | .br | ||
309 | $ firejail \-\-net=eth0 \-\-ip=10.10.20.56 firefox | ||
310 | |||
311 | .TP | ||
312 | \fB\-\-ip=none | ||
313 | No IP address and no default gateway are configured for the last interface | ||
314 | defined by a \-\-net option. Use this option | ||
315 | in case you intend to start an external DHCP client in the sandbox. | ||
316 | .br | ||
317 | |||
318 | .br | ||
319 | Example: | ||
320 | .br | ||
321 | $ firejail \-\-net=eth0 \-\-\ip=none | ||
322 | |||
323 | .TP | ||
324 | \fB\-\-iprange=address,address | ||
325 | Assign an IP address in the provided range to the last network interface defined by a \-\-net option. A | ||
326 | default gateway is assigned by default. | ||
327 | .br | ||
328 | |||
329 | .br | ||
330 | Example: | ||
331 | .br | ||
332 | $ firejail \-\-net=eth0 \-\-\iprange=192.168.1.100,192.168.1.150 | ||
333 | |||
334 | .TP | ||
335 | \fB\-\-ipc-namespace | ||
336 | Enable a new IPC namespace if the sandbox was started as a regular user. IPC namespace is enabled by default | ||
337 | for sandboxes started as root. | ||
338 | .br | ||
339 | |||
340 | .br | ||
341 | Example: | ||
342 | .br | ||
343 | $ firejail \-\-ipc-namespace firefox | ||
344 | .TP | ||
345 | \fB\-\-join=name | ||
346 | Join the sandbox identified by name. By default a /bin/bash shell is started after joining the sandbox. | ||
347 | If a program is specified, the program is run in the sandbox. | ||
348 | .br | ||
349 | |||
350 | .br | ||
351 | Example: | ||
352 | .br | ||
353 | $ firejail \-\-name=mygame \-\-caps.drop=all warzone2100 & | ||
354 | .br | ||
355 | [...] | ||
356 | .br | ||
357 | $ firejail \-\-join=mygame | ||
358 | |||
359 | |||
360 | .TP | ||
361 | \fB\-\-join=pid | ||
362 | Join the sandbox identified by PID. By default a /bin/bash shell is started after joining the sandbox. | ||
363 | If a program is specified, the program is run in the sandbox. | ||
364 | .br | ||
365 | |||
366 | .br | ||
367 | Example: | ||
368 | .br | ||
369 | $ firejail \-\-list | ||
370 | .br | ||
371 | 3272:netblue:firejail \-\-private firefox | ||
372 | .br | ||
373 | $ firejail \-\-join=3272 | ||
374 | |||
375 | .TP | ||
376 | \fB\-\-list | ||
377 | List all sandboxes, see MONITORING section for more details. | ||
378 | .br | ||
379 | |||
380 | .br | ||
381 | Example: | ||
382 | .br | ||
383 | $ firejail \-\-list | ||
384 | .br | ||
385 | 7015:netblue:firejail firefox | ||
386 | .br | ||
387 | 7056:netblue:firejail \-\-net=eth0 transmission-gtk | ||
388 | .br | ||
389 | 7064:netblue:firejail \-\-noroot xterm | ||
390 | .br | ||
391 | $ | ||
392 | .TP | ||
393 | \fB\-\-mac=address | ||
394 | Assign MAC addresses to the last network interface defined by a \-\-net option. | ||
395 | .br | ||
396 | |||
397 | .br | ||
398 | Example: | ||
399 | .br | ||
400 | $ firejail \-\-net=eth0 \-\-mac=00:11:22:33:44:55 firefox | ||
401 | |||
402 | .TP | ||
403 | \fB\-\-name=name | ||
404 | Set sandbox hostname. Several options, such as \-\-join and \-\-shutdown, can use | ||
405 | this name to identify a sandbox. | ||
406 | .br | ||
407 | |||
408 | .br | ||
409 | Example: | ||
410 | .br | ||
411 | $ firejail \-\-name=mybrowser firefox | ||
412 | |||
413 | .TP | ||
414 | \fB\-\-net=bridge_interface | ||
415 | Enable a new network namespace and connect it to this bridge interface. | ||
416 | Unless specified with option \-\-ip and \-\-defaultgw, an IP address and a default gateway will be assigned | ||
417 | automatically to the sandbox. The IP address is verified using ARP before assignment. The address | ||
418 | configured as default gateway is the bridge device IP address. Up to four \-\-net | ||
419 | bridge devices can be defined. Mixing bridge and macvlan devices is allowed. | ||
420 | .br | ||
421 | |||
422 | .br | ||
423 | Example: | ||
424 | .br | ||
425 | $ sudo brctl addbr br0 | ||
426 | .br | ||
427 | $ sudo ifconfig br0 10.10.20.1/24 | ||
428 | .br | ||
429 | $ sudo brctl addbr br1 | ||
430 | .br | ||
431 | $ sudo ifconfig br1 10.10.30.1/24 | ||
432 | .br | ||
433 | $ firejail \-\-net=br0 \-\-net=br1 | ||
434 | |||
435 | .TP | ||
436 | \fB\-\-net=ethernet_interface | ||
437 | Enable a new network namespace and connect it | ||
438 | to this ethernet interface using the standard Linux macvlan | ||
439 | driver. Unless specified with option \-\-ip and \-\-defaultgw, an | ||
440 | IP address and a default gateway will be assigned automatically | ||
441 | to the sandbox. The IP address is verified using ARP before | ||
442 | assignment. The address configured as default gateway is the | ||
443 | default gateway of the host. Up to four \-\-net devices can | ||
444 | be defined. Mixing bridge and macvlan devices is allowed. | ||
445 | .br | ||
446 | |||
447 | .br | ||
448 | Example: | ||
449 | .br | ||
450 | $ firejail \-\-net=eth0 \-\-ip=192.168.1.80 \-\-dns=8.8.8.8 firefox | ||
451 | |||
452 | .TP | ||
453 | \fB\-\-net=none | ||
454 | Enable a new, unconnected network namespace. The only interface | ||
455 | available in the new namespace is a new loopback interface (lo). | ||
456 | Use this option to deny | ||
457 | network access to programs that don't really need network access. | ||
458 | .br | ||
459 | |||
460 | .br | ||
461 | Example: | ||
462 | .br | ||
463 | $ firejail \-\-net=none vlc | ||
464 | |||
465 | .TP | ||
466 | \fB\-\-netfilter | ||
467 | Enable a default client network filter in the new network namespace. | ||
468 | New network namespaces are created using \-\-net option. If a new network namespaces is not created, | ||
469 | \-\-netfilter option does nothing. | ||
470 | The default filter is as follows: | ||
471 | .br | ||
472 | |||
473 | .br | ||
474 | *filter | ||
475 | .br | ||
476 | :INPUT DROP [0:0] | ||
477 | .br | ||
478 | :FORWARD DROP [0:0] | ||
479 | .br | ||
480 | :OUTPUT ACCEPT [0:0] | ||
481 | .br | ||
482 | \-A INPUT \-i lo \-j ACCEPT | ||
483 | .br | ||
484 | \-A INPUT \-m state \-\-state RELATED,ESTABLISHED \-j ACCEPT | ||
485 | .br | ||
486 | \-A INPUT \-p icmp \-\-icmp-type destination-unreachable \-j ACCEPT | ||
487 | .br | ||
488 | \-A INPUT \-p icmp \-\-icmp-type time-exceeded \-j ACCEPT | ||
489 | .br | ||
490 | \-A INPUT \-p icmp \-\-icmp-type echo-request \-j ACCEPT | ||
491 | .br | ||
492 | COMMIT | ||
493 | .br | ||
494 | |||
495 | .br | ||
496 | Example: | ||
497 | .br | ||
498 | $ firejail \-\-net=eth0 \-\-netfilter firefox | ||
499 | .TP | ||
500 | \fB\-\-netfilter=filename | ||
501 | Enable the network filter specified by filename in the new network namespace. The filter file format | ||
502 | is the format of iptables-save and iptable-restore commands. | ||
503 | New network namespaces are created using \-\-net option. If a new network namespaces is not created, | ||
504 | \-\-netfilter option does nothing. | ||
505 | .br | ||
506 | |||
507 | .br | ||
508 | Example: | ||
509 | .br | ||
510 | $ firejail \-\-net=eth0 \-\-netfilter=myfile firefox | ||
511 | .TP | ||
512 | \fB\-\-netstats | ||
513 | Monitor network namespace statistics, see MONITORING section for more details. | ||
514 | .br | ||
515 | |||
516 | .br | ||
517 | Example: | ||
518 | .br | ||
519 | $ firejail \-\-netstats | ||
520 | .br | ||
521 | PID User RX(KB/s) TX(KB/s) Command | ||
522 | .br | ||
523 | 1294 netblue 53.355 1.473 firejail \-\-net=eth0 firefox | ||
524 | .br | ||
525 | 7383 netblue 9.045 0.112 firejail \-\-net=eth0 transmission | ||
526 | |||
527 | |||
528 | .TP | ||
529 | \fB\-\-nogroups | ||
530 | Disable supplementary groups. Without this option, supplementary groups are enabled for the user starting the | ||
531 | sandbox. For root user supplementary groups are always disabled. | ||
532 | .br | ||
533 | |||
534 | .br | ||
535 | Example: | ||
536 | .br | ||
537 | $ id | ||
538 | .br | ||
539 | uid=1000(netblue) gid=1000(netblue) groups=1000(netblue),24(cdrom),25(floppy),27(sudo),29(audio) | ||
540 | .br | ||
541 | $ firejail \-\-nogroups | ||
542 | .br | ||
543 | Parent pid 8704, child pid 8705 | ||
544 | .br | ||
545 | Child process initialized | ||
546 | .br | ||
547 | $ id | ||
548 | .br | ||
549 | uid=1000(netblue) gid=1000(netblue) groups=1000(netblue) | ||
550 | .br | ||
551 | $ | ||
552 | |||
553 | .TP | ||
554 | \fB\-\-noroot | ||
555 | Install a user namespace with a single user - the current user. | ||
556 | root user does not exist in the new namespace. This option | ||
557 | requires a Linux kernel version 3.8 or newer. The option | ||
558 | is not supported for \-\-chroot and \-\-overlay configurations, | ||
559 | or for sandboxes started as root. | ||
560 | .br | ||
561 | |||
562 | .br | ||
563 | Example: | ||
564 | .br | ||
565 | $ firejail \-\-noroot | ||
566 | .br | ||
567 | Parent pid 8553, child pid 8554 | ||
568 | .br | ||
569 | Child process initialized | ||
570 | .br | ||
571 | $ ping google.com | ||
572 | .br | ||
573 | ping: icmp open socket: Operation not permitted | ||
574 | .br | ||
575 | $ | ||
576 | .TP | ||
577 | \fB\-\-output=logfile | ||
578 | stdout logging and log rotation. Copy stdout to logfile, and keep the size of the file under 500KB using log | ||
579 | rotation. Five files with prefixes .1 to .5 are used in rotation. | ||
580 | .br | ||
581 | |||
582 | .br | ||
583 | Example: | ||
584 | .br | ||
585 | $ firejail \-\-output=sandboxlog /bin/bash | ||
586 | .br | ||
587 | [...] | ||
588 | .br | ||
589 | $ ls -l sandboxlog* | ||
590 | .br | ||
591 | -rw-r--r-- 1 netblue netblue 333890 Jun 2 07:48 sadnboxlog | ||
592 | .br | ||
593 | -rw-r--r-- 1 netblue netblue 511488 Jun 2 07:48 sandboxlog.1 | ||
594 | .br | ||
595 | -rw-r--r-- 1 netblue netblue 511488 Jun 2 07:48 sandboxlog.2 | ||
596 | .br | ||
597 | -rw-r--r-- 1 netblue netblue 511488 Jun 2 07:48 sandboxlog.3 | ||
598 | .br | ||
599 | -rw-r--r-- 1 netblue netblue 511488 Jun 2 07:48 sandboxlog.4 | ||
600 | .br | ||
601 | -rw-r--r-- 1 netblue netblue 511488 Jun 2 07:48 sandboxlog.5 | ||
602 | |||
603 | .TP | ||
604 | \fB\-\-overlay | ||
605 | Mount a filesystem overlay on top of the current filesystem. All filesystem modifications go into the overlay, | ||
606 | and are discarded when the sandbox is closed. | ||
607 | .br | ||
608 | |||
609 | .br | ||
610 | OverlayFS support is required in Linux kernel for this option to work. | ||
611 | OverlayFS was officially introduced in Linux kernel version 3.18. It was also | ||
612 | available in earlier kernel versions in some distributions such as Ubuntu and OpenSUSE. | ||
613 | .br | ||
614 | |||
615 | .br | ||
616 | Example: | ||
617 | .br | ||
618 | $ firejail \-\-overlay firefox | ||
619 | |||
620 | .TP | ||
621 | \fB\-\-private | ||
622 | Mount new /root and /home/user directories in temporary | ||
623 | filesystems. All modifications are discarded when the sandbox is | ||
624 | closed. | ||
625 | .br | ||
626 | |||
627 | .br | ||
628 | Example: | ||
629 | .br | ||
630 | $ firejail \-\-private firefox | ||
631 | .TP | ||
632 | \fB\-\-private=directory | ||
633 | Use directory as user home. | ||
634 | .br | ||
635 | |||
636 | .br | ||
637 | Example: | ||
638 | .br | ||
639 | $ firejail \-\-private=/home/netblue/firefox-home firefox | ||
640 | |||
641 | .TP | ||
642 | \fB\-\-private.keep=file,directory | ||
643 | Build a new user home in a temporary | ||
644 | filesystem, and copy the files and directories in the list in the | ||
645 | new home. All modifications are discarded when the sandbox is | ||
646 | closed. | ||
647 | .br | ||
648 | |||
649 | .br | ||
650 | Example: | ||
651 | .br | ||
652 | $ firejail \-\-private.keep=.mozilla firefox | ||
653 | .TP | ||
654 | \fB\-\-private-dev | ||
655 | Create a new /dev directory. Only null, full, zero, tty, pts, ptmx, random, urandom and shm devices are available. | ||
656 | .br | ||
657 | |||
658 | .br | ||
659 | Example: | ||
660 | .br | ||
661 | $ firejail \-\-private-dev | ||
662 | .br | ||
663 | Parent pid 9887, child pid 9888 | ||
664 | .br | ||
665 | Child process initialized | ||
666 | .br | ||
667 | $ ls /dev | ||
668 | .br | ||
669 | full null ptmx pts random shm tty urandom zero | ||
670 | .br | ||
671 | $ | ||
672 | .TP | ||
673 | \fB\-\-profile=filename | ||
674 | Load a custom profile from filename. For filename use an absolute path or a path relative to the current path. | ||
675 | For more information, see PROFILES section below. | ||
676 | .br | ||
677 | |||
678 | .br | ||
679 | Example: | ||
680 | .br | ||
681 | $ firejail \-\-profile=myprofile | ||
682 | .TP | ||
683 | \fB\-\-read-only=dirname_or_filename | ||
684 | Set directory or file read-only. | ||
685 | .br | ||
686 | |||
687 | .br | ||
688 | Example: | ||
689 | .br | ||
690 | $ firejail \-\-read-only=~/.mozilla firefox | ||
691 | .TP | ||
692 | \fB\-\-rlimit-fsize=number | ||
693 | Set the maximum file size that can be created by a process. | ||
694 | .TP | ||
695 | \fB\-\-rlimit-nofile=number | ||
696 | Set the maximum number of files that can be opened by a process. | ||
697 | .TP | ||
698 | \fB\-\-rlimit-nproc=number | ||
699 | Set the maximum number of processes that can be created for the real user ID of the calling process. | ||
700 | .TP | ||
701 | \fB\-\-rlimit-sigpending=number | ||
702 | Set the maximum number of pending signals for a process. | ||
703 | .TP | ||
704 | \fB\-\-scan | ||
705 | ARP-scan all the networks from inside a network namespace. | ||
706 | This makes it possible to detect macvlan kernel device drivers running on the current host. | ||
707 | .br | ||
708 | |||
709 | .br | ||
710 | Example: | ||
711 | .br | ||
712 | $ firejail \-\-net=eth0 \-\-scan | ||
713 | .TP | ||
714 | \fB\-\-seccomp | ||
715 | Enable seccomp filter and blacklist the syscalls in the default list. The default list is as follows: | ||
716 | mount, umount2, ptrace, kexec_load, open_by_handle_at, init_module, finit_module, delete_module, | ||
717 | iopl, ioperm, swapon, swapoff, mknode, syslog, process_vm_readv and process_vm_writev, | ||
718 | sysfs,_sysctl, adjtimex, clock_adjtime, lookup_dcookie, perf_event_open, fanotify_init and kcmp. | ||
719 | .br | ||
720 | |||
721 | .br | ||
722 | Example: | ||
723 | .br | ||
724 | $ firejail \-\-sccomp | ||
725 | .TP | ||
726 | \fB\-\-seccomp=syscall,syscall,syscall | ||
727 | Enable seccomp filter, blacklist the default list and the syscalls specified by the command. | ||
728 | .br | ||
729 | |||
730 | .br | ||
731 | Example: | ||
732 | .br | ||
733 | $ firejail \-\-seccomp=utime,utimensat,utimes firefox | ||
734 | .TP | ||
735 | \fB\-\-seccomp.drop=syscall,syscall,syscall | ||
736 | Enable seccomp filter, and blacklist the syscalls specified by the command. | ||
737 | .br | ||
738 | |||
739 | .br | ||
740 | Example: | ||
741 | .br | ||
742 | $ firejail \-\-seccomp.drop=utime,utimensat,utimes | ||
743 | .TP | ||
744 | \fB\-\-seccomp.keep=syscall,syscall,syscall | ||
745 | Enable seccomp filter, and whitelist the syscalls specified by the command. | ||
746 | .br | ||
747 | |||
748 | .br | ||
749 | Example: | ||
750 | .br | ||
751 | $ firejail \-\-shell=none \-\-seccomp.keep=poll,select,[...] transmission-gtk | ||
752 | .TP | ||
753 | \fB\-\-seccomp.print=name | ||
754 | Print the seccomp filter for the sandbox started using \-\-name option. | ||
755 | .br | ||
756 | |||
757 | .br | ||
758 | Example: | ||
759 | .br | ||
760 | $ firejail \-\-name=browser firefox & | ||
761 | .br | ||
762 | $ firejail \-\-seccomp.print=browser | ||
763 | .br | ||
764 | SECCOMP Filter: | ||
765 | .br | ||
766 | VALIDATE_ARCHITECTURE | ||
767 | .br | ||
768 | EXAMINE_SYSCAL | ||
769 | .br | ||
770 | BLACKLIST 165 mount | ||
771 | .br | ||
772 | BLACKLIST 166 umount2 | ||
773 | .br | ||
774 | BLACKLIST 101 ptrace | ||
775 | .br | ||
776 | BLACKLIST 246 kexec_load | ||
777 | .br | ||
778 | BLACKLIST 304 open_by_handle_at | ||
779 | .br | ||
780 | BLACKLIST 175 init_module | ||
781 | .br | ||
782 | BLACKLIST 176 delete_module | ||
783 | .br | ||
784 | BLACKLIST 172 iopl | ||
785 | .br | ||
786 | BLACKLIST 173 ioperm | ||
787 | .br | ||
788 | BLACKLIST 167 swapon | ||
789 | .br | ||
790 | BLACKLIST 168 swapoff | ||
791 | .br | ||
792 | BLACKLIST 103 syslog | ||
793 | .br | ||
794 | BLACKLIST 310 process_vm_readv | ||
795 | .br | ||
796 | BLACKLIST 311 process_vm_writev | ||
797 | .br | ||
798 | BLACKLIST 133 mknod | ||
799 | .br | ||
800 | BLACKLIST 139 sysfs | ||
801 | .br | ||
802 | BLACKLIST 156 _sysctl | ||
803 | .br | ||
804 | BLACKLIST 159 adjtimex | ||
805 | .br | ||
806 | BLACKLIST 305 clock_adjtime | ||
807 | .br | ||
808 | BLACKLIST 212 lookup_dcookie | ||
809 | .br | ||
810 | BLACKLIST 298 perf_event_open | ||
811 | .br | ||
812 | BLACKLIST 300 fanotify_init | ||
813 | .br | ||
814 | RETURN_ALLOW | ||
815 | .br | ||
816 | $ | ||
817 | .TP | ||
818 | \fB\-\-seccomp.print=pid | ||
819 | Print the seccomp filter for the sandbox specified by process ID. Use \-\-list option to get a list of all active sandboxes. | ||
820 | .br | ||
821 | |||
822 | .br | ||
823 | Example: | ||
824 | .br | ||
825 | $ firejail \-\-list | ||
826 | .br | ||
827 | 10786:netblue:firejail \-\-name=browser firefox | ||
828 | $ firejail \-\-seccomp.print=10786 | ||
829 | .br | ||
830 | SECCOMP Filter: | ||
831 | .br | ||
832 | VALIDATE_ARCHITECTURE | ||
833 | .br | ||
834 | EXAMINE_SYSCAL | ||
835 | .br | ||
836 | BLACKLIST 165 mount | ||
837 | .br | ||
838 | BLACKLIST 166 umount2 | ||
839 | .br | ||
840 | BLACKLIST 101 ptrace | ||
841 | .br | ||
842 | BLACKLIST 246 kexec_load | ||
843 | .br | ||
844 | BLACKLIST 304 open_by_handle_at | ||
845 | .br | ||
846 | BLACKLIST 175 init_module | ||
847 | .br | ||
848 | BLACKLIST 176 delete_module | ||
849 | .br | ||
850 | BLACKLIST 172 iopl | ||
851 | .br | ||
852 | BLACKLIST 173 ioperm | ||
853 | .br | ||
854 | BLACKLIST 167 swapon | ||
855 | .br | ||
856 | BLACKLIST 168 swapoff | ||
857 | .br | ||
858 | BLACKLIST 103 syslog | ||
859 | .br | ||
860 | BLACKLIST 310 process_vm_readv | ||
861 | .br | ||
862 | BLACKLIST 311 process_vm_writev | ||
863 | .br | ||
864 | BLACKLIST 133 mknod | ||
865 | .br | ||
866 | BLACKLIST 139 sysfs | ||
867 | .br | ||
868 | BLACKLIST 156 _sysctl | ||
869 | .br | ||
870 | BLACKLIST 159 adjtimex | ||
871 | .br | ||
872 | BLACKLIST 305 clock_adjtime | ||
873 | .br | ||
874 | BLACKLIST 212 lookup_dcookie | ||
875 | .br | ||
876 | BLACKLIST 298 perf_event_open | ||
877 | .br | ||
878 | BLACKLIST 300 fanotify_init | ||
879 | .br | ||
880 | RETURN_ALLOW | ||
881 | .br | ||
882 | $ | ||
883 | .TP | ||
884 | \fB\-\-shell=none | ||
885 | Run the program directly, without a user shell. | ||
886 | .br | ||
887 | |||
888 | .br | ||
889 | Example: | ||
890 | .br | ||
891 | $ firejail \-\-shell=none script.sh | ||
892 | .TP | ||
893 | \fB\-\-shell=program | ||
894 | Set default user shell. Use this shell to run the application using \-c shell option. | ||
895 | For example "firejail \-\-shell=/bin/dash firefox" will start Mozilla Firefox as "/bin/dash \-c firefox". | ||
896 | By default Bash shell (/bin/bash) is used. Options such as \-\-zsh and \-\-csh can also set the default | ||
897 | shell. | ||
898 | .br | ||
899 | |||
900 | .br | ||
901 | Example: | ||
902 | $firejail \-\-shell=/bin/dash script.sh | ||
903 | .TP | ||
904 | \fB\-\-shutdown=name | ||
905 | Shutdown the sandbox started using \-\-name option. | ||
906 | .br | ||
907 | |||
908 | .br | ||
909 | Example: | ||
910 | .br | ||
911 | $ firejail \-\-name=mygame \-\-caps.drop=all warzone2100 & | ||
912 | .br | ||
913 | [...] | ||
914 | .br | ||
915 | $ firejail \-\-shutdown=mygame | ||
916 | .TP | ||
917 | \fB\-\-shutdown=pid | ||
918 | Shutdown the sandbox specified by process ID. Use \-\-list option to get a list of all active sandboxes. | ||
919 | .br | ||
920 | |||
921 | .br | ||
922 | Example: | ||
923 | .br | ||
924 | $ firejail \-\-list | ||
925 | .br | ||
926 | 3272:netblue:firejail \-\-private firefox | ||
927 | .br | ||
928 | $ firejail \-\-shutdown=3272 | ||
929 | .TP | ||
930 | \fB\-\-tmpfs=dirname | ||
931 | Mount a tmpfs filesystem on directory dirname. | ||
932 | .br | ||
933 | |||
934 | .br | ||
935 | Example: | ||
936 | .br | ||
937 | $ firejail \-\-tmpfs=/var | ||
938 | .TP | ||
939 | \fB\-\-top | ||
940 | Monitor the most CPU-intensive sandboxes, see MONITORING section for more details. | ||
941 | .br | ||
942 | |||
943 | .br | ||
944 | Example: | ||
945 | .br | ||
946 | $ firejail \-\-top | ||
947 | .TP | ||
948 | \fB\-\-trace | ||
949 | Trace open, access and connect system calls. | ||
950 | .br | ||
951 | |||
952 | .br | ||
953 | Example: | ||
954 | .br | ||
955 | $ firejail \-\-trace wget -q www.debian.org | ||
956 | .br | ||
957 | Parent pid 11793, child pid 11794 | ||
958 | .br | ||
959 | Child process initialized | ||
960 | .br | ||
961 | 1:bash:open /dev/tty | ||
962 | .br | ||
963 | 1:wget:fopen64 /etc/wgetrc | ||
964 | .br | ||
965 | 1:wget:fopen /etc/hosts | ||
966 | .br | ||
967 | 1:wget:socket AF_INET SOCK_DGRAM IPPROTO_IP | ||
968 | .br | ||
969 | 1:wget:connect 8.8.8.8:53 | ||
970 | .br | ||
971 | 1:wget:socket AF_INET SOCK_STREAM IPPROTO_IP | ||
972 | .br | ||
973 | 1:wget:connect 140.211.15.34:80 | ||
974 | .br | ||
975 | 1:wget:fopen64 index.html.1 | ||
976 | .br | ||
977 | |||
978 | .br | ||
979 | parent is shutting down, bye... | ||
980 | .TP | ||
981 | \fB\-\-tree | ||
982 | Print a tree of all sandboxed processes, see MONITORING section for more details. | ||
983 | .br | ||
984 | |||
985 | .br | ||
986 | Example: | ||
987 | .br | ||
988 | $ firejail \-\-tree | ||
989 | .br | ||
990 | 11903:netblue:firejail iceweasel | ||
991 | .br | ||
992 | 11904:netblue:iceweasel | ||
993 | .br | ||
994 | 11957:netblue:/usr/lib/iceweasel/plugin-container | ||
995 | .br | ||
996 | 11969:netblue:firejail \-\-net=eth0 transmission-gtk | ||
997 | .br | ||
998 | 11970:netblue:transmission-gtk | ||
999 | .TP | ||
1000 | \fB\-\-version | ||
1001 | Print program version and exit. | ||
1002 | .br | ||
1003 | |||
1004 | .br | ||
1005 | Example: | ||
1006 | .br | ||
1007 | $ firejail \-\-version | ||
1008 | .br | ||
1009 | firejail version 0.9.27 | ||
1010 | .TP | ||
1011 | \fB\-\-zsh | ||
1012 | Use /usr/bin/zsh as default user shell. | ||
1013 | .br | ||
1014 | |||
1015 | .br | ||
1016 | Example: | ||
1017 | .br | ||
1018 | $ firejakil \-\-zsh | ||
1019 | .SH TRAFFIC SHAPING | ||
1020 | Network bandwidth is an expensive resource shared among all sandboxes running on a system. | ||
1021 | Traffic shaping allows the user to increase network performance by controlling | ||
1022 | the amount of data that flows into and out of the sandboxes. | ||
1023 | |||
1024 | Firejail implements a simple rate-limiting shaper based on Linux command tc. | ||
1025 | The shaper works at sandbox level, and can be used only for sandboxes configured with new network namespaces. | ||
1026 | |||
1027 | Set rate-limits: | ||
1028 | |||
1029 | firejail --bandwidth={name|pid} set network download upload | ||
1030 | |||
1031 | Clear rate-limits: | ||
1032 | |||
1033 | firejail --bandwidth={name|pid} clear network | ||
1034 | |||
1035 | Status: | ||
1036 | |||
1037 | firejail --bandwidth={name|pid} status | ||
1038 | |||
1039 | where: | ||
1040 | .br | ||
1041 | name - sandbox name | ||
1042 | .br | ||
1043 | pid - sandbox pid | ||
1044 | .br | ||
1045 | network - network interface as used by \-\-net option | ||
1046 | .br | ||
1047 | download - download speed in KB/s (kilobyte per second) | ||
1048 | .br | ||
1049 | upload - upload speed in KB/s (kilobyte per second) | ||
1050 | |||
1051 | Example: | ||
1052 | .br | ||
1053 | $ firejail \-\-name=mybrowser \-\-net=eth0 firefox & | ||
1054 | .br | ||
1055 | $ firejail \-\-bandwidth=mybrowser set eth0 80 20 | ||
1056 | .br | ||
1057 | $ firejail \-\-bandwidth=mybrowser status | ||
1058 | .br | ||
1059 | $ firejail \-\-bandwidth=mybrowser clear eth0 | ||
1060 | |||
1061 | .SH MONITORING | ||
1062 | Option \-\-list prints a list of all sandboxes. The format | ||
1063 | for each process entry is as follows: | ||
1064 | |||
1065 | PID:USER:Command | ||
1066 | |||
1067 | Option \-\-tree prints the tree of processes running in the sandbox. The format | ||
1068 | for each process entry is as follows: | ||
1069 | |||
1070 | PID:USER:Command | ||
1071 | |||
1072 | Option \-\-top is similar to the UNIX top command, however it applies only to | ||
1073 | sandboxes. | ||
1074 | |||
1075 | Option \-\-netstats prints network statistics for active sandboxes installing new network namespaces. | ||
1076 | |||
1077 | |||
1078 | Listed below are the available fields (columns) in alphabetical | ||
1079 | order for \-\-top and \-\-netstat options: | ||
1080 | |||
1081 | .TP | ||
1082 | Command | ||
1083 | Command used to start the sandbox. | ||
1084 | .TP | ||
1085 | CPU% | ||
1086 | CPU usage, the sandbox share of the elapsed CPU time since the | ||
1087 | last screen update | ||
1088 | .TP | ||
1089 | PID | ||
1090 | Unique process ID for the task controlling the sandbox. | ||
1091 | .TP | ||
1092 | Prcs | ||
1093 | Number of processes running in sandbox, including the controlling process. | ||
1094 | .TP | ||
1095 | RES | ||
1096 | Resident Memory Size (KiB), sandbox non-swapped physical memory. | ||
1097 | It is a sum of the RES values for all processes running in the sandbox. | ||
1098 | .TP | ||
1099 | RX(KB/s) | ||
1100 | Network receive speed. | ||
1101 | .TP | ||
1102 | SHR | ||
1103 | Shared Memory Size (KiB), it reflects memory shared with other | ||
1104 | processes. It is a sum of the SHR values for all processes running | ||
1105 | in the sandbox, including the controlling process. | ||
1106 | .TP | ||
1107 | TX(KB/s) | ||
1108 | Network transmit speed. | ||
1109 | .TP | ||
1110 | Uptime | ||
1111 | Sandbox running time in hours:minutes:seconds format. | ||
1112 | .TP | ||
1113 | User | ||
1114 | The owner of the sandbox. | ||
1115 | |||
1116 | .SH PROFILES | ||
1117 | Several command line configuration options can be passed to the program using | ||
1118 | profile files. Firejail supports user specified profile files and automatic profile files, | ||
1119 | as follows: | ||
1120 | |||
1121 | 1. Load a specific profile file from a full path, or a path relative to the current directory. | ||
1122 | Example: | ||
1123 | .PP | ||
1124 | .RS | ||
1125 | $ firejail --profile=/home/netblue/icecat.profile icecat | ||
1126 | .RE | ||
1127 | |||
1128 | 2. Load a default profile file automatically from ~/.config/firejail or from /etc/firejail, based | ||
1129 | on the name of the executable started in the sandbox. Example: | ||
1130 | .PP | ||
1131 | .RS | ||
1132 | $ firejail icecat | ||
1133 | .br | ||
1134 | Command name #icecat# | ||
1135 | .br | ||
1136 | .br | ||
1137 | Found icecat profile in /home/netblue/.config/firejail directory | ||
1138 | .br | ||
1139 | Reading profile /home/netblue/.config/firejail/icecat.profile | ||
1140 | .br | ||
1141 | [...] | ||
1142 | .RE | ||
1143 | |||
1144 | See man 5 firejail-profile for profile file syntax information. | ||
1145 | |||
1146 | .SH RESTRICTED SHELL | ||
1147 | To configure a restricted shell, replace /bin/bash with /usr/bin/firejail in | ||
1148 | /etc/password file for each user that needs to be restricted. Alternatively, | ||
1149 | you can specify /usr/bin/firejail in adduser command: | ||
1150 | |||
1151 | adduser \-\-shell /usr/bin/firejail username | ||
1152 | |||
1153 | Additional arguments passed to firejail executable upon login are declared in /etc/firejail/login.users file. | ||
1154 | |||
1155 | .SH EXAMPLES | ||
1156 | .TP | ||
1157 | \f\firejail | ||
1158 | Start a regular /bin/bash session in sandbox. | ||
1159 | .TP | ||
1160 | \f\firejail firefox | ||
1161 | Start Mozilla Firefox. | ||
1162 | .TP | ||
1163 | \f\firejail \-\-seccomp firefox | ||
1164 | Start Mozilla Firefox in a seccomp sandbox. | ||
1165 | .TP | ||
1166 | \f\firejail \-\-caps firefox | ||
1167 | Start Mozilla Firefox in a Linux capabilities sandbox. | ||
1168 | .TP | ||
1169 | \f\firejail \-\-debug firefox | ||
1170 | Debug Firefox sandbox. | ||
1171 | .TP | ||
1172 | \f\firejail \-\-private | ||
1173 | Start a /bin/bash session with a new tmpfs home directory. | ||
1174 | .TP | ||
1175 | \f\firejail \-\-net=br0 ip=10.10.20.10 | ||
1176 | Start a /bin/bash session in a new network namespace. The session is | ||
1177 | connected to the main network using br0 bridge device. An IP address | ||
1178 | of 10.10.20.10 is assigned to the sandbox. | ||
1179 | .TP | ||
1180 | \f\firejail \-\-net=br0 \-\-net=br1 \-\-net=br2 | ||
1181 | Start a /bin/bash session in a new network namespace and connect it | ||
1182 | to br0, br1, and br2 host bridge devices. | ||
1183 | .TP | ||
1184 | \f\firejail \-\-list | ||
1185 | List all sandboxed processes. | ||
1186 | .SH LICENSE | ||
1187 | This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. | ||
1188 | .PP | ||
1189 | Homepage: http://firejail.sourceforge.net | ||
1190 | .SH SEE ALSO | ||
1191 | \&\flfiremon\fR\|(1), | ||
1192 | \&\flfirejail-profile\fR\|(5), | ||
1193 | \&\flfirejail-login\fR\|(5) | ||
1194 | |||
1195 | |||
1196 | |||
diff --git a/src/man/firemon.txt b/src/man/firemon.txt new file mode 100644 index 000000000..b6010f46e --- /dev/null +++ b/src/man/firemon.txt | |||
@@ -0,0 +1,107 @@ | |||
1 | .TH man 1 "MONTH YEAR" "VERSION" "firemon man page" | ||
2 | .SH NAME | ||
3 | Firemon \- Monitoring program for processes started in a Firejail sandbox. | ||
4 | .SH SYNOPSIS | ||
5 | firemon [OPTIONS] [PID] | ||
6 | .SH DESCRIPTION | ||
7 | Firemon monitors programs started in a Firejail sandbox. | ||
8 | Without a PID specified, all processes started by Firejail are monitored. Descendants of | ||
9 | these processes are also being monitored. | ||
10 | .SH OPTIONS | ||
11 | .TP | ||
12 | \fB\-\-arp | ||
13 | Print ARP table for each sandbox. | ||
14 | .TP | ||
15 | \fB\-\-caps | ||
16 | Print capabilities configuration for each sandbox. | ||
17 | .TP | ||
18 | \fB\-\-cgroup | ||
19 | Print control group information for each sandbox. | ||
20 | .TP | ||
21 | \fB\-\-cpu | ||
22 | Print CPU affinity for each sandbox. | ||
23 | .TP | ||
24 | \fB\-?\fR, \fB\-\-help\fR | ||
25 | Print options end exit. | ||
26 | .TP | ||
27 | \fB\-\-interface | ||
28 | Print network interface information for each sandbox. | ||
29 | .TP | ||
30 | \fB\-\-list | ||
31 | List all sandboxes. | ||
32 | .TP | ||
33 | \fB\-\-name=name | ||
34 | Print information only about named sandbox. | ||
35 | .TP | ||
36 | \fB\-\-netstats | ||
37 | Monitor network statistics for sandboxes creating a new network namespace. | ||
38 | .TP | ||
39 | \fB\-\-route | ||
40 | Print route table for each sandbox. | ||
41 | .TP | ||
42 | \fB\-\-seccomp | ||
43 | Print seccomp configuration for each sandbox. | ||
44 | .TP | ||
45 | \fB\-\-top | ||
46 | Monitor the most CPU-intensive sandboxes. | ||
47 | .TP | ||
48 | \fB\-\-tree | ||
49 | Print a tree of all sandboxed processes. | ||
50 | .TP | ||
51 | \fB\-\-version | ||
52 | Print program version and exit. | ||
53 | |||
54 | .PP | ||
55 | Option \-\-list prints a list of all sandboxes. The format | ||
56 | for each entry is as follows: | ||
57 | |||
58 | PID:USER:Command | ||
59 | |||
60 | Option \-\-tree prints the tree of processes running in the sandbox. The format | ||
61 | for each process entry is as follows: | ||
62 | |||
63 | PID:USER:Command | ||
64 | |||
65 | Option \-\-top is similar to the UNIX top command, however it applies only to | ||
66 | sandboxes. Listed below are the available fields (columns) in alphabetical | ||
67 | order: | ||
68 | |||
69 | .TP | ||
70 | Command | ||
71 | Command used to start the sandbox. | ||
72 | .TP | ||
73 | CPU% | ||
74 | CPU usage, the sandbox share of the elapsed CPU time since the | ||
75 | last screen update | ||
76 | .TP | ||
77 | PID | ||
78 | Unique process ID for the task controlling the sandbox. | ||
79 | .TP | ||
80 | Prcs | ||
81 | Number of processes running in sandbox, including the controlling process. | ||
82 | .TP | ||
83 | RES | ||
84 | Resident Memory Size (KiB), sandbox non-swapped physical memory. | ||
85 | It is a sum of the RES values for all processes running in the sandbox. | ||
86 | .TP | ||
87 | SHR | ||
88 | Shared Memory Size (KiB), it reflects memory shared with other | ||
89 | processes. It is a sum of the SHR values for all processes running | ||
90 | in the sandbox, including the controlling process. | ||
91 | .TP | ||
92 | Uptime | ||
93 | Sandbox running time in hours:minutes:seconds format. | ||
94 | .TP | ||
95 | User | ||
96 | The owner of the sandbox. | ||
97 | |||
98 | .SH LICENSE | ||
99 | This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. | ||
100 | .PP | ||
101 | Homepage: http://firejail.sourceforge.net | ||
102 | .SH SEE ALSO | ||
103 | \&\flfirejail\fR\|(1), | ||
104 | \&\flfirejail-profile\fR\|(5), | ||
105 | \&\flfirejail-login\fR\|(5) | ||
106 | |||
107 | |||
diff --git a/src/tools/check-caps.sh b/src/tools/check-caps.sh new file mode 100755 index 000000000..13525677b --- /dev/null +++ b/src/tools/check-caps.sh | |||
@@ -0,0 +1,46 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | if [ $# -eq 0 ] | ||
4 | then | ||
5 | echo "Usage: check-caps.sh program-and-arguments" | ||
6 | echo | ||
7 | fi | ||
8 | |||
9 | set -x | ||
10 | |||
11 | firejail --caps.drop=chown "$1" | ||
12 | firejail --caps.drop=dac_override "$1" | ||
13 | firejail --caps.drop=dac_read_search "$1" | ||
14 | firejail --caps.drop=fowner "$1" | ||
15 | firejail --caps.drop=fsetid "$1" | ||
16 | firejail --caps.drop=kill "$1" | ||
17 | firejail --caps.drop=setgid "$1" | ||
18 | firejail --caps.drop=setuid "$1" | ||
19 | firejail --caps.drop=setpcap "$1" | ||
20 | firejail --caps.drop=linux_immutable "$1" | ||
21 | firejail --caps.drop=net_bind_service "$1" | ||
22 | firejail --caps.drop=net_broadcast "$1" | ||
23 | firejail --caps.drop=net_admin "$1" | ||
24 | firejail --caps.drop=net_raw "$1" | ||
25 | firejail --caps.drop=ipc_lock "$1" | ||
26 | firejail --caps.drop=ipc_owner "$1" | ||
27 | firejail --caps.drop=sys_module "$1" | ||
28 | firejail --caps.drop=sys_rawio "$1" | ||
29 | firejail --caps.drop=sys_chroot "$1" | ||
30 | firejail --caps.drop=sys_ptrace "$1" | ||
31 | firejail --caps.drop=sys_pacct "$1" | ||
32 | firejail --caps.drop=sys_admin "$1" | ||
33 | firejail --caps.drop=sys_boot "$1" | ||
34 | firejail --caps.drop=sys_nice "$1" | ||
35 | firejail --caps.drop=sys_resource "$1" | ||
36 | firejail --caps.drop=sys_time "$1" | ||
37 | firejail --caps.drop=sys_tty_config "$1" | ||
38 | firejail --caps.drop=mknod "$1" | ||
39 | firejail --caps.drop=lease "$1" | ||
40 | firejail --caps.drop=audit_write "$1" | ||
41 | firejail --caps.drop=audit_control "$1" | ||
42 | firejail --caps.drop=setfcap "$1" | ||
43 | firejail --caps.drop=mac_override "$1" | ||
44 | firejail --caps.drop=mac_admin "$1" | ||
45 | firejail --caps.drop=syslog "$1" | ||
46 | firejail --caps.drop=wake_alarm "$1" | ||
diff --git a/src/tools/extract_caps.c b/src/tools/extract_caps.c new file mode 100644 index 000000000..94a062ccb --- /dev/null +++ b/src/tools/extract_caps.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include <stdio.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <string.h> | ||
23 | #include <assert.h> | ||
24 | |||
25 | #define BUFMAX 4096 | ||
26 | |||
27 | int main(int argc, char **argv) { | ||
28 | if (argc != 2) { | ||
29 | printf("usage: %s /usr/include/linux/capability.h\n", argv[0]); | ||
30 | return 1; | ||
31 | } | ||
32 | |||
33 | //open file | ||
34 | FILE *fp = fopen(argv[1], "r"); | ||
35 | if (!fp) { | ||
36 | fprintf(stderr, "Error: cannot open file\n"); | ||
37 | return 1; | ||
38 | } | ||
39 | |||
40 | // read file | ||
41 | char buf[BUFMAX]; | ||
42 | while (fgets(buf, BUFMAX, fp)) { | ||
43 | // cleanup | ||
44 | char *start = buf; | ||
45 | while (*start == ' ' || *start == '\t') | ||
46 | start++; | ||
47 | char *end = strchr(start, '\n'); | ||
48 | if (end) | ||
49 | *end = '\0'; | ||
50 | |||
51 | // parsing | ||
52 | if (strncmp(start, "#define CAP_", 12) == 0) { | ||
53 | if (strstr(start, "CAP_LAST_CAP")) | ||
54 | break; | ||
55 | |||
56 | char *ptr1 = start + 8; | ||
57 | char *ptr2 = ptr1; | ||
58 | while (*ptr2 == ' ' || *ptr2 == '\t') | ||
59 | ptr2++; | ||
60 | while (*ptr2 != ' ' && *ptr2 != '\t') | ||
61 | ptr2++; | ||
62 | *ptr2 = '\0'; | ||
63 | |||
64 | ptr2 = strdup(ptr1); | ||
65 | assert(ptr2); | ||
66 | ptr2 += 4; | ||
67 | char *ptr3 = ptr2; | ||
68 | while (*ptr3 != '\0') { | ||
69 | *ptr3 = tolower(*ptr3); | ||
70 | ptr3++; | ||
71 | } | ||
72 | |||
73 | |||
74 | printf("#ifdef %s\n", ptr1); | ||
75 | printf("\t{\"%s\", %s },\n", ptr2, ptr1); | ||
76 | printf("#endif\n"); | ||
77 | |||
78 | } | ||
79 | |||
80 | } | ||
81 | fclose(fp); | ||
82 | return 0; | ||
83 | } | ||
diff --git a/src/tools/extract_syscalls.c b/src/tools/extract_syscalls.c new file mode 100644 index 000000000..0e064a49e --- /dev/null +++ b/src/tools/extract_syscalls.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include <stdio.h> | ||
21 | #include <stdlib.h>6 | ||
22 | #include <string.h> | ||
23 | |||
24 | #define BUFMAX 4096 | ||
25 | |||
26 | int main(int argc, char **argv) { | ||
27 | if (argc != 2) { | ||
28 | printf("usage: %s /media/ubuntu/usr/include/x86_64-linux-gnu/bits/syscall.h\n", argv[0]); | ||
29 | return 1; | ||
30 | } | ||
31 | |||
32 | //open file | ||
33 | FILE *fp = fopen(argv[1], "r"); | ||
34 | if (!fp) { | ||
35 | fprintf(stderr, "Error: cannot open file\n"); | ||
36 | return 1; | ||
37 | } | ||
38 | |||
39 | // read file | ||
40 | char buf[BUFMAX]; | ||
41 | while (fgets(buf, BUFMAX, fp)) { | ||
42 | // cleanup | ||
43 | char *start = buf; | ||
44 | while (*start == ' ' || *start == '\t') | ||
45 | start++; | ||
46 | char *end = strchr(start, '\n'); | ||
47 | if (end) | ||
48 | *end = '\0'; | ||
49 | |||
50 | // parsing | ||
51 | if (strncmp(start, "#endif", 6) == 0) | ||
52 | printf("%s\n", start); | ||
53 | if (strncmp(start, "#endif", 6) == 0) | ||
54 | printf("%s\n", start); | ||
55 | else if (strncmp(start, "#if", 3) == 0) | ||
56 | printf("%s\n", start); | ||
57 | else if (strncmp(start, "#define", 7) == 0) { | ||
58 | // extract data | ||
59 | char *ptr1 = strstr(start, "SYS_"); | ||
60 | char *ptr2 = strstr(start, "__NR_"); | ||
61 | if (!ptr1 || !ptr2) { | ||
62 | fprintf(stderr, "Error: cannot parse \"%s\"\n", start); | ||
63 | fclose(fp); | ||
64 | return 1; | ||
65 | } | ||
66 | *(ptr2 - 1) = '\0'; | ||
67 | |||
68 | char *ptr3 = ptr1; | ||
69 | while (*ptr3 != ' ' && *ptr3 != '\t' && *ptr3 != '\0') | ||
70 | ptr3++; | ||
71 | *ptr3 = '\0'; | ||
72 | ptr3 = ptr2; | ||
73 | while (*ptr3 != ' ' && *ptr3 != '\t' && *ptr3 != '\0') | ||
74 | ptr3++; | ||
75 | *ptr3 = '\0'; | ||
76 | |||
77 | ptr3 = ptr1; | ||
78 | while (*ptr3 != '_') | ||
79 | ptr3++; | ||
80 | ptr3++; | ||
81 | |||
82 | printf("#ifdef %s\n", ptr1); | ||
83 | printf("#ifdef %s\n", ptr2); | ||
84 | printf("\t{\"%s\", %s},\n", ptr3, ptr2); | ||
85 | printf("#endif\n"); | ||
86 | printf("#endif\n"); | ||
87 | } | ||
88 | } | ||
89 | fclose(fp); | ||
90 | return 0; | ||
91 | } | ||
diff --git a/src/tools/mkcoverit.sh b/src/tools/mkcoverit.sh new file mode 100755 index 000000000..4af84a7a1 --- /dev/null +++ b/src/tools/mkcoverit.sh | |||
@@ -0,0 +1,45 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | # unpack firejail archive | ||
4 | ARCFIREJAIL=`ls *.tar.bz2| grep firejail` | ||
5 | if [ "$?" -eq 0 ]; | ||
6 | then | ||
7 | echo "preparing $ARCFIREJAIL" | ||
8 | DIRFIREJAIL=`basename $ARCFIREJAIL .tar.bz2` | ||
9 | rm -fr $DIRFIREJAIL | ||
10 | tar -xjvf $ARCFIREJAIL | ||
11 | cd $DIRFIREJAIL | ||
12 | ./configure --prefix=/usr | ||
13 | cd .. | ||
14 | else | ||
15 | echo "Error: firejail source archive missing" | ||
16 | exit 1 | ||
17 | fi | ||
18 | |||
19 | |||
20 | # unpack firetools archive | ||
21 | ARCFIRETOOLS=`ls *.tar.bz2 | grep firetools` | ||
22 | if [ "$?" -eq 0 ]; | ||
23 | then | ||
24 | echo "preparing $ARCFIRETOOLS" | ||
25 | DIRFIRETOOLS=`basename $ARCFIRETOOLS .tar.bz2` | ||
26 | rm -fr $DIRFIRETOOLS | ||
27 | tar -xjvf $ARCFIRETOOLS | ||
28 | cd $DIRFIRETOOLS | ||
29 | pwd | ||
30 | ./configure --prefix=/usr | ||
31 | cd .. | ||
32 | |||
33 | else | ||
34 | echo "Error: firetools source archive missing" | ||
35 | exit 1 | ||
36 | fi | ||
37 | |||
38 | # move firetools in firejail source tree | ||
39 | mkdir -p $DIRFIREJAIL/extras | ||
40 | mv $DIRFIRETOOLS $DIRFIREJAIL/extras/firetools | ||
41 | |||
42 | # build | ||
43 | cd $DIRFIREJAIL | ||
44 | cov-build --dir cov-int make -j 4 extras | ||
45 | tar czvf myproject.tgz cov-int | ||
diff --git a/src/tools/rvtest.c b/src/tools/rvtest.c new file mode 100644 index 000000000..95050e671 --- /dev/null +++ b/src/tools/rvtest.c | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | // run it as "rvtest 2>/dev/null | grep TESTING" | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <unistd.h> | ||
26 | #include <string.h> | ||
27 | #include <sys/types.h> | ||
28 | #include <signal.h> | ||
29 | |||
30 | #define MAXBUF 1024 // line buffer | ||
31 | #define TIMEOUT 30 // timeout time in seconds | ||
32 | |||
33 | static pid_t pid; | ||
34 | static void catch_alarm(int sig) { | ||
35 | kill(pid, SIGTERM); | ||
36 | sleep(1); | ||
37 | kill(pid, SIGKILL); | ||
38 | printf("TESTING ERROR: SIGALARM triggered\n"); | ||
39 | exit(1); | ||
40 | } | ||
41 | |||
42 | static void usage(void) { | ||
43 | printf("Usage: rvtest testfile\n"); | ||
44 | printf("\n"); | ||
45 | printf("Testfile format:\n"); | ||
46 | printf("\tretval command\n"); | ||
47 | printf("\n"); | ||
48 | printf("Testfile example:\n"); | ||
49 | printf("\n"); | ||
50 | printf("0 firejail --net=none exit\n"); | ||
51 | printf("1 firejail --private=/etc sleep 1\n"); | ||
52 | printf("1 firejail --blablabla\n"); | ||
53 | } | ||
54 | |||
55 | int main(int argc, char **argv) { | ||
56 | if (argc != 2) { | ||
57 | fprintf(stderr, "Error: test file missing\n"); | ||
58 | usage(); | ||
59 | return 1; | ||
60 | } | ||
61 | |||
62 | signal (SIGALRM, catch_alarm); | ||
63 | |||
64 | // open test file | ||
65 | char *fname = argv[1]; | ||
66 | FILE *fp = fopen(fname, "r"); | ||
67 | |||
68 | // read test file | ||
69 | char buf[MAXBUF]; | ||
70 | int line = 0; | ||
71 | while (fgets(buf, MAXBUF, fp)) { | ||
72 | line++; | ||
73 | // skip blanks | ||
74 | char *start = buf; | ||
75 | while (*start == ' ' || *start == '\t') | ||
76 | start++; | ||
77 | // remove '\n' | ||
78 | char *ptr = strchr(start, '\n'); | ||
79 | if (ptr) | ||
80 | *ptr ='\0'; | ||
81 | if (*start == '\0') | ||
82 | continue; | ||
83 | |||
84 | // skip comments | ||
85 | if (*start == '#') | ||
86 | continue; | ||
87 | ptr = strchr(start, '#'); | ||
88 | if (ptr) | ||
89 | *ptr = '\0'; | ||
90 | |||
91 | // extract exit status | ||
92 | int status; | ||
93 | int rv = sscanf(start, "%d\n", &status); | ||
94 | if (rv != 1) { | ||
95 | fprintf(stderr, "Error: invalid line %d in %s\n", line, fname); | ||
96 | exit(1); | ||
97 | } | ||
98 | |||
99 | // extract command | ||
100 | char *cmd = strchr(start, ' '); | ||
101 | if (!cmd) { | ||
102 | fprintf(stderr, "Error: invalid line %d in %s\n", line, fname); | ||
103 | exit(1); | ||
104 | } | ||
105 | |||
106 | // execute command | ||
107 | printf("TESTING %s\n", cmd); | ||
108 | fflush(0); | ||
109 | pid = fork(); | ||
110 | if (pid == -1) { | ||
111 | perror("fork"); | ||
112 | exit(1); | ||
113 | } | ||
114 | |||
115 | // child | ||
116 | if (pid == 0) { | ||
117 | char *earg[50]; | ||
118 | earg[0] = "/bin/bash"; | ||
119 | earg[1] = "-c"; | ||
120 | earg[2] = cmd; | ||
121 | earg[3] = NULL; | ||
122 | execvp(earg[0], earg); | ||
123 | } | ||
124 | // parent | ||
125 | else { | ||
126 | int exit_status; | ||
127 | |||
128 | alarm(TIMEOUT); | ||
129 | pid = waitpid(pid, &exit_status, 0); | ||
130 | if (pid == -1) { | ||
131 | perror("waitpid"); | ||
132 | exit(1); | ||
133 | } | ||
134 | |||
135 | if (WEXITSTATUS(exit_status) != status) | ||
136 | printf("ERROR TESTING: %s\n", cmd); | ||
137 | } | ||
138 | |||
139 | fflush(0); | ||
140 | } | ||
141 | fclose(fp); | ||
142 | |||
143 | return 0; | ||
144 | } \ No newline at end of file | ||
diff --git a/src/tools/ttytest.c b/src/tools/ttytest.c new file mode 100644 index 000000000..a449bf9ba --- /dev/null +++ b/src/tools/ttytest.c | |||
@@ -0,0 +1,36 @@ | |||
1 | #define _XOPEN_SOURCE 600 | ||
2 | #include <stdlib.h> | ||
3 | #include <stdio.h> | ||
4 | #include <fcntl.h> | ||
5 | #include <errno.h> | ||
6 | |||
7 | int main(void) { | ||
8 | int fdm; | ||
9 | int rc; | ||
10 | |||
11 | // initial | ||
12 | system("ls -l /dev/pts"); | ||
13 | |||
14 | fdm = posix_openpt(O_RDWR); | ||
15 | if (fdm < 0) { | ||
16 | perror("posix_openpt"); | ||
17 | return 1; | ||
18 | } | ||
19 | |||
20 | rc = grantpt(fdm); | ||
21 | if (rc != 0) { | ||
22 | perror("grantpt"); | ||
23 | return 1; | ||
24 | } | ||
25 | |||
26 | rc = unlockpt(fdm); | ||
27 | if (rc != 0) { | ||
28 | perror("unlockpt"); | ||
29 | return 1; | ||
30 | } | ||
31 | |||
32 | // final | ||
33 | system("ls -l /dev/pts"); | ||
34 | |||
35 | return 0; | ||
36 | } | ||
diff --git a/test/4bridges_arp.exp b/test/4bridges_arp.exp new file mode 100755 index 000000000..3004082e6 --- /dev/null +++ b/test/4bridges_arp.exp | |||
@@ -0,0 +1,175 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check eth0 | ||
8 | send -- "firejail --net=br0 --net=br1 --net=br2 --net=br3\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0.0\n";exit} | ||
11 | "eth0" | ||
12 | } | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
15 | "10.10.20" | ||
16 | } | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 0.2\n";exit} | ||
19 | "255.255.255.248" | ||
20 | } | ||
21 | expect { | ||
22 | timeout {puts "TESTING ERROR 0.3\n";exit} | ||
23 | "UP" | ||
24 | } | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 0.4\n";exit} | ||
27 | "Child process initialized" | ||
28 | } | ||
29 | sleep 2 | ||
30 | send -- "exit\r" | ||
31 | sleep 2 | ||
32 | |||
33 | # check eth1 | ||
34 | send -- "firejail --net=br0 --net=br1 --net=br2 --net=br3\r" | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 1.0\n";exit} | ||
37 | "eth1" | ||
38 | } | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
41 | "10.10.30" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 1.2\n";exit} | ||
45 | "255.255.255.0" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 1.3\n";exit} | ||
49 | "UP" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 1.4\n";exit} | ||
53 | "Child process initialized" | ||
54 | } | ||
55 | sleep 2 | ||
56 | send -- "exit\r" | ||
57 | sleep 2 | ||
58 | |||
59 | |||
60 | # check eth2 | ||
61 | send -- "firejail --net=br0 --net=br1 --net=br2 --net=br3\r" | ||
62 | expect { | ||
63 | timeout {puts "TESTING ERROR 2.0\n";exit} | ||
64 | "eth2" | ||
65 | } | ||
66 | expect { | ||
67 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
68 | "10.10.40" | ||
69 | } | ||
70 | expect { | ||
71 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
72 | "255.255.255.0" | ||
73 | } | ||
74 | expect { | ||
75 | timeout {puts "TESTING ERROR 2.3\n";exit} | ||
76 | "UP" | ||
77 | } | ||
78 | expect { | ||
79 | timeout {puts "TESTING ERROR 2.4\n";exit} | ||
80 | "Child process initialized" | ||
81 | } | ||
82 | sleep 2 | ||
83 | send -- "exit\r" | ||
84 | sleep 2 | ||
85 | |||
86 | |||
87 | |||
88 | # check eth3 | ||
89 | send -- "firejail --net=br0 --net=br1 --net=br2 --net=br3\r" | ||
90 | expect { | ||
91 | timeout {puts "TESTING ERROR 3.0\n";exit} | ||
92 | "eth3" | ||
93 | } | ||
94 | expect { | ||
95 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
96 | "10.10.50" | ||
97 | } | ||
98 | expect { | ||
99 | timeout {puts "TESTING ERROR 3.2\n";exit} | ||
100 | "255.255.255.0" | ||
101 | } | ||
102 | expect { | ||
103 | timeout {puts "TESTING ERROR 3.3\n";exit} | ||
104 | "UP" | ||
105 | } | ||
106 | expect { | ||
107 | timeout {puts "TESTING ERROR 4\n";exit} | ||
108 | "Child process initialized" | ||
109 | } | ||
110 | sleep 2 | ||
111 | send -- "exit\r" | ||
112 | sleep 2 | ||
113 | |||
114 | |||
115 | |||
116 | |||
117 | # check loopback | ||
118 | send -- "firejail --net=br0 --net=br1 --net=br2 --net=br3\r" | ||
119 | expect { | ||
120 | timeout {puts "TESTING ERROR 5\n";exit} | ||
121 | "lo" | ||
122 | } | ||
123 | expect { | ||
124 | timeout {puts "TESTING ERROR 6\n";exit} | ||
125 | "127.0.0.1" | ||
126 | } | ||
127 | expect { | ||
128 | timeout {puts "TESTING ERROR 7\n";exit} | ||
129 | "255.0.0.0" | ||
130 | } | ||
131 | expect { | ||
132 | timeout {puts "TESTING ERROR 8\n";exit} | ||
133 | "UP" | ||
134 | } | ||
135 | expect { | ||
136 | timeout {puts "TESTING ERROR 9\n";exit} | ||
137 | "Child process initialized" | ||
138 | } | ||
139 | |||
140 | # check default gateway | ||
141 | send -- "bash\r" | ||
142 | sleep 1 | ||
143 | send -- "netstat -rn;pwd\r" | ||
144 | expect { | ||
145 | timeout {puts "TESTING ERROR 10.1\n";exit} | ||
146 | "0.0.0.0" | ||
147 | } | ||
148 | expect { | ||
149 | timeout {puts "TESTING ERROR 10.2\n";exit} | ||
150 | "10.10.20.1" | ||
151 | } | ||
152 | expect { | ||
153 | timeout {puts "TESTING ERROR 10.3\n";exit} | ||
154 | "eth0" | ||
155 | } | ||
156 | expect { | ||
157 | timeout {puts "TESTING ERROR 10.4\n";exit} | ||
158 | "10.10.20.0" | ||
159 | } | ||
160 | expect { | ||
161 | timeout {puts "TESTING ERROR 10.5\n";exit} | ||
162 | "0.0.0.0" | ||
163 | } | ||
164 | expect { | ||
165 | timeout {puts "TESTING ERROR 10.6\n";exit} | ||
166 | "eth0" | ||
167 | } | ||
168 | expect { | ||
169 | timeout {puts "TESTING ERROR 10\n";exit} | ||
170 | "home" | ||
171 | } | ||
172 | sleep 1 | ||
173 | |||
174 | puts "\n" | ||
175 | |||
diff --git a/test/4bridges_ip.exp b/test/4bridges_ip.exp new file mode 100755 index 000000000..9e37b4ff4 --- /dev/null +++ b/test/4bridges_ip.exp | |||
@@ -0,0 +1,175 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check eth0 | ||
8 | send -- "firejail --net=br0 --net=br1 --ip=10.10.30.50 --net=br2 --ip=10.10.40.100 --net=br3\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0.0\n";exit} | ||
11 | "eth0" | ||
12 | } | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
15 | "10.10.20" | ||
16 | } | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 0.2\n";exit} | ||
19 | "255.255.255.248" | ||
20 | } | ||
21 | expect { | ||
22 | timeout {puts "TESTING ERROR 0.3\n";exit} | ||
23 | "UP" | ||
24 | } | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 0.4\n";exit} | ||
27 | "Child process initialized" | ||
28 | } | ||
29 | sleep 2 | ||
30 | send -- "exit\r" | ||
31 | sleep 2 | ||
32 | |||
33 | # check eth1 | ||
34 | send -- "firejail --net=br0 --net=br1 --ip=10.10.30.50 --net=br2 --ip=10.10.40.100 --net=br3\r" | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 1.0\n";exit} | ||
37 | "eth1" | ||
38 | } | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
41 | "10.10.30.50" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 1.2\n";exit} | ||
45 | "255.255.255.0" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 1.3\n";exit} | ||
49 | "UP" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 1.4\n";exit} | ||
53 | "Child process initialized" | ||
54 | } | ||
55 | sleep 2 | ||
56 | send -- "exit\r" | ||
57 | sleep 2 | ||
58 | |||
59 | |||
60 | # check eth2 | ||
61 | send -- "firejail --net=br0 --net=br1 --ip=10.10.30.50 --net=br2 --ip=10.10.40.100 --net=br3\r" | ||
62 | expect { | ||
63 | timeout {puts "TESTING ERROR 2.0\n";exit} | ||
64 | "eth2" | ||
65 | } | ||
66 | expect { | ||
67 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
68 | "10.10.40.100" | ||
69 | } | ||
70 | expect { | ||
71 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
72 | "255.255.255.0" | ||
73 | } | ||
74 | expect { | ||
75 | timeout {puts "TESTING ERROR 2.3\n";exit} | ||
76 | "UP" | ||
77 | } | ||
78 | expect { | ||
79 | timeout {puts "TESTING ERROR 2.4\n";exit} | ||
80 | "Child process initialized" | ||
81 | } | ||
82 | sleep 2 | ||
83 | send -- "exit\r" | ||
84 | sleep 2 | ||
85 | |||
86 | |||
87 | |||
88 | # check eth3 | ||
89 | send -- "firejail --net=br0 --net=br1 --ip=10.10.30.50 --net=br2 --ip=10.10.40.100 --net=br3\r" | ||
90 | expect { | ||
91 | timeout {puts "TESTING ERROR 3.0\n";exit} | ||
92 | "eth3" | ||
93 | } | ||
94 | expect { | ||
95 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
96 | "10.10.50" | ||
97 | } | ||
98 | expect { | ||
99 | timeout {puts "TESTING ERROR 3.2\n";exit} | ||
100 | "255.255.255.0" | ||
101 | } | ||
102 | expect { | ||
103 | timeout {puts "TESTING ERROR 3.3\n";exit} | ||
104 | "UP" | ||
105 | } | ||
106 | expect { | ||
107 | timeout {puts "TESTING ERROR 4\n";exit} | ||
108 | "Child process initialized" | ||
109 | } | ||
110 | sleep 2 | ||
111 | send -- "exit\r" | ||
112 | sleep 2 | ||
113 | |||
114 | |||
115 | |||
116 | |||
117 | # check loopback | ||
118 | send -- "firejail --net=br0 --net=br1 --ip=10.10.30.50 --net=br2 --ip=10.10.40.100 --net=br3\r" | ||
119 | expect { | ||
120 | timeout {puts "TESTING ERROR 5\n";exit} | ||
121 | "lo" | ||
122 | } | ||
123 | expect { | ||
124 | timeout {puts "TESTING ERROR 6\n";exit} | ||
125 | "127.0.0.1" | ||
126 | } | ||
127 | expect { | ||
128 | timeout {puts "TESTING ERROR 7\n";exit} | ||
129 | "255.0.0.0" | ||
130 | } | ||
131 | expect { | ||
132 | timeout {puts "TESTING ERROR 8\n";exit} | ||
133 | "UP" | ||
134 | } | ||
135 | expect { | ||
136 | timeout {puts "TESTING ERROR 9\n";exit} | ||
137 | "Child process initialized" | ||
138 | } | ||
139 | |||
140 | # check default gateway | ||
141 | send -- "bash\r" | ||
142 | sleep 1 | ||
143 | send -- "netstat -rn;pwd\r" | ||
144 | expect { | ||
145 | timeout {puts "TESTING ERROR 10.1\n";exit} | ||
146 | "0.0.0.0" | ||
147 | } | ||
148 | expect { | ||
149 | timeout {puts "TESTING ERROR 10.2\n";exit} | ||
150 | "10.10.20.1" | ||
151 | } | ||
152 | expect { | ||
153 | timeout {puts "TESTING ERROR 10.3\n";exit} | ||
154 | "eth0" | ||
155 | } | ||
156 | expect { | ||
157 | timeout {puts "TESTING ERROR 10.4\n";exit} | ||
158 | "10.10.20.0" | ||
159 | } | ||
160 | expect { | ||
161 | timeout {puts "TESTING ERROR 10.5\n";exit} | ||
162 | "0.0.0.0" | ||
163 | } | ||
164 | expect { | ||
165 | timeout {puts "TESTING ERROR 10.6\n";exit} | ||
166 | "eth0" | ||
167 | } | ||
168 | expect { | ||
169 | timeout {puts "TESTING ERROR 10\n";exit} | ||
170 | "home" | ||
171 | } | ||
172 | sleep 1 | ||
173 | |||
174 | puts "\n" | ||
175 | |||
diff --git a/test/auto/autotest.sh b/test/auto/autotest.sh new file mode 100755 index 000000000..0fb7565af --- /dev/null +++ b/test/auto/autotest.sh | |||
@@ -0,0 +1,202 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | arr[1]="TEST 1: svn and standard compilation" | ||
4 | arr[2]="TEST 2: cppcheck" | ||
5 | arr[3]="TEST 3: compile seccomp disabled, chroot disabled, bind disabled" | ||
6 | arr[4]="TEST 4: rvtest" | ||
7 | arr[5]="TEST 5: expect test as root, no malloc perturb" | ||
8 | arr[6]="TEST 6: expect test as user, no malloc perturb" | ||
9 | arr[7]="TEST 7: expect test as root, malloc perturb" | ||
10 | arr[8]="TEST 8: expect test as user, malloc perturb" | ||
11 | |||
12 | |||
13 | # remove previous reports and output file | ||
14 | cleanup() { | ||
15 | rm -f out-test | ||
16 | rm -f output* | ||
17 | rm -f report* | ||
18 | rm -fr firejail-trunk | ||
19 | } | ||
20 | |||
21 | print_title() { | ||
22 | echo | ||
23 | echo | ||
24 | echo | ||
25 | echo "**************************************************" | ||
26 | echo $1 | ||
27 | echo "**************************************************" | ||
28 | } | ||
29 | |||
30 | while [ $# -gt 0 ]; do # Until you run out of parameters . . . | ||
31 | case "$1" in | ||
32 | --clean) | ||
33 | cleanup | ||
34 | exit | ||
35 | ;; | ||
36 | --help) | ||
37 | echo "./autotest.sh [--clean|--help]" | ||
38 | exit | ||
39 | ;; | ||
40 | esac | ||
41 | shift # Check next set of parameters. | ||
42 | done | ||
43 | |||
44 | cleanup | ||
45 | # enable sudo | ||
46 | sudo ls -al | ||
47 | |||
48 | #***************************************************************** | ||
49 | # TEST 1 | ||
50 | #***************************************************************** | ||
51 | # - checkout source code | ||
52 | # - check compilation | ||
53 | # - install | ||
54 | #***************************************************************** | ||
55 | print_title "${arr[1]}" | ||
56 | svn checkout svn://svn.code.sf.net/p/firejail/code-0/trunk firejail-trunk | ||
57 | cd firejail-trunk | ||
58 | ./configure --prefix=/usr 2>&1 | tee ../output-configure | ||
59 | make -j4 2>&1 | tee ../output-make | ||
60 | sudo make install 2>&1 | tee ../output-install | ||
61 | cd src/tools | ||
62 | gcc -o rvtest rvtest.c | ||
63 | cd ../.. | ||
64 | cd test | ||
65 | sudo ./configure > /dev/null | ||
66 | cd ../.. | ||
67 | grep warning output-configure output-make output-install > ./report-test1 | ||
68 | grep error output-configure output-make output-install >> ./report-test1 | ||
69 | cat report-test1 > out-test1 | ||
70 | |||
71 | #***************************************************************** | ||
72 | # TEST 2 | ||
73 | #***************************************************************** | ||
74 | # - run cppcheck | ||
75 | #***************************************************************** | ||
76 | print_title "${arr[2]}" | ||
77 | cd firejail-trunk | ||
78 | cp /home/netblue/bin/cfg/std.cfg . | ||
79 | cppcheck --force . 2>&1 | tee ../output-cppcheck | ||
80 | cd .. | ||
81 | grep error output-cppcheck > report-test2 | ||
82 | cat report-test2 > out-test2 | ||
83 | |||
84 | #***************************************************************** | ||
85 | # TEST 3 | ||
86 | #***************************************************************** | ||
87 | # - disable seccomp configuration | ||
88 | # - check compilation | ||
89 | #***************************************************************** | ||
90 | print_title "${arr[3]}" | ||
91 | # seccomp | ||
92 | cd firejail-trunk | ||
93 | make distclean | ||
94 | ./configure --prefix=/usr --disable-seccomp 2>&1 | tee ../output-configure-noseccomp | ||
95 | make -j4 2>&1 | tee ../output-make-noseccomp | ||
96 | cd .. | ||
97 | grep warning output-configure-noseccomp output-make-noseccomp > ./report-test3 | ||
98 | grep error output-configure-noseccomp output-make-noseccomp >> ./report-test3 | ||
99 | # chroot | ||
100 | cd firejail-trunk | ||
101 | make distclean | ||
102 | ./configure --prefix=/usr --disable-chroot 2>&1 | tee ../output-configure-nochroot | ||
103 | make -j4 2>&1 | tee ../output-make-nochroot | ||
104 | cd .. | ||
105 | grep warning output-configure-nochroot output-make-nochroot >> ./report-test3 | ||
106 | grep error output-configure-nochroot output-make-nochroot >> ./report-test3 | ||
107 | # bind | ||
108 | cd firejail-trunk | ||
109 | make distclean | ||
110 | ./configure --prefix=/usr --disable-bind 2>&1 | tee ../output-configure-nobind | ||
111 | make -j4 2>&1 | tee ../output-make-nobind | ||
112 | cd .. | ||
113 | grep warning output-configure-nobind output-make-nobind >> ./report-test3 | ||
114 | grep error output-configure-nobind output-make-nobind >> ./report-test3 | ||
115 | # save result | ||
116 | cat report-test3 > out-test3 | ||
117 | |||
118 | #***************************************************************** | ||
119 | # TEST 4 | ||
120 | #***************************************************************** | ||
121 | # - rvtest | ||
122 | #***************************************************************** | ||
123 | print_title "${arr[4]}" | ||
124 | cd firejail-trunk | ||
125 | cd test | ||
126 | ../src/tools/rvtest test.rv 2>/dev/null | tee ../../output-test4 | grep TESTING | ||
127 | cd ../.. | ||
128 | grep TESTING output-test4 > ./report-test4 | ||
129 | grep ERROR report-test4 > out-test4 | ||
130 | |||
131 | |||
132 | #***************************************************************** | ||
133 | # TEST 5 | ||
134 | #***************************************************************** | ||
135 | # - expect test as root, no malloc perturb | ||
136 | #***************************************************************** | ||
137 | print_title "${arr[5]}" | ||
138 | cd firejail-trunk/test | ||
139 | sudo ./test-root.sh 2>&1 | tee ../../output-test5 | grep TESTING | ||
140 | cd ../.. | ||
141 | grep TESTING output-test5 > ./report-test5 | ||
142 | grep ERROR report-test5 > out-test5 | ||
143 | |||
144 | #***************************************************************** | ||
145 | # TEST 6 | ||
146 | #***************************************************************** | ||
147 | # - expect test as user, no malloc perturb | ||
148 | #***************************************************************** | ||
149 | print_title "${arr[6]}" | ||
150 | cd firejail-trunk/test | ||
151 | ./test.sh 2>&1 | tee ../../output-test6 | grep TESTING | ||
152 | cd ../.. | ||
153 | grep TESTING output-test6 > ./report-test6 | ||
154 | grep ERROR report-test6 > out-test6 | ||
155 | |||
156 | |||
157 | |||
158 | #***************************************************************** | ||
159 | # TEST 7 | ||
160 | #***************************************************************** | ||
161 | # - expect test as root, malloc perturb | ||
162 | #***************************************************************** | ||
163 | print_title "${arr[7]}" | ||
164 | export MALLOC_CHECK_=3 | ||
165 | export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) | ||
166 | cd firejail-trunk/test | ||
167 | sudo ./test-root.sh 2>&1 | tee ../../output-test7 | grep TESTING | ||
168 | cd ../.. | ||
169 | grep TESTING output-test7 > ./report-test7 | ||
170 | grep ERROR report-test7 > out-test7 | ||
171 | |||
172 | #***************************************************************** | ||
173 | # TEST 8 | ||
174 | #***************************************************************** | ||
175 | # - expect test as user, malloc perturb | ||
176 | #***************************************************************** | ||
177 | print_title "${arr[8]}" | ||
178 | cd firejail-trunk/test | ||
179 | ./test.sh 2>&1 | tee ../../output-test8| grep TESTING | ||
180 | cd ../.. | ||
181 | grep TESTING output-test8 > ./report-test8 | ||
182 | grep ERROR report-test8 > out-test8 | ||
183 | |||
184 | #***************************************************************** | ||
185 | # PRINT REPORTS | ||
186 | #***************************************************************** | ||
187 | echo | ||
188 | echo | ||
189 | echo | ||
190 | echo | ||
191 | echo "**********************************************************" | ||
192 | echo "TEST RESULTS" | ||
193 | echo "**********************************************************" | ||
194 | |||
195 | wc -l out-test* | ||
196 | rm out-test* | ||
197 | echo | ||
198 | |||
199 | |||
200 | |||
201 | |||
202 | exit | ||
diff --git a/test/caps1.profile b/test/caps1.profile new file mode 100644 index 000000000..e14655b2e --- /dev/null +++ b/test/caps1.profile | |||
@@ -0,0 +1 @@ | |||
caps.drop chown,kill \ No newline at end of file | |||
diff --git a/test/caps2.profile b/test/caps2.profile new file mode 100644 index 000000000..cb2258c52 --- /dev/null +++ b/test/caps2.profile | |||
@@ -0,0 +1 @@ | |||
caps.keep chown,kill \ No newline at end of file | |||
diff --git a/test/chk_config.exp b/test/chk_config.exp new file mode 100755 index 000000000..ada59d655 --- /dev/null +++ b/test/chk_config.exp | |||
@@ -0,0 +1,86 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check br0 | ||
8 | send -- "/sbin/ifconfig;pwd\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0 - please run ./configure\n";exit} | ||
11 | "br0" | ||
12 | } | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 0 - please run ./configure\n";exit} | ||
15 | "10.10.20.1" | ||
16 | } | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 0 - please run ./configure\n";exit} | ||
19 | "home" | ||
20 | } | ||
21 | |||
22 | # check br1 | ||
23 | send -- "/sbin/ifconfig;pwd\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 1\n";exit} | ||
26 | "br1" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 1\n";exit} | ||
30 | "10.10.30.1" | ||
31 | } | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 1\n";exit} | ||
34 | "home" | ||
35 | } | ||
36 | |||
37 | # check br2 | ||
38 | send -- "/sbin/ifconfig;pwd\r" | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 2\n";exit} | ||
41 | "br2" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 2\n";exit} | ||
45 | "10.10.40.1" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 2\n";exit} | ||
49 | "home" | ||
50 | } | ||
51 | |||
52 | # check br3 | ||
53 | send -- "/sbin/ifconfig;pwd\r" | ||
54 | expect { | ||
55 | timeout {puts "TESTING ERROR 3\n";exit} | ||
56 | "br3" | ||
57 | } | ||
58 | expect { | ||
59 | timeout {puts "TESTING ERROR 3\n";exit} | ||
60 | "10.10.50.1" | ||
61 | } | ||
62 | expect { | ||
63 | timeout {puts "TESTING ERROR 3\n";exit} | ||
64 | "home" | ||
65 | } | ||
66 | |||
67 | # start a sandbox and check MALLOC_PERTURB | ||
68 | send -- "firejail\r" | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 4\n";exit} | ||
71 | "Child process initialized" | ||
72 | } | ||
73 | sleep 1 | ||
74 | |||
75 | set timeout 2 | ||
76 | send -- "env | grep MALLOC;pwd\r" | ||
77 | expect { | ||
78 | timeout {puts "\nTESTING: MALLOC_PERTURB_ disabled\n"} | ||
79 | "MALLOC_PERTURB_" {puts "\nTESTING: MALLOC_PERTURB_ enabled\n"} | ||
80 | } | ||
81 | expect { | ||
82 | timeout {puts "TESTING ERROR 5\n";exit} | ||
83 | "home" | ||
84 | } | ||
85 | |||
86 | |||
diff --git a/test/chromium.exp b/test/chromium.exp new file mode 100755 index 000000000..020826f3d --- /dev/null +++ b/test/chromium.exp | |||
@@ -0,0 +1,72 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail chromium-browser www.gentoo.org\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Reading profile /etc/firejail/chromium-browser.profile" | ||
11 | } | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 1\n";exit} | ||
14 | "Child process initialized" | ||
15 | } | ||
16 | sleep 10 | ||
17 | |||
18 | spawn $env(SHELL) | ||
19 | send -- "firejail --list\r" | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 3\n";exit} | ||
22 | ":firejail" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
26 | "chromium-browser" | ||
27 | } | ||
28 | sleep 1 | ||
29 | |||
30 | send -- "firejail --name=blablabla\r" | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 4\n";exit} | ||
33 | "Child process initialized" | ||
34 | } | ||
35 | sleep 2 | ||
36 | |||
37 | spawn $env(SHELL) | ||
38 | send -- "firemon --seccomp\r" | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 5\n";exit} | ||
41 | ":firejail chromium-browser" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
45 | "Seccomp: 0" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
49 | "name=blablabla" | ||
50 | } | ||
51 | sleep 1 | ||
52 | send -- "firemon --caps\r" | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 6\n";exit} | ||
55 | ":firejail chromium-browser" | ||
56 | } | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
59 | "CapBnd:" | ||
60 | } | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
63 | "fffffffff" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
67 | "name=blablabla" | ||
68 | } | ||
69 | sleep 1 | ||
70 | |||
71 | puts "\n" | ||
72 | |||
diff --git a/test/configure b/test/configure new file mode 100755 index 000000000..17bb22e1b --- /dev/null +++ b/test/configure | |||
@@ -0,0 +1,42 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | brctl addbr br0 | ||
4 | ifconfig br0 10.10.20.1/29 up | ||
5 | # NAT masquerade | ||
6 | iptables -t nat -A POSTROUTING -o eth0 -s 10.10.20.0/29 -j MASQUERADE | ||
7 | # port forwarding | ||
8 | # iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to 10.10.20.2:80 | ||
9 | |||
10 | brctl addbr br1 | ||
11 | ifconfig br1 10.10.30.1/24 up | ||
12 | brctl addbr br2 | ||
13 | ifconfig br2 10.10.40.1/24 up | ||
14 | brctl addbr br3 | ||
15 | ifconfig br3 10.10.50.1/24 up | ||
16 | brctl addbr br4 | ||
17 | ifconfig br4 10.10.60.1/24 up | ||
18 | |||
19 | |||
20 | # build a very small chroot | ||
21 | ROOTDIR="/tmp/chroot" # default chroot directory | ||
22 | DEFAULT_FILES="/bin/bash /bin/sh " # basic chroot files | ||
23 | DEFAULT_FILES+="/etc/passwd /etc/nsswitch.conf /etc/group " | ||
24 | DEFAULT_FILES+=`find /lib -name libnss*` # files required by glibc | ||
25 | DEFAULT_FILES+=" /bin/ls /bin/cat /bin/ps /usr/bin/id /usr/bin/whoami /usr/bin/wc /usr/bin/wget" | ||
26 | |||
27 | rm -fr $ROOTDIR | ||
28 | mkdir -p $ROOTDIR/{root,bin,lib,lib64,usr,home,etc,dev/shm,tmp,var/run,var/tmp,var/lock,proc} | ||
29 | SORTED=`for FILE in $* $DEFAULT_FILES; do echo " $FILE "; ldd $FILE | grep -v dynamic | cut -d " " -f 3; done | sort -u` | ||
30 | for FILE in $SORTED | ||
31 | do | ||
32 | cp --parents $FILE $ROOTDIR | ||
33 | done | ||
34 | cp --parents /lib64/ld-linux-x86-64.so.2 $ROOTDIR | ||
35 | cp --parents /lib/ld-linux.so.2 $ROOTDIR | ||
36 | |||
37 | cd $ROOTDIR; find . | ||
38 | mkdir -p usr/lib/firejail/ | ||
39 | cp /usr/lib/firejail/libtrace.so usr/lib/firejail/. | ||
40 | |||
41 | |||
42 | echo "To enter the chroot directory run: firejail --chroot=$ROOTDIR" | ||
diff --git a/test/dns.exp b/test/dns.exp new file mode 100755 index 000000000..96513f278 --- /dev/null +++ b/test/dns.exp | |||
@@ -0,0 +1,69 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 30 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # no chroot | ||
8 | send -- "firejail --trace --dns=208.67.222.222 wget -q debian.org\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
11 | "Child process initialized" | ||
12 | } | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 1.2\n";exit} | ||
15 | "1:wget:connect 208.67.222.222:53" | ||
16 | } | ||
17 | sleep 1 | ||
18 | |||
19 | send -- "rm index.html\r" | ||
20 | sleep 1 | ||
21 | |||
22 | # with chroot | ||
23 | send -- "firejail --chroot=/tmp/chroot --trace --dns=208.67.222.222 wget -q debian.org\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
26 | "Child process initialized" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
30 | "1:wget:connect 208.67.222.222:53" | ||
31 | } | ||
32 | sleep 1 | ||
33 | |||
34 | send -- "rm index.html\r" | ||
35 | sleep 1 | ||
36 | |||
37 | # net eth0 | ||
38 | send -- "firejail --net=eth0 --trace --dns=208.67.222.222 wget -q debian.org\r" | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
41 | "Child process initialized" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 3.2\n";exit} | ||
45 | "1:wget:connect 208.67.222.222:53" | ||
46 | } | ||
47 | sleep 1 | ||
48 | |||
49 | send -- "rm index.html\r" | ||
50 | sleep 1 | ||
51 | |||
52 | # net eth0 and chroot | ||
53 | send -- "firejail --net=eth0 --chroot=/tmp/chroot --trace --dns=208.67.222.222 wget -q debian.org\r" | ||
54 | expect { | ||
55 | timeout {puts "TESTING ERROR 4.1\n";exit} | ||
56 | "Child process initialized" | ||
57 | } | ||
58 | expect { | ||
59 | timeout {puts "TESTING ERROR 4.2\n";exit} | ||
60 | "1:wget:connect 208.67.222.222:53" | ||
61 | } | ||
62 | sleep 1 | ||
63 | |||
64 | send -- "rm index.html\r" | ||
65 | sleep 1 | ||
66 | |||
67 | |||
68 | puts "\n" | ||
69 | |||
diff --git a/test/doubledash.exp b/test/doubledash.exp new file mode 100755 index 000000000..3c8a42471 --- /dev/null +++ b/test/doubledash.exp | |||
@@ -0,0 +1,60 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail -- ls -- -testdir\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 1\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 2\n";exit} | ||
14 | "ttt" | ||
15 | } | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 3\n";exit} | ||
18 | "parent is shutting down" | ||
19 | } | ||
20 | sleep 1 | ||
21 | |||
22 | |||
23 | send -- "firejail --name=testing -- -testdir/bash\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 4\n";exit} | ||
26 | "Child process initialized" | ||
27 | } | ||
28 | sleep 3 | ||
29 | |||
30 | spawn $env(SHELL) | ||
31 | send -- "firejail --join=testing -- -testdir/bash\r" | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 5\n";exit} | ||
34 | "the first child process inside the sandbox" | ||
35 | } | ||
36 | sleep 3 | ||
37 | |||
38 | spawn $env(SHELL) | ||
39 | send -- "firejail --list;pwd\r" | ||
40 | expect { | ||
41 | timeout {puts "TESTING ERROR 6\n";exit} | ||
42 | "name=testing" | ||
43 | } | ||
44 | expect { | ||
45 | timeout {puts "TESTING ERROR 7\n";exit} | ||
46 | "home" | ||
47 | } | ||
48 | send -- "firejail --list;pwd\r" | ||
49 | expect { | ||
50 | timeout {puts "TESTING ERROR 8 (join)\n";exit} | ||
51 | "join=testing" | ||
52 | } | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 9\n";exit} | ||
55 | "home" | ||
56 | } | ||
57 | |||
58 | sleep 1 | ||
59 | |||
60 | puts "\n" | ||
diff --git a/test/evince.exp b/test/evince.exp new file mode 100755 index 000000000..7b115144c --- /dev/null +++ b/test/evince.exp | |||
@@ -0,0 +1,72 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail evince\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Reading profile /etc/firejail/evince.profile" | ||
11 | } | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 1\n";exit} | ||
14 | "Child process initialized" | ||
15 | } | ||
16 | sleep 10 | ||
17 | |||
18 | spawn $env(SHELL) | ||
19 | send -- "firejail --list\r" | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 3\n";exit} | ||
22 | ":firejail" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
26 | "evince" | ||
27 | } | ||
28 | sleep 1 | ||
29 | |||
30 | send -- "firejail --name=blablabla\r" | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 4\n";exit} | ||
33 | "Child process initialized" | ||
34 | } | ||
35 | sleep 2 | ||
36 | |||
37 | spawn $env(SHELL) | ||
38 | send -- "firemon --seccomp\r" | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 5\n";exit} | ||
41 | ":firejail evince" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
45 | "Seccomp: 2" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
49 | "name=blablabla" | ||
50 | } | ||
51 | sleep 1 | ||
52 | send -- "firemon --caps\r" | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 6\n";exit} | ||
55 | ":firejail evince" | ||
56 | } | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
59 | "CapBnd:" | ||
60 | } | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
63 | "0000000000000000" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
67 | "name=blablabla" | ||
68 | } | ||
69 | sleep 1 | ||
70 | |||
71 | puts "\n" | ||
72 | |||
diff --git a/test/extract_command.exp b/test/extract_command.exp new file mode 100755 index 000000000..c49614b84 --- /dev/null +++ b/test/extract_command.exp | |||
@@ -0,0 +1,23 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --debug /usr/bin/firefox www.gentoo.org\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Reading profile /etc/firejail/firefox.profile" | ||
11 | } | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 1\n";exit} | ||
14 | "Starting /usr/bin/firefox" | ||
15 | } | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 1\n";exit} | ||
18 | "Child process initialized" | ||
19 | } | ||
20 | sleep 5 | ||
21 | |||
22 | puts "\n" | ||
23 | |||
diff --git a/test/firefox.exp b/test/firefox.exp new file mode 100755 index 000000000..c2e64e04f --- /dev/null +++ b/test/firefox.exp | |||
@@ -0,0 +1,74 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail firefox www.gentoo.org\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Reading profile /etc/firejail/firefox.profile" | ||
11 | } | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 1\n";exit} | ||
14 | "Child process initialized" | ||
15 | } | ||
16 | sleep 10 | ||
17 | |||
18 | spawn $env(SHELL) | ||
19 | send -- "firejail --list\r" | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 3\n";exit} | ||
22 | ":firejail" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
26 | "firefox" {puts "firefox detected\n";} | ||
27 | "iceweasel" {puts "iceweasel detected\n";} | ||
28 | } | ||
29 | sleep 1 | ||
30 | send -- "firejail --name=blablabla\r" | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 4\n";exit} | ||
33 | "Child process initialized" | ||
34 | } | ||
35 | sleep 2 | ||
36 | |||
37 | spawn $env(SHELL) | ||
38 | send -- "firemon --seccomp\r" | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 5\n";exit} | ||
41 | " firefox" {puts "firefox detected\n";} | ||
42 | " iceweasel" {puts "iceweasel detected\n";} | ||
43 | } | ||
44 | expect { | ||
45 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
46 | "Seccomp: 2" | ||
47 | } | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
50 | "name=blablabla" | ||
51 | } | ||
52 | sleep 1 | ||
53 | send -- "firemon --caps\r" | ||
54 | expect { | ||
55 | timeout {puts "TESTING ERROR 6\n";exit} | ||
56 | " firefox" {puts "firefox detected\n";} | ||
57 | " iceweasel" {puts "iceweasel detected\n";} | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
61 | "CapBnd:" | ||
62 | } | ||
63 | expect { | ||
64 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
65 | "0000000000000000" | ||
66 | } | ||
67 | expect { | ||
68 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
69 | "name=blablabla" | ||
70 | } | ||
71 | sleep 1 | ||
72 | |||
73 | puts "\n" | ||
74 | |||
diff --git a/test/firejail-in-firejail.exp b/test/firejail-in-firejail.exp new file mode 100755 index 000000000..404eb03bb --- /dev/null +++ b/test/firejail-in-firejail.exp | |||
@@ -0,0 +1,37 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 1\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "firejail\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 1 | ||
20 | |||
21 | send -- "firejail\r" | ||
22 | expect { | ||
23 | timeout {puts "TESTING ERROR 1\n";exit} | ||
24 | "Child process initialized" | ||
25 | } | ||
26 | sleep 1 | ||
27 | puts "\n" | ||
28 | |||
29 | send -- "exit\r" | ||
30 | sleep 1 | ||
31 | send -- "exit\r" | ||
32 | sleep 1 | ||
33 | send -- "exit\r" | ||
34 | sleep 1 | ||
35 | |||
36 | |||
37 | puts "\n" | ||
diff --git a/test/firemon-arp.exp b/test/firemon-arp.exp new file mode 100755 index 000000000..3fc8c2aee --- /dev/null +++ b/test/firemon-arp.exp | |||
@@ -0,0 +1,34 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "ping -c 3 192.168.1.1\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "3 packets transmitted" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "firejail\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 1 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firemon --arp\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 2\n";exit} | ||
25 | "192.168.1.1 dev eth0 lladdr" {puts "Debian testing\n";} | ||
26 | "192.168.1.1 dev enp0s3 lladdr" {puts "Centos 7 testing\n";} | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 3\n";exit} | ||
30 | "REACHABLE" | ||
31 | } | ||
32 | sleep 1 | ||
33 | |||
34 | puts "\n" | ||
diff --git a/test/firemon-caps.exp b/test/firemon-caps.exp new file mode 100755 index 000000000..547d04c02 --- /dev/null +++ b/test/firemon-caps.exp | |||
@@ -0,0 +1,135 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --name=bingo1 --caps\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | spawn $env(SHELL) | ||
15 | send -- "firejail --name=bingo2\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 0\n";exit} | ||
18 | "Child process initialized" | ||
19 | } | ||
20 | sleep 1 | ||
21 | |||
22 | spawn $env(SHELL) | ||
23 | send -- "firejail --name=bingo3 --caps.drop=all\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 0\n";exit} | ||
26 | "Child process initialized" | ||
27 | } | ||
28 | sleep 1 | ||
29 | |||
30 | spawn $env(SHELL) | ||
31 | send -- "firejail --name=bingo4 --caps.drop=chown,kill\r" | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 0\n";exit} | ||
34 | "Child process initialized" | ||
35 | } | ||
36 | sleep 1 | ||
37 | |||
38 | spawn $env(SHELL) | ||
39 | send -- "firejail --name=bingo5 --caps.keep=chown,kill\r" | ||
40 | expect { | ||
41 | timeout {puts "TESTING ERROR 0\n";exit} | ||
42 | "Child process initialized" | ||
43 | } | ||
44 | sleep 1 | ||
45 | |||
46 | spawn $env(SHELL) | ||
47 | send -- "firejail --name=bingo6 --profile=caps1.profile\r" | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 0\n";exit} | ||
50 | "Child process initialized" | ||
51 | } | ||
52 | sleep 1 | ||
53 | |||
54 | spawn $env(SHELL) | ||
55 | send -- "firejail --name=bingo7 --profile=caps2.profile\r" | ||
56 | expect { | ||
57 | timeout {puts "TESTING ERROR 0\n";exit} | ||
58 | "Child process initialized" | ||
59 | } | ||
60 | sleep 1 | ||
61 | |||
62 | |||
63 | |||
64 | |||
65 | spawn $env(SHELL) | ||
66 | send -- "firemon --caps\r" | ||
67 | expect { | ||
68 | timeout {puts "TESTING ERROR 1\n";exit} | ||
69 | "bingo1" | ||
70 | } | ||
71 | expect { | ||
72 | timeout {puts "TESTING ERROR 2\n";exit} | ||
73 | "31cffff" | ||
74 | } | ||
75 | expect { | ||
76 | timeout {puts "TESTING ERROR 3\n";exit} | ||
77 | "bingo2" | ||
78 | } | ||
79 | expect { | ||
80 | timeout {puts "TESTING ERROR 4\n";exit} | ||
81 | "fffffff" | ||
82 | } | ||
83 | expect { | ||
84 | timeout {puts "TESTING ERROR 5\n";exit} | ||
85 | "bingo3" | ||
86 | } | ||
87 | expect { | ||
88 | timeout {puts "TESTING ERROR 6\n";exit} | ||
89 | "000000000000" | ||
90 | } | ||
91 | |||
92 | expect { | ||
93 | timeout {puts "TESTING ERROR 7\n";exit} | ||
94 | "bingo4" | ||
95 | } | ||
96 | expect { | ||
97 | timeout {puts "TESTING ERROR 8\n";exit} | ||
98 | "ffffffde" | ||
99 | } | ||
100 | expect { | ||
101 | timeout {puts "TESTING ERROR 7\n";exit} | ||
102 | "bingo5" | ||
103 | } | ||
104 | expect { | ||
105 | timeout {puts "TESTING ERROR 9\n";exit} | ||
106 | "0000000000000021" | ||
107 | } | ||
108 | |||
109 | expect { | ||
110 | timeout {puts "TESTING ERROR 10\n";exit} | ||
111 | "bingo6" | ||
112 | } | ||
113 | expect { | ||
114 | timeout {puts "TESTING ERROR 11\n";exit} | ||
115 | "ffffffde" | ||
116 | } | ||
117 | expect { | ||
118 | timeout {puts "TESTING ERROR 12\n";exit} | ||
119 | "bingo7" | ||
120 | } | ||
121 | expect { | ||
122 | timeout {puts "TESTING ERROR 13\n";exit} | ||
123 | "0000000000000021" | ||
124 | } | ||
125 | |||
126 | |||
127 | |||
128 | |||
129 | |||
130 | |||
131 | |||
132 | sleep 1 | ||
133 | |||
134 | puts "\n" | ||
135 | |||
diff --git a/test/firemon-cgroup.exp b/test/firemon-cgroup.exp new file mode 100755 index 000000000..41a38b3b6 --- /dev/null +++ b/test/firemon-cgroup.exp | |||
@@ -0,0 +1,40 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --name=bingo1 --cgroup=/sys/fs/cgroup/g1/tasks\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | spawn $env(SHELL) | ||
15 | send -- "firejail --name=bingo2\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 0\n";exit} | ||
18 | "Child process initialized" | ||
19 | } | ||
20 | sleep 1 | ||
21 | |||
22 | |||
23 | spawn $env(SHELL) | ||
24 | send -- "firemon --cgroup\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 1\n";exit} | ||
27 | "bingo1" | ||
28 | } | ||
29 | expect { | ||
30 | timeout {puts "TESTING ERROR 2\n";exit} | ||
31 | ":/g1" | ||
32 | } | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 3\n";exit} | ||
35 | "bingo2" | ||
36 | } | ||
37 | sleep 1 | ||
38 | |||
39 | puts "\n" | ||
40 | |||
diff --git a/test/firemon-interface.exp b/test/firemon-interface.exp new file mode 100755 index 000000000..6a82ae41e --- /dev/null +++ b/test/firemon-interface.exp | |||
@@ -0,0 +1,34 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | spawn $env(SHELL) | ||
15 | send -- "firemon --interface\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 1\n";exit} | ||
18 | "lo UP" | ||
19 | } | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 2\n";exit} | ||
22 | "10.10.20.1/29" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3\n";exit} | ||
26 | "10.10.50.1/24" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 3\n";exit} | ||
30 | "br3" | ||
31 | } | ||
32 | sleep 1 | ||
33 | |||
34 | puts "\n" | ||
diff --git a/test/firemon-route.exp b/test/firemon-route.exp new file mode 100755 index 000000000..76ebd70f6 --- /dev/null +++ b/test/firemon-route.exp | |||
@@ -0,0 +1,32 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | spawn $env(SHELL) | ||
15 | send -- "firemon --route\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 1\n";exit} | ||
18 | "0.0.0.0/0 via 192.168.1.1, dev eth0, metric 0" {puts "Debian testing\n";} | ||
19 | "0.0.0.0/0 via 192.168.1.1, dev enp0s3, metric 1024" {puts "Centos 7 testing\n";} | ||
20 | "0.0.0.0/0 via 192.168.1.1, dev enp0s3, metric 0" {puts "OpenSUSE testing\n";} | ||
21 | } | ||
22 | expect { | ||
23 | timeout {puts "TESTING ERROR 2\n";exit} | ||
24 | "10.10.30.0/24, dev br1, scope link src 10.10.30.1" | ||
25 | } | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 3\n";exit} | ||
28 | "10.10.50.0/24, dev br3, scope link src 10.10.50.1" | ||
29 | } | ||
30 | sleep 1 | ||
31 | |||
32 | puts "\n" | ||
diff --git a/test/firemon-seccomp.exp b/test/firemon-seccomp.exp new file mode 100755 index 000000000..0cf53b690 --- /dev/null +++ b/test/firemon-seccomp.exp | |||
@@ -0,0 +1,45 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --name=bingo1 --seccomp\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | spawn $env(SHELL) | ||
15 | send -- "firejail --name=bingo2\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 0\n";exit} | ||
18 | "Child process initialized" | ||
19 | } | ||
20 | sleep 1 | ||
21 | |||
22 | |||
23 | |||
24 | |||
25 | spawn $env(SHELL) | ||
26 | send -- "firemon --seccomp\r" | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 1\n";exit} | ||
29 | "bingo1" | ||
30 | } | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 2\n";exit} | ||
33 | "Seccomp: 2" | ||
34 | } | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 3\n";exit} | ||
37 | "bingo2" | ||
38 | } | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 3\n";exit} | ||
41 | "Seccomp: 0" | ||
42 | } | ||
43 | sleep 1 | ||
44 | |||
45 | puts "\n" | ||
diff --git a/test/fs_chroot.exp b/test/fs_chroot.exp new file mode 100755 index 000000000..ba832337b --- /dev/null +++ b/test/fs_chroot.exp | |||
@@ -0,0 +1,54 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --chroot=/tmp/chroot\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "cd /home;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | "home" | ||
18 | } | ||
19 | sleep 1 | ||
20 | send -- "bash\r" | ||
21 | sleep 1 | ||
22 | send -- "ps aux; pwd\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 1\n";exit} | ||
25 | "/bin/bash" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 2\n";exit} | ||
29 | "bash" | ||
30 | } | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 3\n";exit} | ||
33 | "ps aux" | ||
34 | } | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 4\n";exit} | ||
37 | "home" | ||
38 | } | ||
39 | sleep 1 | ||
40 | |||
41 | |||
42 | send -- "ps aux |wc -l; pwd\r" | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 5\n";exit} | ||
45 | "5" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 6\n";exit} | ||
49 | "home" | ||
50 | } | ||
51 | sleep 1 | ||
52 | |||
53 | puts "\n" | ||
54 | |||
diff --git a/test/fs_dev_shm.exp b/test/fs_dev_shm.exp new file mode 100755 index 000000000..b54f24eb5 --- /dev/null +++ b/test/fs_dev_shm.exp | |||
@@ -0,0 +1,87 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # testing read-write /dev/shm | ||
8 | send -- "firejail\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Child process initialized" | ||
12 | } | ||
13 | sleep 1 | ||
14 | |||
15 | send -- "echo mytest > /dev/shm/ttt;pwd\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 1\n";exit} | ||
18 | "home" | ||
19 | } | ||
20 | |||
21 | send -- "cat /dev/shm/ttt;pwd\r" | ||
22 | expect { | ||
23 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
24 | "mytest" | ||
25 | } | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 2\n";exit} | ||
28 | "home" | ||
29 | } | ||
30 | |||
31 | send -- "rm /dev/shm/ttt;pwd\r" | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 3\n";exit} | ||
34 | "home" | ||
35 | } | ||
36 | |||
37 | send -- "cat /dev/shm/ttt;pwd\r" | ||
38 | expect { | ||
39 | timeout {puts "TESTING ERROR 4\n";exit} | ||
40 | "mytest" {puts "TESTING ERROR 4.1\n";exit} | ||
41 | "home" | ||
42 | } | ||
43 | |||
44 | sleep 1 | ||
45 | send -- "exit\r" | ||
46 | sleep 1 | ||
47 | |||
48 | # redo the test with --private | ||
49 | send -- "firejail\r" | ||
50 | expect { | ||
51 | timeout {puts "TESTING ERROR 10\n";exit} | ||
52 | "Child process initialized" | ||
53 | } | ||
54 | sleep 1 | ||
55 | |||
56 | send -- "echo mytest > /dev/shm/ttt;pwd\r" | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 11\n";exit} | ||
59 | "home" | ||
60 | } | ||
61 | |||
62 | send -- "cat /dev/shm/ttt;pwd\r" | ||
63 | expect { | ||
64 | timeout {puts "TESTING ERROR 12.1\n";exit} | ||
65 | "mytest" | ||
66 | } | ||
67 | expect { | ||
68 | timeout {puts "TESTING ERROR 12\n";exit} | ||
69 | "home" | ||
70 | } | ||
71 | |||
72 | send -- "rm /dev/shm/ttt;pwd\r" | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 13\n";exit} | ||
75 | "home" | ||
76 | } | ||
77 | |||
78 | send -- "cat /dev/shm/ttt;pwd\r" | ||
79 | expect { | ||
80 | timeout {puts "TESTING ERROR 14\n";exit} | ||
81 | "mytest" {puts "TESTING ERROR 14.1\n";exit} | ||
82 | "home" | ||
83 | } | ||
84 | |||
85 | sleep 1 | ||
86 | |||
87 | puts "\n" | ||
diff --git a/test/fs_home_sanitize.exp b/test/fs_home_sanitize.exp new file mode 100755 index 000000000..300babd1c --- /dev/null +++ b/test/fs_home_sanitize.exp | |||
@@ -0,0 +1,33 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "ls /home;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "bingo" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 2\n";exit} | ||
21 | "home" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | send -- "ls /home/bingo;pwd\r" | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 3\n";exit} | ||
28 | "cannot open directory" | ||
29 | } | ||
30 | sleep 1 | ||
31 | |||
32 | puts "\n" | ||
33 | |||
diff --git a/test/fs_overlay.exp b/test/fs_overlay.exp new file mode 100755 index 000000000..166970a5c --- /dev/null +++ b/test/fs_overlay.exp | |||
@@ -0,0 +1,64 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "rm -f /tmp/firejail-overlay-test;pwd\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "home" | ||
11 | } | ||
12 | |||
13 | send -- "ls > /tmp/firejail-overlay-test;pwd\r" | ||
14 | expect { | ||
15 | timeout {puts "TESTING ERROR 1\n";exit} | ||
16 | "home" | ||
17 | } | ||
18 | |||
19 | send -- "firejail --overlay\r" | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 2\n";exit} | ||
22 | "Child process initialized" | ||
23 | } | ||
24 | sleep 1 | ||
25 | |||
26 | send -- "echo xyzxyzxyz > /tmp/firejail-overlay-test;pwd\r" | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3\n";exit} | ||
29 | "home" | ||
30 | } | ||
31 | sleep 1 | ||
32 | |||
33 | send -- "cat /tmp/firejail-overlay-test;pwd\r" | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 4\n";exit} | ||
36 | "xyzxyzxyz" | ||
37 | } | ||
38 | expect { | ||
39 | timeout {puts "TESTING ERROR 4.1\n";exit} | ||
40 | "home" | ||
41 | } | ||
42 | sleep 1 | ||
43 | |||
44 | send -- "exit\r" | ||
45 | sleep 2 | ||
46 | |||
47 | send -- "cat /tmp/firejail-overlay-test;pwd\r" | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 5\n";exit} | ||
50 | "xyzxyzxyz" {puts "TESTING ERROR 5.1\n";exit} | ||
51 | "home" | ||
52 | } | ||
53 | |||
54 | sleep 1 | ||
55 | send -- "rm -f /tmp/firejail-overlay-test;pwd\r" | ||
56 | expect { | ||
57 | timeout {puts "TESTING ERROR 0\n";exit} | ||
58 | "home" | ||
59 | } | ||
60 | |||
61 | |||
62 | sleep 1 | ||
63 | puts "\n" | ||
64 | |||
diff --git a/test/fs_sys.exp b/test/fs_sys.exp new file mode 100755 index 000000000..69f080460 --- /dev/null +++ b/test/fs_sys.exp | |||
@@ -0,0 +1,34 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --net=br0\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 1\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "find /sys | grep --color=never eth0;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 2\n";exit} | ||
17 | "/sys/class/net/eth0" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3\n";exit} | ||
21 | "home" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | send -- "find /sys | grep --color=never br0;pwd\r" | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 4\n";exit} | ||
28 | "/sys/class/net/br0" {puts "TESTING ERROR 5\n";exit} | ||
29 | "home" | ||
30 | } | ||
31 | sleep 1 | ||
32 | |||
33 | puts "\n" | ||
34 | |||
diff --git a/test/fs_var_lock.exp b/test/fs_var_lock.exp new file mode 100755 index 000000000..dfcf571f4 --- /dev/null +++ b/test/fs_var_lock.exp | |||
@@ -0,0 +1,87 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # testing read-write /var/lock | ||
8 | send -- "firejail\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Child process initialized" | ||
12 | } | ||
13 | sleep 1 | ||
14 | |||
15 | send -- "echo mytest > /var/lock/ttt;pwd\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 1\n";exit} | ||
18 | "home" | ||
19 | } | ||
20 | |||
21 | send -- "cat /var/lock/ttt;pwd\r" | ||
22 | expect { | ||
23 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
24 | "mytest" | ||
25 | } | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 2\n";exit} | ||
28 | "home" | ||
29 | } | ||
30 | |||
31 | send -- "rm /var/lock/ttt;pwd\r" | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 3\n";exit} | ||
34 | "home" | ||
35 | } | ||
36 | |||
37 | send -- "cat /var/lock/ttt;pwd\r" | ||
38 | expect { | ||
39 | timeout {puts "TESTING ERROR 4\n";exit} | ||
40 | "mytest" {puts "TESTING ERROR 4.1\n";exit} | ||
41 | "home" | ||
42 | } | ||
43 | |||
44 | sleep 1 | ||
45 | send -- "exit\r" | ||
46 | sleep 1 | ||
47 | |||
48 | # redo the test with --private | ||
49 | send -- "firejail\r" | ||
50 | expect { | ||
51 | timeout {puts "TESTING ERROR 10\n";exit} | ||
52 | "Child process initialized" | ||
53 | } | ||
54 | sleep 1 | ||
55 | |||
56 | send -- "echo mytest > /var/lock/ttt;pwd\r" | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 11\n";exit} | ||
59 | "home" | ||
60 | } | ||
61 | |||
62 | send -- "cat /var/lock/ttt;pwd\r" | ||
63 | expect { | ||
64 | timeout {puts "TESTING ERROR 12.1\n";exit} | ||
65 | "mytest" | ||
66 | } | ||
67 | expect { | ||
68 | timeout {puts "TESTING ERROR 12\n";exit} | ||
69 | "home" | ||
70 | } | ||
71 | |||
72 | send -- "rm /var/lock/ttt;pwd\r" | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 13\n";exit} | ||
75 | "home" | ||
76 | } | ||
77 | |||
78 | send -- "cat /var/lock/ttt;pwd\r" | ||
79 | expect { | ||
80 | timeout {puts "TESTING ERROR 14\n";exit} | ||
81 | "mytest" {puts "TESTING ERROR 14.1\n";exit} | ||
82 | "home" | ||
83 | } | ||
84 | |||
85 | sleep 1 | ||
86 | |||
87 | puts "\n" | ||
diff --git a/test/fs_var_tmp.exp b/test/fs_var_tmp.exp new file mode 100755 index 000000000..95ceeb2a4 --- /dev/null +++ b/test/fs_var_tmp.exp | |||
@@ -0,0 +1,87 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # testing read-write /var/tmp | ||
8 | send -- "firejail\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Child process initialized" | ||
12 | } | ||
13 | sleep 1 | ||
14 | |||
15 | send -- "echo mytest > /var/tmp/ttt;pwd\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 1\n";exit} | ||
18 | "home" | ||
19 | } | ||
20 | |||
21 | send -- "cat /var/tmp/ttt;pwd\r" | ||
22 | expect { | ||
23 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
24 | "mytest" | ||
25 | } | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 2\n";exit} | ||
28 | "home" | ||
29 | } | ||
30 | |||
31 | send -- "rm /var/tmp/ttt;pwd\r" | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 3\n";exit} | ||
34 | "home" | ||
35 | } | ||
36 | |||
37 | send -- "cat /var/tmp/ttt;pwd\r" | ||
38 | expect { | ||
39 | timeout {puts "TESTING ERROR 4\n";exit} | ||
40 | "mytest" {puts "TESTING ERROR 4.1\n";exit} | ||
41 | "home" | ||
42 | } | ||
43 | |||
44 | sleep 1 | ||
45 | send -- "exit\r" | ||
46 | sleep 1 | ||
47 | |||
48 | # redo the test with --private | ||
49 | send -- "firejail\r" | ||
50 | expect { | ||
51 | timeout {puts "TESTING ERROR 10\n";exit} | ||
52 | "Child process initialized" | ||
53 | } | ||
54 | sleep 1 | ||
55 | |||
56 | send -- "echo mytest > /var/tmp/ttt;pwd\r" | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 11\n";exit} | ||
59 | "home" | ||
60 | } | ||
61 | |||
62 | send -- "cat /var/tmp/ttt;pwd\r" | ||
63 | expect { | ||
64 | timeout {puts "TESTING ERROR 12.1\n";exit} | ||
65 | "mytest" | ||
66 | } | ||
67 | expect { | ||
68 | timeout {puts "TESTING ERROR 12\n";exit} | ||
69 | "home" | ||
70 | } | ||
71 | |||
72 | send -- "rm /var/tmp/ttt;pwd\r" | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 13\n";exit} | ||
75 | "home" | ||
76 | } | ||
77 | |||
78 | send -- "cat /var/tmp/ttt;pwd\r" | ||
79 | expect { | ||
80 | timeout {puts "TESTING ERROR 14\n";exit} | ||
81 | "mytest" {puts "TESTING ERROR 14.1\n";exit} | ||
82 | "home" | ||
83 | } | ||
84 | |||
85 | sleep 1 | ||
86 | |||
87 | puts "\n" | ||
diff --git a/test/fscheck-bindnoroot.exp b/test/fscheck-bindnoroot.exp new file mode 100755 index 000000000..796a7d975 --- /dev/null +++ b/test/fscheck-bindnoroot.exp | |||
@@ -0,0 +1,14 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # dir | ||
8 | send -- "firejail --net=br0 --bind=fscheck-dir,/etc\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Error" | ||
12 | } | ||
13 | after 100 | ||
14 | |||
diff --git a/test/fscheck-blacklist.exp b/test/fscheck-blacklist.exp new file mode 100755 index 000000000..5b6a9623c --- /dev/null +++ b/test/fscheck-blacklist.exp | |||
@@ -0,0 +1,14 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # dir | ||
8 | send -- "firejail --net=br0 --blacklist=../test/fscheck-dir\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Error" | ||
12 | } | ||
13 | after 100 | ||
14 | |||
diff --git a/test/fscheck-chroot.exp b/test/fscheck-chroot.exp new file mode 100755 index 000000000..208ca6a43 --- /dev/null +++ b/test/fscheck-chroot.exp | |||
@@ -0,0 +1,77 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # dir | ||
8 | #send -- "firejail --net=br0 --chroot=fscheck-dir\r" | ||
9 | #expect { | ||
10 | # timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | # "Error" | ||
12 | #} | ||
13 | #after 100 | ||
14 | |||
15 | # .. | ||
16 | send -- "firejail --net=br0 --chroot=../test/fscheck-dir\r" | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
19 | "Error" | ||
20 | } | ||
21 | after 100 | ||
22 | |||
23 | # dir link | ||
24 | send -- "firejail --net=br0 --chroot=fscheck-dir-link\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 1\n";exit} | ||
27 | "Error" | ||
28 | } | ||
29 | after 100 | ||
30 | |||
31 | # .. | ||
32 | send -- "firejail --net=br0 --chroot=../test/fscheck-dir-link\r" | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
35 | "Error" | ||
36 | } | ||
37 | after 100 | ||
38 | |||
39 | # file link | ||
40 | send -- "firejail --net=br0 --chroot=fscheck-file-link\r" | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 2\n";exit} | ||
43 | "Error" | ||
44 | } | ||
45 | after 100 | ||
46 | |||
47 | # file | ||
48 | send -- "firejail --net=br0 --chroot=fscheck-file\r" | ||
49 | expect { | ||
50 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
51 | "Error" | ||
52 | } | ||
53 | after 100 | ||
54 | |||
55 | # .. | ||
56 | send -- "firejail --net=br0 --chroot=../test/fscheck-file\r" | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
59 | "Error" | ||
60 | } | ||
61 | after 100 | ||
62 | |||
63 | # no file | ||
64 | send -- "firejail --net=br0 --chroot=../test/nodir\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 3\n";exit} | ||
67 | "Error" | ||
68 | } | ||
69 | after 100 | ||
70 | |||
71 | # same owner | ||
72 | #send -- "firejail --net=br0 --chroot=/etc\r" | ||
73 | #expect { | ||
74 | # timeout {puts "TESTING ERROR 4\n";exit} | ||
75 | # "Error" | ||
76 | #} | ||
77 | #after 100 | ||
diff --git a/test/fscheck-netfilter.exp b/test/fscheck-netfilter.exp new file mode 100755 index 000000000..d2339c8b9 --- /dev/null +++ b/test/fscheck-netfilter.exp | |||
@@ -0,0 +1,69 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # dir | ||
8 | send -- "firejail --net=br0 --netfilter=fscheck-dir\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Error" | ||
12 | } | ||
13 | after 100 | ||
14 | |||
15 | # .. | ||
16 | send -- "firejail --net=br0 --netfilter=../test/fscheck-dir\r" | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
19 | "Error" | ||
20 | } | ||
21 | after 100 | ||
22 | |||
23 | # dir link | ||
24 | send -- "firejail --net=br0 --netfilter=fscheck-dir-link\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 1\n";exit} | ||
27 | "Error" | ||
28 | } | ||
29 | after 100 | ||
30 | |||
31 | # .. | ||
32 | send -- "firejail --net=br0 --netfilter=../test/fscheck-dir-link\r" | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
35 | "Error" | ||
36 | } | ||
37 | after 100 | ||
38 | |||
39 | # file link | ||
40 | send -- "firejail --net=br0 --netfilter=fscheck-file-link\r" | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 2\n";exit} | ||
43 | "Error" | ||
44 | } | ||
45 | after 100 | ||
46 | |||
47 | # .. | ||
48 | send -- "firejail --net=br0 --netfilter=../test/fscheck-file-link\r" | ||
49 | expect { | ||
50 | timeout {puts "TESTING ERROR 2\n";exit} | ||
51 | "Error" | ||
52 | } | ||
53 | after 100 | ||
54 | |||
55 | # no file | ||
56 | send -- "firejail --net=br0 --netfilter=../test/nofile\r" | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 3\n";exit} | ||
59 | "Error" | ||
60 | } | ||
61 | after 100 | ||
62 | |||
63 | # real GID/UID | ||
64 | send -- "firejail --net=br0 --netfilter=/etc/shadow\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 4\n";exit} | ||
67 | "Error" | ||
68 | } | ||
69 | after 100 | ||
diff --git a/test/fscheck-output.exp b/test/fscheck-output.exp new file mode 100755 index 000000000..0b444d6ba --- /dev/null +++ b/test/fscheck-output.exp | |||
@@ -0,0 +1,104 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # dir | ||
8 | send -- "firejail --net=br0 --output=fscheck-dir\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Error" | ||
12 | } | ||
13 | after 100 | ||
14 | |||
15 | # .. | ||
16 | send -- "firejail --net=br0 --output=../test/fscheck-dir\r" | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
19 | "Error" | ||
20 | } | ||
21 | after 100 | ||
22 | |||
23 | # dir link | ||
24 | send -- "firejail --net=br0 --output=fscheck-dir-link\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 1\n";exit} | ||
27 | "Error" | ||
28 | } | ||
29 | after 100 | ||
30 | |||
31 | # .. | ||
32 | send -- "firejail --net=br0 --output=../test/fscheck-dir-link\r" | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
35 | "Error" | ||
36 | } | ||
37 | after 100 | ||
38 | |||
39 | # file link | ||
40 | send -- "firejail --net=br0 --output=fscheck-file-link\r" | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 2\n";exit} | ||
43 | "Error" | ||
44 | } | ||
45 | after 100 | ||
46 | |||
47 | # .. | ||
48 | send -- "firejail --net=br0 --output=../test/fscheck-file-link\r" | ||
49 | expect { | ||
50 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
51 | "Error" | ||
52 | } | ||
53 | after 100 | ||
54 | |||
55 | # hard link1 | ||
56 | send -- "firejail --net=br0 --output=fscheck-file-hard1\r" | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
59 | "Error" | ||
60 | } | ||
61 | after 100 | ||
62 | |||
63 | # hard link2 | ||
64 | send -- "firejail --net=br0 --output=fscheck-file-hard2\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 2.3\n";exit} | ||
67 | "Error" | ||
68 | } | ||
69 | after 100 | ||
70 | |||
71 | # .. | ||
72 | send -- "firejail --net=br0 --output=../test/fscheck-file-hard1\r" | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 2.4\n";exit} | ||
75 | "Error" | ||
76 | } | ||
77 | after 100 | ||
78 | |||
79 | # .. | ||
80 | send -- "firejail --net=br0 --output=../test/fscheck-file-hard2\r" | ||
81 | expect { | ||
82 | timeout {puts "TESTING ERROR 2.5\n";exit} | ||
83 | "Error" | ||
84 | } | ||
85 | after 100 | ||
86 | |||
87 | |||
88 | |||
89 | |||
90 | # no file | ||
91 | send -- "firejail --net=br0 --output=../test/nofile\r" | ||
92 | expect { | ||
93 | timeout {puts "TESTING ERROR 3\n";exit} | ||
94 | "Error" | ||
95 | } | ||
96 | after 100 | ||
97 | |||
98 | # real GID/UID | ||
99 | send -- "firejail --net=br0 --output=/etc/shadow\r" | ||
100 | expect { | ||
101 | timeout {puts "TESTING ERROR 4\n";exit} | ||
102 | "Error" | ||
103 | } | ||
104 | after 100 | ||
diff --git a/test/fscheck-private.exp b/test/fscheck-private.exp new file mode 100755 index 000000000..4c791423d --- /dev/null +++ b/test/fscheck-private.exp | |||
@@ -0,0 +1,77 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # dir | ||
8 | #send -- "firejail --net=br0 --private=fscheck-dir\r" | ||
9 | #expect { | ||
10 | # timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | # "Error" | ||
12 | #} | ||
13 | #after 100 | ||
14 | |||
15 | # .. | ||
16 | send -- "firejail --net=br0 --private=../test/fscheck-dir\r" | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
19 | "Error" | ||
20 | } | ||
21 | after 100 | ||
22 | |||
23 | # dir link | ||
24 | send -- "firejail --net=br0 --private=fscheck-dir-link\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 1\n";exit} | ||
27 | "Error" | ||
28 | } | ||
29 | after 100 | ||
30 | |||
31 | # .. | ||
32 | send -- "firejail --net=br0 --private=../test/fscheck-dir-link\r" | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
35 | "Error" | ||
36 | } | ||
37 | after 100 | ||
38 | |||
39 | # file link | ||
40 | send -- "firejail --net=br0 --private=fscheck-file-link\r" | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 2\n";exit} | ||
43 | "Error" | ||
44 | } | ||
45 | after 100 | ||
46 | |||
47 | # file | ||
48 | send -- "firejail --net=br0 --private=fscheck-file\r" | ||
49 | expect { | ||
50 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
51 | "Error" | ||
52 | } | ||
53 | after 100 | ||
54 | |||
55 | # .. | ||
56 | send -- "firejail --net=br0 --private=../test/fscheck-file\r" | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
59 | "Error" | ||
60 | } | ||
61 | after 100 | ||
62 | |||
63 | # no file | ||
64 | send -- "firejail --net=br0 --private=../test/nodir\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 3\n";exit} | ||
67 | "Error" | ||
68 | } | ||
69 | after 100 | ||
70 | |||
71 | # same owner | ||
72 | send -- "firejail --net=br0 --private=/etc\r" | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 4\n";exit} | ||
75 | "Error" | ||
76 | } | ||
77 | after 100 | ||
diff --git a/test/fscheck-privatekeep.exp b/test/fscheck-privatekeep.exp new file mode 100755 index 000000000..513dcc37a --- /dev/null +++ b/test/fscheck-privatekeep.exp | |||
@@ -0,0 +1,93 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # dir | ||
8 | #send -- "firejail --net=br0 --private.keep=fscheck-dir\r" | ||
9 | #expect { | ||
10 | # timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | # "Error" | ||
12 | #} | ||
13 | #after 100 | ||
14 | |||
15 | # .. | ||
16 | send -- "firejail --net=br0 --private.keep=../test/fscheck-dir\r" | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
19 | "Error" | ||
20 | } | ||
21 | after 100 | ||
22 | |||
23 | # dir link | ||
24 | send -- "firejail --net=br0 --private.keep=fscheck-dir-link\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 1\n";exit} | ||
27 | "Error" | ||
28 | } | ||
29 | after 100 | ||
30 | |||
31 | # .. | ||
32 | send -- "firejail --net=br0 --private.keep=../test/fscheck-dir-link\r" | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
35 | "Error" | ||
36 | } | ||
37 | after 100 | ||
38 | |||
39 | # file link | ||
40 | send -- "firejail --net=br0 --private.keep=fscheck-file-link\r" | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 2\n";exit} | ||
43 | "Error" | ||
44 | } | ||
45 | after 100 | ||
46 | |||
47 | # file | ||
48 | #send -- "firejail --net=br0 --private.keep=fscheck-file\r" | ||
49 | #expect { | ||
50 | # timeout {puts "TESTING ERROR 2.1\n";exit} | ||
51 | # "Error" | ||
52 | #} | ||
53 | #after 100 | ||
54 | |||
55 | # .. | ||
56 | send -- "firejail --net=br0 --private.keep=../test/fscheck-file\r" | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
59 | "Error" | ||
60 | } | ||
61 | after 100 | ||
62 | |||
63 | # no dir | ||
64 | send -- "firejail --net=br0 --private.keep=../test/nodir\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 3\n";exit} | ||
67 | "Error" | ||
68 | } | ||
69 | after 100 | ||
70 | |||
71 | # no file | ||
72 | send -- "firejail --net=br0 --private.keep=../test/nofile\r" | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
75 | "Error" | ||
76 | } | ||
77 | after 100 | ||
78 | |||
79 | # same owner | ||
80 | send -- "firejail --net=br0 --private=/etc\r" | ||
81 | expect { | ||
82 | timeout {puts "TESTING ERROR 4\n";exit} | ||
83 | "Error" | ||
84 | } | ||
85 | after 100 | ||
86 | |||
87 | # same owner | ||
88 | send -- "firejail --net=br0 --private=/etc/shadow\r" | ||
89 | expect { | ||
90 | timeout {puts "TESTING ERROR 4\n";exit} | ||
91 | "Error" | ||
92 | } | ||
93 | after 100 | ||
diff --git a/test/fscheck-profile.exp b/test/fscheck-profile.exp new file mode 100755 index 000000000..d7d7c7cd1 --- /dev/null +++ b/test/fscheck-profile.exp | |||
@@ -0,0 +1,69 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # dir | ||
8 | send -- "firejail --net=br0 --profile=fscheck-dir\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Error" | ||
12 | } | ||
13 | after 100 | ||
14 | |||
15 | # .. | ||
16 | send -- "firejail --net=br0 --profile=../test/fscheck-dir\r" | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
19 | "Error" | ||
20 | } | ||
21 | after 100 | ||
22 | |||
23 | # dir link | ||
24 | send -- "firejail --net=br0 --profile=fscheck-dir-link\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 1\n";exit} | ||
27 | "Error" | ||
28 | } | ||
29 | after 100 | ||
30 | |||
31 | # .. | ||
32 | send -- "firejail --net=br0 --profile=../test/fscheck-dir-link\r" | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
35 | "Error" | ||
36 | } | ||
37 | after 100 | ||
38 | |||
39 | # file link | ||
40 | send -- "firejail --net=br0 --profile=fscheck-file-link\r" | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 2\n";exit} | ||
43 | "Error" | ||
44 | } | ||
45 | after 100 | ||
46 | |||
47 | # .. | ||
48 | send -- "firejail --net=br0 --profile=../test/fscheck-file-link\r" | ||
49 | expect { | ||
50 | timeout {puts "TESTING ERROR 2\n";exit} | ||
51 | "Error" | ||
52 | } | ||
53 | after 100 | ||
54 | |||
55 | # no file | ||
56 | send -- "firejail --net=br0 --profile=../test/nofile\r" | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 3\n";exit} | ||
59 | "Error" | ||
60 | } | ||
61 | after 100 | ||
62 | |||
63 | # real GID/UID | ||
64 | send -- "firejail --net=br0 --profile=/etc/shadow\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 4\n";exit} | ||
67 | "Error" | ||
68 | } | ||
69 | after 100 | ||
diff --git a/test/fscheck-readonly.exp b/test/fscheck-readonly.exp new file mode 100755 index 000000000..e0f0a8a1d --- /dev/null +++ b/test/fscheck-readonly.exp | |||
@@ -0,0 +1,14 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # dir | ||
8 | send -- "firejail --net=br0 --read-only=../test/fscheck-dir\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Error" | ||
12 | } | ||
13 | after 100 | ||
14 | |||
diff --git a/test/fscheck-shell.exp b/test/fscheck-shell.exp new file mode 100755 index 000000000..d2320a4c3 --- /dev/null +++ b/test/fscheck-shell.exp | |||
@@ -0,0 +1,69 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # dir | ||
8 | send -- "firejail --net=br0 --shell=fscheck-dir\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Error" | ||
12 | } | ||
13 | after 100 | ||
14 | |||
15 | # .. | ||
16 | send -- "firejail --net=br0 --shell=../test/fscheck-dir\r" | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
19 | "Error" | ||
20 | } | ||
21 | after 100 | ||
22 | |||
23 | # dir link | ||
24 | send -- "firejail --net=br0 --shell=fscheck-dir-link\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 1\n";exit} | ||
27 | "Error" | ||
28 | } | ||
29 | after 100 | ||
30 | |||
31 | # .. | ||
32 | send -- "firejail --net=br0 --shell=../test/fscheck-dir-link\r" | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
35 | "Error" | ||
36 | } | ||
37 | after 100 | ||
38 | |||
39 | # file link | ||
40 | send -- "firejail --net=br0 --shell=fscheck-file-link\r" | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 2\n";exit} | ||
43 | "Error" | ||
44 | } | ||
45 | after 100 | ||
46 | |||
47 | # .. | ||
48 | send -- "firejail --net=br0 --shell=../test/fscheck-file-link\r" | ||
49 | expect { | ||
50 | timeout {puts "TESTING ERROR 2\n";exit} | ||
51 | "Error" | ||
52 | } | ||
53 | after 100 | ||
54 | |||
55 | # no file | ||
56 | send -- "firejail --net=br0 --shell=../test/nofile\r" | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 3\n";exit} | ||
59 | "Error" | ||
60 | } | ||
61 | after 100 | ||
62 | |||
63 | # real GID/UID | ||
64 | send -- "firejail --net=br0 --shell=/etc/shadow\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 4\n";exit} | ||
67 | "Error" | ||
68 | } | ||
69 | after 100 | ||
diff --git a/test/fscheck-tmpfs.exp b/test/fscheck-tmpfs.exp new file mode 100755 index 000000000..d5bbccd96 --- /dev/null +++ b/test/fscheck-tmpfs.exp | |||
@@ -0,0 +1,14 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # .. | ||
8 | send -- "firejail --net=br0 --tmpfs=../test/fscheck-dir\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
11 | "Error" | ||
12 | } | ||
13 | after 100 | ||
14 | |||
diff --git a/test/fscheck.sh b/test/fscheck.sh new file mode 100755 index 000000000..25756d5be --- /dev/null +++ b/test/fscheck.sh | |||
@@ -0,0 +1,39 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | mkdir fscheck-dir | ||
4 | ln -s fscheck-dir fscheck-dir-link | ||
5 | touch fscheck-file | ||
6 | ln -s fscheck-file fscheck-file-link | ||
7 | touch fscheck-file-hard1 | ||
8 | ln fscheck-file-hard1 fscheck-file-hard2 | ||
9 | |||
10 | echo "TESTING: fscheck netfilter" | ||
11 | ./fscheck-netfilter.exp | ||
12 | echo "TESTING: fscheck shell" | ||
13 | ./fscheck-shell.exp | ||
14 | echo "TESTING: fscheck private" | ||
15 | ./fscheck-private.exp | ||
16 | echo "TESTING: fscheck private keep" | ||
17 | ./fscheck-privatekeep.exp | ||
18 | echo "TESTING: fscheck profile" | ||
19 | ./fscheck-profile.exp | ||
20 | echo "TESTING: fscheck chroot" | ||
21 | ./fscheck-chroot.exp | ||
22 | echo "TESTING: fscheck output" | ||
23 | ./fscheck-output.exp | ||
24 | echo "TESTING: fscheck bind nonroot" | ||
25 | ./fscheck-bindnoroot.exp | ||
26 | echo "TESTING: fscheck tmpfs" | ||
27 | ./fscheck-tmpfs.exp | ||
28 | echo "TESTING: fscheck readonly" | ||
29 | ./fscheck-readonly.exp | ||
30 | echo "TESTING: fscheck blacklist" | ||
31 | ./fscheck-blacklist.exp | ||
32 | |||
33 | |||
34 | rm -fr fscheck-dir | ||
35 | rm -fr fscheck-dir-link | ||
36 | rm -fr fscheck-file-link | ||
37 | rm -fr fscheck-file | ||
38 | rm -fr fscheck-file-hard1 | ||
39 | rm -fr fscheck-file-hard2 | ||
diff --git a/test/login_ssh.exp b/test/login_ssh.exp new file mode 100755 index 000000000..dff6dc655 --- /dev/null +++ b/test/login_ssh.exp | |||
@@ -0,0 +1,59 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "ssh bingo@0\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "password:" { | ||
11 | puts "\nTESTING: please enter SSH password" | ||
12 | set oldmode [stty -echo -raw] | ||
13 | expect_user -re "(.*)\n" | ||
14 | send_user "\n" | ||
15 | eval stty $oldmode | ||
16 | # stty echo | ||
17 | set pass $expect_out(1,string) | ||
18 | send -- "$pass\r" | ||
19 | puts "TESTING: password sent to the server" | ||
20 | } | ||
21 | "Child process initialized" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | # test default gw | ||
26 | send -- "bash\r" | ||
27 | sleep 1 | ||
28 | send -- "ps aux; pwd\r" | ||
29 | expect { | ||
30 | timeout {puts "TESTING ERROR 1\n";exit} | ||
31 | "/bin/bash" | ||
32 | } | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 2\n";exit} | ||
35 | "bash" | ||
36 | } | ||
37 | expect { | ||
38 | timeout {puts "TESTING ERROR 3\n";exit} | ||
39 | "ps aux" | ||
40 | } | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 4\n";exit} | ||
43 | "home" | ||
44 | } | ||
45 | sleep 1 | ||
46 | |||
47 | |||
48 | send -- "ps aux |wc -l; pwd\r" | ||
49 | expect { | ||
50 | timeout {puts "TESTING ERROR 5\n";exit} | ||
51 | "5" | ||
52 | } | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 6\n";exit} | ||
55 | "home" | ||
56 | } | ||
57 | sleep 1 | ||
58 | |||
59 | puts "\n" | ||
diff --git a/test/midori.exp b/test/midori.exp new file mode 100755 index 000000000..ec33816dd --- /dev/null +++ b/test/midori.exp | |||
@@ -0,0 +1,73 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail midori www.gentoo.org\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Reading profile /etc/firejail/midori.profile" | ||
11 | } | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 1\n";exit} | ||
14 | "Child process initialized" | ||
15 | } | ||
16 | sleep 10 | ||
17 | |||
18 | spawn $env(SHELL) | ||
19 | send -- "firejail --list\r" | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 3\n";exit} | ||
22 | ":firejail" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
26 | "midori" | ||
27 | } | ||
28 | sleep 1 | ||
29 | |||
30 | send -- "firejail --name=blablabla\r" | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 4\n";exit} | ||
33 | "Child process initialized" | ||
34 | } | ||
35 | sleep 2 | ||
36 | |||
37 | spawn $env(SHELL) | ||
38 | send -- "firemon --seccomp\r" | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 5\n";exit} | ||
41 | ":firejail midori" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
45 | "Seccomp: 2" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
49 | "name=blablabla" | ||
50 | } | ||
51 | sleep 1 | ||
52 | send -- "firemon --caps\r" | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 6\n";exit} | ||
55 | ":firejail midori" | ||
56 | } | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
59 | "CapBnd" | ||
60 | } | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
63 | "0000000000000000" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6.3n";exit} | ||
67 | "name=blablabla" | ||
68 | } | ||
69 | sleep 1 | ||
70 | |||
71 | |||
72 | puts "\n" | ||
73 | |||
diff --git a/test/name.exp b/test/name.exp new file mode 100755 index 000000000..704b8315e --- /dev/null +++ b/test/name.exp | |||
@@ -0,0 +1,25 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --name=baluba\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 1\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "ping -c 3 baluba;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 2\n";exit} | ||
17 | "3 packets transmitted, 3 received" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3\n";exit} | ||
21 | "home" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | puts "\n" | ||
diff --git a/test/net_arp.exp b/test/net_arp.exp new file mode 100755 index 000000000..9e07744f3 --- /dev/null +++ b/test/net_arp.exp | |||
@@ -0,0 +1,71 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --net=br0 sleep 20 &\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | send -- "firejail --net=br0 sleep 20 &\r" | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 1\n";exit} | ||
15 | "Child process initialized" | ||
16 | } | ||
17 | send -- "firejail --net=br0 sleep 20 &\r" | ||
18 | expect { | ||
19 | timeout {puts "TESTING ERROR 2\n";exit} | ||
20 | "Child process initialized" | ||
21 | } | ||
22 | send -- "firejail --net=br0 sleep 20 &\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | "Child process initialized" | ||
26 | } | ||
27 | send -- "firejail --net=br0 sleep 20 &\r" | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 4\n";exit} | ||
30 | "Child process initialized" | ||
31 | } | ||
32 | |||
33 | # will fail | ||
34 | send -- "firejail --net=br0 sleep 20 &\r" | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 5n";exit} | ||
37 | "cannot assign an IP address" | ||
38 | } | ||
39 | |||
40 | send -- "firejail --net=br0 sleep 20 &\r" | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 6\n";exit} | ||
43 | "cannot assign an IP address" | ||
44 | } | ||
45 | |||
46 | # check firejail --list | ||
47 | send -- "firejail --list\r" | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 7.1\n";exit} | ||
50 | "sleep 20" | ||
51 | } | ||
52 | expect { | ||
53 | timeout {puts "TESTING ERROR 7.2\n";exit} | ||
54 | "sleep 20" | ||
55 | } | ||
56 | expect { | ||
57 | timeout {puts "TESTING ERROR 7.3\n";exit} | ||
58 | "sleep 20" | ||
59 | } | ||
60 | expect { | ||
61 | timeout {puts "TESTING ERROR 7.4\n";exit} | ||
62 | "sleep 20" | ||
63 | } | ||
64 | expect { | ||
65 | timeout {puts "TESTING ERROR 7.5\n";exit} | ||
66 | "sleep 20" | ||
67 | } | ||
68 | |||
69 | # wait for snadboxes to be shutdown | ||
70 | sleep 30 | ||
71 | puts "\n" | ||
diff --git a/test/net_badip.exp b/test/net_badip.exp new file mode 100755 index 000000000..71b69e104 --- /dev/null +++ b/test/net_badip.exp | |||
@@ -0,0 +1,16 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check eth0 | ||
8 | send -- "firejail --net=br0 --net=br1 --ip=10.100.10.47\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0.0\n";exit} | ||
11 | "the IP address is not" | ||
12 | } | ||
13 | sleep 1 | ||
14 | |||
15 | puts "\n" | ||
16 | |||
diff --git a/test/net_defaultgw.exp b/test/net_defaultgw.exp new file mode 100755 index 000000000..9820660b7 --- /dev/null +++ b/test/net_defaultgw.exp | |||
@@ -0,0 +1,65 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check ip address | ||
8 | send -- "firejail --net=br0 --ip=10.10.20.5 --defaultgw=10.10.20.2\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "eth0" | ||
12 | } | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 1\n";exit} | ||
15 | "10.10.20.5" | ||
16 | } | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 2\n";exit} | ||
19 | "255.255.255.248" | ||
20 | } | ||
21 | expect { | ||
22 | timeout {puts "TESTING ERROR 3\n";exit} | ||
23 | "UP" | ||
24 | } | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 4\n";exit} | ||
27 | "Child process initialized" | ||
28 | } | ||
29 | |||
30 | # check default gateway | ||
31 | send -- "bash\r" | ||
32 | sleep 1 | ||
33 | send -- "netstat -rn;pwd\r" | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 10.1\n";exit} | ||
36 | "0.0.0.0" | ||
37 | } | ||
38 | expect { | ||
39 | timeout {puts "TESTING ERROR 10.2\n";exit} | ||
40 | "10.10.20.2" | ||
41 | } | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 10.3\n";exit} | ||
44 | "eth0" | ||
45 | } | ||
46 | expect { | ||
47 | timeout {puts "TESTING ERROR 10.4\n";exit} | ||
48 | "10.10.20.0" | ||
49 | } | ||
50 | expect { | ||
51 | timeout {puts "TESTING ERROR 10.5\n";exit} | ||
52 | "0.0.0.0" | ||
53 | } | ||
54 | expect { | ||
55 | timeout {puts "TESTING ERROR 10.6\n";exit} | ||
56 | "eth0" | ||
57 | } | ||
58 | expect { | ||
59 | timeout {puts "TESTING ERROR 10\n";exit} | ||
60 | "home" | ||
61 | } | ||
62 | sleep 1 | ||
63 | |||
64 | puts "\n" | ||
65 | |||
diff --git a/test/net_defaultgw2.exp b/test/net_defaultgw2.exp new file mode 100755 index 000000000..be9b4882a --- /dev/null +++ b/test/net_defaultgw2.exp | |||
@@ -0,0 +1,65 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check ip address | ||
8 | send -- "firejail --net=br0 --net=br1 --defaultgw=10.10.30.89\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "eth1" | ||
12 | } | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 4\n";exit} | ||
15 | "Child process initialized" | ||
16 | } | ||
17 | |||
18 | # check default gateway | ||
19 | send -- "bash\r" | ||
20 | sleep 1 | ||
21 | send -- "netstat -rn;pwd\r" | ||
22 | expect { | ||
23 | timeout {puts "TESTING ERROR 10.1\n";exit} | ||
24 | "0.0.0.0" | ||
25 | } | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 10.2\n";exit} | ||
28 | "10.10.30.89" | ||
29 | } | ||
30 | expect { | ||
31 | timeout {puts "TESTING ERROR 10.3\n";exit} | ||
32 | "eth1" | ||
33 | } | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 10.4\n";exit} | ||
36 | "10.10.20.0" | ||
37 | } | ||
38 | expect { | ||
39 | timeout {puts "TESTING ERROR 10.5\n";exit} | ||
40 | "0.0.0.0" | ||
41 | } | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 10.6\n";exit} | ||
44 | "eth0" | ||
45 | } | ||
46 | expect { | ||
47 | timeout {puts "TESTING ERROR 10.4\n";exit} | ||
48 | "10.10.30.0" | ||
49 | } | ||
50 | expect { | ||
51 | timeout {puts "TESTING ERROR 10.5\n";exit} | ||
52 | "0.0.0.0" | ||
53 | } | ||
54 | expect { | ||
55 | timeout {puts "TESTING ERROR 10.6\n";exit} | ||
56 | "eth1" | ||
57 | } | ||
58 | expect { | ||
59 | timeout {puts "TESTING ERROR 10\n";exit} | ||
60 | "home" | ||
61 | } | ||
62 | sleep 1 | ||
63 | |||
64 | puts "\n" | ||
65 | |||
diff --git a/test/net_defaultgw3.exp b/test/net_defaultgw3.exp new file mode 100755 index 000000000..64da9dfca --- /dev/null +++ b/test/net_defaultgw3.exp | |||
@@ -0,0 +1,17 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check ip address | ||
8 | send -- "firejail --net=br0 --net=br1 --defaultgw=10.10.95.89\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "default gateway 10.10.95.89 is not in the range of any network" | ||
12 | } | ||
13 | |||
14 | sleep 1 | ||
15 | |||
16 | puts "\n" | ||
17 | |||
diff --git a/test/net_ip.exp b/test/net_ip.exp new file mode 100755 index 000000000..5995296c7 --- /dev/null +++ b/test/net_ip.exp | |||
@@ -0,0 +1,91 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check ip address | ||
8 | send -- "firejail --net=br0 --ip=10.10.20.5\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "eth0" | ||
12 | } | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 1\n";exit} | ||
15 | "10.10.20.5" | ||
16 | } | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 2\n";exit} | ||
19 | "255.255.255.248" | ||
20 | } | ||
21 | expect { | ||
22 | timeout {puts "TESTING ERROR 3\n";exit} | ||
23 | "UP" | ||
24 | } | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 4\n";exit} | ||
27 | "Child process initialized" | ||
28 | } | ||
29 | sleep 2 | ||
30 | send -- "exit\r" | ||
31 | sleep 2 | ||
32 | |||
33 | # check loopback | ||
34 | send -- "firejail --net=br0 --ip=10.10.20.5\r" | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 5\n";exit} | ||
37 | "lo" | ||
38 | } | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 6\n";exit} | ||
41 | "127.0.0.1" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 7\n";exit} | ||
45 | "255.0.0.0" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 8\n";exit} | ||
49 | "UP" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 9\n";exit} | ||
53 | "Child process initialized" | ||
54 | } | ||
55 | |||
56 | # check default gateway | ||
57 | send -- "bash\r" | ||
58 | sleep 1 | ||
59 | send -- "netstat -rn;pwd\r" | ||
60 | expect { | ||
61 | timeout {puts "TESTING ERROR 10.1\n";exit} | ||
62 | "0.0.0.0" | ||
63 | } | ||
64 | expect { | ||
65 | timeout {puts "TESTING ERROR 10.2\n";exit} | ||
66 | "10.10.20.1" | ||
67 | } | ||
68 | expect { | ||
69 | timeout {puts "TESTING ERROR 10.3\n";exit} | ||
70 | "eth0" | ||
71 | } | ||
72 | expect { | ||
73 | timeout {puts "TESTING ERROR 10.4\n";exit} | ||
74 | "10.10.20.0" | ||
75 | } | ||
76 | expect { | ||
77 | timeout {puts "TESTING ERROR 10.5\n";exit} | ||
78 | "0.0.0.0" | ||
79 | } | ||
80 | expect { | ||
81 | timeout {puts "TESTING ERROR 10.6\n";exit} | ||
82 | "eth0" | ||
83 | } | ||
84 | expect { | ||
85 | timeout {puts "TESTING ERROR 10\n";exit} | ||
86 | "home" | ||
87 | } | ||
88 | sleep 1 | ||
89 | |||
90 | puts "\n" | ||
91 | |||
diff --git a/test/net_local.exp b/test/net_local.exp new file mode 100755 index 000000000..9302ec4ef --- /dev/null +++ b/test/net_local.exp | |||
@@ -0,0 +1,49 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check ip address | ||
8 | send -- "firejail --debug\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Using the local network stack" | ||
12 | } | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 4\n";exit} | ||
15 | "Child process initialized" | ||
16 | } | ||
17 | sleep 2 | ||
18 | send -- "exit\r" | ||
19 | sleep 2 | ||
20 | |||
21 | # check loopback | ||
22 | send -- "firejail\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 9\n";exit} | ||
25 | "Child process initialized" | ||
26 | } | ||
27 | sleep 1 | ||
28 | |||
29 | |||
30 | send -- "/sbin/ifconfig\r" | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 5\n";exit} | ||
33 | "lo" | ||
34 | } | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 6\n";exit} | ||
37 | "127.0.0.1" | ||
38 | } | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 7\n";exit} | ||
41 | "255.0.0.0" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 8\n";exit} | ||
45 | "UP" | ||
46 | } | ||
47 | |||
48 | puts "\n" | ||
49 | |||
diff --git a/test/net_mac.exp b/test/net_mac.exp new file mode 100755 index 000000000..555d86b74 --- /dev/null +++ b/test/net_mac.exp | |||
@@ -0,0 +1,36 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check ip address | ||
8 | send -- "firejail --net=br0 --ip=10.10.20.5 --mac=00:11:22:33:44:55\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "eth0" | ||
12 | } | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
15 | "00:11:22:33:44:55" | ||
16 | } | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 1\n";exit} | ||
19 | "10.10.20.5" | ||
20 | } | ||
21 | expect { | ||
22 | timeout {puts "TESTING ERROR 2\n";exit} | ||
23 | "255.255.255.248" | ||
24 | } | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 3\n";exit} | ||
27 | "UP" | ||
28 | } | ||
29 | expect { | ||
30 | timeout {puts "TESTING ERROR 4\n";exit} | ||
31 | "Child process initialized" | ||
32 | } | ||
33 | sleep 1 | ||
34 | |||
35 | puts "\n" | ||
36 | |||
diff --git a/test/net_macvlan.exp b/test/net_macvlan.exp new file mode 100755 index 000000000..20d022de9 --- /dev/null +++ b/test/net_macvlan.exp | |||
@@ -0,0 +1,88 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check the existing address | ||
8 | spawn $env(SHELL) | ||
9 | send -- "firejail --net=eth0 --ip=192.168.1.60\r" | ||
10 | expect { | ||
11 | timeout {puts "TESTING ERROR 1.1\n";puts "Please open a sandbox on 192.168.1.60\n";exit} | ||
12 | "the address 192.168.1.60 is already in use" | ||
13 | } | ||
14 | |||
15 | |||
16 | |||
17 | # grab 30 ip addresses | ||
18 | set MAXi 229 | ||
19 | set i 200 | ||
20 | while { $i <= $MAXi } { | ||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --net=eth0 --ip=192.168.1.$i\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 0\n";exit} | ||
25 | "Child process initialized" | ||
26 | } | ||
27 | incr i | ||
28 | after 100 | ||
29 | } | ||
30 | |||
31 | |||
32 | # check an existing address | ||
33 | spawn $env(SHELL) | ||
34 | send -- "firejail --net=eth0 --ip=192.168.1.200\r" | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 1\n";exit} | ||
37 | "the address 192.168.1.200 is already in use" | ||
38 | } | ||
39 | |||
40 | |||
41 | set MAXi 254 | ||
42 | set i 2 | ||
43 | while { $i <= $MAXi } { | ||
44 | spawn $env(SHELL) | ||
45 | send -- "firejail --net=eth0\r" | ||
46 | expect { | ||
47 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
48 | "192.168.1.60" {puts "TESTING ERROR 2.2\n";exit} | ||
49 | "192.168.1.200" {puts "TESTING ERROR 3\n";exit} | ||
50 | "192.168.1.201" {puts "TESTING ERROR 3\n";exit} | ||
51 | "192.168.1.202" {puts "TESTING ERROR 3\n";exit} | ||
52 | "192.168.1.203" {puts "TESTING ERROR 3\n";exit} | ||
53 | "192.168.1.204" {puts "TESTING ERROR 3\n";exit} | ||
54 | "192.168.1.205" {puts "TESTING ERROR 3\n";exit} | ||
55 | "192.168.1.206" {puts "TESTING ERROR 3\n";exit} | ||
56 | "192.168.1.207" {puts "TESTING ERROR 3\n";exit} | ||
57 | "192.168.1.208" {puts "TESTING ERROR 3\n";exit} | ||
58 | "192.168.1.209" {puts "TESTING ERROR 3\n";exit} | ||
59 | "192.168.1.210" {puts "TESTING ERROR 3\n";exit} | ||
60 | "192.168.1.211" {puts "TESTING ERROR 3\n";exit} | ||
61 | "192.168.1.212" {puts "TESTING ERROR 3\n";exit} | ||
62 | "192.168.1.213" {puts "TESTING ERROR 3\n";exit} | ||
63 | "192.168.1.214" {puts "TESTING ERROR 3\n";exit} | ||
64 | "192.168.1.215" {puts "TESTING ERROR 3\n";exit} | ||
65 | "192.168.1.216" {puts "TESTING ERROR 3\n";exit} | ||
66 | "192.168.1.217" {puts "TESTING ERROR 3\n";exit} | ||
67 | "192.168.1.218" {puts "TESTING ERROR 3\n";exit} | ||
68 | "192.168.1.219" {puts "TESTING ERROR 3\n";exit} | ||
69 | "192.168.1.220" {puts "TESTING ERROR 3\n";exit} | ||
70 | "192.168.1.221" {puts "TESTING ERROR 3\n";exit} | ||
71 | "192.168.1.222" {puts "TESTING ERROR 3\n";exit} | ||
72 | "192.168.1.223" {puts "TESTING ERROR 3\n";exit} | ||
73 | "192.168.1.224" {puts "TESTING ERROR 3\n";exit} | ||
74 | "192.168.1.225" {puts "TESTING ERROR 3\n";exit} | ||
75 | "192.168.1.226" {puts "TESTING ERROR 3\n";exit} | ||
76 | "192.168.1.227" {puts "TESTING ERROR 3\n";exit} | ||
77 | "192.168.1.228" {puts "TESTING ERROR 3\n";exit} | ||
78 | "192.168.1.229" {puts "TESTING ERROR 3\n";exit} | ||
79 | "Child process initialized" | ||
80 | } | ||
81 | puts "************ $i ******************\n" | ||
82 | incr i | ||
83 | after 100 | ||
84 | # sleep 1 | ||
85 | } | ||
86 | |||
87 | puts "\n" | ||
88 | |||
diff --git a/test/net_netfilter.exp b/test/net_netfilter.exp new file mode 100755 index 000000000..8583d4625 --- /dev/null +++ b/test/net_netfilter.exp | |||
@@ -0,0 +1,88 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check default netfilter on br0 | ||
8 | send -- "firejail --debug --net=br0 --ip=10.10.20.5 --netfilter\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Installing network filter" | ||
12 | } | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 1\n";exit} | ||
15 | "Chain INPUT (policy DROP" | ||
16 | } | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 2\n";exit} | ||
19 | "ACCEPT all -- any any anywhere" | ||
20 | } | ||
21 | expect { | ||
22 | timeout {puts "TESTING ERROR 3\n";exit} | ||
23 | "ACCEPT icmp -- any any anywhere" | ||
24 | } | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 4\n";exit} | ||
27 | "Child process initialized" | ||
28 | } | ||
29 | sleep 2 | ||
30 | send -- "exit\r" | ||
31 | sleep 1 | ||
32 | |||
33 | # check default netfilter no new network | ||
34 | send -- "firejail --debug --netfilter\r" | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 5\n";exit} | ||
37 | "Installing network filter" {puts "TESTING ERROR 5.1\n";exit} | ||
38 | "Chain INPUT (policy DROP" {puts "TESTING ERROR 5.1\n";exit} | ||
39 | "ACCEPT all -- any any anywhere" {puts "TESTING ERROR 5.1\n";exit} | ||
40 | "ACCEPT icmp -- any any anywhere" {puts "TESTING ERROR 5.1\n";exit} | ||
41 | "Child process initialized" | ||
42 | } | ||
43 | sleep 2 | ||
44 | send -- "exit\r" | ||
45 | sleep 1 | ||
46 | |||
47 | # check file filter netfilter on br0 | ||
48 | send -- "firejail --debug --net=br0 --ip=10.10.20.5 --netfilter=netfilter.filter\r" | ||
49 | expect { | ||
50 | timeout {puts "TESTING ERROR 6\n";exit} | ||
51 | "Installing network filter" | ||
52 | } | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
55 | "Child process initialized" | ||
56 | } | ||
57 | sleep 2 | ||
58 | send -- "ping -c 1 -w 3 10.10.20.1\r" | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
61 | "0 received, 100% packet loss" | ||
62 | } | ||
63 | |||
64 | send -- "exit\r" | ||
65 | sleep 1 | ||
66 | |||
67 | # check profile netfilter on br0 | ||
68 | send -- "firejail --debug --net=br0 --ip=10.10.20.5 --profile=netfilter.profile\r" | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 7\n";exit} | ||
71 | "Installing network filter" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 7.1\n";exit} | ||
75 | "Child process initialized" | ||
76 | } | ||
77 | sleep 2 | ||
78 | send -- "ping -c 1 -w 3 10.10.20.1\r" | ||
79 | expect { | ||
80 | timeout {puts "TESTING ERROR 7.2\n";exit} | ||
81 | "0 received, 100% packet loss" | ||
82 | } | ||
83 | |||
84 | send -- "exit\r" | ||
85 | sleep 1 | ||
86 | |||
87 | puts "\n" | ||
88 | |||
diff --git a/test/net_noip.exp b/test/net_noip.exp new file mode 100755 index 000000000..3db67885d --- /dev/null +++ b/test/net_noip.exp | |||
@@ -0,0 +1,41 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check ip address | ||
8 | send -- "firejail --net=br0 --ip=none\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "eth0" {puts "TESTING ERROR 1\n";exit} | ||
12 | "Child process initialized" | ||
13 | } | ||
14 | sleep 1 | ||
15 | send -- "bash\r" | ||
16 | sleep 1 | ||
17 | |||
18 | # no default gateway configured | ||
19 | send -- "netstat -rn;pwd\r" | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 2\n";exit} | ||
22 | "0.0.0.0" {puts "TESTING ERROR 3\n";exit} | ||
23 | "eth0" {puts "TESTING ERROR 4\n";exit} | ||
24 | "home" | ||
25 | } | ||
26 | sleep 1 | ||
27 | |||
28 | # eth0 configured | ||
29 | send -- "/sbin/ifconfig;pwd\r" | ||
30 | expect { | ||
31 | timeout {puts "TESTING ERROR 5\n";exit} | ||
32 | "eth0" | ||
33 | } | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 6\n";exit} | ||
36 | "home" | ||
37 | } | ||
38 | sleep 1 | ||
39 | |||
40 | puts "\n" | ||
41 | |||
diff --git a/test/net_noip2.exp b/test/net_noip2.exp new file mode 100755 index 000000000..234aec8a8 --- /dev/null +++ b/test/net_noip2.exp | |||
@@ -0,0 +1,41 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # check ip address | ||
8 | send -- "firejail --net=br1 --ip=none --defaultgw=10.10.30.78\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "eth0" {puts "TESTING ERROR 1\n";exit} | ||
12 | "Child process initialized" | ||
13 | } | ||
14 | sleep 1 | ||
15 | send -- "bash\r" | ||
16 | sleep 1 | ||
17 | |||
18 | # no default gateway configured | ||
19 | send -- "netstat -rn;pwd\r" | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 2\n";exit} | ||
22 | "0.0.0.0" {puts "TESTING ERROR 3\n";exit} | ||
23 | "eth0" {puts "TESTING ERROR 4\n";exit} | ||
24 | "home" | ||
25 | } | ||
26 | sleep 1 | ||
27 | |||
28 | # eth0 configured | ||
29 | send -- "/sbin/ifconfig;pwd\r" | ||
30 | expect { | ||
31 | timeout {puts "TESTING ERROR 5\n";exit} | ||
32 | "eth0" | ||
33 | } | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 6\n";exit} | ||
36 | "home" | ||
37 | } | ||
38 | sleep 1 | ||
39 | |||
40 | puts "\n" | ||
41 | |||
diff --git a/test/net_none.exp b/test/net_none.exp new file mode 100755 index 000000000..dfa14a211 --- /dev/null +++ b/test/net_none.exp | |||
@@ -0,0 +1,36 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --net=none\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "eth0" {puts "TESTING ERROR 0.1\n";exit} | ||
11 | "Child process initialized" | ||
12 | } | ||
13 | sleep 1 | ||
14 | |||
15 | # test default gw | ||
16 | send -- "bash\r" | ||
17 | sleep 1 | ||
18 | send -- "netstat -rn; pwd\r" | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 1\n";exit} | ||
21 | "0.0.0.0" {puts "TESTING ERROR 1.1\n";exit} | ||
22 | "home" | ||
23 | } | ||
24 | sleep 1 | ||
25 | |||
26 | # check again devices | ||
27 | send -- "cat /proc/1/net/dev;pwd\r" | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 2\n";exit} | ||
30 | "eth0" {puts "TESTING ERROR 2.1\n";exit} | ||
31 | "home" | ||
32 | } | ||
33 | sleep 1 | ||
34 | |||
35 | |||
36 | puts "\n" | ||
diff --git a/test/netfilter.filter b/test/netfilter.filter new file mode 100644 index 000000000..3e232065c --- /dev/null +++ b/test/netfilter.filter | |||
@@ -0,0 +1,6 @@ | |||
1 | *filter | ||
2 | :INPUT DROP [0:0] | ||
3 | :FORWARD DROP [0:0] | ||
4 | :OUTPUT ACCEPT [0:0] | ||
5 | -A INPUT -i lo -j ACCEPT | ||
6 | COMMIT | ||
diff --git a/test/netfilter.profile b/test/netfilter.profile new file mode 100644 index 000000000..824c6cd0f --- /dev/null +++ b/test/netfilter.profile | |||
@@ -0,0 +1 @@ | |||
netfilter netfilter.filter | |||
diff --git a/test/noroot.exp b/test/noroot.exp new file mode 100755 index 000000000..78991d4a9 --- /dev/null +++ b/test/noroot.exp | |||
@@ -0,0 +1,124 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --debug --noroot --caps.drop=all --seccomp --cpu=0,1 --name=noroot-sandbox\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "cat /proc/self/status\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "CapBnd:" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
21 | "0000000000000000" | ||
22 | } | ||
23 | |||
24 | send -- "cat /proc/self/status\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 2\n";exit} | ||
27 | "Cpus_allowed:" | ||
28 | } | ||
29 | expect { | ||
30 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
31 | "3" | ||
32 | } | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
35 | "Cpus_allowed_list:" | ||
36 | } | ||
37 | puts "\n" | ||
38 | |||
39 | send -- "cat /proc/self/status\r" | ||
40 | expect { | ||
41 | timeout {puts "TESTING ERROR 2\n";exit} | ||
42 | "Seccomp:" | ||
43 | } | ||
44 | expect { | ||
45 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
46 | "2" | ||
47 | } | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
50 | "Cpus_allowed:" | ||
51 | } | ||
52 | puts "\n" | ||
53 | |||
54 | send -- "cat /etc/hostname\r" | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 3\n";exit} | ||
57 | "noroot-sandbox" | ||
58 | } | ||
59 | puts "\n" | ||
60 | |||
61 | send -- "ping 0\r" | ||
62 | expect { | ||
63 | timeout {puts "TESTING ERROR 4\n";exit} | ||
64 | "Operation not permitted" | ||
65 | } | ||
66 | puts "\n" | ||
67 | |||
68 | send -- "whoami\r" | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 55\\n";exit} | ||
71 | "netblue" | ||
72 | } | ||
73 | puts "\n" | ||
74 | send -- "exit\r" | ||
75 | sleep 2 | ||
76 | |||
77 | |||
78 | send -- "firejail --noroot\r" | ||
79 | expect { | ||
80 | timeout {puts "TESTING ERROR 6\n";exit} | ||
81 | "Child process initialized" | ||
82 | } | ||
83 | sleep 1 | ||
84 | send -- "whoami\r" | ||
85 | expect { | ||
86 | timeout {puts "TESTING ERROR 7\n";exit} | ||
87 | "netblue" | ||
88 | } | ||
89 | send -- "sudo -s\r" | ||
90 | expect { | ||
91 | timeout {puts "TESTING ERROR 8\n";exit} | ||
92 | "effective uid is not 0, is sudo installed setuid root?" { puts "OK\n";} | ||
93 | "sudo must be owned by uid 0 and have the setuid bit set" { puts "OK\n";} | ||
94 | } | ||
95 | puts "\n" | ||
96 | send -- "exit\r" | ||
97 | sleep 2 | ||
98 | |||
99 | send -- "firejail --name=test --noroot\r" | ||
100 | expect { | ||
101 | timeout {puts "TESTING ERROR 9\n";exit} | ||
102 | "Child process initialized" | ||
103 | } | ||
104 | sleep 1 | ||
105 | |||
106 | spawn $env(SHELL) | ||
107 | send -- "firejail --debug --join=test\r" | ||
108 | expect { | ||
109 | timeout {puts "TESTING ERROR 9\n";exit} | ||
110 | "User namespace detected" | ||
111 | } | ||
112 | expect { | ||
113 | timeout {puts "TESTING ERROR 9\n";exit} | ||
114 | "Joining user namespace" | ||
115 | } | ||
116 | sleep 1 | ||
117 | |||
118 | send -- "sudo -s\r" | ||
119 | expect { | ||
120 | timeout {puts "TESTING ERROR 8\n";exit} | ||
121 | "effective uid is not 0, is sudo installed setuid root?" { puts "OK\n";} | ||
122 | "sudo must be owned by uid 0 and have the setuid bit set" { puts "OK\n";} | ||
123 | } | ||
124 | puts "\n" | ||
diff --git a/test/opera.exp b/test/opera.exp new file mode 100755 index 000000000..f536ae866 --- /dev/null +++ b/test/opera.exp | |||
@@ -0,0 +1,72 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail opera www.gentoo.org\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Reading profile /etc/firejail/opera.profile" | ||
11 | } | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 1\n";exit} | ||
14 | "Child process initialized" | ||
15 | } | ||
16 | sleep 10 | ||
17 | |||
18 | spawn $env(SHELL) | ||
19 | send -- "firejail --list\r" | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 3\n";exit} | ||
22 | ":firejail" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
26 | "opera" | ||
27 | } | ||
28 | sleep 1 | ||
29 | |||
30 | send -- "firejail --name=blablabla\r" | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 4\n";exit} | ||
33 | "Child process initialized" | ||
34 | } | ||
35 | sleep 2 | ||
36 | |||
37 | spawn $env(SHELL) | ||
38 | send -- "firemon --seccomp\r" | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 5\n";exit} | ||
41 | ":firejail opera" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
45 | "Seccomp: 0" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
49 | "name=blablabla" | ||
50 | } | ||
51 | sleep 1 | ||
52 | send -- "firemon --caps\r" | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 6\n";exit} | ||
55 | ":firejail opera" | ||
56 | } | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
59 | "CapBnd:" | ||
60 | } | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
63 | "fffffffff" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
67 | "name=blablabla" | ||
68 | } | ||
69 | sleep 1 | ||
70 | |||
71 | puts "\n" | ||
72 | |||
diff --git a/test/option-join.exp b/test/option-join.exp new file mode 100755 index 000000000..ad8ba73e0 --- /dev/null +++ b/test/option-join.exp | |||
@@ -0,0 +1,43 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --name=svntesting\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 3 | ||
13 | |||
14 | spawn $env(SHELL) | ||
15 | send -- "firejail --join=svntesting;pwd\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 1\n";exit} | ||
18 | "Switching to pid" | ||
19 | } | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 2 (join) \n";exit} | ||
22 | "@svntesting" | ||
23 | } | ||
24 | sleep 1 | ||
25 | |||
26 | |||
27 | spawn $env(SHELL) | ||
28 | send -- "firejail --shutdown=svntesting;pwd\r" | ||
29 | expect { | ||
30 | timeout {puts "TESTING ERROR 3\n";exit} | ||
31 | "home" | ||
32 | } | ||
33 | sleep 1 | ||
34 | |||
35 | send -- "firejail --list;pwd\r" | ||
36 | expect { | ||
37 | timeout {puts "TESTING ERROR 4\n";exit} | ||
38 | "svntesting" {puts "TESTING ERROR 5\n";exit} | ||
39 | "home" | ||
40 | } | ||
41 | sleep 1 | ||
42 | |||
43 | puts "\n" | ||
diff --git a/test/option-shutdown.exp b/test/option-shutdown.exp new file mode 100755 index 000000000..260a5b84f --- /dev/null +++ b/test/option-shutdown.exp | |||
@@ -0,0 +1,30 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --name=svntesting\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 3 | ||
13 | |||
14 | spawn $env(SHELL) | ||
15 | send -- "firejail --shutdown=svntesting;pwd\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 4\n";exit} | ||
18 | "home" | ||
19 | } | ||
20 | sleep 1 | ||
21 | |||
22 | send -- "firejail --list;pwd\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 5\n";exit} | ||
25 | "svntesting" {puts "TESTING ERROR 6\n";exit} | ||
26 | "home" | ||
27 | } | ||
28 | sleep 1 | ||
29 | |||
30 | puts "\n" | ||
diff --git a/test/option-trace.exp b/test/option-trace.exp new file mode 100755 index 000000000..b8f723fb8 --- /dev/null +++ b/test/option-trace.exp | |||
@@ -0,0 +1,31 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --trace firefox --name=testing\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 | "command not found" {puts "\nTESTING: not tested, firefox not found\n"; exit} | ||
15 | "1:firefox:open" {puts "\n"} | ||
16 | "1:iceweasel:open" | ||
17 | } | ||
18 | expect { | ||
19 | timeout {puts "TESTING ERROR 2\n";exit} | ||
20 | "1:firefox:access" {puts "\n"} | ||
21 | "1:iceweasel:access" | ||
22 | } | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | "1:firefox:connect" {puts "\n"} | ||
26 | "1:iceweasel:connect" | ||
27 | } | ||
28 | |||
29 | sleep 1 | ||
30 | |||
31 | puts "\n" | ||
diff --git a/test/option_bind_directory.exp b/test/option_bind_directory.exp new file mode 100755 index 000000000..1c1acc814 --- /dev/null +++ b/test/option_bind_directory.exp | |||
@@ -0,0 +1,26 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --bind=/tmp/chroot,mntpoint\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "ls mntpoint;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "root" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 2\n";exit} | ||
21 | "home" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | puts "\n" | ||
26 | |||
diff --git a/test/option_bind_file.exp b/test/option_bind_file.exp new file mode 100755 index 000000000..0380b68b5 --- /dev/null +++ b/test/option_bind_file.exp | |||
@@ -0,0 +1,26 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --bind=tmpfile,/etc/passwd\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "cat /etc/passwd;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "hello" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 2\n";exit} | ||
21 | "home" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | puts "\n" | ||
26 | |||
diff --git a/test/option_bind_user.exp b/test/option_bind_user.exp new file mode 100755 index 000000000..9d2d17d7f --- /dev/null +++ b/test/option_bind_user.exp | |||
@@ -0,0 +1,15 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --bind=/tmp/chroot,mntpoint\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "bind option is available only if running as root" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | puts "\n" | ||
15 | |||
diff --git a/test/option_blacklist.exp b/test/option_blacklist.exp new file mode 100755 index 000000000..b80d0cc60 --- /dev/null +++ b/test/option_blacklist.exp | |||
@@ -0,0 +1,35 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --blacklist=/var\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "ls -l /var;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Permission denied" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 2\n";exit} | ||
21 | "home" | ||
22 | } | ||
23 | send -- "cd /var;pwd\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3\n";exit} | ||
26 | "Permission denied" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 4\n";exit} | ||
30 | "home" | ||
31 | } | ||
32 | sleep 1 | ||
33 | |||
34 | puts "\n" | ||
35 | |||
diff --git a/test/option_blacklist_file.exp b/test/option_blacklist_file.exp new file mode 100755 index 000000000..ecdfe3b82 --- /dev/null +++ b/test/option_blacklist_file.exp | |||
@@ -0,0 +1,26 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --blacklist=/etc/passwd\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "cat /etc/passwd;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Permission denied" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 2\n";exit} | ||
21 | "home" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | puts "\n" | ||
26 | |||
diff --git a/test/option_chroot_overlay.exp b/test/option_chroot_overlay.exp new file mode 100755 index 000000000..b39bc0c8e --- /dev/null +++ b/test/option_chroot_overlay.exp | |||
@@ -0,0 +1,21 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --chroot=/tmp/chroot --overlay\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "mutually exclusive" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "firejail --overlay --chroot=/tmp/chroot\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 0\n";exit} | ||
17 | "mutually exclusive" | ||
18 | } | ||
19 | sleep 1 | ||
20 | |||
21 | puts "\n" | ||
diff --git a/test/option_help.exp b/test/option_help.exp new file mode 100755 index 000000000..f4518219c --- /dev/null +++ b/test/option_help.exp | |||
@@ -0,0 +1,22 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --help\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "License GPL version 2 or later" | ||
11 | } | ||
12 | after 100 | ||
13 | |||
14 | send -- "firejail -?\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 0\n";exit} | ||
17 | "License GPL version 2 or later" | ||
18 | } | ||
19 | after 100 | ||
20 | |||
21 | puts "\n" | ||
22 | |||
diff --git a/test/option_list.exp b/test/option_list.exp new file mode 100755 index 000000000..b9c73e52b --- /dev/null +++ b/test/option_list.exp | |||
@@ -0,0 +1,48 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | after 100 | ||
13 | |||
14 | spawn $env(SHELL) | ||
15 | send -- "firejail\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 1\n";exit} | ||
18 | "Child process initialized" | ||
19 | } | ||
20 | after 100 | ||
21 | |||
22 | spawn $env(SHELL) | ||
23 | send -- "firejail\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 2\n";exit} | ||
26 | "Child process initialized" | ||
27 | } | ||
28 | sleep 1 | ||
29 | |||
30 | spawn $env(SHELL) | ||
31 | send -- "firejail --list\r" | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 3\n";exit} | ||
34 | ":firejail" | ||
35 | } | ||
36 | expect { | ||
37 | timeout {puts "TESTING ERROR 4\n";exit} | ||
38 | ":firejail" | ||
39 | } | ||
40 | expect { | ||
41 | timeout {puts "TESTING ERROR 5\n";exit} | ||
42 | ":firejail" | ||
43 | } | ||
44 | after 100 | ||
45 | |||
46 | |||
47 | puts "\n" | ||
48 | |||
diff --git a/test/option_man.exp b/test/option_man.exp new file mode 100755 index 000000000..d941a2432 --- /dev/null +++ b/test/option_man.exp | |||
@@ -0,0 +1,17 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "man firejail\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Linux namespaces sandbox program" | ||
11 | } | ||
12 | after 100 | ||
13 | |||
14 | send -- "q\r" | ||
15 | after 100 | ||
16 | puts "\n" | ||
17 | |||
diff --git a/test/option_readonly.exp b/test/option_readonly.exp new file mode 100755 index 000000000..4abbef617 --- /dev/null +++ b/test/option_readonly.exp | |||
@@ -0,0 +1,26 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --read-only=tmpreadonly\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "touch tmpreadonly;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Read-only file system" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 2\n";exit} | ||
21 | "home" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | puts "\n" | ||
26 | |||
diff --git a/test/option_rlimit.exp b/test/option_rlimit.exp new file mode 100755 index 000000000..17d2bd9d1 --- /dev/null +++ b/test/option_rlimit.exp | |||
@@ -0,0 +1,36 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --rlimit-fsize=1024 --rlimit-nproc=1000 --rlimit-nofile=500 --rlimit-sigpending=200\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "cat /proc/self/limits; pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
17 | "Max file size 1024 1024" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 1.2\n";exit} | ||
21 | "Max processes 1000 1000" | ||
22 | } | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 1.3\n";exit} | ||
25 | "Max open files 500 500" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 1.4\n";exit} | ||
29 | "Max pending signals 200 200" | ||
30 | } | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 1.5\n";exit} | ||
33 | "home" | ||
34 | } | ||
35 | sleep 1 | ||
36 | puts "\n" | ||
diff --git a/test/option_tmpfs.exp b/test/option_tmpfs.exp new file mode 100755 index 000000000..1ff47ab13 --- /dev/null +++ b/test/option_tmpfs.exp | |||
@@ -0,0 +1,26 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --tmpfs=/var\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "ls -l /var;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "total 0" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 2\n";exit} | ||
21 | "home" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | puts "\n" | ||
26 | |||
diff --git a/test/option_tree.exp b/test/option_tree.exp new file mode 100755 index 000000000..1841907d1 --- /dev/null +++ b/test/option_tree.exp | |||
@@ -0,0 +1,60 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | after 100 | ||
13 | |||
14 | spawn $env(SHELL) | ||
15 | send -- "firejail\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 1\n";exit} | ||
18 | "Child process initialized" | ||
19 | } | ||
20 | after 100 | ||
21 | |||
22 | spawn $env(SHELL) | ||
23 | send -- "firejail\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 2\n";exit} | ||
26 | "Child process initialized" | ||
27 | } | ||
28 | sleep 1 | ||
29 | |||
30 | spawn $env(SHELL) | ||
31 | send -- "firejail --tree\r" | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 3\n";exit} | ||
34 | ":firejail" | ||
35 | } | ||
36 | expect { | ||
37 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
38 | ":/bin/bash" | ||
39 | } | ||
40 | expect { | ||
41 | timeout {puts "TESTING ERROR 4\n";exit} | ||
42 | ":firejail" | ||
43 | } | ||
44 | expect { | ||
45 | timeout {puts "TESTING ERROR 4.1\n";exit} | ||
46 | ":/bin/bash" | ||
47 | } | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 5\n";exit} | ||
50 | ":firejail" | ||
51 | } | ||
52 | expect { | ||
53 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
54 | ":/bin/bash" | ||
55 | } | ||
56 | after 100 | ||
57 | |||
58 | |||
59 | puts "\n" | ||
60 | |||
diff --git a/test/option_version.exp b/test/option_version.exp new file mode 100755 index 000000000..44c0c217f --- /dev/null +++ b/test/option_version.exp | |||
@@ -0,0 +1,15 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --version\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "firejail version " | ||
11 | } | ||
12 | after 100 | ||
13 | |||
14 | puts "\n" | ||
15 | |||
diff --git a/test/output.exp b/test/output.exp new file mode 100755 index 000000000..90a9d64b6 --- /dev/null +++ b/test/output.exp | |||
@@ -0,0 +1,66 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "rm -f logfile*\r" | ||
8 | sleep 1 | ||
9 | puts "\n" | ||
10 | |||
11 | send -- "firejail --output=logfile -- ./output.sh\r" | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 1\n";exit} | ||
14 | "20000" | ||
15 | } | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
18 | "60000" | ||
19 | } | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 1.2\n";exit} | ||
22 | "100000" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 1.3\n";exit} | ||
26 | "120000" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 1.4\n";exit} | ||
30 | "14999" | ||
31 | } | ||
32 | sleep 2 | ||
33 | puts "\n" | ||
34 | |||
35 | |||
36 | set timeout 2 | ||
37 | send -- "ls -al logfile*\r" | ||
38 | expect { | ||
39 | timeout {puts "TESTING ERROR 2\n";exit} | ||
40 | "logfile" | ||
41 | } | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 3\n";exit} | ||
44 | "logfile.1" | ||
45 | } | ||
46 | expect { | ||
47 | timeout {puts "TESTING ERROR 4\n";exit} | ||
48 | "logfile.2" | ||
49 | } | ||
50 | expect { | ||
51 | timeout {puts "TESTING ERROR 5\n";exit} | ||
52 | "logfile.3" | ||
53 | } | ||
54 | expect { | ||
55 | timeout {puts "TESTING ERROR 6\n";exit} | ||
56 | "logfile.4" | ||
57 | } | ||
58 | expect { | ||
59 | timeout {puts "TESTING ERROR 7\n";exit} | ||
60 | "logfile.5" | ||
61 | } | ||
62 | sleep 1 | ||
63 | send -- "rm -f logfile*\r" | ||
64 | sleep 1 | ||
65 | |||
66 | puts "\n" | ||
diff --git a/test/output.sh b/test/output.sh new file mode 100755 index 000000000..2be188e3a --- /dev/null +++ b/test/output.sh | |||
@@ -0,0 +1,9 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | i="0" | ||
4 | |||
5 | while [ $i -lt 150000 ] | ||
6 | do | ||
7 | echo message number $i | ||
8 | i=$[$i+1] | ||
9 | done | ||
diff --git a/test/pid.exp b/test/pid.exp new file mode 100755 index 000000000..0baf3af0e --- /dev/null +++ b/test/pid.exp | |||
@@ -0,0 +1,48 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | # test processes | ||
15 | send -- "bash\r" | ||
16 | sleep 1 | ||
17 | send -- "ps aux; pwd\r" | ||
18 | expect { | ||
19 | timeout {puts "TESTING ERROR 1\n";exit} | ||
20 | "/bin/bash" | ||
21 | } | ||
22 | expect { | ||
23 | timeout {puts "TESTING ERROR 2\n";exit} | ||
24 | "bash" | ||
25 | } | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 3\n";exit} | ||
28 | "ps aux" | ||
29 | } | ||
30 | expect { | ||
31 | timeout {puts "TESTING ERROR 4\n";exit} | ||
32 | "home" | ||
33 | } | ||
34 | sleep 1 | ||
35 | |||
36 | |||
37 | send -- "ps aux |wc -l; pwd\r" | ||
38 | expect { | ||
39 | timeout {puts "TESTING ERROR 5\n";exit} | ||
40 | "5" | ||
41 | } | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 6\n";exit} | ||
44 | "home" | ||
45 | } | ||
46 | sleep 1 | ||
47 | |||
48 | puts "\n" | ||
diff --git a/test/private-keep.exp b/test/private-keep.exp new file mode 100755 index 000000000..cdae12ac3 --- /dev/null +++ b/test/private-keep.exp | |||
@@ -0,0 +1,66 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --private.keep=.mozilla,.config/firejail\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "ls -al\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
17 | ".config" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 0.2\n";exit} | ||
21 | ".mozilla" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | send -- "find .config\r" | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 0.3\n";exit} | ||
28 | ".config" | ||
29 | } | ||
30 | expect { | ||
31 | timeout {puts "TESTING ERROR 0.4\n";exit} | ||
32 | ".config/firejail" | ||
33 | } | ||
34 | sleep 1 | ||
35 | puts "\n" | ||
36 | send -- "exit\r" | ||
37 | sleep 2 | ||
38 | |||
39 | |||
40 | send -- "firejail --profile=private-keep.profile\r" | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 1.0\n";exit} | ||
43 | "Child process initialized" | ||
44 | } | ||
45 | sleep 1 | ||
46 | |||
47 | send -- "ls -al\r" | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
50 | ".config" | ||
51 | } | ||
52 | expect { | ||
53 | timeout {puts "TESTING ERROR 1.2\n";exit} | ||
54 | ".mozilla" | ||
55 | } | ||
56 | sleep 1 | ||
57 | |||
58 | send -- "find .config\r" | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 1.3\n";exit} | ||
61 | ".config" | ||
62 | } | ||
63 | expect { | ||
64 | timeout {puts "TESTING ERROR 1.4\n";exit} | ||
65 | ".config/firejail" | ||
66 | } | ||
diff --git a/test/private-keep.profile b/test/private-keep.profile new file mode 100644 index 000000000..7f842cc04 --- /dev/null +++ b/test/private-keep.profile | |||
@@ -0,0 +1 @@ | |||
private.keep .mozilla,.config/firejail | |||
diff --git a/test/private.exp b/test/private.exp new file mode 100755 index 000000000..e2ae80b33 --- /dev/null +++ b/test/private.exp | |||
@@ -0,0 +1,95 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | if { $argc != 1 } { | ||
8 | puts "TESTING ERROR: argument missing" | ||
9 | puts "Usage: private.exp username" | ||
10 | puts "where username is the name of the current user" | ||
11 | exit | ||
12 | } | ||
13 | |||
14 | # testing profile and private | ||
15 | send -- "firejail --private --profile=/etc/firejail/firefox.profile\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 0\n";exit} | ||
18 | "Child process initialized" | ||
19 | } | ||
20 | sleep 1 | ||
21 | send -- "exit\r" | ||
22 | sleep 1 | ||
23 | |||
24 | send -- "firejail --private\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 0\n";exit} | ||
27 | "Child process initialized" | ||
28 | } | ||
29 | |||
30 | sleep 1 | ||
31 | send -- "ls -al; pwd\r" | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
34 | ".bashrc" | ||
35 | } | ||
36 | expect { | ||
37 | timeout {puts "TESTING ERROR 0.2\n";exit} | ||
38 | [lindex $argv 0] | ||
39 | } | ||
40 | send -- "ls -al; pwd\r" | ||
41 | expect { | ||
42 | timeout { | ||
43 | # OpenSUSE doesn't use .Xauthority from user home directory | ||
44 | send -- "env | grep XAUTHORITY\r" | ||
45 | |||
46 | expect { | ||
47 | timeout {puts "TESTING ERROR 0.3\n";exit} | ||
48 | "/run/lightdm/netblue/xauthority" | ||
49 | } | ||
50 | } | ||
51 | ".Xauthority" | ||
52 | } | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 0.4\n";exit} | ||
55 | [lindex $argv 0] | ||
56 | } | ||
57 | |||
58 | |||
59 | # testing private only | ||
60 | send -- "bash\r" | ||
61 | sleep 1 | ||
62 | # owner /home/netblue | ||
63 | send -- "ls -l /home;pwd\r" | ||
64 | expect { | ||
65 | timeout {puts "TESTING ERROR 1\n";exit} | ||
66 | [lindex $argv 0] | ||
67 | } | ||
68 | expect { | ||
69 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
70 | [lindex $argv 0] | ||
71 | } | ||
72 | expect { | ||
73 | timeout {puts "TESTING ERROR 1.2\n";exit} | ||
74 | [lindex $argv 0] | ||
75 | } | ||
76 | expect { | ||
77 | timeout {puts "TESTING ERROR 1.3\n";exit} | ||
78 | "home" | ||
79 | } | ||
80 | sleep 1 | ||
81 | |||
82 | # owner /tmp | ||
83 | send -- "stat -c %U%a /tmp;pwd\r" | ||
84 | expect { | ||
85 | timeout {puts "TESTING ERROR 2\n";exit} | ||
86 | "root777" {puts "version 1\n";} | ||
87 | "root1777" {puts "version 2\n";} | ||
88 | } | ||
89 | expect { | ||
90 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
91 | "home" | ||
92 | } | ||
93 | sleep 1 | ||
94 | |||
95 | puts "\n" | ||
diff --git a/test/private.profile b/test/private.profile new file mode 100644 index 000000000..1b947b6f7 --- /dev/null +++ b/test/private.profile | |||
@@ -0,0 +1 @@ | |||
private ./dirprivate | |||
diff --git a/test/private_dir.exp b/test/private_dir.exp new file mode 100755 index 000000000..95f89362a --- /dev/null +++ b/test/private_dir.exp | |||
@@ -0,0 +1,53 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # testing private | ||
8 | send -- "firejail --private=./dirprivate\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Child process initialized" | ||
12 | } | ||
13 | sleep 1 | ||
14 | |||
15 | send -- "ls -al;pwd\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
18 | "bashrc" | ||
19 | } | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 0.2\n";exit} | ||
22 | "home" | ||
23 | } | ||
24 | send -- "ls -al;pwd\r" | ||
25 | expect { | ||
26 | timeout { | ||
27 | # OpenSUSE doesn't use .Xauthority from user home directory | ||
28 | send -- "env | grep XAUTHORITY\r" | ||
29 | |||
30 | expect { | ||
31 | timeout {puts "TESTING ERROR 0.3\n";exit} | ||
32 | "/run/lightdm/netblue/xauthority" | ||
33 | } | ||
34 | } | ||
35 | ".Xauthority" | ||
36 | } | ||
37 | expect { | ||
38 | timeout {puts "TESTING ERROR 0.4\n";exit} | ||
39 | [lindex $argv 0] | ||
40 | } | ||
41 | |||
42 | send -- "ls -al | wc -l;pwd\r" | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 1\n";exit} | ||
45 | "5" {puts "normal system\n";} | ||
46 | "4" {puts "OpenSUSE\n";} | ||
47 | } | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 2\n";exit} | ||
50 | "home" | ||
51 | } | ||
52 | |||
53 | puts "\n" | ||
diff --git a/test/private_dir_profile.exp b/test/private_dir_profile.exp new file mode 100755 index 000000000..e6c01798e --- /dev/null +++ b/test/private_dir_profile.exp | |||
@@ -0,0 +1,54 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # testing private | ||
8 | send -- "firejail --profile=private.profile\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Child process initialized" | ||
12 | } | ||
13 | sleep 1 | ||
14 | |||
15 | send -- "ls -al;pwd\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
18 | "bashrc" | ||
19 | } | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 0.2\n";exit} | ||
22 | "home" | ||
23 | } | ||
24 | send -- "ls -al;pwd\r" | ||
25 | expect { | ||
26 | timeout { | ||
27 | # OpenSUSE doesn't use .Xauthority from user home directory | ||
28 | send -- "env | grep XAUTHORITY\r" | ||
29 | |||
30 | expect { | ||
31 | timeout {puts "TESTING ERROR 0.3\n";exit} | ||
32 | "/run/lightdm/netblue/xauthority" | ||
33 | } | ||
34 | } | ||
35 | ".Xauthority" | ||
36 | } | ||
37 | expect { | ||
38 | timeout {puts "TESTING ERROR 0.4\n";exit} | ||
39 | [lindex $argv 0] | ||
40 | } | ||
41 | |||
42 | send -- "ls -al | wc -l;pwd\r" | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 1\n";exit} | ||
45 | "5" {puts "normal system\n";} | ||
46 | "4" {puts "OpenSUSE\n";} | ||
47 | } | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 2\n";exit} | ||
50 | "home" | ||
51 | } | ||
52 | |||
53 | puts "\n" | ||
54 | |||
diff --git a/test/profile_apps.exp b/test/profile_apps.exp new file mode 100755 index 000000000..c57b31489 --- /dev/null +++ b/test/profile_apps.exp | |||
@@ -0,0 +1,48 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | # firefox | ||
8 | send -- "firejail --profile=/etc/firejail/firefox.profile\r" | ||
9 | expect { | ||
10 | timeout {puts "TESTING ERROR 0\n";exit} | ||
11 | "Child process initialized" | ||
12 | } | ||
13 | sleep 1 | ||
14 | send -- "exit\r" | ||
15 | sleep 1 | ||
16 | |||
17 | # iceweasel | ||
18 | send -- "firejail --profile=/etc/firejail/iceweasel.profile\r" | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 1\n";exit} | ||
21 | "Child process initialized" | ||
22 | } | ||
23 | sleep 1 | ||
24 | send -- "exit\r" | ||
25 | sleep 1 | ||
26 | |||
27 | # evince | ||
28 | send -- "firejail --profile=/etc/firejail/evince.profile\r" | ||
29 | expect { | ||
30 | timeout {puts "TESTING ERROR 2\n";exit} | ||
31 | "Child process initialized" | ||
32 | } | ||
33 | sleep 1 | ||
34 | send -- "exit\r" | ||
35 | sleep 1 | ||
36 | |||
37 | # midori | ||
38 | send -- "firejail --profile=/etc/firejail/midori.profile\r" | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 3\n";exit} | ||
41 | "Child process initialized" | ||
42 | } | ||
43 | sleep 1 | ||
44 | send -- "exit\r" | ||
45 | sleep 1 | ||
46 | |||
47 | |||
48 | puts "\n" | ||
diff --git a/test/profile_followlnk.exp b/test/profile_followlnk.exp new file mode 100755 index 000000000..e2ede2865 --- /dev/null +++ b/test/profile_followlnk.exp | |||
@@ -0,0 +1,68 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "mkdir /tmp/firejailtestdir\r" | ||
8 | sleep 1 | ||
9 | send -- "ln -s /tmp/firejailtestdir /tmp/firejailtestdirlnk\r" | ||
10 | sleep 1 | ||
11 | send -- "touch /tmp/firejailtestfile\r" | ||
12 | sleep 1 | ||
13 | send -- "ln -s /tmp/firejailtestfile /tmp/firejailtestfilelnk\r" | ||
14 | sleep 1 | ||
15 | |||
16 | send -- "firejail --profile=readonly-lnk.profile --debug\r" | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 0\n";exit} | ||
19 | "Child process initialized" | ||
20 | } | ||
21 | |||
22 | # testing private only | ||
23 | send -- "bash\r" | ||
24 | sleep 1 | ||
25 | |||
26 | |||
27 | send -- "ls > /tmp/firejailtestdirlnk/ttt;pwd\r" | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 1\n";exit} | ||
30 | "Read-only file system" | ||
31 | } | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
34 | "home" | ||
35 | } | ||
36 | sleep 1 | ||
37 | |||
38 | send -- "ls > /tmp/firejailtestfilelnk;pwd\r" | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 2\n";exit} | ||
41 | "Read-only file system" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
45 | "home" | ||
46 | } | ||
47 | sleep 1 | ||
48 | |||
49 | send -- "exit\r" | ||
50 | sleep 1 | ||
51 | send -- "pwd\r" | ||
52 | expect { | ||
53 | timeout {puts "TESTING ERROR 3\n";exit} | ||
54 | "home" | ||
55 | } | ||
56 | sleep 1 | ||
57 | send -- "exit\r" | ||
58 | sleep 1 | ||
59 | send -- "pwd\r" | ||
60 | expect { | ||
61 | timeout {puts "TESTING ERROR 4\n";exit} | ||
62 | "home" | ||
63 | } | ||
64 | sleep 2 | ||
65 | send -- "rm -fr /tmp/firejailtest*\r" | ||
66 | sleep 1 | ||
67 | |||
68 | puts "\n" | ||
diff --git a/test/profile_noperm.exp b/test/profile_noperm.exp new file mode 100755 index 000000000..b3ed558bc --- /dev/null +++ b/test/profile_noperm.exp | |||
@@ -0,0 +1,13 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --profile=/etc/shadow\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "cannot access profile" | ||
11 | } | ||
12 | sleep 1 | ||
13 | puts "\n" | ||
diff --git a/test/profile_readonly.exp b/test/profile_readonly.exp new file mode 100755 index 000000000..046b0d738 --- /dev/null +++ b/test/profile_readonly.exp | |||
@@ -0,0 +1,64 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "mkdir /tmp/firejailtestdir\r" | ||
8 | sleep 1 | ||
9 | send -- "touch /tmp/firejailtestfile\r" | ||
10 | sleep 1 | ||
11 | |||
12 | send -- "firejail --profile=readonly.profile\r" | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 0\n";exit} | ||
15 | "Child process initialized" | ||
16 | } | ||
17 | |||
18 | # testing private only | ||
19 | send -- "bash\r" | ||
20 | sleep 1 | ||
21 | |||
22 | |||
23 | send -- "ls > /tmp/firejailtestdir/ttt;pwd\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 1\n";exit} | ||
26 | "Read-only file system" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
30 | "home" | ||
31 | } | ||
32 | sleep 1 | ||
33 | |||
34 | send -- "ls > /tmp/firejailtestfile;pwd\r" | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 2\n";exit} | ||
37 | "Read-only file system" | ||
38 | } | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
41 | "home" | ||
42 | } | ||
43 | sleep 1 | ||
44 | |||
45 | send -- "exit\r" | ||
46 | sleep 1 | ||
47 | send -- "pwd\r" | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 3\n";exit} | ||
50 | "home" | ||
51 | } | ||
52 | sleep 1 | ||
53 | send -- "exit\r" | ||
54 | sleep 1 | ||
55 | send -- "pwd\r" | ||
56 | expect { | ||
57 | timeout {puts "TESTING ERROR 4\n";exit} | ||
58 | "home" | ||
59 | } | ||
60 | sleep 2 | ||
61 | send -- "rm -fr /tmp/firejailtest*\r" | ||
62 | sleep 1 | ||
63 | |||
64 | puts "\n" | ||
diff --git a/test/profile_rlimit.exp b/test/profile_rlimit.exp new file mode 100755 index 000000000..7d2637444 --- /dev/null +++ b/test/profile_rlimit.exp | |||
@@ -0,0 +1,36 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --profile=rlimit.profile\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "cat /proc/self/limits; pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
17 | "Max file size 1024 1024" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 1.2\n";exit} | ||
21 | "Max processes 1000 1000" | ||
22 | } | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 1.3\n";exit} | ||
25 | "Max open files 500 500" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 1.4\n";exit} | ||
29 | "Max pending signals 200 200" | ||
30 | } | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 1.5\n";exit} | ||
33 | "home" | ||
34 | } | ||
35 | sleep 1 | ||
36 | puts "\n" | ||
diff --git a/test/profile_syntax.exp b/test/profile_syntax.exp new file mode 100755 index 000000000..3218177c3 --- /dev/null +++ b/test/profile_syntax.exp | |||
@@ -0,0 +1,69 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --profile=test.profile\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | |||
13 | sleep 2 | ||
14 | send -- "ls /sbin\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "cannot open" | ||
18 | } | ||
19 | |||
20 | sleep 1 | ||
21 | send -- "ls /usr/sbin\r" | ||
22 | expect { | ||
23 | timeout {puts "TESTING ERROR 2\n";exit} | ||
24 | "cannot open" | ||
25 | } | ||
26 | |||
27 | sleep 1 | ||
28 | send -- "ls -l /etc/shadow\r" | ||
29 | expect { | ||
30 | timeout {puts "TESTING ERROR 3\n";exit} | ||
31 | "root root 0" | ||
32 | } | ||
33 | |||
34 | sleep 1 | ||
35 | send -- "rmdir;pwd\r" | ||
36 | expect { | ||
37 | timeout {puts "TESTING ERROR 4\n";exit} | ||
38 | "Permission denied" | ||
39 | } | ||
40 | expect { | ||
41 | timeout {puts "TESTING ERROR 5\n";exit} | ||
42 | "home" | ||
43 | } | ||
44 | |||
45 | sleep 1 | ||
46 | send -- "mount;pwd\r" | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 6\n";exit} | ||
49 | "Permission denied" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 7\n";exit} | ||
53 | "home" | ||
54 | } | ||
55 | |||
56 | sleep 1 | ||
57 | send -- "umount;pwd\r" | ||
58 | expect { | ||
59 | timeout {puts "TESTING ERROR 8\n";exit} | ||
60 | "Permission denied" | ||
61 | } | ||
62 | expect { | ||
63 | timeout {puts "TESTING ERROR 9\n";exit} | ||
64 | "home" | ||
65 | } | ||
66 | send -- "exit\r" | ||
67 | |||
68 | sleep 1 | ||
69 | puts "\n" | ||
diff --git a/test/profile_syntax2.exp b/test/profile_syntax2.exp new file mode 100755 index 000000000..cd514aa0e --- /dev/null +++ b/test/profile_syntax2.exp | |||
@@ -0,0 +1,47 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --debug --profile=test2.profile\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Reading profile test2.profile" | ||
11 | } | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 1\n";exit} | ||
14 | "Reading profile test.profile" | ||
15 | } | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 2\n";exit} | ||
18 | "Disable /bin/rmdir" {puts "Most Linux platforms\n"} | ||
19 | "Disable /usr/bin/rmdir" { puts "OpenSUSE platform\n"} | ||
20 | } | ||
21 | expect { | ||
22 | timeout {puts "TESTING ERROR 3\n";exit} | ||
23 | "Mounting a new /home directory" | ||
24 | } | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 4\n";exit} | ||
27 | "Drop CAP_SYS_MODULE" | ||
28 | } | ||
29 | expect { | ||
30 | timeout {puts "TESTING ERROR 5\n";exit} | ||
31 | "Initialize seccomp filter" | ||
32 | } | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 6\n";exit} | ||
35 | "Blacklisting syscall" | ||
36 | } | ||
37 | expect { | ||
38 | timeout {puts "TESTING ERROR 7\n";exit} | ||
39 | "mount" | ||
40 | } | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 8\n";exit} | ||
43 | "Child process initialized" | ||
44 | } | ||
45 | |||
46 | sleep 1 | ||
47 | puts "\n" | ||
diff --git a/test/profile_tmpfs.exp b/test/profile_tmpfs.exp new file mode 100755 index 000000000..a2faa32f7 --- /dev/null +++ b/test/profile_tmpfs.exp | |||
@@ -0,0 +1,37 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "mkdir /tmp/firejailtestdir\r" | ||
8 | sleep 1 | ||
9 | send -- "ls > /tmp/firejailtestdir/tmpfile\r" | ||
10 | sleep 1 | ||
11 | |||
12 | send -- "firejail --profile=tmpfs.profile\r" | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 0\n";exit} | ||
15 | "Child process initialized" | ||
16 | } | ||
17 | |||
18 | # testing private only | ||
19 | send -- "bash\r" | ||
20 | sleep 1 | ||
21 | |||
22 | send -- "ls -l /tmp/firejailtestdir;pwd\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
25 | "tmpfile" {puts "TESTING ERROR 1\n";exit} | ||
26 | "home" | ||
27 | } | ||
28 | sleep 1 | ||
29 | send -- "exit\r" | ||
30 | sleep 1 | ||
31 | send -- "exit\r" | ||
32 | sleep 1 | ||
33 | send -- "rm -fr /tmp/firejailtestdir\r" | ||
34 | |||
35 | sleep 1 | ||
36 | |||
37 | puts "\n" | ||
diff --git a/test/readonly-lnk.profile b/test/readonly-lnk.profile new file mode 100644 index 000000000..71ffb1a26 --- /dev/null +++ b/test/readonly-lnk.profile | |||
@@ -0,0 +1,2 @@ | |||
1 | read-only /tmp/firejailtestdirlnk | ||
2 | read-only /tmp/firejailtestfilelnk | ||
diff --git a/test/readonly.profile b/test/readonly.profile new file mode 100644 index 000000000..55d89e3d7 --- /dev/null +++ b/test/readonly.profile | |||
@@ -0,0 +1,2 @@ | |||
1 | read-only /tmp/firejailtestdir | ||
2 | read-only /tmp/firejailtestfile \ No newline at end of file | ||
diff --git a/test/rlimit.profile b/test/rlimit.profile new file mode 100644 index 000000000..271891c03 --- /dev/null +++ b/test/rlimit.profile | |||
@@ -0,0 +1,4 @@ | |||
1 | rlimit-fsize 1024 | ||
2 | rlimit-nproc 1000 | ||
3 | rlimit-nofile 500 | ||
4 | rlimit-sigpending 200 \ No newline at end of file | ||
diff --git a/test/seccomp-bad-empty.exp b/test/seccomp-bad-empty.exp new file mode 100755 index 000000000..53b5c2e21 --- /dev/null +++ b/test/seccomp-bad-empty.exp | |||
@@ -0,0 +1,38 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --seccomp=\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Error: empty syscall lists are not allowed" | ||
11 | } | ||
12 | |||
13 | send -- "firejail --seccomp.drop=\r" | ||
14 | expect { | ||
15 | timeout {puts "TESTING ERROR 2\n";exit} | ||
16 | "Error: empty syscall lists are not allowed" | ||
17 | } | ||
18 | |||
19 | send -- "firejail --seccomp.keep=\r" | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 4\n";exit} | ||
22 | "Error: empty syscall lists are not allowed" | ||
23 | } | ||
24 | |||
25 | send -- "firejail --profile=seccomp-bad-empty.profile\r" | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 6\n";exit} | ||
28 | "Error: line 1 in the custom profile is invalid" | ||
29 | } | ||
30 | |||
31 | send -- "firejail --profile=seccomp-bad-empty2.profile\r" | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 7\n";exit} | ||
34 | "Error: line 1 in the custom profile is invalid" | ||
35 | } | ||
36 | sleep 1 | ||
37 | puts "\n" | ||
38 | |||
diff --git a/test/seccomp-bad-empty.profile b/test/seccomp-bad-empty.profile new file mode 100644 index 000000000..2d4fcde7c --- /dev/null +++ b/test/seccomp-bad-empty.profile | |||
@@ -0,0 +1 @@ | |||
seccomp.drop | |||
diff --git a/test/seccomp-bad-empty2.profile b/test/seccomp-bad-empty2.profile new file mode 100644 index 000000000..c4e6c9f74 --- /dev/null +++ b/test/seccomp-bad-empty2.profile | |||
@@ -0,0 +1 @@ | |||
seccomp.keep | |||
diff --git a/test/seccomp-chmod-profile.exp b/test/seccomp-chmod-profile.exp new file mode 100755 index 000000000..098328cea --- /dev/null +++ b/test/seccomp-chmod-profile.exp | |||
@@ -0,0 +1,46 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --profile=seccomp.profile --private\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 2 | ||
13 | |||
14 | send -- "touch testfile;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "/root" {puts "running as root"} | ||
18 | "/home" | ||
19 | } | ||
20 | |||
21 | send -- "ls -l testfile;pwd\r" | ||
22 | expect { | ||
23 | timeout {puts "TESTING ERROR 2\n";exit} | ||
24 | "testfile" | ||
25 | } | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 3\n";exit} | ||
28 | "/root" {puts "running as root"} | ||
29 | "/home" | ||
30 | } | ||
31 | |||
32 | send -- "chmod +x testfile;pwd\r" | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 2\n";exit} | ||
35 | "Bad system call" | ||
36 | } | ||
37 | expect { | ||
38 | timeout {puts "TESTING ERROR 3\n";exit} | ||
39 | "/root" {puts "running as root"} | ||
40 | "/home" | ||
41 | } | ||
42 | |||
43 | |||
44 | send -- "exit\r" | ||
45 | sleep 1 | ||
46 | puts "\n" | ||
diff --git a/test/seccomp-chmod.exp b/test/seccomp-chmod.exp new file mode 100755 index 000000000..b4a213206 --- /dev/null +++ b/test/seccomp-chmod.exp | |||
@@ -0,0 +1,46 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --seccomp=chmod,fchmod,fchmodat --private\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 2 | ||
13 | |||
14 | send -- "touch testfile;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "/root" {puts "running as root"} | ||
18 | "/home" | ||
19 | } | ||
20 | |||
21 | send -- "ls -l testfile;pwd\r" | ||
22 | expect { | ||
23 | timeout {puts "TESTING ERROR 2\n";exit} | ||
24 | "testfile" | ||
25 | } | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 3\n";exit} | ||
28 | "/root" {puts "running as root"} | ||
29 | "/home" | ||
30 | } | ||
31 | |||
32 | send -- "chmod +x testfile;pwd\r" | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 2\n";exit} | ||
35 | "Bad system call" | ||
36 | } | ||
37 | expect { | ||
38 | timeout {puts "TESTING ERROR 3\n";exit} | ||
39 | "/root" {puts "running as root"} | ||
40 | "/home" | ||
41 | } | ||
42 | |||
43 | |||
44 | send -- "exit\r" | ||
45 | sleep 1 | ||
46 | puts "\n" | ||
diff --git a/test/seccomp-chown.exp b/test/seccomp-chown.exp new file mode 100755 index 000000000..69b896700 --- /dev/null +++ b/test/seccomp-chown.exp | |||
@@ -0,0 +1,46 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --seccomp=chown,fchown,fchownat,lchown --private\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 2 | ||
13 | |||
14 | send -- "touch testfile;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "/root" {puts "running as root"} | ||
18 | "/home" | ||
19 | } | ||
20 | |||
21 | send -- "ls -l testfile;pwd\r" | ||
22 | expect { | ||
23 | timeout {puts "TESTING ERROR 2\n";exit} | ||
24 | "testfile" | ||
25 | } | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 3\n";exit} | ||
28 | "/root" {puts "running as root"} | ||
29 | "/home" | ||
30 | } | ||
31 | |||
32 | send -- "chown netblue:netblue testfile;pwd\r" | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 2\n";exit} | ||
35 | "Bad system call" | ||
36 | } | ||
37 | expect { | ||
38 | timeout {puts "TESTING ERROR 3\n";exit} | ||
39 | "/root" {puts "running as root"} | ||
40 | "/home" | ||
41 | } | ||
42 | |||
43 | |||
44 | send -- "exit\r" | ||
45 | sleep 1 | ||
46 | puts "\n" | ||
diff --git a/test/seccomp-debug.exp b/test/seccomp-debug.exp new file mode 100755 index 000000000..a7b89912a --- /dev/null +++ b/test/seccomp-debug.exp | |||
@@ -0,0 +1,32 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --seccomp --debug\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Blacklisting syscall" | ||
11 | } | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 1\n";exit} | ||
14 | "open_by_handle_at" | ||
15 | } | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 2\n";exit} | ||
18 | "BLACKLIST" | ||
19 | } | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 3\n";exit} | ||
22 | "open_by_handle_at" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 4\n";exit} | ||
26 | "Child process initialized" | ||
27 | } | ||
28 | sleep 2 | ||
29 | |||
30 | send -- "exit\r" | ||
31 | sleep 1 | ||
32 | puts "\n" | ||
diff --git a/test/seccomp-empty.exp b/test/seccomp-empty.exp new file mode 100755 index 000000000..11abf2e00 --- /dev/null +++ b/test/seccomp-empty.exp | |||
@@ -0,0 +1,145 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --debug --seccomp=chmod,fchmod,fchmodat --private\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "VALIDATE_ARCHITECTURE" | ||
11 | } | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
14 | "mount" | ||
15 | } | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 0.2\n";exit} | ||
18 | "ptrace" | ||
19 | } | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 0.3\n";exit} | ||
22 | "chmod" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 0.4\n";exit} | ||
26 | "fchmod" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 0.5\n";exit} | ||
30 | "fchmodat" | ||
31 | } | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 0.6\n";exit} | ||
34 | "RETURN_ALLOW" | ||
35 | } | ||
36 | expect { | ||
37 | timeout {puts "TESTING ERROR 0.7\n";exit} | ||
38 | "Child process initialized" | ||
39 | } | ||
40 | sleep 2 | ||
41 | send -- "exit\r" | ||
42 | sleep 3 | ||
43 | puts "\n" | ||
44 | |||
45 | send -- "firejail --debug --seccomp.drop=chmod,fchmod,fchmodat --private\r" | ||
46 | expect { | ||
47 | timeout {puts "TESTING ERROR 1\n";exit} | ||
48 | "VALIDATE_ARCHITECTURE" | ||
49 | } | ||
50 | expect { | ||
51 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
52 | "mount" {puts "TESTING ERROR 1.2\n";exit} | ||
53 | "ptrace" {puts "TESTING ERROR 1.3\n";exit} | ||
54 | "chmod" | ||
55 | } | ||
56 | expect { | ||
57 | timeout {puts "TESTING ERROR 1.4\n";exit} | ||
58 | "fchmod" | ||
59 | } | ||
60 | expect { | ||
61 | timeout {puts "TESTING ERROR 1.5\n";exit} | ||
62 | "fchmodat" | ||
63 | } | ||
64 | expect { | ||
65 | timeout {puts "TESTING ERROR 1.6\n";exit} | ||
66 | "RETURN_ALLOW" | ||
67 | } | ||
68 | expect { | ||
69 | timeout {puts "TESTING ERROR 1.7\n";exit} | ||
70 | "Child process initialized" | ||
71 | } | ||
72 | sleep 2 | ||
73 | send -- "exit\r" | ||
74 | puts "\n" | ||
75 | |||
76 | sleep 2 | ||
77 | send -- "firejail --debug --profile=seccomp.profile --private\r" | ||
78 | expect { | ||
79 | timeout {puts "TESTING ERROR 2\n";exit} | ||
80 | "VALIDATE_ARCHITECTURE" | ||
81 | } | ||
82 | expect { | ||
83 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
84 | "mount" | ||
85 | } | ||
86 | expect { | ||
87 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
88 | "ptrace" | ||
89 | } | ||
90 | expect { | ||
91 | timeout {puts "TESTING ERROR 2.3\n";exit} | ||
92 | "chmod" | ||
93 | } | ||
94 | expect { | ||
95 | timeout {puts "TESTING ERROR 2.4\n";exit} | ||
96 | "fchmod" | ||
97 | } | ||
98 | expect { | ||
99 | timeout {puts "TESTING ERROR 2.5\n";exit} | ||
100 | "fchmodat" | ||
101 | } | ||
102 | expect { | ||
103 | timeout {puts "TESTING ERROR 2.6\n";exit} | ||
104 | "RETURN_ALLOW" | ||
105 | } | ||
106 | expect { | ||
107 | timeout {puts "TESTING ERROR 2.7\n";exit} | ||
108 | "Child process initialized" | ||
109 | } | ||
110 | sleep 2 | ||
111 | send -- "exit\r" | ||
112 | sleep 3 | ||
113 | puts "\n" | ||
114 | |||
115 | send -- "firejail --debug --profile=seccomp-empty.profile --private\r" | ||
116 | expect { | ||
117 | timeout {puts "TESTING ERROR 3\n";exit} | ||
118 | "VALIDATE_ARCHITECTURE" | ||
119 | } | ||
120 | expect { | ||
121 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
122 | "mount" {puts "TESTING ERROR 3.2\n";exit} | ||
123 | "ptrace" {puts "TESTING ERROR 3.3\n";exit} | ||
124 | "chmod" | ||
125 | } | ||
126 | expect { | ||
127 | timeout {puts "TESTING ERROR 3.4\n";exit} | ||
128 | "fchmod" | ||
129 | } | ||
130 | expect { | ||
131 | timeout {puts "TESTING ERROR 3.5\n";exit} | ||
132 | "fchmodat" | ||
133 | } | ||
134 | expect { | ||
135 | timeout {puts "TESTING ERROR 3.6\n";exit} | ||
136 | "RETURN_ALLOW" | ||
137 | } | ||
138 | expect { | ||
139 | timeout {puts "TESTING ERROR 3.7\n";exit} | ||
140 | "Child process initialized" | ||
141 | } | ||
142 | sleep 2 | ||
143 | send -- "exit\r" | ||
144 | puts "\n" | ||
145 | |||
diff --git a/test/seccomp-empty.profile b/test/seccomp-empty.profile new file mode 100644 index 000000000..8f71f55a5 --- /dev/null +++ b/test/seccomp-empty.profile | |||
@@ -0,0 +1 @@ | |||
seccomp.drop chmod,fchmod,fchmodat | |||
diff --git a/test/seccomp-ptrace.exp b/test/seccomp-ptrace.exp new file mode 100755 index 000000000..c5411c249 --- /dev/null +++ b/test/seccomp-ptrace.exp | |||
@@ -0,0 +1,23 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --seccomp\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 2 | ||
13 | |||
14 | send -- "strace ls\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Bad system call" {puts "version 1\n";} | ||
18 | " unexpected signal 31" {puts "version 2\n"} | ||
19 | } | ||
20 | |||
21 | send -- "exit\r" | ||
22 | sleep 1 | ||
23 | puts "\n" | ||
diff --git a/test/seccomp-su.exp b/test/seccomp-su.exp new file mode 100755 index 000000000..dca6f15ee --- /dev/null +++ b/test/seccomp-su.exp | |||
@@ -0,0 +1,34 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --seccomp\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 2 | ||
13 | |||
14 | send -- "sudo su -\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "effective uid is not 0" | ||
18 | } | ||
19 | |||
20 | send -- "sudo ls\r" | ||
21 | expect { | ||
22 | timeout {puts "TESTING ERROR 2\n";exit} | ||
23 | "effective uid is not 0" | ||
24 | } | ||
25 | |||
26 | send -- "ping google.com\r" | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 2\n";exit} | ||
29 | "Operation not permitted" | ||
30 | } | ||
31 | |||
32 | send -- "exit\r" | ||
33 | sleep 1 | ||
34 | puts "\n" | ||
diff --git a/test/seccomp-umount.exp b/test/seccomp-umount.exp new file mode 100755 index 000000000..e037d3264 --- /dev/null +++ b/test/seccomp-umount.exp | |||
@@ -0,0 +1,28 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "sudo ls; sudo whoami; sudo pwd\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR: you need to root run this test as root\n";exit} | ||
10 | "root" | ||
11 | } | ||
12 | |||
13 | send -- "firejail --net=br0 --ip=10.10.20.5 --seccomp\r" | ||
14 | expect { | ||
15 | timeout {puts "TESTING ERROR 0\n";exit} | ||
16 | "Child process initialized" | ||
17 | } | ||
18 | sleep 2 | ||
19 | |||
20 | send -- "umount /proc\r" | ||
21 | expect { | ||
22 | timeout {puts "TESTING ERROR 1\n";exit} | ||
23 | "Bad system call" | ||
24 | } | ||
25 | |||
26 | send -- "exit\r" | ||
27 | sleep 1 | ||
28 | puts "\n" | ||
diff --git a/test/seccomp.profile b/test/seccomp.profile new file mode 100644 index 000000000..cb0b15aee --- /dev/null +++ b/test/seccomp.profile | |||
@@ -0,0 +1 @@ | |||
seccomp chmod,fchmod,fchmodat | |||
diff --git a/test/servers.exp b/test/servers.exp new file mode 100755 index 000000000..a36814a69 --- /dev/null +++ b/test/servers.exp | |||
@@ -0,0 +1,40 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "sudo ls; sudo whoami; sudo pwd\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR: you need to root run this test as root\n";exit} | ||
10 | "root" | ||
11 | } | ||
12 | |||
13 | send -- "firejail --net=br0 --ip=10.10.20.5 --seccomp\r" | ||
14 | expect { | ||
15 | timeout {puts "TESTING ERROR 0\n";exit} | ||
16 | "Child process initialized" | ||
17 | } | ||
18 | sleep 2 | ||
19 | |||
20 | |||
21 | send -- "/etc/init.d/rsyslog start;sleep 1;/etc/init.d/ssh start;sleep 1;/etc/init.d/nginx start\r" | ||
22 | sleep 3 | ||
23 | |||
24 | send -- "ps aux; pwd\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 1\n";exit} | ||
27 | "rsyslogd" | ||
28 | } | ||
29 | expect { | ||
30 | timeout {puts "TESTING ERROR 2\n";exit} | ||
31 | "sshd" | ||
32 | } | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 3\n";exit} | ||
35 | "nginx" | ||
36 | } | ||
37 | |||
38 | send -- "exit\r" | ||
39 | sleep 1 | ||
40 | puts "\n" | ||
diff --git a/test/servers2.exp b/test/servers2.exp new file mode 100755 index 000000000..28bcae207 --- /dev/null +++ b/test/servers2.exp | |||
@@ -0,0 +1,31 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "sudo ls; sudo whoami; sudo pwd\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR: you need to root run this test as root\n";exit} | ||
10 | "root" | ||
11 | } | ||
12 | |||
13 | send -- "firejail --net=br0 --ip=10.10.20.5--seccomp\r" | ||
14 | expect { | ||
15 | timeout {puts "TESTING ERROR 0\n";exit} | ||
16 | "Child process initialized" | ||
17 | } | ||
18 | sleep 2 | ||
19 | |||
20 | send -- "/etc/init.d/snmpd start" | ||
21 | sleep 2 | ||
22 | |||
23 | send -- "ps aux; pwd\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 1\n";exit} | ||
26 | "snmpd" | ||
27 | } | ||
28 | |||
29 | send -- "exit\r" | ||
30 | sleep 1 | ||
31 | puts "\n" | ||
diff --git a/test/servers3.exp b/test/servers3.exp new file mode 100755 index 000000000..f23ffba46 --- /dev/null +++ b/test/servers3.exp | |||
@@ -0,0 +1,31 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "sudo ls; sudo whoami; sudo pwd\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR: you need to root run this test as root\n";exit} | ||
10 | "root" | ||
11 | } | ||
12 | |||
13 | send -- "firejail --net=br0 --ip=10.10.20.5 --seccomp\r" | ||
14 | expect { | ||
15 | timeout {puts "TESTING ERROR 0\n";exit} | ||
16 | "Child process initialized" | ||
17 | } | ||
18 | sleep 2 | ||
19 | |||
20 | send -- "/etc/init.d/apache2 start\r" | ||
21 | sleep 2 | ||
22 | |||
23 | send -- "ps aux; pwd\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 1\n";exit} | ||
26 | "apache" | ||
27 | } | ||
28 | |||
29 | send -- "exit\r" | ||
30 | sleep 1 | ||
31 | puts "\n" | ||
diff --git a/test/servers4.exp b/test/servers4.exp new file mode 100755 index 000000000..9feeecf61 --- /dev/null +++ b/test/servers4.exp | |||
@@ -0,0 +1,32 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "sudo ls; sudo whoami; sudo pwd\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR: you need to root run this test as root\n";exit} | ||
10 | "root" | ||
11 | } | ||
12 | |||
13 | send -- "firejail --net=br0 --ip=10.10.20.5 --seccomp\r" | ||
14 | expect { | ||
15 | timeout {puts "TESTING ERROR 0\n";exit} | ||
16 | "Child process initialized" | ||
17 | } | ||
18 | sleep 2 | ||
19 | |||
20 | send -- "/etc/init.d/isc-dhcp-server start\r" | ||
21 | sleep 5 | ||
22 | |||
23 | |||
24 | send -- "ps aux; pwd\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 1\n";exit} | ||
27 | "dhcpd" | ||
28 | } | ||
29 | |||
30 | send -- "exit\r" | ||
31 | sleep 1 | ||
32 | puts "\n" | ||
diff --git a/test/shell_csh.exp b/test/shell_csh.exp new file mode 100755 index 000000000..8fa1ef166 --- /dev/null +++ b/test/shell_csh.exp | |||
@@ -0,0 +1,40 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --private --csh\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "ls -al;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | ".cshrc" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
21 | "home" | ||
22 | } | ||
23 | send -- "env | grep SHELL;pwd\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 2\n";exit} | ||
26 | "SHELL" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
30 | "/bin/csh" | ||
31 | } | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
34 | "home" | ||
35 | } | ||
36 | send -- "exit\r" | ||
37 | sleep 1 | ||
38 | |||
39 | puts "\n" | ||
40 | |||
diff --git a/test/shell_dash.exp b/test/shell_dash.exp new file mode 100755 index 000000000..298b65a0d --- /dev/null +++ b/test/shell_dash.exp | |||
@@ -0,0 +1,41 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --private --shell=/bin/dash\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | #send -- "ls -al;pwd\r" | ||
15 | #expect { | ||
16 | # timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | # ".zshrc" | ||
18 | #} | ||
19 | #expect { | ||
20 | # timeout {puts "TESTING ERROR 1.1\n";exit} | ||
21 | # "home" | ||
22 | #} | ||
23 | |||
24 | send -- "env | grep SHELL;pwd\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 2\n";exit} | ||
27 | "SHELL" | ||
28 | } | ||
29 | expect { | ||
30 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
31 | "/bin/dash" | ||
32 | } | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
35 | "home" | ||
36 | } | ||
37 | send -- "exit\r" | ||
38 | sleep 1 | ||
39 | |||
40 | puts "\n" | ||
41 | |||
diff --git a/test/shell_zsh.exp b/test/shell_zsh.exp new file mode 100755 index 000000000..79cd78a3e --- /dev/null +++ b/test/shell_zsh.exp | |||
@@ -0,0 +1,40 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --private --zsh\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "ls -al;pwd\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | ".zshrc" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 1.1\n";exit} | ||
21 | "home" | ||
22 | } | ||
23 | send -- "env | grep SHELL;pwd\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 2\n";exit} | ||
26 | "SHELL" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 2.1\n";exit} | ||
30 | "/usr/bin/zsh" | ||
31 | } | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 2.2\n";exit} | ||
34 | "home" | ||
35 | } | ||
36 | send -- "exit\r" | ||
37 | sleep 1 | ||
38 | |||
39 | puts "\n" | ||
40 | |||
diff --git a/test/sysrq-trigger.exp b/test/sysrq-trigger.exp new file mode 100755 index 000000000..18fb4a01a --- /dev/null +++ b/test/sysrq-trigger.exp | |||
@@ -0,0 +1,21 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 1 | ||
13 | |||
14 | send -- "echo b > /proc/sysrq-trigger\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Read-only file system" | ||
18 | } | ||
19 | sleep 1 | ||
20 | |||
21 | puts "\n" | ||
diff --git a/test/test-nonet.sh b/test/test-nonet.sh new file mode 100755 index 000000000..3df8b2d4e --- /dev/null +++ b/test/test-nonet.sh | |||
@@ -0,0 +1,44 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | echo "TESTING: version" | ||
4 | ./option_version.exp | ||
5 | |||
6 | echo "TESTING: help" | ||
7 | ./option_help.exp | ||
8 | |||
9 | echo "TESTING: man" | ||
10 | ./option_man.exp | ||
11 | |||
12 | echo "TESTING: list" | ||
13 | ./option_list.exp | ||
14 | |||
15 | echo "TESTING: PID" | ||
16 | ./pid.exp | ||
17 | |||
18 | echo "TESTING: profile no permissions" | ||
19 | ./profile_noperm.exp | ||
20 | |||
21 | echo "TESTING: profile syntax" | ||
22 | ./profile_syntax.exp | ||
23 | |||
24 | echo "TESTING: profile read-only" | ||
25 | ./profile_readonly.exp | ||
26 | |||
27 | echo "TESTING: profile tmpfs" | ||
28 | ./profile_tmpfs.exp | ||
29 | |||
30 | echo "TESTING: private" | ||
31 | ./private.exp `whoami` | ||
32 | |||
33 | echo "TESTING: read/write /var/tmp" | ||
34 | ./fs_var_tmp.exp | ||
35 | |||
36 | echo "TESTING: read/write /var/run" | ||
37 | ./fs_var_run.exp | ||
38 | |||
39 | echo "TESTING: read/write /var/lock" | ||
40 | ./fs_var_lock.exp | ||
41 | |||
42 | echo "TESTING: read/write /dev/shm" | ||
43 | ./fs_dev_shm.exp | ||
44 | |||
diff --git a/test/test-root.sh b/test/test-root.sh new file mode 100755 index 000000000..cd607b75b --- /dev/null +++ b/test/test-root.sh | |||
@@ -0,0 +1,56 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | ./chk_config.exp | ||
4 | |||
5 | echo "TESTING: servers rsyslogd, sshd, nginx" | ||
6 | ./servers.exp | ||
7 | |||
8 | if [ -f /etc/init.d/snmpd ] | ||
9 | then | ||
10 | echo "TESTING: servers snmpd" | ||
11 | ./servers2.exp | ||
12 | fi | ||
13 | |||
14 | if [ -f /etc/init.d/apache2 ] | ||
15 | then | ||
16 | echo "TESTING: servers apache2" | ||
17 | ./servers3.exp | ||
18 | fi | ||
19 | |||
20 | if [ -f /etc/init.d/isc-dhcp-server ] | ||
21 | then | ||
22 | echo "TESTING: servers isc dhcp server" | ||
23 | ./servers4.exp | ||
24 | fi | ||
25 | |||
26 | echo "TESTING: /proc/sysrq-trigger reset disabled" | ||
27 | ./sysrq-trigger.exp | ||
28 | |||
29 | echo "TESTING: seccomp umount" | ||
30 | ./seccomp-umount.exp | ||
31 | |||
32 | echo "TESTING: seccomp chmod (seccomp lists)" | ||
33 | ./seccomp-chmod.exp | ||
34 | |||
35 | echo "TESTING: seccomp chown (seccomp lists)" | ||
36 | ./seccomp-chown.exp | ||
37 | |||
38 | echo "TESTING: bind directory" | ||
39 | ./option_bind_directory.exp | ||
40 | |||
41 | echo "TESTING: bind file" | ||
42 | echo hello > tmpfile | ||
43 | ./option_bind_file.exp | ||
44 | rm -f tmpfile | ||
45 | |||
46 | echo "TESTING: chroot" | ||
47 | ./fs_chroot.exp | ||
48 | |||
49 | echo "TESTING: firemon --interface" | ||
50 | ./firemon-interface.exp | ||
51 | |||
52 | if [ -f /sys/fs/cgroup/g1/tasks ] | ||
53 | then | ||
54 | echo "TESTING: firemon --cgroup" | ||
55 | ./firemon-cgroup.exp | ||
56 | fi | ||
diff --git a/test/test.profile b/test/test.profile new file mode 100644 index 000000000..716419fd0 --- /dev/null +++ b/test/test.profile | |||
@@ -0,0 +1,6 @@ | |||
1 | blacklist /sbin | ||
2 | blacklist /usr/sbin | ||
3 | blacklist /etc/shadow | ||
4 | blacklist /bin/rmdir | ||
5 | blacklist ${PATH}/umount | ||
6 | blacklist ${PATH}/mount | ||
diff --git a/test/test.rv b/test/test.rv new file mode 100644 index 000000000..98a04fba2 --- /dev/null +++ b/test/test.rv | |||
@@ -0,0 +1,49 @@ | |||
1 | # run it as: | ||
2 | # ../src/tools/rvtest test.rv 2>/dev/null | grep TESTING | ||
3 | # | ||
4 | |||
5 | |||
6 | # invalid options | ||
7 | 1 firejail -blablabla | ||
8 | 1 firejail --blablabla | ||
9 | 1 firejail --debug --blablabla | ||
10 | |||
11 | # misc options | ||
12 | 0 firejail --help | ||
13 | 0 firejail --list | ||
14 | |||
15 | # network testing | ||
16 | 0 firejail --net=none exit | ||
17 | 1 firejail --ip=none --net=none exit # noip requires at least one network | ||
18 | 0 firejail --net=br0 exit | ||
19 | 1 firejail --net=none --net=br0 exit # --net and --net=none are mutually exclusive | ||
20 | 1 firejail --ip=none exit # noip requires at least one network | ||
21 | 1 firejail --defaultgw=10.10.20.1 # no bridge configured | ||
22 | 0 firejail --net=br0 --ip=10.10.20.6 exit | ||
23 | 1 firejail --net=br0 --ip=192.168.5.6 exit # interface range | ||
24 | 1 firejail --net=br0 --ip=10.10 # bad ip | ||
25 | 1 firejail --net=br0 --ip=asdf #bad ip | ||
26 | 1 firejail --ip=asdf # no bridge configured | ||
27 | 0 firejail --net=br0 --defaultgw=10.10.20.1 exit | ||
28 | 1 firejail --net=br0 --defaultgw=10.10.20 exit # invalid ip address | ||
29 | 1 firejail --net=br0 --defaultgw=asdf exit # invalid ip address | ||
30 | 0 firejail --net=br0 --ip=10.10.20.2 --defaultgw=10.10.20.1 exit | ||
31 | 0 firejail --net=br0 --net=br1 --net=br2 --net=br3 exit | ||
32 | 1 firejail --net | ||
33 | 1 firejail --net= | ||
34 | 1 firejail --net=bingo | ||
35 | 1 firejail --net=loopback | ||
36 | 1 firejail --net=lo #invalid network device | ||
37 | 1 firejail --net=/br0 exit | ||
38 | 1 firejail --net=br0 --net=br1 --net=br2 --net=br3 --net=br4 exit # only 4 networks allowed | ||
39 | 0 firejail --net=eth0 exit | ||
40 | 1 firejail --net=/dev/eth0 exit | ||
41 | 1 firejail --net=br0 --net=br1 --net=/dev/eth0 exit | ||
42 | 0 firejail --net=br0 --net=br0 exit # same device twice | ||
43 | 0 firejail --net=eth0 --net=br2 --net=br3 --net=eth0 exit # same device twice | ||
44 | 0 firejail --net=eth0 --net=br0 exit | ||
45 | |||
46 | # private mode | ||
47 | 0 firejail --private exit | ||
48 | 1 firejail --private=/etc sleep 1 | ||
49 | 1 firejail --private=bingo sleep 1 | ||
diff --git a/test/test.sh b/test/test.sh new file mode 100755 index 000000000..5fe01eb2a --- /dev/null +++ b/test/test.sh | |||
@@ -0,0 +1,329 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | ./chk_config.exp | ||
4 | |||
5 | ./fscheck.sh | ||
6 | |||
7 | echo "TESTING: version" | ||
8 | ./option_version.exp | ||
9 | |||
10 | echo "TESTING: help" | ||
11 | ./option_help.exp | ||
12 | |||
13 | echo "TESTING: man" | ||
14 | ./option_man.exp | ||
15 | |||
16 | echo "TESTING: list" | ||
17 | ./option_list.exp | ||
18 | |||
19 | echo "TESTING: tree" | ||
20 | ./option_tree.exp | ||
21 | |||
22 | if [ -f /proc/self/uid_map ]; | ||
23 | then | ||
24 | echo "TESTING: noroot" | ||
25 | ./noroot.exp | ||
26 | else | ||
27 | echo "TESTING: user namespaces not available" | ||
28 | fi | ||
29 | |||
30 | echo "TESTING: doubledash" | ||
31 | mkdir -- -testdir | ||
32 | touch -- -testdir/ttt | ||
33 | cp -- /bin/bash -testdir/. | ||
34 | ./doubledash.exp | ||
35 | rm -fr -- -testdir | ||
36 | |||
37 | echo "TESTING: trace1" | ||
38 | ./option-trace.exp | ||
39 | |||
40 | echo "TESTING: trace2" | ||
41 | rm -f index.html* | ||
42 | ./trace.exp | ||
43 | rm -f index.html* | ||
44 | |||
45 | echo "TESTING: extract command" | ||
46 | ./extract_command.exp | ||
47 | |||
48 | echo "TESTING: rlimit" | ||
49 | ./option_rlimit.exp | ||
50 | |||
51 | echo "TESTING: shutdown" | ||
52 | ./option-shutdown.exp | ||
53 | |||
54 | echo "TESTING: join" | ||
55 | ./option-join.exp | ||
56 | |||
57 | echo "TESTING: firejail in firejail" | ||
58 | ./firejail-in-firejail.exp | ||
59 | |||
60 | echo "TESTING: chroot overlay" | ||
61 | ./option_chroot_overlay.exp | ||
62 | |||
63 | echo "TESTING: tmpfs" | ||
64 | ./option_tmpfs.exp | ||
65 | |||
66 | echo "TESTING: blacklist directory" | ||
67 | ./option_blacklist.exp | ||
68 | |||
69 | echo "TESTING: blacklist file" | ||
70 | ./option_blacklist_file.exp | ||
71 | |||
72 | echo "TESTING: bind as user" | ||
73 | ./option_bind_user.exp | ||
74 | |||
75 | if [ -d /home/bingo ]; | ||
76 | then | ||
77 | echo "TESTING: home sanitize" | ||
78 | ./option_version.exp | ||
79 | fi | ||
80 | |||
81 | echo "TESTING: chroot as user" | ||
82 | ./fs_chroot.exp | ||
83 | |||
84 | echo "TESTING: /sys" | ||
85 | ./fs_sys.exp | ||
86 | |||
87 | echo "TESTING: readonly" | ||
88 | ls -al > tmpreadonly | ||
89 | ./option_readonly.exp | ||
90 | sleep 5 | ||
91 | rm -f tmpreadonly | ||
92 | |||
93 | echo "TESTING: name" | ||
94 | ./name.exp | ||
95 | |||
96 | echo "TESTING: zsh" | ||
97 | ./shell_zsh.exp | ||
98 | |||
99 | echo "TESTING: csh" | ||
100 | ./shell_csh.exp | ||
101 | |||
102 | which dash | ||
103 | if [ "$?" -eq 0 ]; | ||
104 | then | ||
105 | echo "TESTING: dash" | ||
106 | ./shell_dash.exp | ||
107 | else | ||
108 | echo "TESTING: dash not found" | ||
109 | fi | ||
110 | |||
111 | which firefox | ||
112 | if [ "$?" -eq 0 ]; | ||
113 | then | ||
114 | echo "TESTING: firefox" | ||
115 | ./firefox.exp | ||
116 | else | ||
117 | echo "TESTING: firefox not found" | ||
118 | fi | ||
119 | |||
120 | which midori | ||
121 | if [ "$?" -eq 0 ]; | ||
122 | then | ||
123 | echo "TESTING: midori" | ||
124 | ./midori.exp | ||
125 | else | ||
126 | echo "TESTING: midori not found" | ||
127 | fi | ||
128 | |||
129 | which chromium-browser | ||
130 | if [ "$?" -eq 0 ]; | ||
131 | then | ||
132 | echo "TESTING: chromium" | ||
133 | ./chromium.exp | ||
134 | else | ||
135 | echo "TESTING: chromium not found" | ||
136 | fi | ||
137 | |||
138 | which opera | ||
139 | if [ "$?" -eq 0 ]; | ||
140 | then | ||
141 | echo "TESTING: opera" | ||
142 | ./opera.exp | ||
143 | else | ||
144 | echo "TESTING: opera not found" | ||
145 | fi | ||
146 | |||
147 | which transmission-gtk | ||
148 | if [ "$?" -eq 0 ]; | ||
149 | then | ||
150 | echo "TESTING: transmission-gtk" | ||
151 | ./transmission-gtk.exp | ||
152 | else | ||
153 | echo "TESTING: transmission-gtk not found" | ||
154 | fi | ||
155 | |||
156 | which transmission-qt | ||
157 | if [ "$?" -eq 0 ]; | ||
158 | then | ||
159 | echo "TESTING: transmission-qt" | ||
160 | ./transmission-qt.exp | ||
161 | else | ||
162 | echo "TESTING: transmission-qt not found" | ||
163 | fi | ||
164 | |||
165 | which evince | ||
166 | if [ "$?" -eq 0 ]; | ||
167 | then | ||
168 | echo "TESTING: evince" | ||
169 | ./evince.exp | ||
170 | else | ||
171 | echo "TESTING: evince not found" | ||
172 | fi | ||
173 | |||
174 | echo "TESTING: PID" | ||
175 | ./pid.exp | ||
176 | |||
177 | echo "TESTING: output" | ||
178 | ./output.exp | ||
179 | |||
180 | echo "TESTING: profile no permissions" | ||
181 | ./profile_noperm.exp | ||
182 | |||
183 | echo "TESTING: profile syntax" | ||
184 | ./profile_syntax.exp | ||
185 | |||
186 | echo "TESTING: profile syntax 2" | ||
187 | ./profile_syntax2.exp | ||
188 | |||
189 | echo "TESTING: profile rlimit" | ||
190 | ./profile_rlimit.exp | ||
191 | |||
192 | echo "TESTING: profile read-only" | ||
193 | ./profile_readonly.exp | ||
194 | |||
195 | echo "TESTING: profile tmpfs" | ||
196 | ./profile_tmpfs.exp | ||
197 | |||
198 | echo "TESTING: profile applications" | ||
199 | ./profile_apps.exp | ||
200 | |||
201 | echo "TESTING: private" | ||
202 | ./private.exp `whoami` | ||
203 | |||
204 | echo "TESTING: private directory" | ||
205 | rm -fr dirprivate | ||
206 | mkdir dirprivate | ||
207 | ./private_dir.exp | ||
208 | rm -fr dirprivate | ||
209 | |||
210 | echo "TESTING: private directory profile" | ||
211 | rm -fr dirprivate | ||
212 | mkdir dirprivate | ||
213 | ./private_dir_profile.exp | ||
214 | rm -fr dirprivate | ||
215 | |||
216 | echo "TESTING: private keep" | ||
217 | ./private-keep.exp | ||
218 | |||
219 | uname -r | grep "3.18" | ||
220 | if [ "$?" -eq 0 ]; | ||
221 | then | ||
222 | echo "TESTING: overlayfs on 3.18 kernel" | ||
223 | ./fs_overlay.exp | ||
224 | fi | ||
225 | |||
226 | grep "openSUSE" /etc/os-release | ||
227 | if [ "$?" -eq 0 ]; | ||
228 | then | ||
229 | echo "TESTING: overlayfs" | ||
230 | ./fs_overlay.exp | ||
231 | fi | ||
232 | |||
233 | grep "Ubuntu" /etc/os-release | ||
234 | if [ "$?" -eq 0 ]; | ||
235 | then | ||
236 | echo "TESTING: overlayfs" | ||
237 | ./fs_overlay.exp | ||
238 | fi | ||
239 | |||
240 | echo "TESTING: seccomp debug" | ||
241 | ./seccomp-debug.exp | ||
242 | |||
243 | echo "TESTING: seccomp su" | ||
244 | ./seccomp-su.exp | ||
245 | |||
246 | echo "TESTING: seccomp ptrace" | ||
247 | ./seccomp-ptrace.exp | ||
248 | |||
249 | echo "TESTING: seccomp chmod (seccomp lists)" | ||
250 | ./seccomp-chmod.exp | ||
251 | |||
252 | echo "TESTING: seccomp chmod profile (seccomp lists)" | ||
253 | ./seccomp-chmod-profile.exp | ||
254 | |||
255 | echo "TESTING: seccomp empty" | ||
256 | ./seccomp-empty.exp | ||
257 | |||
258 | echo "TESTING: seccomp bad empty" | ||
259 | ./seccomp-bad-empty.exp | ||
260 | |||
261 | echo "TESTING: read/write /var/tmp" | ||
262 | ./fs_var_tmp.exp | ||
263 | |||
264 | echo "TESTING: read/write /var/lock" | ||
265 | ./fs_var_lock.exp | ||
266 | |||
267 | echo "TESTING: read/write /dev/shm" | ||
268 | ./fs_dev_shm.exp | ||
269 | |||
270 | echo "TESTING: local network" | ||
271 | ./net_local.exp | ||
272 | |||
273 | echo "TESTING: no network" | ||
274 | ./net_none.exp | ||
275 | |||
276 | echo "TESTING: network IP" | ||
277 | ./net_ip.exp | ||
278 | |||
279 | echo "TESTING: network MAC" | ||
280 | ./net_mac.exp | ||
281 | |||
282 | echo "TESTING: network bad IP" | ||
283 | ./net_badip.exp | ||
284 | |||
285 | echo "TESTING: network no IP test 1" | ||
286 | ./net_noip.exp | ||
287 | |||
288 | echo "TESTING: network no IP test 2" | ||
289 | ./net_noip2.exp | ||
290 | |||
291 | echo "TESTING: network default gateway test 1" | ||
292 | ./net_defaultgw.exp | ||
293 | |||
294 | echo "TESTING: network default gateway test 2" | ||
295 | ./net_defaultgw2.exp | ||
296 | |||
297 | echo "TESTING: network default gateway test 3" | ||
298 | ./net_defaultgw3.exp | ||
299 | |||
300 | echo "TESTING: netfilter" | ||
301 | ./net_netfilter.exp | ||
302 | |||
303 | echo "TESTING: 4 bridges ARP" | ||
304 | ./4bridges_arp.exp | ||
305 | |||
306 | echo "TESTING: 4 bridges IP" | ||
307 | ./4bridges_ip.exp | ||
308 | |||
309 | echo "TESTING: login SSH" | ||
310 | ./login_ssh.exp | ||
311 | |||
312 | echo "TESTING: ARP" | ||
313 | ./net_arp.exp | ||
314 | |||
315 | echo "TESTING: DNS" | ||
316 | ./dns.exp | ||
317 | |||
318 | echo "TESTING: firemon --arp" | ||
319 | ./firemon-arp.exp | ||
320 | |||
321 | echo "TESTING: firemon --route" | ||
322 | ./firemon-route.exp | ||
323 | |||
324 | echo "TESTING: firemon --seccomp" | ||
325 | ./firemon-seccomp.exp | ||
326 | |||
327 | echo "TESTING: firemon --caps" | ||
328 | ./firemon-caps.exp | ||
329 | |||
diff --git a/test/test2.profile b/test/test2.profile new file mode 100644 index 000000000..d7e1a1f21 --- /dev/null +++ b/test/test2.profile | |||
@@ -0,0 +1,4 @@ | |||
1 | caps | ||
2 | seccomp | ||
3 | private | ||
4 | include test.profile | ||
diff --git a/test/tmpfs.profile b/test/tmpfs.profile new file mode 100644 index 000000000..0680f4d69 --- /dev/null +++ b/test/tmpfs.profile | |||
@@ -0,0 +1 @@ | |||
tmpfs /tmp/firejailtestdir \ No newline at end of file | |||
diff --git a/test/trace.exp b/test/trace.exp new file mode 100755 index 000000000..bca3ac3b3 --- /dev/null +++ b/test/trace.exp | |||
@@ -0,0 +1,95 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 30 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --trace mkdir ttt\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 | "1:mkdir:mkdir ttt" | ||
15 | } | ||
16 | sleep 1 | ||
17 | |||
18 | send -- "firejail --trace rmdir ttt\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 | "1:rmdir:rmdir ttt" | ||
26 | } | ||
27 | sleep 1 | ||
28 | |||
29 | send -- "firejail --trace touch ttt\r" | ||
30 | expect { | ||
31 | timeout {puts "TESTING ERROR 4\n";exit} | ||
32 | "Child process initialized" | ||
33 | } | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 5\n";exit} | ||
36 | "1:touch:open ttt" {puts "OK\n";} | ||
37 | "1:touch:open64 ttt" {puts "OK\n";} | ||
38 | } | ||
39 | sleep 1 | ||
40 | |||
41 | send -- "firejail --trace rm ttt\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 6\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | expect { | ||
47 | timeout {puts "TESTING ERROR 7\n";exit} | ||
48 | "1:rm:unlinkat ttt" | ||
49 | } | ||
50 | sleep 1 | ||
51 | |||
52 | send -- "firejail --trace wget -q debian.org\r" | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 8.1\n";exit} | ||
55 | "Child process initialized" | ||
56 | } | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 8.2\n";exit} | ||
59 | "1:bash:open /dev/tty" {puts "OK\n";} | ||
60 | "1:bash:open64 /dev/tty" {puts "OK\n";} | ||
61 | } | ||
62 | expect { | ||
63 | timeout {puts "TESTING ERROR 8.3\n";exit} | ||
64 | "1:wget:fopen64 /etc/wgetrc" {puts "OK\n";} | ||
65 | "1:wget:fopen /etc/wgetrc" {puts "OK\n";} | ||
66 | } | ||
67 | expect { | ||
68 | timeout {puts "TESTING ERROR 8.4\n";exit} | ||
69 | "1:wget:fopen /etc/hosts" | ||
70 | } | ||
71 | expect { | ||
72 | timeout {puts "TESTING ERROR 8.5\n";exit} | ||
73 | "1:wget:connect" | ||
74 | } | ||
75 | expect { | ||
76 | timeout {puts "TESTING ERROR 8.6\n";exit} | ||
77 | "1:wget:fopen64 index.html" {puts "OK\n";} | ||
78 | "1:wget:fopen index.html" {puts "OK\n";} | ||
79 | } | ||
80 | sleep 1 | ||
81 | |||
82 | send -- "firejail --trace rm index.html\r" | ||
83 | expect { | ||
84 | timeout {puts "TESTING ERROR 9\n";exit} | ||
85 | "Child process initialized" | ||
86 | } | ||
87 | expect { | ||
88 | timeout {puts "TESTING ERROR 10\n";exit} | ||
89 | "1:rm:unlinkat index.html" | ||
90 | } | ||
91 | sleep 1 | ||
92 | |||
93 | |||
94 | puts "\n" | ||
95 | |||
diff --git a/test/transmission-gtk.exp b/test/transmission-gtk.exp new file mode 100755 index 000000000..7760ae3ad --- /dev/null +++ b/test/transmission-gtk.exp | |||
@@ -0,0 +1,68 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail transmission-gtk\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 1\n";exit} | ||
10 | "Child process initialized" | ||
11 | } | ||
12 | sleep 10 | ||
13 | |||
14 | spawn $env(SHELL) | ||
15 | send -- "firejail --list\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 3\n";exit} | ||
18 | ":firejail" | ||
19 | } | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
22 | "transmission-gtk" | ||
23 | } | ||
24 | sleep 1 | ||
25 | |||
26 | send -- "firejail --name=blablabla\r" | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 4\n";exit} | ||
29 | "Child process initialized" | ||
30 | } | ||
31 | sleep 2 | ||
32 | |||
33 | spawn $env(SHELL) | ||
34 | send -- "firemon --seccomp\r" | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 5\n";exit} | ||
37 | ":firejail transmission-gtk" | ||
38 | } | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
41 | "Seccomp: 2" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
45 | "name=blablabla" | ||
46 | } | ||
47 | sleep 1 | ||
48 | send -- "firemon --caps\r" | ||
49 | expect { | ||
50 | timeout {puts "TESTING ERROR 6\n";exit} | ||
51 | ":firejail transmission-gtk" | ||
52 | } | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
55 | "CapBnd" | ||
56 | } | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
59 | "0000000000000000" | ||
60 | } | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
63 | "name=blablabla" | ||
64 | } | ||
65 | sleep 1 | ||
66 | |||
67 | puts "\n" | ||
68 | |||
diff --git a/test/transmission-qt.exp b/test/transmission-qt.exp new file mode 100755 index 000000000..85457aeb8 --- /dev/null +++ b/test/transmission-qt.exp | |||
@@ -0,0 +1,72 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail transmission-qt\r" | ||
8 | expect { | ||
9 | timeout {puts "TESTING ERROR 0\n";exit} | ||
10 | "Reading profile /etc/firejail/transmission-qt.profile" | ||
11 | } | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 1\n";exit} | ||
14 | "Child process initialized" | ||
15 | } | ||
16 | sleep 10 | ||
17 | |||
18 | spawn $env(SHELL) | ||
19 | send -- "firejail --list\r" | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 3\n";exit} | ||
22 | ":firejail" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
26 | "transmission-qt" | ||
27 | } | ||
28 | sleep 1 | ||
29 | |||
30 | send -- "firejail --name=blablabla\r" | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 4\n";exit} | ||
33 | "Child process initialized" | ||
34 | } | ||
35 | sleep 2 | ||
36 | |||
37 | spawn $env(SHELL) | ||
38 | send -- "firemon --seccomp\r" | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 5\n";exit} | ||
41 | ":firejail transmission-qt" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
45 | "Seccomp: 2" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
49 | "name=blablabla" | ||
50 | } | ||
51 | sleep 1 | ||
52 | send -- "firemon --caps\r" | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 6\n";exit} | ||
55 | ":firejail transmission-qt" | ||
56 | } | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
59 | "CapBnd" | ||
60 | } | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
63 | "0000000000000000" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
67 | "name=blablabla" | ||
68 | } | ||
69 | sleep 1 | ||
70 | |||
71 | puts "\n" | ||
72 | |||