Imported Debian patch 2.1.1-1
Kees Cook authored 10 years ago
Luca Bruno committed 8 years ago
0 | libseccomp: Releases | |
1 | =============================================================================== | |
2 | http://libseccomp.sf.net | |
3 | ||
4 | * Version 2.1.1 - October 31, 2013 | |
5 | - Build system improvements | |
6 | - Automated test improvments, including a "check" target for use by | |
7 | packagers to verify the build | |
8 | - Numerous bug fixes related to the filter's internal rule database which | |
9 | affect those creating rules with syscall arguments | |
10 | - Introduced tools to verify the style/formatting of the code, including a | |
11 | "check-syntax" target for use by developers | |
12 | - Non-public symbols are now hidden in the library | |
13 | ||
14 | * Version 2.1.0 - June 11, 2013 | |
15 | - Add support for the x32 and ARM architectures | |
16 | - Improvements to the regression tests, including support for live tests | |
17 | - More verbose PFC output, including translation of syscall numbers to names | |
18 | - Several assorted bugfixes affecting the seccomp BPF generation | |
19 | - The syscall number/name resolver tool is now available to install | |
20 | ||
21 | * Version 2.0.0 - January 28, 2013 | |
22 | - Fixes for the x86 multiplexed syscalls | |
23 | - Additions to the API to better support non-native architecures | |
24 | - Additions to the API to support multiple architecures in one filter | |
25 | - Additions to the API to resolve syscall name/number mappings | |
26 | - Assorted minor bug fixes | |
27 | - Improved build messages regardless of build verbosity | |
28 | - More automated tests added as well as a number of improvements to the test | |
29 | harness | |
30 | ||
31 | * Version 1.0.1 - November 12, 2012 | |
32 | - The header file is now easier to use with C++ compilers | |
33 | - Minor documentation fixes | |
34 | - Minor memory leak fixes | |
35 | - Corrected x86 filter generation on x86_64 systems | |
36 | - Corrected problems with small filters and filters with arguments | |
37 | ||
38 | * Version 1.0.0 - July 31, 2012 | |
39 | - Change the API to be context-aware; eliminates all internal state but breaks | |
40 | compatibility with the previous 0.1.0 release | |
41 | - Added support for multiple build jobs ("make -j8") and verbose builds using | |
42 | the "V=1" build variable ("make V=1") | |
43 | - Minor tweaks to the regression test script output | |
44 | ||
45 | * Version 0.1.0 - June 8, 2012 | |
46 | - Initial release |
0 | libseccomp: Contributors | |
1 | =============================================================================== | |
2 | http://libseccomp.sf.net | |
3 | ||
4 | Andy Lutomirski <luto@amacapital.net> | |
5 | Ashley Lai <adlai@us.ibm.com> | |
6 | Corey Bryant <coreyb@linux.vnet.ibm.com> | |
7 | Eduardo Otubo <otubo@linux.vnet.ibm.com> | |
8 | Eric Paris <eparis@redhat.com> | |
9 | Jake Edge <jake@lwn.net> | |
10 | Joe MacDonald <joe@deserted.net> | |
11 | Kees Cook <keescook@chromium.org> | |
12 | Paul Moore <pmoore@redhat.com> | |
13 | Thiago Marcos P. Santos <thiago.santos@intel.com> | |
14 | Vitaly Vi Shukela <vi0oss@gmail.com> |
0 | GNU LESSER GENERAL PUBLIC LICENSE | |
1 | Version 2.1, February 1999 | |
2 | ||
3 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. | |
4 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
5 | Everyone is permitted to copy and distribute verbatim copies | |
6 | of this license document, but changing it is not allowed. | |
7 | ||
8 | [This is the first released version of the Lesser GPL. It also counts | |
9 | as the successor of the GNU Library Public License, version 2, hence | |
10 | the version number 2.1.] | |
11 | ||
12 | Preamble | |
13 | ||
14 | The licenses for most software are designed to take away your | |
15 | freedom to share and change it. By contrast, the GNU General Public | |
16 | Licenses are intended to guarantee your freedom to share and change | |
17 | free software--to make sure the software is free for all its users. | |
18 | ||
19 | This license, the Lesser General Public License, applies to some | |
20 | specially designated software packages--typically libraries--of the | |
21 | Free Software Foundation and other authors who decide to use it. You | |
22 | can use it too, but we suggest you first think carefully about whether | |
23 | this license or the ordinary General Public License is the better | |
24 | strategy to use in any particular case, based on the explanations below. | |
25 | ||
26 | When we speak of free software, we are referring to freedom of use, | |
27 | not price. Our General Public Licenses are designed to make sure that | |
28 | you have the freedom to distribute copies of free software (and charge | |
29 | for this service if you wish); that you receive source code or can get | |
30 | it if you want it; that you can change the software and use pieces of | |
31 | it in new free programs; and that you are informed that you can do | |
32 | these things. | |
33 | ||
34 | To protect your rights, we need to make restrictions that forbid | |
35 | distributors to deny you these rights or to ask you to surrender these | |
36 | rights. These restrictions translate to certain responsibilities for | |
37 | you if you distribute copies of the library or if you modify it. | |
38 | ||
39 | For example, if you distribute copies of the library, whether gratis | |
40 | or for a fee, you must give the recipients all the rights that we gave | |
41 | you. You must make sure that they, too, receive or can get the source | |
42 | code. If you link other code with the library, you must provide | |
43 | complete object files to the recipients, so that they can relink them | |
44 | with the library after making changes to the library and recompiling | |
45 | it. And you must show them these terms so they know their rights. | |
46 | ||
47 | We protect your rights with a two-step method: (1) we copyright the | |
48 | library, and (2) we offer you this license, which gives you legal | |
49 | permission to copy, distribute and/or modify the library. | |
50 | ||
51 | To protect each distributor, we want to make it very clear that | |
52 | there is no warranty for the free library. Also, if the library is | |
53 | modified by someone else and passed on, the recipients should know | |
54 | that what they have is not the original version, so that the original | |
55 | author's reputation will not be affected by problems that might be | |
56 | introduced by others. | |
57 | ||
58 | Finally, software patents pose a constant threat to the existence of | |
59 | any free program. We wish to make sure that a company cannot | |
60 | effectively restrict the users of a free program by obtaining a | |
61 | restrictive license from a patent holder. Therefore, we insist that | |
62 | any patent license obtained for a version of the library must be | |
63 | consistent with the full freedom of use specified in this license. | |
64 | ||
65 | Most GNU software, including some libraries, is covered by the | |
66 | ordinary GNU General Public License. This license, the GNU Lesser | |
67 | General Public License, applies to certain designated libraries, and | |
68 | is quite different from the ordinary General Public License. We use | |
69 | this license for certain libraries in order to permit linking those | |
70 | libraries into non-free programs. | |
71 | ||
72 | When a program is linked with a library, whether statically or using | |
73 | a shared library, the combination of the two is legally speaking a | |
74 | combined work, a derivative of the original library. The ordinary | |
75 | General Public License therefore permits such linking only if the | |
76 | entire combination fits its criteria of freedom. The Lesser General | |
77 | Public License permits more lax criteria for linking other code with | |
78 | the library. | |
79 | ||
80 | We call this license the "Lesser" General Public License because it | |
81 | does Less to protect the user's freedom than the ordinary General | |
82 | Public License. It also provides other free software developers Less | |
83 | of an advantage over competing non-free programs. These disadvantages | |
84 | are the reason we use the ordinary General Public License for many | |
85 | libraries. However, the Lesser license provides advantages in certain | |
86 | special circumstances. | |
87 | ||
88 | For example, on rare occasions, there may be a special need to | |
89 | encourage the widest possible use of a certain library, so that it becomes | |
90 | a de-facto standard. To achieve this, non-free programs must be | |
91 | allowed to use the library. A more frequent case is that a free | |
92 | library does the same job as widely used non-free libraries. In this | |
93 | case, there is little to gain by limiting the free library to free | |
94 | software only, so we use the Lesser General Public License. | |
95 | ||
96 | In other cases, permission to use a particular library in non-free | |
97 | programs enables a greater number of people to use a large body of | |
98 | free software. For example, permission to use the GNU C Library in | |
99 | non-free programs enables many more people to use the whole GNU | |
100 | operating system, as well as its variant, the GNU/Linux operating | |
101 | system. | |
102 | ||
103 | Although the Lesser General Public License is Less protective of the | |
104 | users' freedom, it does ensure that the user of a program that is | |
105 | linked with the Library has the freedom and the wherewithal to run | |
106 | that program using a modified version of the Library. | |
107 | ||
108 | The precise terms and conditions for copying, distribution and | |
109 | modification follow. Pay close attention to the difference between a | |
110 | "work based on the library" and a "work that uses the library". The | |
111 | former contains code derived from the library, whereas the latter must | |
112 | be combined with the library in order to run. | |
113 | ||
114 | GNU LESSER GENERAL PUBLIC LICENSE | |
115 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
116 | ||
117 | 0. This License Agreement applies to any software library or other | |
118 | program which contains a notice placed by the copyright holder or | |
119 | other authorized party saying it may be distributed under the terms of | |
120 | this Lesser General Public License (also called "this License"). | |
121 | Each licensee is addressed as "you". | |
122 | ||
123 | A "library" means a collection of software functions and/or data | |
124 | prepared so as to be conveniently linked with application programs | |
125 | (which use some of those functions and data) to form executables. | |
126 | ||
127 | The "Library", below, refers to any such software library or work | |
128 | which has been distributed under these terms. A "work based on the | |
129 | Library" means either the Library or any derivative work under | |
130 | copyright law: that is to say, a work containing the Library or a | |
131 | portion of it, either verbatim or with modifications and/or translated | |
132 | straightforwardly into another language. (Hereinafter, translation is | |
133 | included without limitation in the term "modification".) | |
134 | ||
135 | "Source code" for a work means the preferred form of the work for | |
136 | making modifications to it. For a library, complete source code means | |
137 | all the source code for all modules it contains, plus any associated | |
138 | interface definition files, plus the scripts used to control compilation | |
139 | and installation of the library. | |
140 | ||
141 | Activities other than copying, distribution and modification are not | |
142 | covered by this License; they are outside its scope. The act of | |
143 | running a program using the Library is not restricted, and output from | |
144 | such a program is covered only if its contents constitute a work based | |
145 | on the Library (independent of the use of the Library in a tool for | |
146 | writing it). Whether that is true depends on what the Library does | |
147 | and what the program that uses the Library does. | |
148 | ||
149 | 1. You may copy and distribute verbatim copies of the Library's | |
150 | complete source code as you receive it, in any medium, provided that | |
151 | you conspicuously and appropriately publish on each copy an | |
152 | appropriate copyright notice and disclaimer of warranty; keep intact | |
153 | all the notices that refer to this License and to the absence of any | |
154 | warranty; and distribute a copy of this License along with the | |
155 | Library. | |
156 | ||
157 | You may charge a fee for the physical act of transferring a copy, | |
158 | and you may at your option offer warranty protection in exchange for a | |
159 | fee. | |
160 | ||
161 | 2. You may modify your copy or copies of the Library or any portion | |
162 | of it, thus forming a work based on the Library, and copy and | |
163 | distribute such modifications or work under the terms of Section 1 | |
164 | above, provided that you also meet all of these conditions: | |
165 | ||
166 | a) The modified work must itself be a software library. | |
167 | ||
168 | b) You must cause the files modified to carry prominent notices | |
169 | stating that you changed the files and the date of any change. | |
170 | ||
171 | c) You must cause the whole of the work to be licensed at no | |
172 | charge to all third parties under the terms of this License. | |
173 | ||
174 | d) If a facility in the modified Library refers to a function or a | |
175 | table of data to be supplied by an application program that uses | |
176 | the facility, other than as an argument passed when the facility | |
177 | is invoked, then you must make a good faith effort to ensure that, | |
178 | in the event an application does not supply such function or | |
179 | table, the facility still operates, and performs whatever part of | |
180 | its purpose remains meaningful. | |
181 | ||
182 | (For example, a function in a library to compute square roots has | |
183 | a purpose that is entirely well-defined independent of the | |
184 | application. Therefore, Subsection 2d requires that any | |
185 | application-supplied function or table used by this function must | |
186 | be optional: if the application does not supply it, the square | |
187 | root function must still compute square roots.) | |
188 | ||
189 | These requirements apply to the modified work as a whole. If | |
190 | identifiable sections of that work are not derived from the Library, | |
191 | and can be reasonably considered independent and separate works in | |
192 | themselves, then this License, and its terms, do not apply to those | |
193 | sections when you distribute them as separate works. But when you | |
194 | distribute the same sections as part of a whole which is a work based | |
195 | on the Library, the distribution of the whole must be on the terms of | |
196 | this License, whose permissions for other licensees extend to the | |
197 | entire whole, and thus to each and every part regardless of who wrote | |
198 | it. | |
199 | ||
200 | Thus, it is not the intent of this section to claim rights or contest | |
201 | your rights to work written entirely by you; rather, the intent is to | |
202 | exercise the right to control the distribution of derivative or | |
203 | collective works based on the Library. | |
204 | ||
205 | In addition, mere aggregation of another work not based on the Library | |
206 | with the Library (or with a work based on the Library) on a volume of | |
207 | a storage or distribution medium does not bring the other work under | |
208 | the scope of this License. | |
209 | ||
210 | 3. You may opt to apply the terms of the ordinary GNU General Public | |
211 | License instead of this License to a given copy of the Library. To do | |
212 | this, you must alter all the notices that refer to this License, so | |
213 | that they refer to the ordinary GNU General Public License, version 2, | |
214 | instead of to this License. (If a newer version than version 2 of the | |
215 | ordinary GNU General Public License has appeared, then you can specify | |
216 | that version instead if you wish.) Do not make any other change in | |
217 | these notices. | |
218 | ||
219 | Once this change is made in a given copy, it is irreversible for | |
220 | that copy, so the ordinary GNU General Public License applies to all | |
221 | subsequent copies and derivative works made from that copy. | |
222 | ||
223 | This option is useful when you wish to copy part of the code of | |
224 | the Library into a program that is not a library. | |
225 | ||
226 | 4. You may copy and distribute the Library (or a portion or | |
227 | derivative of it, under Section 2) in object code or executable form | |
228 | under the terms of Sections 1 and 2 above provided that you accompany | |
229 | it with the complete corresponding machine-readable source code, which | |
230 | must be distributed under the terms of Sections 1 and 2 above on a | |
231 | medium customarily used for software interchange. | |
232 | ||
233 | If distribution of object code is made by offering access to copy | |
234 | from a designated place, then offering equivalent access to copy the | |
235 | source code from the same place satisfies the requirement to | |
236 | distribute the source code, even though third parties are not | |
237 | compelled to copy the source along with the object code. | |
238 | ||
239 | 5. A program that contains no derivative of any portion of the | |
240 | Library, but is designed to work with the Library by being compiled or | |
241 | linked with it, is called a "work that uses the Library". Such a | |
242 | work, in isolation, is not a derivative work of the Library, and | |
243 | therefore falls outside the scope of this License. | |
244 | ||
245 | However, linking a "work that uses the Library" with the Library | |
246 | creates an executable that is a derivative of the Library (because it | |
247 | contains portions of the Library), rather than a "work that uses the | |
248 | library". The executable is therefore covered by this License. | |
249 | Section 6 states terms for distribution of such executables. | |
250 | ||
251 | When a "work that uses the Library" uses material from a header file | |
252 | that is part of the Library, the object code for the work may be a | |
253 | derivative work of the Library even though the source code is not. | |
254 | Whether this is true is especially significant if the work can be | |
255 | linked without the Library, or if the work is itself a library. The | |
256 | threshold for this to be true is not precisely defined by law. | |
257 | ||
258 | If such an object file uses only numerical parameters, data | |
259 | structure layouts and accessors, and small macros and small inline | |
260 | functions (ten lines or less in length), then the use of the object | |
261 | file is unrestricted, regardless of whether it is legally a derivative | |
262 | work. (Executables containing this object code plus portions of the | |
263 | Library will still fall under Section 6.) | |
264 | ||
265 | Otherwise, if the work is a derivative of the Library, you may | |
266 | distribute the object code for the work under the terms of Section 6. | |
267 | Any executables containing that work also fall under Section 6, | |
268 | whether or not they are linked directly with the Library itself. | |
269 | ||
270 | 6. As an exception to the Sections above, you may also combine or | |
271 | link a "work that uses the Library" with the Library to produce a | |
272 | work containing portions of the Library, and distribute that work | |
273 | under terms of your choice, provided that the terms permit | |
274 | modification of the work for the customer's own use and reverse | |
275 | engineering for debugging such modifications. | |
276 | ||
277 | You must give prominent notice with each copy of the work that the | |
278 | Library is used in it and that the Library and its use are covered by | |
279 | this License. You must supply a copy of this License. If the work | |
280 | during execution displays copyright notices, you must include the | |
281 | copyright notice for the Library among them, as well as a reference | |
282 | directing the user to the copy of this License. Also, you must do one | |
283 | of these things: | |
284 | ||
285 | a) Accompany the work with the complete corresponding | |
286 | machine-readable source code for the Library including whatever | |
287 | changes were used in the work (which must be distributed under | |
288 | Sections 1 and 2 above); and, if the work is an executable linked | |
289 | with the Library, with the complete machine-readable "work that | |
290 | uses the Library", as object code and/or source code, so that the | |
291 | user can modify the Library and then relink to produce a modified | |
292 | executable containing the modified Library. (It is understood | |
293 | that the user who changes the contents of definitions files in the | |
294 | Library will not necessarily be able to recompile the application | |
295 | to use the modified definitions.) | |
296 | ||
297 | b) Use a suitable shared library mechanism for linking with the | |
298 | Library. A suitable mechanism is one that (1) uses at run time a | |
299 | copy of the library already present on the user's computer system, | |
300 | rather than copying library functions into the executable, and (2) | |
301 | will operate properly with a modified version of the library, if | |
302 | the user installs one, as long as the modified version is | |
303 | interface-compatible with the version that the work was made with. | |
304 | ||
305 | c) Accompany the work with a written offer, valid for at | |
306 | least three years, to give the same user the materials | |
307 | specified in Subsection 6a, above, for a charge no more | |
308 | than the cost of performing this distribution. | |
309 | ||
310 | d) If distribution of the work is made by offering access to copy | |
311 | from a designated place, offer equivalent access to copy the above | |
312 | specified materials from the same place. | |
313 | ||
314 | e) Verify that the user has already received a copy of these | |
315 | materials or that you have already sent this user a copy. | |
316 | ||
317 | For an executable, the required form of the "work that uses the | |
318 | Library" must include any data and utility programs needed for | |
319 | reproducing the executable from it. However, as a special exception, | |
320 | the materials to be distributed need not include anything that is | |
321 | normally distributed (in either source or binary form) with the major | |
322 | components (compiler, kernel, and so on) of the operating system on | |
323 | which the executable runs, unless that component itself accompanies | |
324 | the executable. | |
325 | ||
326 | It may happen that this requirement contradicts the license | |
327 | restrictions of other proprietary libraries that do not normally | |
328 | accompany the operating system. Such a contradiction means you cannot | |
329 | use both them and the Library together in an executable that you | |
330 | distribute. | |
331 | ||
332 | 7. You may place library facilities that are a work based on the | |
333 | Library side-by-side in a single library together with other library | |
334 | facilities not covered by this License, and distribute such a combined | |
335 | library, provided that the separate distribution of the work based on | |
336 | the Library and of the other library facilities is otherwise | |
337 | permitted, and provided that you do these two things: | |
338 | ||
339 | a) Accompany the combined library with a copy of the same work | |
340 | based on the Library, uncombined with any other library | |
341 | facilities. This must be distributed under the terms of the | |
342 | Sections above. | |
343 | ||
344 | b) Give prominent notice with the combined library of the fact | |
345 | that part of it is a work based on the Library, and explaining | |
346 | where to find the accompanying uncombined form of the same work. | |
347 | ||
348 | 8. You may not copy, modify, sublicense, link with, or distribute | |
349 | the Library except as expressly provided under this License. Any | |
350 | attempt otherwise to copy, modify, sublicense, link with, or | |
351 | distribute the Library is void, and will automatically terminate your | |
352 | rights under this License. However, parties who have received copies, | |
353 | or rights, from you under this License will not have their licenses | |
354 | terminated so long as such parties remain in full compliance. | |
355 | ||
356 | 9. You are not required to accept this License, since you have not | |
357 | signed it. However, nothing else grants you permission to modify or | |
358 | distribute the Library or its derivative works. These actions are | |
359 | prohibited by law if you do not accept this License. Therefore, by | |
360 | modifying or distributing the Library (or any work based on the | |
361 | Library), you indicate your acceptance of this License to do so, and | |
362 | all its terms and conditions for copying, distributing or modifying | |
363 | the Library or works based on it. | |
364 | ||
365 | 10. Each time you redistribute the Library (or any work based on the | |
366 | Library), the recipient automatically receives a license from the | |
367 | original licensor to copy, distribute, link with or modify the Library | |
368 | subject to these terms and conditions. You may not impose any further | |
369 | restrictions on the recipients' exercise of the rights granted herein. | |
370 | You are not responsible for enforcing compliance by third parties with | |
371 | this License. | |
372 | ||
373 | 11. If, as a consequence of a court judgment or allegation of patent | |
374 | infringement or for any other reason (not limited to patent issues), | |
375 | conditions are imposed on you (whether by court order, agreement or | |
376 | otherwise) that contradict the conditions of this License, they do not | |
377 | excuse you from the conditions of this License. If you cannot | |
378 | distribute so as to satisfy simultaneously your obligations under this | |
379 | License and any other pertinent obligations, then as a consequence you | |
380 | may not distribute the Library at all. For example, if a patent | |
381 | license would not permit royalty-free redistribution of the Library by | |
382 | all those who receive copies directly or indirectly through you, then | |
383 | the only way you could satisfy both it and this License would be to | |
384 | refrain entirely from distribution of the Library. | |
385 | ||
386 | If any portion of this section is held invalid or unenforceable under any | |
387 | particular circumstance, the balance of the section is intended to apply, | |
388 | and the section as a whole is intended to apply in other circumstances. | |
389 | ||
390 | It is not the purpose of this section to induce you to infringe any | |
391 | patents or other property right claims or to contest validity of any | |
392 | such claims; this section has the sole purpose of protecting the | |
393 | integrity of the free software distribution system which is | |
394 | implemented by public license practices. Many people have made | |
395 | generous contributions to the wide range of software distributed | |
396 | through that system in reliance on consistent application of that | |
397 | system; it is up to the author/donor to decide if he or she is willing | |
398 | to distribute software through any other system and a licensee cannot | |
399 | impose that choice. | |
400 | ||
401 | This section is intended to make thoroughly clear what is believed to | |
402 | be a consequence of the rest of this License. | |
403 | ||
404 | 12. If the distribution and/or use of the Library is restricted in | |
405 | certain countries either by patents or by copyrighted interfaces, the | |
406 | original copyright holder who places the Library under this License may add | |
407 | an explicit geographical distribution limitation excluding those countries, | |
408 | so that distribution is permitted only in or among countries not thus | |
409 | excluded. In such case, this License incorporates the limitation as if | |
410 | written in the body of this License. | |
411 | ||
412 | 13. The Free Software Foundation may publish revised and/or new | |
413 | versions of the Lesser General Public License from time to time. | |
414 | Such new versions will be similar in spirit to the present version, | |
415 | but may differ in detail to address new problems or concerns. | |
416 | ||
417 | Each version is given a distinguishing version number. If the Library | |
418 | specifies a version number of this License which applies to it and | |
419 | "any later version", you have the option of following the terms and | |
420 | conditions either of that version or of any later version published by | |
421 | the Free Software Foundation. If the Library does not specify a | |
422 | license version number, you may choose any version ever published by | |
423 | the Free Software Foundation. | |
424 | ||
425 | 14. If you wish to incorporate parts of the Library into other free | |
426 | programs whose distribution conditions are incompatible with these, | |
427 | write to the author to ask for permission. For software which is | |
428 | copyrighted by the Free Software Foundation, write to the Free | |
429 | Software Foundation; we sometimes make exceptions for this. Our | |
430 | decision will be guided by the two goals of preserving the free status | |
431 | of all derivatives of our free software and of promoting the sharing | |
432 | and reuse of software generally. | |
433 | ||
434 | NO WARRANTY | |
435 | ||
436 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO | |
437 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. | |
438 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR | |
439 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY | |
440 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE | |
441 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
442 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE | |
443 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME | |
444 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | |
445 | ||
446 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN | |
447 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY | |
448 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU | |
449 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR | |
450 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE | |
451 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING | |
452 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A | |
453 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF | |
454 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH | |
455 | DAMAGES. |
0 | # | |
1 | # Enhanced Seccomp Library Makefile | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | # | |
22 | # macros | |
23 | # | |
24 | ||
25 | include macros.mk | |
26 | ||
27 | # | |
28 | # configuration | |
29 | # | |
30 | ||
31 | -include version_info.mk | |
32 | -include configure.mk | |
33 | include install.mk | |
34 | ||
35 | # | |
36 | # targets | |
37 | # | |
38 | ||
39 | CONFIGS = configure.mk configure.h version_info.mk libseccomp.pc | |
40 | SUBDIRS_BUILD = include src tests tools | |
41 | SUBDIRS_INSTALL = include src tools doc | |
42 | ||
43 | .PHONY: tarball install check check-syntax ctags cstags clean dist-clean \ | |
44 | $(SUBDIRS_BUILD) | |
45 | ||
46 | all: $(SUBDIRS_BUILD) | |
47 | ||
48 | $(CONFIGS): version_info | |
49 | @$(ECHO_INFO) "automatically generating configuration ..." | |
50 | @./configure | |
51 | ||
52 | tarball: dist-clean | |
53 | @ver=$(VERSION_RELEASE); \ | |
54 | tarball=libseccomp-$$ver.tar.gz; \ | |
55 | $(ECHO_INFO) "creating the tarball ../$$tarball"; \ | |
56 | tmp_dir=$$(mktemp -d /tmp/libseccomp.XXXXX); \ | |
57 | rel_dir=$$tmp_dir/libseccomp-$$ver; \ | |
58 | $(MKDIR) $$rel_dir; \ | |
59 | $(TAR) cf - --exclude=*~ --exclude=.git* --exclude=.stgit* . | \ | |
60 | (cd $$rel_dir; tar xf -); \ | |
61 | (cd $$tmp_dir; $(TAR) zcf $$tarball libseccomp-$$ver); \ | |
62 | $(MV) $$tmp_dir/$$tarball ..; \ | |
63 | $(RM) -rf $$tmp_dir; | |
64 | ||
65 | $(VERSION_HDR): version_info.mk | |
66 | @$(ECHO_INFO) "creating the version header file" | |
67 | @hdr="$(VERSION_HDR)"; \ | |
68 | $(ECHO) "/* automatically generated - do not edit */" > $$hdr; \ | |
69 | $(ECHO) "#ifndef _VERSION_H" >> $$hdr; \ | |
70 | $(ECHO) "#define _VERSION_H" >> $$hdr; \ | |
71 | $(ECHO) "#define VERSION_RELEASE \"$(VERSION_RELEASE)\"" >> $$hdr; \ | |
72 | $(ECHO) "#define VERSION_MAJOR $(VERSION_MAJOR)" >> $$hdr; \ | |
73 | $(ECHO) "#define VERSION_MINOR $(VERSION_MINOR)" >> $$hdr; \ | |
74 | $(ECHO) "#define VERSION_MICRO $(VERSION_MICRO)" >> $$hdr; \ | |
75 | $(ECHO) "#endif" >> $$hdr; | |
76 | ||
77 | include: $(VERSION_HDR) $(CONFIGS) | |
78 | @$(ECHO_INFO) "building in directory $@/ ..." | |
79 | @$(MAKE) -C $@ | |
80 | ||
81 | src: $(VERSION_HDR) $(CONFIGS) include | |
82 | @$(ECHO_INFO) "building in directory $@/ ..." | |
83 | @$(MAKE) -C $@ | |
84 | ||
85 | tests: src include | |
86 | @$(ECHO_INFO) "building in directory $@/ ..." | |
87 | @$(MAKE) -C $@ | |
88 | ||
89 | tools: src include | |
90 | @$(ECHO_INFO) "building in directory $@/ ..." | |
91 | @$(MAKE) -C $@ | |
92 | ||
93 | install: $(SUBDIRS_BUILD) | |
94 | @$(ECHO_INFO) "installing in $(INSTALL_PREFIX) ..." | |
95 | $(INSTALL_PC_MACRO) libseccomp.pc | |
96 | @for dir in $(SUBDIRS_INSTALL); do \ | |
97 | $(ECHO_INFO) "installing from $$dir/"; \ | |
98 | $(MAKE) -C $$dir install; \ | |
99 | done | |
100 | ||
101 | check: tools tests | |
102 | @$(ECHO_INFO) "checking in directory tests/ ..." | |
103 | @$(MAKE) -C tests check | |
104 | ||
105 | check-syntax: | |
106 | @./tools/check-syntax | |
107 | ||
108 | ctags: | |
109 | @$(ECHO_INFO) "generating ctags for the project ..." | |
110 | @ctags -R * | |
111 | ||
112 | cstags: | |
113 | @$(ECHO_INFO) "generating cscope tags for the project ..." | |
114 | @find -iname *.[ch] > cscope.files | |
115 | @cscope -b -q -k | |
116 | ||
117 | clean: | |
118 | @$(ECHO_INFO) "cleaning up libseccomp" | |
119 | @for dir in $(SUBDIRS_BUILD); do \ | |
120 | $(MAKE) -C $$dir clean; \ | |
121 | done | |
122 | ||
123 | dist-clean: clean | |
124 | @$(ECHO_INFO) "removing the configuration files" | |
125 | @$(RM) $(CONFIGS) |
0 | libseccomp: An Enhanced Seccomp (mode 2) Helper Library | |
1 | =============================================================================== | |
2 | http://libseccomp.sf.net | |
3 | ||
4 | The libseccomp library provides and easy to use, platform independent, | |
5 | interface to the Linux Kernel's syscall filtering mechanism: seccomp. The | |
6 | libseccomp API is designed to abstract away the underlying BPF based syscall | |
7 | filter language and present a more conventional function-call based filtering | |
8 | interface that should be familiar to, and easily adopted by application | |
9 | developers. | |
10 | ||
11 | * Documentation | |
12 | ||
13 | The "doc/" directory contains all of the documentation aside from the README | |
14 | file (this file) and the LICENSE file which can be found in the top level | |
15 | directory. | |
16 | ||
17 | * Building and Installing the Library | |
18 | ||
19 | In order to build the library you should follow the familiar three step | |
20 | process used by most applications: | |
21 | ||
22 | # ./configure | |
23 | # make [V=0|1] | |
24 | # make install | |
25 | ||
26 | As usual, running "./configure -h" will display a list of build-time | |
27 | configuration options. | |
28 | ||
29 | * Testing the Library | |
30 | ||
31 | There are a number of tests located in the "tests/" directory and a script | |
32 | which can be used to help automate their execution, "regression". If you want | |
33 | to run all of the tests you can simply run the script: | |
34 | ||
35 | # ./configure | |
36 | # make | |
37 | # cd tests | |
38 | # ./regression | |
39 | ||
40 | However, the script takes a number of options to customize its execution; the | |
41 | options can be displayed by running "./regression -h". | |
42 | ||
43 | * Other Useful Tools | |
44 | ||
45 | The "tools/" directory includes a number of tools which may be helpful in the | |
46 | development of the library, or applications using the library, but for various | |
47 | reasons are not installed by default. |
0 | #!/bin/bash | |
1 | ||
2 | # | |
3 | # Enhanced Seccomp Library Configure Script | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | # configuration defaults | |
24 | opt_prefix="/usr/local" | |
25 | opt_libdir="" | |
26 | opt_sysinc_seccomp="yes" | |
27 | opt_bindings_python="no" | |
28 | ||
29 | # output files | |
30 | cnf_mk_file="configure.mk" | |
31 | cnf_h_file="configure.h" | |
32 | ||
33 | #### | |
34 | # functions | |
35 | ||
36 | function test_deps() { | |
37 | [[ -z "$1" ]] && return 0 | |
38 | which "$1" >& /dev/null && return 0 | |
39 | return 1 | |
40 | } | |
41 | ||
42 | function verify_deps() { | |
43 | [[ -z "$1" ]] && return | |
44 | if ! test_deps "$1"; then | |
45 | echo "error: install \"$1\" and include it in your \$PATH" | |
46 | exit 1 | |
47 | fi | |
48 | } | |
49 | ||
50 | function msg_usage() { | |
51 | cat << EOF | |
52 | Configure the enhanced seccomp library, libseccomp, for this system. | |
53 | ||
54 | Usage: | |
55 | ./configure <options> | |
56 | ||
57 | Options: | |
58 | * general configuration | |
59 | -h, --help display this help and exit | |
60 | * installation configuration | |
61 | --prefix=PREFIX installation base [/usr/local] | |
62 | --libdir=DIR library directory [/usr/local/lib] | |
63 | EOF | |
64 | } | |
65 | ||
66 | function msg_summary() { | |
67 | cat << EOF | |
68 | CONFIGURATION SUMMARY | |
69 | libseccomp version: ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO} | |
70 | installation base: $opt_prefix | |
71 | library directory: $opt_libdir | |
72 | use system includes: $opt_sysinc_seccomp | |
73 | EOF | |
74 | } | |
75 | ||
76 | function msg_error() { | |
77 | echo "error: $@" | |
78 | } | |
79 | ||
80 | function cnf_mk_header() { | |
81 | echo "# generated by configure on $(date -R)" >> $cnf_mk_file | |
82 | echo "# options: \"$opt_str\"" >> $cnf_mk_file | |
83 | echo "" >> $cnf_mk_file | |
84 | } | |
85 | ||
86 | function cnf_mk_footer() { | |
87 | echo "" >> $cnf_mk_file | |
88 | } | |
89 | ||
90 | function cnf_mk_entry() { | |
91 | [[ $# -ne 2 ]] && return | |
92 | case "$2" in | |
93 | no) | |
94 | echo "$1 = 0" >> $cnf_mk_file | |
95 | ;; | |
96 | yes) | |
97 | echo "$1 = 1" >> $cnf_mk_file | |
98 | ;; | |
99 | *) | |
100 | echo "$1 = \"$2\"" >> $cnf_mk_file | |
101 | esac | |
102 | } | |
103 | ||
104 | function cnf_h_header() { | |
105 | echo "/* generated by configure on $(date -R) */" >> $cnf_h_file | |
106 | echo "/* options: \"$opt_str\" */" >> $cnf_h_file | |
107 | echo "" >> $cnf_h_file | |
108 | echo "#ifndef _CONFIGURE_H" >> $cnf_h_file | |
109 | echo "#define _CONFIGURE_H" >> $cnf_h_file | |
110 | echo "" >> $cnf_h_file | |
111 | } | |
112 | ||
113 | function cnf_h_footer() { | |
114 | echo "" >> $cnf_h_file | |
115 | echo "#endif" >> $cnf_h_file | |
116 | echo "" >> $cnf_h_file | |
117 | } | |
118 | ||
119 | function cnf_h_entry() { | |
120 | [[ $# -ne 2 ]] && return | |
121 | case "$2" in | |
122 | no) | |
123 | echo "#undef $1" >> $cnf_h_file | |
124 | ;; | |
125 | yes) | |
126 | echo "#define $1 1" >> $cnf_h_file | |
127 | ;; | |
128 | *) | |
129 | echo "#define $1 $2" >> $cnf_h_file | |
130 | esac | |
131 | } | |
132 | ||
133 | function cnf_reset() { | |
134 | cat /dev/null > $cnf_mk_file | |
135 | cat /dev/null > $cnf_h_file | |
136 | } | |
137 | ||
138 | function cnf_header() { | |
139 | cnf_mk_header | |
140 | cnf_h_header | |
141 | } | |
142 | ||
143 | function cnf_entry() { | |
144 | cnf_mk_entry "$1" "$2" | |
145 | cnf_h_entry "$1" "$2" | |
146 | } | |
147 | ||
148 | function cnf_footer() { | |
149 | cnf_mk_footer | |
150 | cnf_h_footer | |
151 | } | |
152 | ||
153 | function tmpl_filter() { | |
154 | name="echo \$$1" | |
155 | val="$(eval $name)" | |
156 | cat - | sed -e 's/%%'"$1"'%%/'"${val//\//\\/}"'/g;' | |
157 | } | |
158 | ||
159 | #### | |
160 | # main | |
161 | ||
162 | # | |
163 | # setup | |
164 | # | |
165 | ||
166 | # verify script dependencies | |
167 | verify_deps getopt | |
168 | ||
169 | # parse the command line options | |
170 | opt_str="$@" | |
171 | opt=$(getopt -n "$0" --options "h" --longoptions "help,prefix:,libdir:" -- "$@") | |
172 | eval set -- "$opt" | |
173 | while [[ $# -gt 0 ]]; do | |
174 | case "$1" in | |
175 | --prefix) | |
176 | opt_prefix="$2" | |
177 | shift 2 | |
178 | ;; | |
179 | --libdir) | |
180 | opt_libdir="$2" | |
181 | shift 2 | |
182 | ;; | |
183 | -h|--help) | |
184 | msg_usage | |
185 | exit 0 | |
186 | ;; | |
187 | --) | |
188 | shift | |
189 | ;; | |
190 | *) | |
191 | msg_usage | |
192 | exit 1 | |
193 | esac | |
194 | done | |
195 | ||
196 | # | |
197 | # validate the command line options | |
198 | # | |
199 | ||
200 | if [[ -e "$opt_prefix" && ! -d "$opt_prefix" ]]; then | |
201 | msg_error "install prefix ($opt_prefix) is not a directory" | |
202 | exit 1 | |
203 | fi | |
204 | ||
205 | if [[ -z $opt_libdir ]]; then | |
206 | opt_libdir="$opt_prefix/lib" | |
207 | fi | |
208 | if [[ -e "$opt_libdir" && ! -d "$opt_libdir" ]]; then | |
209 | msg_error "libdir ($opt_libdir) is not a directory" | |
210 | exit 1 | |
211 | fi | |
212 | ||
213 | if [[ "$opt_bindings_python" = "yes" ]]; then | |
214 | if ! test_deps cython; then | |
215 | msg_error "python bindings require the cython package" | |
216 | exit 1 | |
217 | fi | |
218 | cython_ver=$(cython -V 2>&1 | cut -d' ' -f 3) | |
219 | if [[ $(echo $cython_ver | cut -d'.' -f 1) -lt 1 && | |
220 | $(echo $cython_ver | cut -d'.' -f 2) -lt 16 ]]; then | |
221 | msg_error "python bindings require cython 0.16 or higher" | |
222 | exit 1 | |
223 | fi | |
224 | fi | |
225 | ||
226 | # | |
227 | # automatic configuration | |
228 | # | |
229 | ||
230 | # system seccomp includes | |
231 | if [[ -r "/usr/include/linux/seccomp.h" ]]; then | |
232 | opt_sysinc_seccomp="yes" | |
233 | else | |
234 | opt_sysinc_seccomp="no" | |
235 | fi | |
236 | ||
237 | # generate the version files | |
238 | . ./version_info | |
239 | VERSION_RELEASE="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO}" | |
240 | rm -f ./version_info.mk | |
241 | echo "# generated by configure on $(date -R)" >> ./version_info.mk | |
242 | echo "VERSION_MAJOR=$VERSION_MAJOR" >> ./version_info.mk | |
243 | echo "VERSION_MINOR=$VERSION_MINOR" >> ./version_info.mk | |
244 | echo "VERSION_MICRO=$VERSION_MICRO" >> ./version_info.mk | |
245 | echo "VERSION_RELEASE=$VERSION_RELEASE" >> ./version_info.mk | |
246 | ||
247 | # generate the pkg-config metadata | |
248 | INSTALL_PREFIX="$opt_prefix" | |
249 | INSTALL_LIBDIR="$opt_libdir" | |
250 | rm -f ./libseccomp.pc | |
251 | cat ./libseccomp.pc.in | \ | |
252 | tmpl_filter INSTALL_PREFIX | \ | |
253 | tmpl_filter INSTALL_LIBDIR | \ | |
254 | tmpl_filter VERSION_RELEASE \ | |
255 | >> ./libseccomp.pc | |
256 | ||
257 | # | |
258 | # finish | |
259 | # | |
260 | ||
261 | # reset the configuration files | |
262 | cnf_reset | |
263 | cnf_header | |
264 | ||
265 | # output the configuration files | |
266 | cnf_mk_entry "CONF_INSTALL_PREFIX" "$opt_prefix" | |
267 | cnf_mk_entry "CONF_INSTALL_LIBDIR" "$opt_libdir" | |
268 | cnf_entry "CONF_SYSINC_SECCOMP" "$opt_sysinc_seccomp" | |
269 | cnf_entry "CONF_BINDINGS_PYTHON" "$opt_bindings_python" | |
270 | ||
271 | # configuration footer | |
272 | cnf_footer | |
273 | ||
274 | # display a summary and exit | |
275 | msg_summary | |
276 | exit 0 |
0 | libseccomp (2.1.1-1) unstable; urgency=low | |
1 | ||
2 | * New upstream release (Closes: 733293). | |
3 | * copyright: add a few missed people. | |
4 | * rules: adjusted for new test target. | |
5 | * libseccomp2.symbols: drop accidentally exported functions. | |
6 | * control: | |
7 | - bump standards, no changes needed. | |
8 | - add armel target | |
9 | ||
10 | -- Kees Cook <kees@debian.org> Sat, 12 Apr 2014 10:44:22 -0700 | |
11 | ||
12 | libseccomp (2.1.0+dfsg-1) unstable; urgency=low | |
13 | ||
14 | * Rebuild source package without accidental binaries (Closes: 725617). | |
15 | - debian/watch: mangle upstream version check. | |
16 | * debian/rules: make tests non-fatal while upstream fixes them | |
17 | (Closes: 721292). | |
18 | ||
19 | -- Kees Cook <kees@debian.org> Sun, 06 Oct 2013 15:05:51 -0700 | |
20 | ||
21 | libseccomp (2.1.0-1) unstable; urgency=low | |
22 | ||
23 | * New upstream release (Closes: 718398): | |
24 | - dropped debian/patches/manpage-dashes.patch: taken upstream. | |
25 | - dropped debian/patches/include-unistd.patch: not needed. | |
26 | - debian/patches/testsuite-x86-write.patch: taken upstream. | |
27 | - ABI bump: moved from libseccomp1 to libseccomp2. | |
28 | * debian/control: | |
29 | - added Arch: armhf, now supported upstream. | |
30 | - added seccomp binary package for helper tools. | |
31 | * Added debian/patches/manpage-typo.patch: spelling fix. | |
32 | * Added debian/patches/build-ldflags.patch: fix LDFLAGS handling. | |
33 | ||
34 | -- Kees Cook <kees@debian.org> Tue, 13 Aug 2013 00:02:01 -0700 | |
35 | ||
36 | libseccomp (1.0.1-2) unstable; urgency=low | |
37 | ||
38 | * debian/rules: enable testsuite at build time, thanks to | |
39 | Stéphane Graber (Closes: 698803). | |
40 | * Added debian/patches/include-unistd.patch: detect location of | |
41 | asm/unistd.h correctly. | |
42 | * Added debian/patches/testsuite-x86-write.patch: skip the "write" | |
43 | syscall correctly on x86. | |
44 | * debian/control: bump standards to 3.9.4, no changes needed. | |
45 | ||
46 | -- Kees Cook <kees@debian.org> Wed, 23 Jan 2013 13:11:53 -0800 | |
47 | ||
48 | libseccomp (1.0.1-1) unstable; urgency=low | |
49 | ||
50 | * New upstream release. | |
51 | * debian/control: only build on amd64 and i386 (Closes: 687368). | |
52 | ||
53 | -- Kees Cook <kees@debian.org> Fri, 07 Dec 2012 11:38:03 -0800 | |
54 | ||
55 | libseccomp (1.0.0-1) unstable; urgency=low | |
56 | ||
57 | * New upstream release. | |
58 | - bump ABI. | |
59 | - drop build verbosity patch, use upstream V=1 instead. | |
60 | * libseccomp-dev.manpages: fix build location (Closes: 682152, 682471). | |
61 | * debian/patches/pkgconfig-macro.patch: use literals for macro. | |
62 | ||
63 | -- Kees Cook <kees@debian.org> Fri, 03 Aug 2012 16:59:41 -0700 | |
64 | ||
65 | libseccomp (0.1.0-1) unstable; urgency=low | |
66 | ||
67 | * New upstream release. | |
68 | - drop patches taken upstream: | |
69 | - libexecdir.patch | |
70 | - pass-flags.patch | |
71 | ||
72 | -- Kees Cook <kees@debian.org> Fri, 08 Jun 2012 12:32:22 -0700 | |
73 | ||
74 | libseccomp (0.0.0~20120605-1) unstable; urgency=low | |
75 | ||
76 | * Initial release (Closes: #676257). | |
77 | ||
78 | -- Kees Cook <kees@debian.org> Tue, 05 Jun 2012 11:28:07 -0700 |
0 | 9 |
0 | Source: libseccomp | |
1 | Section: libs | |
2 | Priority: optional | |
3 | Maintainer: Kees Cook <kees@debian.org> | |
4 | Build-Depends: debhelper (>= 9), linux-libc-dev | |
5 | Standards-Version: 3.9.5 | |
6 | Homepage: https://sourceforge.net/projects/libseccomp/ | |
7 | ||
8 | Package: libseccomp-dev | |
9 | Section: libdevel | |
10 | Architecture: i386 amd64 armhf armel | |
11 | Multi-Arch: same | |
12 | Pre-Depends: ${misc:Pre-Depends} | |
13 | Depends: libseccomp2 (= ${binary:Version}), ${misc:Depends} | |
14 | Suggests: seccomp | |
15 | Description: high level interface to Linux seccomp filter (development files) | |
16 | This library provides a high level interface to constructing, analyzing | |
17 | and installing seccomp filters via a BPF passed to the Linux Kernel's | |
18 | prctl() syscall. | |
19 | . | |
20 | This package contains the development files. | |
21 | ||
22 | Package: libseccomp2 | |
23 | Architecture: i386 amd64 armhf armel | |
24 | Multi-Arch: same | |
25 | Pre-Depends: ${misc:Pre-Depends} | |
26 | Depends: ${shlibs:Depends}, ${misc:Depends} | |
27 | Description: high level interface to Linux seccomp filter | |
28 | This library provides a high level interface to constructing, analyzing | |
29 | and installing seccomp filters via a BPF passed to the Linux Kernel's | |
30 | prctl() syscall. | |
31 | ||
32 | Package: seccomp | |
33 | Section: utils | |
34 | Architecture: i386 amd64 armhf armel | |
35 | Depends: ${shlibs:Depends}, ${misc:Depends} | |
36 | Suggests: libseccomp-dev | |
37 | Description: helper tools for high level interface to Linux seccomp filter | |
38 | Provides helper tools for interacting with libseccomp. Currently, only | |
39 | a single tool exists, providing a way to easily enumerate syscalls across | |
40 | the supported architectures. |
0 | Format: http://dep.debian.net/deps/dep5 | |
1 | Upstream-Name: libseccomp | |
2 | Source: https://sourceforge.net/projects/libseccomp/ | |
3 | ||
4 | Files: * | |
5 | Copyright: 2012 Paul Moore <pmoore@redhat.com> | |
6 | 2012 Ashley Lai <adlai@us.ibm.com> | |
7 | 2012 Corey Bryant <coreyb@linux.vnet.ibm.com> | |
8 | 2012 Eduardo Otubo <otubo@linux.vnet.ibm.com> | |
9 | 2012 Eric Paris <eparis@redhat.com> | |
10 | License: LGPL-2.0+ | |
11 | ||
12 | Files: tests/22-sim-basic_chains_array.tests | |
13 | Copyright: 2013 Vitaly Shukela <vi0oss@gmail.com> | |
14 | License: LGPL-2.0+ | |
15 | ||
16 | Files: src/hash.* | |
17 | Copyright: 2006 Bob Jenkins <bob_jenkins@burtleburtle.net> | |
18 | License: LGPL-2.0+ | |
19 | ||
20 | Files: debian/* | |
21 | Copyright: 2012 Kees Cook <kees@debian.org> | |
22 | License: LGPL-2.0+ | |
23 | ||
24 | License: LGPL-2.0+ | |
25 | This package is free software; you can redistribute it and/or | |
26 | modify it under the terms of the GNU Lesser General Public | |
27 | License as published by the Free Software Foundation; either | |
28 | version 2 of the License, or (at your option) any later version. | |
29 | . | |
30 | This package is distributed in the hope that it will be useful, | |
31 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
33 | Lesser General Public License for more details. | |
34 | . | |
35 | You should have received a copy of the GNU General Public License | |
36 | along with this program. If not, see <http://www.gnu.org/licenses/>. | |
37 | . | |
38 | On Debian systems, the complete text of the GNU Lesser General | |
39 | Public License can be found in "/usr/share/common-licenses/LGPL-2". |
0 | README |
0 | [DEFAULT] | |
1 | upstream-tag = upstream/%(version)s | |
2 | debian-tag = debian/%(version)s | |
3 | pristine-tar = True | |
4 | upstream-branch = upstream | |
5 | debian-branch = debian/sid | |
6 | ||
7 | [buildpackage] | |
8 | submodules = True |
0 | debian/tmp/usr/share/man/man3/* |
0 | usr/lib/*/lib*.so.* |
0 | libseccomp.so.2 libseccomp2 #MINVER# | |
1 | arch_arg_count_max@Base 0.0.0~20120605 | |
2 | arch_arg_offset_hi@Base 0.0.0~20120605 | |
3 | arch_arg_offset_lo@Base 0.0.0~20120605 | |
4 | arch_def_native@Base 0.0.0~20120605 | |
5 | arch_filter_rewrite@Base 0.0.0~20120605 | |
6 | arch_syscall_rewrite@Base 0.0.0~20120605 | |
7 | db_action_valid@Base 0.0.0~20120605 | |
8 | db_init@Base 0.0.0~20120605 | |
9 | db_release@Base 0.0.0~20120605 | |
10 | db_reset@Base 1.0.0 | |
11 | db_rule_add@Base 0.0.0~20120605 | |
12 | db_syscall_priority@Base 0.0.0~20120605 | |
13 | gen_bpf_generate@Base 0.0.0~20120605 | |
14 | gen_bpf_release@Base 0.0.0~20120605 | |
15 | gen_pfc_generate@Base 0.0.0~20120605 | |
16 | jhash@Base 0.0.0~20120605 | |
17 | seccomp_attr_get@Base 0.0.0~20120605 | |
18 | seccomp_attr_set@Base 0.0.0~20120605 | |
19 | seccomp_export_bpf@Base 0.0.0~20120605 | |
20 | seccomp_export_pfc@Base 0.0.0~20120605 | |
21 | seccomp_init@Base 0.0.0~20120605 | |
22 | seccomp_load@Base 0.0.0~20120605 | |
23 | seccomp_release@Base 0.0.0~20120605 | |
24 | seccomp_reset@Base 0.0.0~20120605 | |
25 | seccomp_rule_add@Base 0.0.0~20120605 | |
26 | seccomp_rule_add_exact@Base 0.0.0~20120605 | |
27 | seccomp_syscall_priority@Base 0.0.0~20120605 | |
28 | seccomp_syscall_resolve_name@Base 1.0.1 | |
29 | x86_64_syscall_table@Base 1.0.1 | |
30 | seccomp_merge@Base 1.0.1 | |
31 | seccomp_arch_add@Base 1.0.1 | |
32 | seccomp_arch_exist@Base 1.0.1 | |
33 | seccomp_arch_remove@Base 1.0.1 | |
34 | arch_def_lookup@Base 1.0.1 | |
35 | arch_def_x86_64@Base 1.0.1 | |
36 | arch_syscall_resolve_name@Base 1.0.1 | |
37 | arch_syscall_resolve_num@Base 1.0.1 | |
38 | arch_syscall_translate@Base 1.0.1 | |
39 | arch_valid@Base 1.0.1 | |
40 | db_col_arch_exist@Base 1.0.1 | |
41 | db_col_attr_get@Base 1.0.1 | |
42 | db_col_attr_set@Base 1.0.1 | |
43 | db_col_db_add@Base 1.0.1 | |
44 | db_col_db_remove@Base 1.0.1 | |
45 | db_col_init@Base 1.0.1 | |
46 | db_col_merge@Base 1.0.1 | |
47 | db_col_release@Base 1.0.1 | |
48 | db_col_reset@Base 1.0.1 | |
49 | db_col_valid@Base 1.0.1 | |
50 | arch_def_arm@Base 2.1.0 | |
51 | arch_def_x32@Base 2.1.0 | |
52 | arch_def_x86@Base 2.1.0 | |
53 | arm_syscall_resolve_name@Base 2.1.0 | |
54 | arm_syscall_resolve_num@Base 2.1.0 | |
55 | arm_syscall_table@Base 2.1.0 | |
56 | seccomp_arch_native@Base 2.1.0 | |
57 | seccomp_rule_add_array@Base 2.1.0 | |
58 | seccomp_rule_add_exact_array@Base 2.1.0 | |
59 | seccomp_syscall_resolve_name_arch@Base 2.1.0 | |
60 | seccomp_syscall_resolve_num_arch@Base 2.1.0 | |
61 | x32_syscall_resolve_name@Base 2.1.0 | |
62 | x32_syscall_resolve_num@Base 2.1.0 | |
63 | x86_64_syscall_resolve_name@Base 2.1.0 | |
64 | x86_64_syscall_resolve_num@Base 2.1.0 | |
65 | x86_filter_rewrite@Base 2.1.0 | |
66 | x86_syscall_resolve_name@Base 2.1.0 | |
67 | x86_syscall_resolve_num@Base 2.1.0 | |
68 | x86_syscall_rewrite@Base 2.1.0 |
0 | Description: LIBFLAGS are for libraries, LDFLAGS are for linker arguments. | |
1 | Author: Kees Cook <kees@debian.org> | |
2 | ||
3 | Index: libseccomp-2.1.0/macros.mk | |
4 | =================================================================== | |
5 | --- libseccomp-2.1.0.orig/macros.mk 2013-08-13 00:55:29.615739819 -0700 | |
6 | +++ libseccomp-2.1.0/macros.mk 2013-08-13 01:00:12.123634186 -0700 | |
7 | @@ -136,7 +136,7 @@ | |
8 | ifeq ($(V),0) | |
9 | COMPILE_EXEC = @echo " CC $@"; | |
10 | endif | |
11 | -COMPILE_EXEC += $(GCC) $(CFLAGS) $(CPPFLAGS) -o $@ $< $(LDFLAGS); | |
12 | +COMPILE_EXEC += $(GCC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LIBFLAGS); | |
13 | ||
14 | ifeq ($(V),0) | |
15 | ARCHIVE = @echo " AR $@"; | |
16 | Index: libseccomp-2.1.0/tools/Makefile | |
17 | =================================================================== | |
18 | --- libseccomp-2.1.0.orig/tools/Makefile 2013-05-29 11:46:02.000000000 -0700 | |
19 | +++ libseccomp-2.1.0/tools/Makefile 2013-08-13 00:58:11.025965101 -0700 | |
20 | @@ -32,7 +32,7 @@ | |
21 | include $(TOPDIR)/configure.mk | |
22 | include $(TOPDIR)/install.mk | |
23 | ||
24 | -LDFLAGS := ../src/libseccomp.a | |
25 | +LIBFLAGS := ../src/libseccomp.a | |
26 | ||
27 | TOOLS = scmp_bpf_disasm \ | |
28 | scmp_bpf_sim \ | |
29 | Index: libseccomp-2.1.0/tests/Makefile | |
30 | =================================================================== | |
31 | --- libseccomp-2.1.0.orig/tests/Makefile 2013-05-23 13:53:11.000000000 -0700 | |
32 | +++ libseccomp-2.1.0/tests/Makefile 2013-08-13 00:59:44.707256337 -0700 | |
33 | @@ -34,7 +34,7 @@ | |
34 | ||
35 | OBJS = util.o | |
36 | ||
37 | -LDFLAGS := ../src/libseccomp.a $(OBJS) | |
38 | +LIBFLAGS := ../src/libseccomp.a $(OBJS) | |
39 | ||
40 | TEST_PRIVATE = 00-test | |
41 |
0 | Description: fix typo in manpage, noticed by lintian. | |
1 | Author: Kees Cook <kees@debian.org> | |
2 | ||
3 | Index: libseccomp-2.1.0/doc/man/man1/scmp_sys_resolver.1 | |
4 | =================================================================== | |
5 | --- libseccomp-2.1.0.orig/doc/man/man1/scmp_sys_resolver.1 2013-05-29 11:46:16.000000000 -0700 | |
6 | +++ libseccomp-2.1.0/doc/man/man1/scmp_sys_resolver.1 2013-08-13 00:34:46.002565608 -0700 | |
7 | @@ -37,7 +37,7 @@ | |
8 | values are "x86", "x86_64", "x32", and "arm". | |
9 | .TP | |
10 | .B \-t | |
11 | -If neccessary, translate the system call name to the proper system call number, | |
12 | +If necessary, translate the system call name to the proper system call number, | |
13 | even if the system call name is different, e.g. socket(2) on x86. | |
14 | .TP | |
15 | .B \-h |
0 | Description: this bash trick doesn't work for some reason, so just replace | |
1 | with the needed literal "libseccomp.pc" instead. | |
2 | Author: Kees Cook <kees@debian.org> | |
3 | ||
4 | Index: libseccomp-2.1.0/macros.mk | |
5 | =================================================================== | |
6 | --- libseccomp-2.1.0.orig/macros.mk 2013-08-13 00:02:48.756235141 -0700 | |
7 | +++ libseccomp-2.1.0/macros.mk 2013-08-13 00:02:48.752235086 -0700 | |
8 | @@ -185,15 +185,13 @@ | |
9 | ||
10 | ifeq ($(V),0) | |
11 | INSTALL_PC_MACRO = \ | |
12 | - @echo " INSTALL $$(cat /proc/$$$$/cmdline | awk '{print $$(NF)}')" \ | |
13 | - " ($(INSTALL_LIB_DIR)/pkgconfig)"; | |
14 | + @echo " INSTALL libseccomp.pc ($(INSTALL_LIB_DIR)/pkgconfig)"; | |
15 | endif | |
16 | INSTALL_PC_MACRO += \ | |
17 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) \ | |
18 | -d "$(INSTALL_LIB_DIR)/pkgconfig"; \ | |
19 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) -m 0644 \ | |
20 | - "$$(cat /proc/$$$$/cmdline | awk '{print $$(NF)}')" \ | |
21 | - "$(INSTALL_LIB_DIR)/pkgconfig"; \# | |
22 | + "libseccomp.pc" "$(INSTALL_LIB_DIR)/pkgconfig"; \# | |
23 | ||
24 | ifeq ($(V),0) | |
25 | INSTALL_INC_MACRO = @echo " INSTALL $^ ($(INSTALL_INC_DIR))"; |
0 | #!/usr/bin/make -f | |
1 | # -*- makefile -*- | |
2 | ||
3 | # Uncomment this to turn on verbose mode. | |
4 | #export DH_VERBOSE=1 | |
5 | DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) | |
6 | ||
7 | # Enable verbose build details. | |
8 | export V=1 | |
9 | ||
10 | %: | |
11 | dh $@ --parallel | |
12 | ||
13 | override_dh_auto_clean: | |
14 | $(MAKE) dist-clean | |
15 | rm -f regression.out | |
16 | ||
17 | override_dh_auto_configure: | |
18 | ./configure --prefix=/usr \ | |
19 | --libdir=/usr/lib/$(DEB_HOST_MULTIARCH) | |
20 | ||
21 | override_dh_auto_test: | |
22 | ifeq (,$(findstring nocheck,$(DEB_BUILD_OPTIONS))) | |
23 | make check 2>&1 | tee regression.out && \ | |
24 | grep -q "^ tests failed: 0" regression.out || true | |
25 | endif |
0 | usr/bin/* |
0 | debian/tmp/usr/share/man/man1/* |
0 | 3.0 (quilt) |
0 | # See uscan(1) for format | |
1 | version=3 | |
2 | opts=dversionmangle=s/\+dfsg// \ | |
3 | http://sf.net/libseccomp/libseccomp-(.*)\.tar\.gz \ | |
4 | debian uupdate |
0 | # | |
1 | # Enhanced Seccomp Library Makefile | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | # | |
22 | # macros | |
23 | # | |
24 | ||
25 | include ../macros.mk | |
26 | ||
27 | # | |
28 | # configuration | |
29 | # | |
30 | ||
31 | include $(TOPDIR)/version_info.mk | |
32 | include $(TOPDIR)/configure.mk | |
33 | include $(TOPDIR)/install.mk | |
34 | ||
35 | MAN1 = \ | |
36 | man/man1/scmp_sys_resolver.1 | |
37 | ||
38 | MAN3 = \ | |
39 | man/man3/seccomp_init.3 \ | |
40 | man/man3/seccomp_load.3 \ | |
41 | man/man3/seccomp_release.3 \ | |
42 | man/man3/seccomp_reset.3 \ | |
43 | man/man3/seccomp_rule_add.3 \ | |
44 | man/man3/seccomp_rule_add_exact.3 \ | |
45 | man/man3/seccomp_syscall_priority.3 \ | |
46 | man/man3/seccomp_syscall_resolve_name.3 \ | |
47 | man/man3/seccomp_syscall_resolve_name_arch.3 \ | |
48 | man/man3/seccomp_syscall_resolve_num_arch.3 \ | |
49 | man/man3/seccomp_export_bpf.3 \ | |
50 | man/man3/seccomp_export_pfc.3 \ | |
51 | man/man3/seccomp_attr_set.3 \ | |
52 | man/man3/seccomp_attr_get.3 \ | |
53 | man/man3/seccomp_arch_add.3 \ | |
54 | man/man3/seccomp_arch_exist.3 \ | |
55 | man/man3/seccomp_arch_native.3 \ | |
56 | man/man3/seccomp_arch_remove.3 \ | |
57 | man/man3/seccomp_merge.3 | |
58 | ||
59 | # | |
60 | # targets | |
61 | # | |
62 | ||
63 | .PHONY: all install install_man1 install_man3 | |
64 | ||
65 | all: | |
66 | ||
67 | install: install_man1 install_man3 | |
68 | ||
69 | install_man1: $(MAN1) | |
70 | $(INSTALL_MAN1_MACRO) | |
71 | ||
72 | install_man3: $(MAN3) | |
73 | $(INSTALL_MAN3_MACRO) |
0 | .TH "scmp_sys_resolver" 1 "23 May 2013" "paul@paul-moore.com" "libseccomp Documentation" | |
1 | .\" ////////////////////////////////////////////////////////////////////////// | |
2 | .SH NAME | |
3 | .\" ////////////////////////////////////////////////////////////////////////// | |
4 | scmp_sys_resolver \- Resolve system calls | |
5 | .\" ////////////////////////////////////////////////////////////////////////// | |
6 | .SH SYNOPSIS | |
7 | .\" ////////////////////////////////////////////////////////////////////////// | |
8 | .B scmp_sys_resolver | |
9 | [\-h] [\-a | |
10 | .I ARCH | |
11 | ] [\-t] | |
12 | .I SYSCALL_NAME | |
13 | | | |
14 | .I SYSCALL_NUMBER | |
15 | .\" ////////////////////////////////////////////////////////////////////////// | |
16 | .SH DESCRIPTION | |
17 | .\" ////////////////////////////////////////////////////////////////////////// | |
18 | .P | |
19 | This command resolves both system call names and numbers with respect to the | |
20 | given architecture supplied in the optional | |
21 | .I ARCH | |
22 | argument. If the architecture is not supplied on the command line then the | |
23 | native architecture is used. If the "\-t" argument is specified along with a | |
24 | system call name, then the system call will be translated as necessary for the | |
25 | given architecture. The "\-t" argument has no effect if a system call number | |
26 | is specified. | |
27 | .P | |
28 | In some combinations of architecture and system call, a negative system call | |
29 | number will be displayed. A negative system call number indicates that the | |
30 | system call is not defined for the given architecture and is treated in a | |
31 | special manner by libseccomp depending on the operation. | |
32 | .TP | |
33 | .B \-a \fIARCH | |
34 | The architecture to use for resolving the system call. Valid | |
35 | .I ARCH | |
36 | values are "x86", "x86_64", "x32", and "arm". | |
37 | .TP | |
38 | .B \-t | |
39 | If neccessary, translate the system call name to the proper system call number, | |
40 | even if the system call name is different, e.g. socket(2) on x86. | |
41 | .TP | |
42 | .B \-h | |
43 | A simple one-line usage display. | |
44 | .\" ////////////////////////////////////////////////////////////////////////// | |
45 | .SH EXIT STATUS | |
46 | .\" ////////////////////////////////////////////////////////////////////////// | |
47 | Returns zero on success, errno values on failure. | |
48 | .\" ////////////////////////////////////////////////////////////////////////// | |
49 | .SH NOTES | |
50 | .\" ////////////////////////////////////////////////////////////////////////// | |
51 | .P | |
52 | The libseccomp project site, with more information and the source code | |
53 | repository, can be found at http://libseccomp.sf.net. This tool, as well as | |
54 | the libseccomp library, is currently under development, please report any bugs | |
55 | at the project site or directly to the author. | |
56 | .\" ////////////////////////////////////////////////////////////////////////// | |
57 | .SH AUTHOR | |
58 | .\" ////////////////////////////////////////////////////////////////////////// | |
59 | Paul Moore <paul@paul-moore.com> |
0 | .TH "seccomp_arch_add" 3 "26 November 2012" "paul@paul-moore.com" "libseccomp Documentation" | |
1 | .\" ////////////////////////////////////////////////////////////////////////// | |
2 | .SH NAME | |
3 | .\" ////////////////////////////////////////////////////////////////////////// | |
4 | seccomp_arch_add, seccomp_arch_remove, seccomp_arch_exist, seccomp_arch_native \- Manage seccomp filter architectures | |
5 | .\" ////////////////////////////////////////////////////////////////////////// | |
6 | .SH SYNOPSIS | |
7 | .\" ////////////////////////////////////////////////////////////////////////// | |
8 | .nf | |
9 | .B #include <seccomp.h> | |
10 | .sp | |
11 | .B typedef void * scmp_filter_ctx; | |
12 | .sp | |
13 | .B #define SCMP_ARCH_NATIVE | |
14 | .B #define SCMP_ARCH_X86 | |
15 | .B #define SCMP_ARCH_X86_64 | |
16 | .sp | |
17 | .BI "uint32_t seccomp_arch_native();" | |
18 | .BI "int seccomp_arch_exist(const scmp_filter_ctx " ctx ", uint32_t " arch_token ");" | |
19 | .BI "int seccomp_arch_add(scmp_filter_ctx " ctx ", uint32_t " arch_token ");" | |
20 | .BI "int seccomp_arch_remove(scmp_filter_ctx " ctx ", uint32_t " arch_token ");" | |
21 | .sp | |
22 | Link with \fI\-lseccomp\fP. | |
23 | .fi | |
24 | .\" ////////////////////////////////////////////////////////////////////////// | |
25 | .SH DESCRIPTION | |
26 | .\" ////////////////////////////////////////////////////////////////////////// | |
27 | .P | |
28 | The | |
29 | .BR seccomp_arch_exist () | |
30 | function tests to see if a given architecture has been added to the seccomp | |
31 | filter in | |
32 | .I ctx | |
33 | , where the | |
34 | .BR seccomp_arch_add () | |
35 | and | |
36 | .BR seccomp_arch_remove () | |
37 | add and remove, respectively, architectures from the seccomp filter. In all | |
38 | three functions, the architecture values given in | |
39 | .I arch_token | |
40 | should be the | |
41 | .BR SCMP_ARCH_* | |
42 | defined constants; with the | |
43 | .BR SCMP_ARCH_NATIVE | |
44 | constant always referring to the native compiled architecture. The | |
45 | .BR seccomp_arch_native () | |
46 | function returns the system's architecture such that it will match one of the | |
47 | .BR SCMP_ARCH_* | |
48 | constants. | |
49 | .P | |
50 | When a seccomp filter is initialized with the call to | |
51 | .BR seccomp_init (3) | |
52 | the native architecture is automatically added to the filter. If you want to | |
53 | remove the native architecture from the filter, you first need to add another | |
54 | architecture to the filter as a seccomp filter must contain at least one | |
55 | architecture at all times. After you have added a second architecture to the | |
56 | seccomp filter, you can remove the native architecture. | |
57 | .P | |
58 | When adding a new architecture to an existing filter, the existing rules will | |
59 | not be added to the new architecture. However, rules added after adding the | |
60 | new architecture will be added to all of the architectures in the filter. | |
61 | .\" ////////////////////////////////////////////////////////////////////////// | |
62 | .SH RETURN VALUE | |
63 | .\" ////////////////////////////////////////////////////////////////////////// | |
64 | The | |
65 | .BR seccomp_arch_add () | |
66 | and | |
67 | .BR seccomp_arch_remove () | |
68 | functions return zero on success, negative errno values on failure. The | |
69 | .BR seccomp_arch_exist () | |
70 | function returns zero if the architecture exists, \-EEXIST if it does not, and | |
71 | other negative errno values on failure. | |
72 | .\" ////////////////////////////////////////////////////////////////////////// | |
73 | .SH EXAMPLES | |
74 | .\" ////////////////////////////////////////////////////////////////////////// | |
75 | .nf | |
76 | #include <seccomp.h> | |
77 | ||
78 | int main(int argc, char *argv[]) | |
79 | { | |
80 | int rc = \-1; | |
81 | scmp_filter_ctx ctx; | |
82 | ||
83 | ctx = seccomp_init(SCMP_ACT_KILL); | |
84 | if (ctx == NULL) | |
85 | goto out; | |
86 | ||
87 | if (seccomp_arch_exist(ctx, SCMP_ARCH_X86) == \-EEXIST) { | |
88 | rc = seccomp_arch_add(ctx, SCMP_ARCH_X86); | |
89 | if (rc != 0) | |
90 | goto out_all; | |
91 | rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE); | |
92 | if (rc != 0) | |
93 | goto out_all; | |
94 | } | |
95 | ||
96 | /* ... */ | |
97 | ||
98 | out: | |
99 | seccomp_release(ctx); | |
100 | return \-rc; | |
101 | } | |
102 | .fi | |
103 | .\" ////////////////////////////////////////////////////////////////////////// | |
104 | .SH NOTES | |
105 | .\" ////////////////////////////////////////////////////////////////////////// | |
106 | .P | |
107 | While the seccomp filter can be generated independent of the kernel, kernel | |
108 | support is required to load and enforce the seccomp filter generated by | |
109 | libseccomp. | |
110 | .P | |
111 | The libseccomp project site, with more information and the source code | |
112 | repository, can be found at http://libseccomp.sf.net. This library is currently | |
113 | under development, please report any bugs at the project site or directly to | |
114 | the author. | |
115 | .\" ////////////////////////////////////////////////////////////////////////// | |
116 | .SH AUTHOR | |
117 | .\" ////////////////////////////////////////////////////////////////////////// | |
118 | Paul Moore <paul@paul-moore.com> | |
119 | .\" ////////////////////////////////////////////////////////////////////////// | |
120 | .SH SEE ALSO | |
121 | .\" ////////////////////////////////////////////////////////////////////////// | |
122 | .BR seccomp_init (3), | |
123 | .BR seccomp_reset (3), | |
124 | .BR seccom_merge (3) |
0 | .so man3/seccomp_arch_add.3 |
0 | .so man3/seccomp_arch_add.3 |
0 | .so man3/seccomp_arch_add.3 |
0 | .so man3/seccomp_attr_set.3 |
0 | .TH "seccomp_attr_set" 3 "25 July 2012" "paul@paul-moore.com" "libseccomp Documentation" | |
1 | .\" ////////////////////////////////////////////////////////////////////////// | |
2 | .SH NAME | |
3 | .\" ////////////////////////////////////////////////////////////////////////// | |
4 | seccomp_attr_set, seccomp_attr_get \- Manage the seccomp filter attributes | |
5 | .\" ////////////////////////////////////////////////////////////////////////// | |
6 | .SH SYNOPSIS | |
7 | .\" ////////////////////////////////////////////////////////////////////////// | |
8 | .nf | |
9 | .B #include <seccomp.h> | |
10 | .sp | |
11 | .B typedef void * scmp_filter_ctx; | |
12 | .B enum scmp_filter_attr; | |
13 | .sp | |
14 | .BI "int seccomp_attr_set(scmp_filter_ctx " ctx "," | |
15 | .BI " enum scmp_filter_attr " attr ", uint32_t " value ");" | |
16 | .BI "int seccomp_attr_get(scmp_filter_ctx " ctx "," | |
17 | .BI " enum scmp_filter_attr " attr ", uint32_t *" value ");" | |
18 | .sp | |
19 | Link with \fI\-lseccomp\fP. | |
20 | .fi | |
21 | .\" ////////////////////////////////////////////////////////////////////////// | |
22 | .SH DESCRIPTION | |
23 | .\" ////////////////////////////////////////////////////////////////////////// | |
24 | .P | |
25 | The | |
26 | .BR seccomp_attr_set () | |
27 | function sets the different seccomp filter attributes while the | |
28 | .BR seccomp_attr_get () | |
29 | function fetches the filter attributes. The seccomp filter attributes are | |
30 | tunable values that affect how the library behaves when generating and loading | |
31 | the seccomp filter into the kernel. The attributes are reset to their default | |
32 | values whenever the filter is initialized or reset via | |
33 | .BR seccomp_filter_init (3) | |
34 | or | |
35 | .BR seccomp_filter_reset (3). | |
36 | .P | |
37 | The filter context | |
38 | .I ctx | |
39 | is the value returned by the call to | |
40 | .BR seccomp_init (3). | |
41 | .P | |
42 | Valid | |
43 | .I attr | |
44 | values are as follows: | |
45 | .TP | |
46 | .B SCMP_FLTATR_ACT_DEFAULT | |
47 | The default filter action as specified in the call to | |
48 | .BR seccomp_filter_init (3) | |
49 | or | |
50 | .BR seccomp_filter_reset (3). | |
51 | This attribute is read-only. | |
52 | .TP | |
53 | .B SCMP_FLTATR_ACT_BADARCH | |
54 | The filter action taken when the loaded filter does not match the architecture | |
55 | of the executing application. Defaults to the | |
56 | .B SCMP_ACT_KILL | |
57 | action. | |
58 | .TP | |
59 | .B SCMP_FLTATR_CTL_NNP | |
60 | A flag to specify if the NO_NEW_PRIVS functionality should be enabled before | |
61 | loading the seccomp filter into the kernel. If set to off ( | |
62 | .I value | |
63 | == 0) then loading the seccomp filter into the kernel will fail if CAP_SYS_ADMIN | |
64 | is not set. Defaults to on ( | |
65 | .I value | |
66 | == 1). | |
67 | .\" ////////////////////////////////////////////////////////////////////////// | |
68 | .SH RETURN VALUE | |
69 | .\" ////////////////////////////////////////////////////////////////////////// | |
70 | Returns zero on success, negative errno values on failure. | |
71 | .\" ////////////////////////////////////////////////////////////////////////// | |
72 | .SH EXAMPLES | |
73 | .\" ////////////////////////////////////////////////////////////////////////// | |
74 | .nf | |
75 | #include <seccomp.h> | |
76 | ||
77 | int main(int argc, char *argv[]) | |
78 | { | |
79 | int rc = \-1; | |
80 | scmp_filter_ctx ctx; | |
81 | ||
82 | ctx = seccomp_init(SCMP_ACT_ALLOW); | |
83 | if (ctx == NULL) | |
84 | goto out; | |
85 | ||
86 | /* ... */ | |
87 | ||
88 | rc = seccomp_attr_set(ctx, SCMP_FLTATR_ACT_BADARCH, SCMP_ACT_TRAP); | |
89 | if (rc < 0) | |
90 | goto out; | |
91 | ||
92 | /* ... */ | |
93 | ||
94 | out: | |
95 | seccomp_release(ctx); | |
96 | return \-rc; | |
97 | } | |
98 | .fi | |
99 | .\" ////////////////////////////////////////////////////////////////////////// | |
100 | .SH NOTES | |
101 | .\" ////////////////////////////////////////////////////////////////////////// | |
102 | .P | |
103 | While the seccomp filter can be generated independent of the kernel, kernel | |
104 | support is required to load and enforce the seccomp filter generated by | |
105 | libseccomp. | |
106 | .P | |
107 | The libseccomp project site, with more information and the source code | |
108 | repository, can be found at http://libseccomp.sf.net. This library is currently | |
109 | under development, please report any bugs at the project site or directly to | |
110 | the author. | |
111 | .\" ////////////////////////////////////////////////////////////////////////// | |
112 | .SH AUTHOR | |
113 | .\" ////////////////////////////////////////////////////////////////////////// | |
114 | Paul Moore <paul@paul-moore.com> | |
115 | .\" ////////////////////////////////////////////////////////////////////////// | |
116 | .SH SEE ALSO | |
117 | .\" ////////////////////////////////////////////////////////////////////////// | |
118 | .BR seccomp_init (3), | |
119 | .BR seccomp_reset (3), | |
120 | .BR seccomp_load (3) |
0 | .TH "seccomp_export_bpf" 3 "25 July 2012" "paul@paul-moore.com" "libseccomp Documentation" | |
1 | .\" ////////////////////////////////////////////////////////////////////////// | |
2 | .SH NAME | |
3 | .\" ////////////////////////////////////////////////////////////////////////// | |
4 | seccomp_export_bpf, seccomp_export_pfc \- Export the seccomp filter | |
5 | .\" ////////////////////////////////////////////////////////////////////////// | |
6 | .SH SYNOPSIS | |
7 | .\" ////////////////////////////////////////////////////////////////////////// | |
8 | .nf | |
9 | .B #include <seccomp.h> | |
10 | .sp | |
11 | .B typedef void * scmp_filter_ctx; | |
12 | .sp | |
13 | .BI "int seccomp_export_bpf(const scmp_filter_ctx " ctx ", int " fd ");" | |
14 | .BI "int seccomp_export_pfc(const scmp_filter_ctx " ctx ", int " fd ");" | |
15 | .sp | |
16 | Link with \fI\-lseccomp\fP. | |
17 | .fi | |
18 | .\" ////////////////////////////////////////////////////////////////////////// | |
19 | .SH DESCRIPTION | |
20 | .\" ////////////////////////////////////////////////////////////////////////// | |
21 | .P | |
22 | The | |
23 | .BR seccomp_export_bpf () | |
24 | and | |
25 | .BR seccomp_export_pfc () | |
26 | functions generate and output the current seccomp filter in either BPF (Berkley | |
27 | Packet Filter) or PFC (Pseudo Filter Code). The output of | |
28 | .BR seccomp_export_bpf () | |
29 | is suitable for loading into the kernel, while the output of | |
30 | .BR seccomp_export_pfc () | |
31 | is human readable and is intended primarily as a debugging tool for developers | |
32 | using libseccomp. Both functions write the filter to the | |
33 | .I fd | |
34 | file descriptor. | |
35 | .P | |
36 | The filter context | |
37 | .I ctx | |
38 | is the value returned by the call to | |
39 | .BR seccomp_init (3). | |
40 | .P | |
41 | While the two output formats are guaranteed to be functionally equivalent for | |
42 | the given seccomp filter configuration, the filter instructions, and their | |
43 | ordering, are not guaranteed to be the same in both the BPF and PFC formats. | |
44 | .\" ////////////////////////////////////////////////////////////////////////// | |
45 | .SH RETURN VALUE | |
46 | .\" ////////////////////////////////////////////////////////////////////////// | |
47 | Returns zero on success, negative errno values on failure. | |
48 | .\" ////////////////////////////////////////////////////////////////////////// | |
49 | .SH EXAMPLES | |
50 | .\" ////////////////////////////////////////////////////////////////////////// | |
51 | .nf | |
52 | #include <seccomp.h> | |
53 | ||
54 | int main(int argc, char *argv[]) | |
55 | { | |
56 | int rc = \-1; | |
57 | scmp_filter_ctx ctx; | |
58 | int filter_fd; | |
59 | ||
60 | ctx = seccomp_init(SCMP_ACT_KILL); | |
61 | if (ctx == NULL) | |
62 | goto out; | |
63 | ||
64 | /* ... */ | |
65 | ||
66 | filter_fd = open("/tmp/seccomp_filter.bpf", O_WRONLY); | |
67 | if (filter_fd == \-1) { | |
68 | rc = \-errno; | |
69 | goto out; | |
70 | } | |
71 | ||
72 | rc = seccomp_export_bpf(ctx, filter_fd); | |
73 | if (rc < 0) { | |
74 | close(filter_fd); | |
75 | goto out; | |
76 | } | |
77 | close(filter_fd); | |
78 | ||
79 | /* ... */ | |
80 | ||
81 | out: | |
82 | seccomp_release(ctx); | |
83 | return \-rc; | |
84 | } | |
85 | .fi | |
86 | .\" ////////////////////////////////////////////////////////////////////////// | |
87 | .SH NOTES | |
88 | .\" ////////////////////////////////////////////////////////////////////////// | |
89 | .P | |
90 | While the seccomp filter can be generated independent of the kernel, kernel | |
91 | support is required to load and enforce the seccomp filter generated by | |
92 | libseccomp. | |
93 | .P | |
94 | The libseccomp project site, with more information and the source code | |
95 | repository, can be found at http://libseccomp.sf.net. This library is currently | |
96 | under development, please report any bugs at the project site or directly to | |
97 | the author. | |
98 | .\" ////////////////////////////////////////////////////////////////////////// | |
99 | .SH AUTHOR | |
100 | .\" ////////////////////////////////////////////////////////////////////////// | |
101 | Paul Moore <paul@paul-moore.com> | |
102 | .\" ////////////////////////////////////////////////////////////////////////// | |
103 | .SH SEE ALSO | |
104 | .\" ////////////////////////////////////////////////////////////////////////// | |
105 | .BR seccomp_init (3), | |
106 | .BR seccomp_release (3) | |
107 |
0 | .so man3/seccomp_export_bpf.3 |
0 | .TH "seccomp_init" 3 "25 July 2012" "paul@paul-moore.com" "libseccomp Documentation" | |
1 | .\" ////////////////////////////////////////////////////////////////////////// | |
2 | .SH NAME | |
3 | .\" ////////////////////////////////////////////////////////////////////////// | |
4 | seccomp_init, seccomp_reset \- Initialize the seccomp filter state | |
5 | .\" ////////////////////////////////////////////////////////////////////////// | |
6 | .SH SYNOPSIS | |
7 | .\" ////////////////////////////////////////////////////////////////////////// | |
8 | .nf | |
9 | .B #include <seccomp.h> | |
10 | .sp | |
11 | .B typedef void * scmp_filter_ctx; | |
12 | .sp | |
13 | .BI "scmp_filter_ctx seccomp_init(uint32_t " def_action ");" | |
14 | .BI "int seccomp_reset(scmp_filter_ctx " ctx ", uint32_t " def_action ");" | |
15 | .sp | |
16 | Link with \fI\-lseccomp\fP. | |
17 | .fi | |
18 | .\" ////////////////////////////////////////////////////////////////////////// | |
19 | .SH DESCRIPTION | |
20 | .\" ////////////////////////////////////////////////////////////////////////// | |
21 | .P | |
22 | The | |
23 | .BR seccomp_init () | |
24 | and | |
25 | .BR seccomp_reset () | |
26 | functions (re)initialize the internal seccomp filter state, prepares it for | |
27 | use, and sets the default action based on the | |
28 | .I def_action | |
29 | parameter. The | |
30 | .BR seccomp_init () | |
31 | function must be called before any other libseccomp functions as the rest | |
32 | of the library API will fail if the filter context is not initialized properly. | |
33 | The | |
34 | .BR seccomp_reset () | |
35 | function releases the existing filter context state before reinitializing it | |
36 | and can only be called after a call to | |
37 | .BR seccomp_init () | |
38 | has succeeded. | |
39 | .P | |
40 | When the caller is finished configuring the seccomp filter and has loaded it | |
41 | into the kernel, the caller should call | |
42 | .BR seccomp_release (3) | |
43 | to release all of the filter context state. | |
44 | .P | |
45 | Valid | |
46 | .I def_action | |
47 | values are as follows: | |
48 | .TP | |
49 | .B SCMP_ACT_KILL | |
50 | The process will be killed by the kernel when it calls a syscall that does not | |
51 | match any of the configured seccomp filter rules. | |
52 | .TP | |
53 | .B SCMP_ACT_TRAP | |
54 | The process will throw a SIGSYS signal when it calls a syscall that does not | |
55 | match any of the configured seccomp filter rules. | |
56 | .TP | |
57 | .B SCMP_ACT_ERRNO(uint16_t errno) | |
58 | The process will receive a return value of | |
59 | .I errno | |
60 | when it calls a syscall that does not match any of the configured seccomp filter | |
61 | rules. | |
62 | .TP | |
63 | .B SCMP_ACT_TRACE(uint16_t msg_num) | |
64 | If the process is being traced and the tracing process specified the | |
65 | .B PTRACE_O_TRACESECCOMP | |
66 | option in the call to | |
67 | .BR ptrace (2), | |
68 | the tracing process will be notified, via | |
69 | .B PTRACE_EVENT_SECCOMP | |
70 | , and the value provided in | |
71 | .I msg_num | |
72 | can be retrieved using the | |
73 | .B PTRACE_GETEVENTMSG | |
74 | option. | |
75 | .TP | |
76 | .B SCMP_ACT_ALLOW | |
77 | The seccomp filter will have no effect on the process calling the syscall if it | |
78 | does not match any of the configured seccomp filter rules. | |
79 | .\" ////////////////////////////////////////////////////////////////////////// | |
80 | .SH RETURN VALUE | |
81 | .\" ////////////////////////////////////////////////////////////////////////// | |
82 | The | |
83 | .BR seccomp_init () | |
84 | function returns a filter context on success, NULL on failure. The | |
85 | .BR seccomp_reset () | |
86 | function returns zero on success, negative errno values on failure. | |
87 | .\" ////////////////////////////////////////////////////////////////////////// | |
88 | .SH EXAMPLES | |
89 | .\" ////////////////////////////////////////////////////////////////////////// | |
90 | .nf | |
91 | #include <seccomp.h> | |
92 | ||
93 | int main(int argc, char *argv[]) | |
94 | { | |
95 | int rc = \-1; | |
96 | scmp_filter_ctx ctx; | |
97 | ||
98 | ctx = seccomp_init(SCMP_ACT_KILL); | |
99 | if (ctx == NULL) | |
100 | goto out; | |
101 | ||
102 | /* ... */ | |
103 | ||
104 | rc = seccomp_reset(ctx, SCMP_ACT_KILL); | |
105 | if (rc < 0) | |
106 | goto out; | |
107 | ||
108 | /* ... */ | |
109 | ||
110 | out: | |
111 | seccomp_release(ctx); | |
112 | return \-rc; | |
113 | } | |
114 | .fi | |
115 | .\" ////////////////////////////////////////////////////////////////////////// | |
116 | .SH NOTES | |
117 | .\" ////////////////////////////////////////////////////////////////////////// | |
118 | .P | |
119 | While the seccomp filter can be generated independent of the kernel, kernel | |
120 | support is required to load and enforce the seccomp filter generated by | |
121 | libseccomp. | |
122 | .P | |
123 | The libseccomp project site, with more information and the source code | |
124 | repository, can be found at http://libseccomp.sf.net. This library is currently | |
125 | under development, please report any bugs at the project site or directly to | |
126 | the author. | |
127 | .\" ////////////////////////////////////////////////////////////////////////// | |
128 | .SH AUTHOR | |
129 | .\" ////////////////////////////////////////////////////////////////////////// | |
130 | Paul Moore <paul@paul-moore.com> | |
131 | .\" ////////////////////////////////////////////////////////////////////////// | |
132 | .SH SEE ALSO | |
133 | .\" ////////////////////////////////////////////////////////////////////////// | |
134 | .BR seccomp_release (3) | |
135 |
0 | .TH "seccomp_load" 3 "25 July 2012" "paul@paul-moore.com" "libseccomp Documentation" | |
1 | .\" ////////////////////////////////////////////////////////////////////////// | |
2 | .SH NAME | |
3 | .\" ////////////////////////////////////////////////////////////////////////// | |
4 | seccomp_load \- Load the current seccomp filter into the kernel | |
5 | .\" ////////////////////////////////////////////////////////////////////////// | |
6 | .SH SYNOPSIS | |
7 | .\" ////////////////////////////////////////////////////////////////////////// | |
8 | .nf | |
9 | .B #include <seccomp.h> | |
10 | .sp | |
11 | .B typedef void * scmp_filter_ctx; | |
12 | .sp | |
13 | .BI "int seccomp_load(scmp_filter_ctx " ctx ");" | |
14 | .sp | |
15 | Link with \fI\-lseccomp\fP. | |
16 | .fi | |
17 | .\" ////////////////////////////////////////////////////////////////////////// | |
18 | .SH DESCRIPTION | |
19 | .\" ////////////////////////////////////////////////////////////////////////// | |
20 | .P | |
21 | Loads the seccomp filter provided by | |
22 | .I ctx | |
23 | into the kernel; if the function | |
24 | succeeds the new seccomp filter will be active when the function returns. | |
25 | .\" ////////////////////////////////////////////////////////////////////////// | |
26 | .SH RETURN VALUE | |
27 | .\" ////////////////////////////////////////////////////////////////////////// | |
28 | Returns zero on success, negative errno values on failure. | |
29 | .\" ////////////////////////////////////////////////////////////////////////// | |
30 | .SH EXAMPLES | |
31 | .\" ////////////////////////////////////////////////////////////////////////// | |
32 | .nf | |
33 | #include <seccomp.h> | |
34 | ||
35 | int main(int argc, char *argv[]) | |
36 | { | |
37 | int rc = \-1; | |
38 | scmp_filter_ctx ctx; | |
39 | ||
40 | ctx = seccomp_init(SCMP_ACT_KILL); | |
41 | if (ctx == NULL) | |
42 | goto out; | |
43 | ||
44 | /* ... */ | |
45 | ||
46 | rc = seccomp_load(ctx); | |
47 | if (rc < 0) | |
48 | goto out; | |
49 | ||
50 | /* ... */ | |
51 | ||
52 | out: | |
53 | seccomp_release(ctx); | |
54 | return \-rc; | |
55 | } | |
56 | .fi | |
57 | .\" ////////////////////////////////////////////////////////////////////////// | |
58 | .SH NOTES | |
59 | .\" ////////////////////////////////////////////////////////////////////////// | |
60 | .P | |
61 | While the seccomp filter can be generated independent of the kernel, kernel | |
62 | support is required to load and enforce the seccomp filter generated by | |
63 | libseccomp. | |
64 | .P | |
65 | The libseccomp project site, with more information and the source code | |
66 | repository, can be found at http://libseccomp.sf.net. This library is currently | |
67 | under development, please report any bugs at the project site or directly to | |
68 | the author. | |
69 | .\" ////////////////////////////////////////////////////////////////////////// | |
70 | .SH AUTHOR | |
71 | .\" ////////////////////////////////////////////////////////////////////////// | |
72 | Paul Moore <paul@paul-moore.com> | |
73 | .\" ////////////////////////////////////////////////////////////////////////// | |
74 | .SH SEE ALSO | |
75 | .\" ////////////////////////////////////////////////////////////////////////// | |
76 | .BR seccomp_init (3), | |
77 | .BR seccomp_reset (3), | |
78 | .BR seccomp_release (3), | |
79 | .BR seccomp_rule_add (3), | |
80 | .BR seccomp_rule_add_exact (3) | |
81 | ||
82 |
0 | .TH "seccomp_merge" 3 "28 September 2012" "paul@paul-moore.com" "libseccomp Documentation" | |
1 | .\" ////////////////////////////////////////////////////////////////////////// | |
2 | .SH NAME | |
3 | .\" ////////////////////////////////////////////////////////////////////////// | |
4 | seccomp_merge \- Merge two seccomp filters | |
5 | .\" ////////////////////////////////////////////////////////////////////////// | |
6 | .SH SYNOPSIS | |
7 | .\" ////////////////////////////////////////////////////////////////////////// | |
8 | .nf | |
9 | .B #include <seccomp.h> | |
10 | .sp | |
11 | .B typedef void * scmp_filter_ctx; | |
12 | .sp | |
13 | .BI "int seccomp_merge(scmp_filter_ctx " dst ", scmp_filter_ctx " src ");" | |
14 | .sp | |
15 | Link with \fI\-lseccomp\fP. | |
16 | .fi | |
17 | .\" ////////////////////////////////////////////////////////////////////////// | |
18 | .SH DESCRIPTION | |
19 | .\" ////////////////////////////////////////////////////////////////////////// | |
20 | .P | |
21 | The | |
22 | .BR seccomp_merge () | |
23 | function merges the seccomp filter in | |
24 | .I src | |
25 | with the filter in | |
26 | .I dst | |
27 | and stores the resulting in the | |
28 | .I dst | |
29 | filter. If successfull, the | |
30 | .I src | |
31 | seccomp filter is released and all internal memory assocated with the filter | |
32 | is freed; there is no need to call | |
33 | .BR seccomp_release (3) | |
34 | on | |
35 | .I src | |
36 | and the caller should discard any references to the filter. | |
37 | .P | |
38 | In order to merge two seccomp filters, both filters must have the same | |
39 | attribute values and no overlapping architectures. | |
40 | .\" ////////////////////////////////////////////////////////////////////////// | |
41 | .SH RETURN VALUE | |
42 | .\" ////////////////////////////////////////////////////////////////////////// | |
43 | Returns zero on success and negative values on failure. | |
44 | .\" ////////////////////////////////////////////////////////////////////////// | |
45 | .SH EXAMPLES | |
46 | .\" ////////////////////////////////////////////////////////////////////////// | |
47 | .nf | |
48 | #include <seccomp.h> | |
49 | ||
50 | int main(int argc, char *argv[]) | |
51 | { | |
52 | int rc = \-1; | |
53 | scmp_filter_ctx ctx_32, ctx_64; | |
54 | ||
55 | ctx_32 = seccomp_init(SCMP_ACT_KILL); | |
56 | if (ctx_32 == NULL) | |
57 | goto out_all; | |
58 | ctx_64 = seccomp_init(SCMP_ACT_KILL); | |
59 | if (ctx_64 == NULL) | |
60 | goto out_all; | |
61 | ||
62 | if (seccomp_arch_exist(ctx_32, SCMP_ARCH_X86) == \-EEXIST) { | |
63 | rc = seccomp_arch_add(ctx_32, SCMP_ARCH_X86); | |
64 | if (rc != 0) | |
65 | goto out_all; | |
66 | rc = seccomp_arch_remove(ctx_32, SCMP_ARCH_NATIVE); | |
67 | if (rc != 0) | |
68 | goto out_all; | |
69 | } | |
70 | if (seccomp_arch_exist(ctx_64, SCMP_ARCH_X86_64) == \-EEXIST) { | |
71 | rc = seccomp_arch_add(ctx_64, SCMP_ARCH_X86_64); | |
72 | if (rc != 0) | |
73 | goto out_all; | |
74 | rc = seccomp_arch_remove(ctx_64, SCMP_ARCH_NATIVE); | |
75 | if (rc != 0) | |
76 | goto out_all; | |
77 | } | |
78 | ||
79 | /* ... */ | |
80 | ||
81 | rc = seccomp_merge(ctx_64, ctx_32); | |
82 | if (rc != 0) | |
83 | goto out_all; | |
84 | ||
85 | /* NOTE: the 'ctx_32' filter is no longer valid at this point */ | |
86 | ||
87 | /* ... */ | |
88 | ||
89 | out: | |
90 | seccomp_release(ctx_64); | |
91 | return \-rc; | |
92 | out_all: | |
93 | seccomp_release(ctx_32); | |
94 | goto out; | |
95 | } | |
96 | .fi | |
97 | .\" ////////////////////////////////////////////////////////////////////////// | |
98 | .SH NOTES | |
99 | .\" ////////////////////////////////////////////////////////////////////////// | |
100 | .P | |
101 | While the seccomp filter can be generated independent of the kernel, kernel | |
102 | support is required to load and enforce the seccomp filter generated by | |
103 | libseccomp. | |
104 | .P | |
105 | The libseccomp project site, with more information and the source code | |
106 | repository, can be found at http://libseccomp.sf.net. This library is currently | |
107 | under development, please report any bugs at the project site or directly to | |
108 | the author. | |
109 | .\" ////////////////////////////////////////////////////////////////////////// | |
110 | .SH AUTHOR | |
111 | .\" ////////////////////////////////////////////////////////////////////////// | |
112 | Paul Moore <paul@paul-moore.com> | |
113 | .\" ////////////////////////////////////////////////////////////////////////// | |
114 | .SH SEE ALSO | |
115 | .\" ////////////////////////////////////////////////////////////////////////// | |
116 | .BR seccomp_init (3), | |
117 | .BR seccomp_reset (3), | |
118 | .BR seccomp_arch_add (3), | |
119 | .BR seccomp_arch_remove (3), | |
120 | .BR seccomp_attr_get (3), | |
121 | .BR seccomp_attr_set (3) |
0 | .TH "seccomp_release" 3 "25 July 2012" "paul@paul-moore.com" "libseccomp Documentation" | |
1 | .\" ////////////////////////////////////////////////////////////////////////// | |
2 | .SH NAME | |
3 | .\" ////////////////////////////////////////////////////////////////////////// | |
4 | seccomp_release \- Release the seccomp filter state | |
5 | .\" ////////////////////////////////////////////////////////////////////////// | |
6 | .SH SYNOPSIS | |
7 | .\" ////////////////////////////////////////////////////////////////////////// | |
8 | .nf | |
9 | .B #include <seccomp.h> | |
10 | .sp | |
11 | .B typedef void * scmp_filter_ctx; | |
12 | .sp | |
13 | .BI "void seccomp_release(scmp_filter_ctx " ctx ");" | |
14 | .sp | |
15 | Link with \fI\-lseccomp\fP. | |
16 | .fi | |
17 | .\" ////////////////////////////////////////////////////////////////////////// | |
18 | .SH DESCRIPTION | |
19 | .\" ////////////////////////////////////////////////////////////////////////// | |
20 | .P | |
21 | Releases the seccomp filter in | |
22 | .I ctx | |
23 | which was first initialized by | |
24 | .BR seccomp_init (3) | |
25 | or | |
26 | .BR seccomp_reset (3) | |
27 | and frees any memory associated with the given seccomp filter context. | |
28 | Any seccomp filters loaded into the kernel are not affected. | |
29 | .\" ////////////////////////////////////////////////////////////////////////// | |
30 | .SH RETURN VALUE | |
31 | .\" ////////////////////////////////////////////////////////////////////////// | |
32 | Does not return a value. | |
33 | .\" ////////////////////////////////////////////////////////////////////////// | |
34 | .SH EXAMPLES | |
35 | .\" ////////////////////////////////////////////////////////////////////////// | |
36 | .nf | |
37 | #include <seccomp.h> | |
38 | ||
39 | int main(int argc, char *argv[]) | |
40 | { | |
41 | int rc; | |
42 | scmp_filter_ctx ctx; | |
43 | ||
44 | ctx = seccomp_init(SCMP_ACT_KILL); | |
45 | if (ctx == NULL) | |
46 | return \-1; | |
47 | ||
48 | /* ... */ | |
49 | ||
50 | seccomp_release(ctx); | |
51 | return 0; | |
52 | } | |
53 | .fi | |
54 | .\" ////////////////////////////////////////////////////////////////////////// | |
55 | .SH NOTES | |
56 | .\" ////////////////////////////////////////////////////////////////////////// | |
57 | .P | |
58 | While the seccomp filter can be generated independent of the kernel, kernel | |
59 | support is required to load and enforce the seccomp filter generated by | |
60 | libseccomp. | |
61 | .P | |
62 | The libseccomp project site, with more information and the source code | |
63 | repository, can be found at http://libseccomp.sf.net. This library is currently | |
64 | under development, please report any bugs at the project site or directly to | |
65 | the author. | |
66 | .\" ////////////////////////////////////////////////////////////////////////// | |
67 | .SH AUTHOR | |
68 | .\" ////////////////////////////////////////////////////////////////////////// | |
69 | Paul Moore <paul@paul-moore.com> | |
70 | .\" ////////////////////////////////////////////////////////////////////////// | |
71 | .SH SEE ALSO | |
72 | .\" ////////////////////////////////////////////////////////////////////////// | |
73 | .BR seccomp_init (3), | |
74 | .BR seccomp_reset (3) | |
75 | ||
76 |
0 | .so man3/seccomp_init.3 |
0 | .TH "seccomp_rule_add" 3 "25 July 2012" "paul@paul-moore.com" "libseccomp Documentation" | |
1 | .\" ////////////////////////////////////////////////////////////////////////// | |
2 | .SH NAME | |
3 | .\" ////////////////////////////////////////////////////////////////////////// | |
4 | seccomp_rule_add, seccomp_rule_add_exact \- Add a seccomp filter rule | |
5 | .\" ////////////////////////////////////////////////////////////////////////// | |
6 | .SH SYNOPSIS | |
7 | .\" ////////////////////////////////////////////////////////////////////////// | |
8 | .nf | |
9 | .B #include <seccomp.h> | |
10 | .sp | |
11 | .B typedef void * scmp_filter_ctx; | |
12 | .sp | |
13 | .BI "int SCMP_SYS(" syscall_name ");" | |
14 | .sp | |
15 | .BI "struct scmp_arg_cmp SCMP_CMP(unsigned int " arg "," | |
16 | .BI " enum scmp_compare " op ", " ... ");" | |
17 | .BI "struct scmp_arg_cmp SCMP_A0(enum scmp_compare " op ", " ... ");" | |
18 | .BI "struct scmp_arg_cmp SCMP_A1(enum scmp_compare " op ", " ... ");" | |
19 | .BI "struct scmp_arg_cmp SCMP_A2(enum scmp_compare " op ", " ... ");" | |
20 | .BI "struct scmp_arg_cmp SCMP_A3(enum scmp_compare " op ", " ... ");" | |
21 | .BI "struct scmp_arg_cmp SCMP_A4(enum scmp_compare " op ", " ... ");" | |
22 | .BI "struct scmp_arg_cmp SCMP_A5(enum scmp_compare " op ", " ... ");" | |
23 | .sp | |
24 | .BI "int seccomp_rule_add(scmp_filter_ctx " ctx ", uint32_t " action "," | |
25 | .BI " int " syscall ", unsigned int " arg_cnt ", " ... ");" | |
26 | .BI "int seccomp_rule_add_exact(scmp_filter_ctx " ctx ", uint32_t " action "," | |
27 | .BI " int " syscall ", unsigned int " arg_cnt ", " ... ");" | |
28 | .sp | |
29 | .BI "int seccomp_rule_add_array(scmp_filter_ctx " ctx "," | |
30 | .BI " uint32_t " action ", int " syscall "," | |
31 | .BI " unsigned int " arg_cnt "," | |
32 | .BI " const struct scmp_arg_cmp *"arg_array ");" | |
33 | .BI "int seccomp_rule_add_exact_array(scmp_filter_ctx " ctx "," | |
34 | .BI " uint32_t " action ", int " syscall "," | |
35 | .BI " unsigned int " arg_cnt "," | |
36 | .BI " const struct scmp_arg_cmp *"arg_array ");" | |
37 | .sp | |
38 | Link with \fI\-lseccomp\fP. | |
39 | .fi | |
40 | .\" ////////////////////////////////////////////////////////////////////////// | |
41 | .SH DESCRIPTION | |
42 | .\" ////////////////////////////////////////////////////////////////////////// | |
43 | .P | |
44 | The | |
45 | .BR seccomp_rule_add (), | |
46 | .BR seccomp_rule_add_array (), | |
47 | .BR seccomp_rule_add_exact (), | |
48 | and | |
49 | .BR seccomp_rule_add_exact_array () | |
50 | functions all add a new filter rule to the current seccomp filter. The | |
51 | .BR seccomp_rule_add () | |
52 | and | |
53 | .BR seccomp_rule_add_array () | |
54 | functions will make a "best effort" to add the rule as specified, but may alter | |
55 | the rule slightly due to architecture specifics, e.g. socket and ipc functions | |
56 | on x86. The | |
57 | .BR seccomp_rule_add_exact () | |
58 | and | |
59 | .BR seccomp_rule_add_exact_array () | |
60 | functions will attempt to add the rule exactly as specified so it may behave | |
61 | differently on different architectures. While it does not guarantee a exact | |
62 | filter ruleset, | |
63 | .BR seccomp_rule_add () | |
64 | and | |
65 | .BR seccomp_rule_add_array () | |
66 | do guarantee the same behavior regardless of the architecture. | |
67 | .P | |
68 | The newly added filter rule does not take effect until the entire filter is | |
69 | loaded into the kernel using | |
70 | .BR seccomp_load (3). | |
71 | .P | |
72 | The | |
73 | .BR SCMP_CMP () | |
74 | and | |
75 | .BR SCMP_A{0-5} () | |
76 | macros generate a scmp_arg_cmp structure for use with the above functions. The | |
77 | .BR SCMP_CMP () | |
78 | macro allows the caller to specify an arbitrary argument along with the | |
79 | comparison operator, mask, and datum values where the | |
80 | .BR SCMP_A{0-5} () | |
81 | macros are specific to a certain argument. See the EXAMPLES section below. | |
82 | .P | |
83 | While it is possible to specify the | |
84 | .I syscall | |
85 | value directly using the standard | |
86 | .B __NR_syscall | |
87 | values, in order to ensure proper operation across multiple architectures it | |
88 | is highly recommended to use the | |
89 | .BR SCMP_SYS () | |
90 | macro instead. See the EXAMPLES section below. | |
91 | .P | |
92 | The filter context | |
93 | .I ctx | |
94 | is the value returned by the call to | |
95 | .BR seccomp_init (3). | |
96 | .P | |
97 | Valid | |
98 | .I action | |
99 | values are as follows: | |
100 | .TP | |
101 | .B SCMP_ACT_KILL | |
102 | The process will be killed by the kernel when it calls a syscall that does not | |
103 | match any of the configured seccomp filter rules. | |
104 | .TP | |
105 | .B SCMP_ACT_TRAP | |
106 | The process will throw a SIGSYS signal when it calls a syscall that does not | |
107 | match any of the configured seccomp filter rules. | |
108 | .TP | |
109 | .B SCMP_ACT_ERRNO(uint16_t errno) | |
110 | The process will receive a return value of | |
111 | .I errno | |
112 | when it calls a syscall that does not match any of the configured seccomp filter | |
113 | rules. | |
114 | .TP | |
115 | .B SCMP_ACT_TRACE(uint16_t msg_num) | |
116 | If the process is being traced and the tracing process specified the | |
117 | .B PTRACE_O_TRACESECCOMP | |
118 | option in the call to | |
119 | .BR ptrace (2), | |
120 | the tracing process will be notified, via | |
121 | .B PTRACE_EVENT_SECCOMP | |
122 | , and the value provided in | |
123 | .I msg_num | |
124 | can be retrieved using the | |
125 | .B PTRACE_GETEVENTMSG | |
126 | option. | |
127 | .TP | |
128 | .B SCMP_ACT_ALLOW | |
129 | The seccomp filter will have no effect on the process calling the syscall if it | |
130 | does not match any of the configured seccomp filter rules. | |
131 | .P | |
132 | Valid comparison | |
133 | .I op | |
134 | values are as follows: | |
135 | .TP | |
136 | .B SCMP_CMP_NE | |
137 | Matches when the argument value is not equal to the datum value, example: | |
138 | .sp | |
139 | SCMP_CMP( | |
140 | .I arg | |
141 | , SCMP_CMP_NE , | |
142 | .I datum | |
143 | ) | |
144 | .TP | |
145 | .B SCMP_CMP_LT | |
146 | Matches when the argument value is less than the datum value, example: | |
147 | .sp | |
148 | SCMP_CMP( | |
149 | .I arg | |
150 | , SCMP_CMP_LT , | |
151 | .I datum | |
152 | ) | |
153 | .TP | |
154 | .B SCMP_CMP_LE | |
155 | Matches when the argument value is less than or equal to the datum value, | |
156 | example: | |
157 | .sp | |
158 | SCMP_CMP( | |
159 | .I arg | |
160 | , SCMP_CMP_LE , | |
161 | .I datum | |
162 | ) | |
163 | .TP | |
164 | .B SCMP_CMP_EQ | |
165 | Matches when the argument value is equal to the datum value, example: | |
166 | .sp | |
167 | SCMP_CMP( | |
168 | .I arg | |
169 | , SCMP_CMP_EQ , | |
170 | .I datum | |
171 | ) | |
172 | .TP | |
173 | .B SCMP_CMP_GE | |
174 | Matches when the argument value is greater than or equal to the datum value, | |
175 | example: | |
176 | .sp | |
177 | SCMP_CMP( | |
178 | .I arg | |
179 | , SCMP_CMP_GE , | |
180 | .I datum | |
181 | ) | |
182 | .TP | |
183 | .B SCMP_CMP_GT | |
184 | Matches when the argument value is greater than the datum value, example: | |
185 | .sp | |
186 | SCMP_CMP( | |
187 | .I arg | |
188 | , SCMP_CMP_GT , | |
189 | .I datum | |
190 | ) | |
191 | .TP | |
192 | .B SCMP_CMP_MASKED_EQ | |
193 | Matches when the masked argument value is equal to the masked datum value, | |
194 | example: | |
195 | .sp | |
196 | SCMP_CMP( | |
197 | .I arg | |
198 | , SCMP_CMP_MASKED_EQ , | |
199 | .I mask | |
200 | , | |
201 | .I datum | |
202 | ) | |
203 | .\" ////////////////////////////////////////////////////////////////////////// | |
204 | .SH RETURN VALUE | |
205 | .\" ////////////////////////////////////////////////////////////////////////// | |
206 | The | |
207 | .BR seccomp_rule_add (), | |
208 | .BR seccomp_rule_add_array (), | |
209 | .BR seccomp_rule_add_exact (), | |
210 | and | |
211 | .BR seccomp_rule_add_exact_array () | |
212 | functions return zero on success, negative errno values on failure. | |
213 | .\" ////////////////////////////////////////////////////////////////////////// | |
214 | .SH EXAMPLES | |
215 | .\" ////////////////////////////////////////////////////////////////////////// | |
216 | .nf | |
217 | #include <fcntl.h> | |
218 | #include <seccomp.h> | |
219 | #include <sys/stat.h> | |
220 | #include <sys/types.h> | |
221 | ||
222 | #define BUF_SIZE 256 | |
223 | ||
224 | int main(int argc, char *argv[]) | |
225 | { | |
226 | int rc = \-1; | |
227 | scmp_filter_ctx ctx; | |
228 | struct scmp_arg_cmp arg_cmp[] = { SCMP_A0(SCMP_CMP_EQ, 2) }; | |
229 | int fd; | |
230 | unsigned char buf[BUF_SIZE]; | |
231 | ||
232 | ctx = seccomp_init(SCMP_ACT_KILL); | |
233 | if (ctx == NULL) | |
234 | goto out; | |
235 | ||
236 | /* ... */ | |
237 | ||
238 | fd = open("file.txt", 0); | |
239 | ||
240 | /* ... */ | |
241 | ||
242 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); | |
243 | if (rc < 0) | |
244 | goto out; | |
245 | ||
246 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 3, | |
247 | SCMP_A0(SCMP_CMP_EQ, fd), | |
248 | SCMP_A1(SCMP_CMP_EQ, (scmp_datum_t)buf), | |
249 | SCMP_A2(SCMP_CMP_LE, BUF_SIZE)); | |
250 | if (rc < 0) | |
251 | goto out; | |
252 | ||
253 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, | |
254 | SCMP_CMP(0, SCMP_CMP_EQ, fd)); | |
255 | if (rc < 0) | |
256 | goto out; | |
257 | ||
258 | rc = seccomp_rule_add_array(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, | |
259 | arg_cmp); | |
260 | if (rc < 0) | |
261 | goto out; | |
262 | ||
263 | rc = seccomp_load(ctx); | |
264 | if (rc < 0) | |
265 | goto out; | |
266 | ||
267 | /* ... */ | |
268 | ||
269 | out: | |
270 | seccomp_release(ctx); | |
271 | return \-rc; | |
272 | } | |
273 | .fi | |
274 | .\" ////////////////////////////////////////////////////////////////////////// | |
275 | .SH NOTES | |
276 | .\" ////////////////////////////////////////////////////////////////////////// | |
277 | .P | |
278 | While the seccomp filter can be generated independent of the kernel, kernel | |
279 | support is required to load and enforce the seccomp filter generated by | |
280 | libseccomp. | |
281 | .P | |
282 | The libseccomp project site, with more information and the source code | |
283 | repository, can be found at http://libseccomp.sf.net. This library is currently | |
284 | under development, please report any bugs at the project site or directly to | |
285 | the author. | |
286 | .\" ////////////////////////////////////////////////////////////////////////// | |
287 | .SH AUTHOR | |
288 | .\" ////////////////////////////////////////////////////////////////////////// | |
289 | Paul Moore <paul@paul-moore.com> | |
290 | .\" ////////////////////////////////////////////////////////////////////////// | |
291 | .SH SEE ALSO | |
292 | .\" ////////////////////////////////////////////////////////////////////////// | |
293 | .BR seccomp_syscall_priority (3), | |
294 | .BR seccomp_load (3) |
0 | .so man3/seccomp_rule_add.3 |
0 | .so man3/seccomp_rule_add.3 |
0 | .so man3/seccomp_rule_add.3 |
0 | .TH "seccomp_syscall_priority" 3 "25 July 2012" "paul@paul-moore.com" "libseccomp Documentation" | |
1 | .\" ////////////////////////////////////////////////////////////////////////// | |
2 | .SH NAME | |
3 | .\" ////////////////////////////////////////////////////////////////////////// | |
4 | seccomp_syscall_priority \- Prioritize syscalls in the seccomp filter | |
5 | .\" ////////////////////////////////////////////////////////////////////////// | |
6 | .SH SYNOPSIS | |
7 | .\" ////////////////////////////////////////////////////////////////////////// | |
8 | .nf | |
9 | .B #include <seccomp.h> | |
10 | .sp | |
11 | .B typedef void * scmp_filter_ctx; | |
12 | .sp | |
13 | .BI "int SCMP_SYS(" syscall_name ");" | |
14 | .sp | |
15 | .BI "int seccomp_syscall_priority(scmp_filter_ctx " ctx "," | |
16 | .BI " int " syscall ", uint8_t " priority ");" | |
17 | .sp | |
18 | Link with \fI\-lseccomp\fP. | |
19 | .fi | |
20 | .\" ////////////////////////////////////////////////////////////////////////// | |
21 | .SH DESCRIPTION | |
22 | .\" ////////////////////////////////////////////////////////////////////////// | |
23 | .P | |
24 | The | |
25 | .BR seccomp_syscall_priority () | |
26 | function provides a priority hint to the seccomp filter generator in libseccomp | |
27 | such that higher priority syscalls are placed earlier in the seccomp filter code | |
28 | so that they incur less overhead at the expense of lower priority syscalls. A | |
29 | syscall's priority can be set regardless of if any rules currently exist for | |
30 | that syscall; the library will remember the priority and it will be assigned to | |
31 | the syscall if and when a rule for that syscall is created. | |
32 | .P | |
33 | While it is possible to specify the | |
34 | .I syscall | |
35 | value directly using the standard | |
36 | .B __NR_syscall | |
37 | values, in order to ensure proper operation across multiple architectures it | |
38 | is highly recommended to use the | |
39 | .BR SCMP_SYS () | |
40 | macro instead. See the EXAMPLES section below. | |
41 | .P | |
42 | The | |
43 | .I priority | |
44 | parameter takes an 8-bit value ranging from 0 \- 255; a higher value represents | |
45 | a higher priority. | |
46 | .P | |
47 | The filter context | |
48 | .I ctx | |
49 | is the value returned by the call to | |
50 | .BR seccomp_init (). | |
51 | .\" ////////////////////////////////////////////////////////////////////////// | |
52 | .SH RETURN VALUE | |
53 | .\" ////////////////////////////////////////////////////////////////////////// | |
54 | The | |
55 | .BR seccomp_syscall_priority () | |
56 | function returns zero on success, negative errno values on failure. The | |
57 | .BR SCMP_SYS () | |
58 | macro returns a value suitable for use as the | |
59 | .I syscall | |
60 | value in | |
61 | .BR seccomp_syscall_priority (). | |
62 | .\" ////////////////////////////////////////////////////////////////////////// | |
63 | .SH EXAMPLES | |
64 | .\" ////////////////////////////////////////////////////////////////////////// | |
65 | .nf | |
66 | #include <seccomp.h> | |
67 | ||
68 | int main(int argc, char *argv[]) | |
69 | { | |
70 | int rc = \-1; | |
71 | scmp_filter_ctx ctx; | |
72 | ||
73 | ctx = seccomp_init(SCMP_ACT_KILL); | |
74 | if (ctx == NULL) | |
75 | goto out; | |
76 | ||
77 | /* ... */ | |
78 | ||
79 | rc = seccomp_syscall_priority(ctx, SCMP_SYS(read), 200); | |
80 | if (rc < 0) | |
81 | goto out; | |
82 | ||
83 | /* ... */ | |
84 | ||
85 | out: | |
86 | seccomp_release(ctx); | |
87 | return \-rc; | |
88 | } | |
89 | .fi | |
90 | .\" ////////////////////////////////////////////////////////////////////////// | |
91 | .SH NOTES | |
92 | .\" ////////////////////////////////////////////////////////////////////////// | |
93 | .P | |
94 | While the seccomp filter can be generated independent of the kernel, kernel | |
95 | support is required to load and enforce the seccomp filter generated by | |
96 | libseccomp. | |
97 | .P | |
98 | The libseccomp project site, with more information and the source code | |
99 | repository, can be found at http://libseccomp.sf.net. This library is currently | |
100 | under development, please report any bugs at the project site or directly to | |
101 | the author. | |
102 | .\" ////////////////////////////////////////////////////////////////////////// | |
103 | .SH AUTHOR | |
104 | .\" ////////////////////////////////////////////////////////////////////////// | |
105 | Paul Moore <paul@paul-moore.com> | |
106 | .\" ////////////////////////////////////////////////////////////////////////// | |
107 | .SH SEE ALSO | |
108 | .\" ////////////////////////////////////////////////////////////////////////// | |
109 | .BR seccomp_rule_add (3), | |
110 | .BR seccomp_rule_add_exact (3) |
0 | .TH "seccomp_syscall_resolve_name" 3 "7 January 2013" "paul@paul-moore.com" "libseccomp Documentation" | |
1 | .\" ////////////////////////////////////////////////////////////////////////// | |
2 | .SH NAME | |
3 | .\" ////////////////////////////////////////////////////////////////////////// | |
4 | seccomp_syscall_resolve_name \- Resolve a syscall name | |
5 | .\" ////////////////////////////////////////////////////////////////////////// | |
6 | .SH SYNOPSIS | |
7 | .\" ////////////////////////////////////////////////////////////////////////// | |
8 | .nf | |
9 | .B #include <seccomp.h> | |
10 | .sp | |
11 | .BI "int seccomp_syscall_resolve_name(const char *" name ");" | |
12 | .BI "int seccomp_syscall_resolve_name_arch(uint32_t " arch_token "," | |
13 | .BI " const char *" name ");" | |
14 | .BI "char *seccomp_syscall_resolve_num_arch(uint32_t " arch_token ", int " num ");" | |
15 | .sp | |
16 | Link with \fI\-lseccomp\fP. | |
17 | .fi | |
18 | .\" ////////////////////////////////////////////////////////////////////////// | |
19 | .SH DESCRIPTION | |
20 | .\" ////////////////////////////////////////////////////////////////////////// | |
21 | .P | |
22 | The | |
23 | .BR seccomp_syscall_resolve_name () | |
24 | and | |
25 | .BR seccomp_syscall_resolve_name_arch() | |
26 | functions resolve the commonly used syscall name to the syscall number used by | |
27 | the kernel and the rest of the libseccomp API. The | |
28 | .BR seccomp_syscall_resolve_num_arch() | |
29 | function resolves the syscall number used by the kernel to the commonly used | |
30 | syscall name. | |
31 | .P | |
32 | The caller is responsible for freeing the returned string from | |
33 | .BR seccomp_syscall_resolve_num_arch() . | |
34 | .\" ////////////////////////////////////////////////////////////////////////// | |
35 | .SH RETURN VALUE | |
36 | .\" ////////////////////////////////////////////////////////////////////////// | |
37 | .P | |
38 | In the case of | |
39 | .BR seccomp_syscall_resolve_name () | |
40 | and | |
41 | .BR seccomp_syscall_resolve_name_arch() | |
42 | the associated syscall number is returned, with the negative pseudo syscall | |
43 | number being returned in cases where the given syscall does not exist for the | |
44 | architeture. The value | |
45 | .BR __NR_SCMP_ERROR | |
46 | is returned in case of error. In all cases, the return value is suitable for | |
47 | use in any libseccomp API function which requires the syscall number, examples include | |
48 | .BR seccomp_rule_add () | |
49 | and | |
50 | .BR seccomp_rule_add_exact (). | |
51 | .P | |
52 | In the case of | |
53 | .BR seccomp_syscall_resolve_num_arch() | |
54 | the associated syscall name is returned and it remains the callers | |
55 | responsibility to free the returned string via | |
56 | .BR free (3). | |
57 | .\" ////////////////////////////////////////////////////////////////////////// | |
58 | .SH EXAMPLES | |
59 | .\" ////////////////////////////////////////////////////////////////////////// | |
60 | .nf | |
61 | #include <seccomp.h> | |
62 | ||
63 | int main(int argc, char *argv[]) | |
64 | { | |
65 | int rc = \-1; | |
66 | scmp_filter_ctx ctx; | |
67 | ||
68 | ctx = seccomp_init(SCMP_ACT_KILL); | |
69 | if (ctx == NULL) | |
70 | goto out; | |
71 | ||
72 | /* ... */ | |
73 | ||
74 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, | |
75 | seccomp_syscall_resolve_name("open"), 0); | |
76 | if (rc < 0) | |
77 | goto out; | |
78 | ||
79 | /* ... */ | |
80 | ||
81 | rc = seccomp_load(ctx); | |
82 | if (rc < 0) | |
83 | goto out; | |
84 | ||
85 | /* ... */ | |
86 | ||
87 | out: | |
88 | seccomp_release(ctx); | |
89 | return \-rc; | |
90 | } | |
91 | .fi | |
92 | .\" ////////////////////////////////////////////////////////////////////////// | |
93 | .SH NOTES | |
94 | .\" ////////////////////////////////////////////////////////////////////////// | |
95 | .P | |
96 | While the seccomp filter can be generated independent of the kernel, kernel | |
97 | support is required to load and enforce the seccomp filter generated by | |
98 | libseccomp. | |
99 | .P | |
100 | The libseccomp project site, with more information and the source code | |
101 | repository, can be found at http://libseccomp.sf.net. This library is currently | |
102 | under development, please report any bugs at the project site or directly to | |
103 | the author. | |
104 | .\" ////////////////////////////////////////////////////////////////////////// | |
105 | .SH AUTHOR | |
106 | .\" ////////////////////////////////////////////////////////////////////////// | |
107 | Paul Moore <paul@paul-moore.com> | |
108 | .\" ////////////////////////////////////////////////////////////////////////// | |
109 | .SH SEE ALSO | |
110 | .\" ////////////////////////////////////////////////////////////////////////// | |
111 | .BR seccomp_rule_add (3), | |
112 | .BR seccomp_rule_add_exact (3) |
0 | .so man3/seccomp_syscall_resolve_name.3 |
0 | .so man3/seccomp_syscall_resolve_name.3 |
0 | # | |
1 | # Enhanced Seccomp Library Makefile | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | # | |
22 | # macros | |
23 | # | |
24 | ||
25 | include ../macros.mk | |
26 | ||
27 | # | |
28 | # configuration | |
29 | # | |
30 | ||
31 | include $(TOPDIR)/version_info.mk | |
32 | include $(TOPDIR)/configure.mk | |
33 | include $(TOPDIR)/install.mk | |
34 | ||
35 | HDR_BUILD = seccomp.h | |
36 | ||
37 | # | |
38 | # targets | |
39 | # | |
40 | ||
41 | .PHONY: all install clean | |
42 | ||
43 | all: $(HDR_BUILD) | |
44 | ||
45 | install: $(HDR_BUILD) | |
46 | $(INSTALL_INC_MACRO) | |
47 | ||
48 | seccomp.h: seccomp.h.in | |
49 | @$(ECHO) " GEN $@" | |
50 | $(CAT) $< | \ | |
51 | $(SED) -e 's/%%VERSION_MAJOR%%/$(VERSION_MAJOR)/g' | \ | |
52 | $(SED) -e 's/%%VERSION_MINOR%%/$(VERSION_MINOR)/g' | \ | |
53 | $(SED) -e 's/%%VERSION_MICRO%%/$(VERSION_MICRO)/g' > $@ | |
54 | ||
55 | clean: | |
56 | @$(RM) $(HDR_BUILD) |
0 | /** | |
1 | * Seccomp Library | |
2 | * | |
3 | * Copyright (c) 2012,2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #ifndef _SECCOMP_H | |
22 | #define _SECCOMP_H | |
23 | ||
24 | #include <elf.h> | |
25 | #include <inttypes.h> | |
26 | #include <asm/unistd.h> | |
27 | #include <linux/audit.h> | |
28 | ||
29 | #ifdef __cplusplus | |
30 | extern "C" { | |
31 | #endif | |
32 | ||
33 | /* | |
34 | * version information | |
35 | */ | |
36 | ||
37 | #define SCMP_VER_MAJOR %%VERSION_MAJOR%% | |
38 | #define SCMP_VER_MINOR %%VERSION_MINOR%% | |
39 | #define SCMP_VER_MICRO %%VERSION_MICRO%% | |
40 | ||
41 | /* | |
42 | * types | |
43 | */ | |
44 | ||
45 | /** | |
46 | * Filter context/handle | |
47 | */ | |
48 | typedef void *scmp_filter_ctx; | |
49 | ||
50 | /** | |
51 | * Filter attributes | |
52 | */ | |
53 | enum scmp_filter_attr { | |
54 | _SCMP_FLTATR_MIN = 0, | |
55 | SCMP_FLTATR_ACT_DEFAULT = 1, /**< default filter action */ | |
56 | SCMP_FLTATR_ACT_BADARCH = 2, /**< bad architecture action */ | |
57 | SCMP_FLTATR_CTL_NNP = 3, /**< set NO_NEW_PRIVS on filter load */ | |
58 | _SCMP_FLTATR_MAX, | |
59 | }; | |
60 | ||
61 | /** | |
62 | * Comparison operators | |
63 | */ | |
64 | enum scmp_compare { | |
65 | _SCMP_CMP_MIN = 0, | |
66 | SCMP_CMP_NE = 1, /**< not equal */ | |
67 | SCMP_CMP_LT = 2, /**< less than */ | |
68 | SCMP_CMP_LE = 3, /**< less than or equal */ | |
69 | SCMP_CMP_EQ = 4, /**< equal */ | |
70 | SCMP_CMP_GE = 5, /**< greater than or equal */ | |
71 | SCMP_CMP_GT = 6, /**< greater than */ | |
72 | SCMP_CMP_MASKED_EQ = 7, /**< masked equality */ | |
73 | _SCMP_CMP_MAX, | |
74 | }; | |
75 | ||
76 | /** | |
77 | * Argument datum | |
78 | */ | |
79 | typedef uint64_t scmp_datum_t; | |
80 | ||
81 | /** | |
82 | * Argument / Value comparison definition | |
83 | */ | |
84 | struct scmp_arg_cmp { | |
85 | unsigned int arg; /**< argument number, starting at 0 */ | |
86 | enum scmp_compare op; /**< the comparison op, e.g. SCMP_CMP_* */ | |
87 | scmp_datum_t datum_a; | |
88 | scmp_datum_t datum_b; | |
89 | }; | |
90 | ||
91 | /* | |
92 | * macros/defines | |
93 | */ | |
94 | ||
95 | /** | |
96 | * The native architecture token | |
97 | */ | |
98 | #define SCMP_ARCH_NATIVE 0 | |
99 | ||
100 | /** | |
101 | * The x86 (32-bit) architecture token | |
102 | */ | |
103 | #define SCMP_ARCH_X86 AUDIT_ARCH_I386 | |
104 | ||
105 | /** | |
106 | * The x86-64 (64-bit) architecture token | |
107 | */ | |
108 | #define SCMP_ARCH_X86_64 AUDIT_ARCH_X86_64 | |
109 | ||
110 | /** | |
111 | * The x32 (32-bit x86_64) architecture token | |
112 | * | |
113 | * NOTE: this is different from the value used by the kernel because we need to | |
114 | * be able to distinguish between x32 and x86_64 | |
115 | */ | |
116 | #define SCMP_ARCH_X32 (EM_X86_64|__AUDIT_ARCH_LE) | |
117 | ||
118 | /** | |
119 | * The ARM architecture token | |
120 | */ | |
121 | #define SCMP_ARCH_ARM AUDIT_ARCH_ARM | |
122 | ||
123 | /** | |
124 | * Convert a syscall name into the associated syscall number | |
125 | * @param x the syscall name | |
126 | */ | |
127 | #define SCMP_SYS(x) (__NR_##x) | |
128 | ||
129 | /** | |
130 | * Specify an argument comparison struct for use in declaring rules | |
131 | * @param arg the argument number, starting at 0 | |
132 | * @param op the comparison operator, e.g. SCMP_CMP_* | |
133 | * @param datum_a dependent on comparison | |
134 | * @param datum_b dependent on comparison, optional | |
135 | */ | |
136 | #define SCMP_CMP(...) ((struct scmp_arg_cmp){__VA_ARGS__}) | |
137 | ||
138 | /** | |
139 | * Specify an argument comparison struct for argument 0 | |
140 | */ | |
141 | #define SCMP_A0(...) SCMP_CMP(0, __VA_ARGS__) | |
142 | ||
143 | /** | |
144 | * Specify an argument comparison struct for argument 1 | |
145 | */ | |
146 | #define SCMP_A1(...) SCMP_CMP(1, __VA_ARGS__) | |
147 | ||
148 | /** | |
149 | * Specify an argument comparison struct for argument 2 | |
150 | */ | |
151 | #define SCMP_A2(...) SCMP_CMP(2, __VA_ARGS__) | |
152 | ||
153 | /** | |
154 | * Specify an argument comparison struct for argument 3 | |
155 | */ | |
156 | #define SCMP_A3(...) SCMP_CMP(3, __VA_ARGS__) | |
157 | ||
158 | /** | |
159 | * Specify an argument comparison struct for argument 4 | |
160 | */ | |
161 | #define SCMP_A4(...) SCMP_CMP(4, __VA_ARGS__) | |
162 | ||
163 | /** | |
164 | * Specify an argument comparison struct for argument 5 | |
165 | */ | |
166 | #define SCMP_A5(...) SCMP_CMP(5, __VA_ARGS__) | |
167 | ||
168 | /* | |
169 | * seccomp actions | |
170 | */ | |
171 | ||
172 | /** | |
173 | * Kill the process | |
174 | */ | |
175 | #define SCMP_ACT_KILL 0x00000000U | |
176 | /** | |
177 | * Throw a SIGSYS signal | |
178 | */ | |
179 | #define SCMP_ACT_TRAP 0x00030000U | |
180 | /** | |
181 | * Return the specified error code | |
182 | */ | |
183 | #define SCMP_ACT_ERRNO(x) (0x00050000U | ((x) & 0x0000ffffU)) | |
184 | /** | |
185 | * Notify a tracing process with the specified value | |
186 | */ | |
187 | #define SCMP_ACT_TRACE(x) (0x7ff00000U | ((x) & 0x0000ffffU)) | |
188 | /** | |
189 | * Allow the syscall to be executed | |
190 | */ | |
191 | #define SCMP_ACT_ALLOW 0x7fff0000U | |
192 | ||
193 | /* | |
194 | * functions | |
195 | */ | |
196 | ||
197 | /** | |
198 | * Initialize the filter state | |
199 | * @param def_action the default filter action | |
200 | * | |
201 | * This function initializes the internal seccomp filter state and should | |
202 | * be called before any other functions in this library to ensure the filter | |
203 | * state is initialized. Returns a filter context on success, NULL on failure. | |
204 | * | |
205 | */ | |
206 | scmp_filter_ctx seccomp_init(uint32_t def_action); | |
207 | ||
208 | /** | |
209 | * Reset the filter state | |
210 | * @param ctx the filter context | |
211 | * @param def_action the default filter action | |
212 | * | |
213 | * This function resets the given seccomp filter state and ensures the | |
214 | * filter state is reinitialized. This function does not reset any seccomp | |
215 | * filters already loaded into the kernel. Returns zero on success, negative | |
216 | * values on failure. | |
217 | * | |
218 | */ | |
219 | int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action); | |
220 | ||
221 | /** | |
222 | * Destroys the filter state and releases any resources | |
223 | * @param ctx the filter context | |
224 | * | |
225 | * This functions destroys the given seccomp filter state and releases any | |
226 | * resources, including memory, associated with the filter state. This | |
227 | * function does not reset any seccomp filters already loaded into the kernel. | |
228 | * The filter context can no longer be used after calling this function. | |
229 | * | |
230 | */ | |
231 | void seccomp_release(scmp_filter_ctx ctx); | |
232 | ||
233 | /** | |
234 | * Merge two filters | |
235 | * @param ctx_dst the destination filter context | |
236 | * @param ctx_src the source filter context | |
237 | * | |
238 | * This function merges two filter contexts into a single filter context and | |
239 | * destroys the second filter context. The two filter contexts must have the | |
240 | * same attribute values and not contain any of the same architectures; if they | |
241 | * do, the merge operation will fail. On success, the source filter context | |
242 | * will be destroyed and should no longer be used; it is not necessary to | |
243 | * call seccomp_release() on the source filter context. Returns zero on | |
244 | * success, negative values on failure. | |
245 | * | |
246 | */ | |
247 | int seccomp_merge(scmp_filter_ctx ctx_dst, scmp_filter_ctx ctx_src); | |
248 | ||
249 | /** | |
250 | * Return the native architecture token | |
251 | * | |
252 | * This function returns the native architecture token value, e.g. SCMP_ARCH_*. | |
253 | * | |
254 | */ | |
255 | uint32_t seccomp_arch_native(void); | |
256 | ||
257 | /** | |
258 | * Check to see if an existing architecture is present in the filter | |
259 | * @param ctx the filter context | |
260 | * @param arch_token the architecture token, e.g. SCMP_ARCH_* | |
261 | * | |
262 | * This function tests to see if a given architecture is included in the filter | |
263 | * context. If the architecture token is SCMP_ARCH_NATIVE then the native | |
264 | * architecture will be assumed. Returns zero if the architecture exists in | |
265 | * the filter, -EEXIST if it is not present, and other negative values on | |
266 | * failure. | |
267 | * | |
268 | */ | |
269 | int seccomp_arch_exist(const scmp_filter_ctx ctx, uint32_t arch_token); | |
270 | ||
271 | /** | |
272 | * Adds an architecture to the filter | |
273 | * @param ctx the filter context | |
274 | * @param arch_token the architecture token, e.g. SCMP_ARCH_* | |
275 | * | |
276 | * This function adds a new architecture to the given seccomp filter context. | |
277 | * Any new rules added after this function successfully returns will be added | |
278 | * to this architecture but existing rules will not be added to this | |
279 | * architecture. If the architecture token is SCMP_ARCH_NATIVE then the native | |
280 | * architecture will be assumed. Returns zero on success, negative values on | |
281 | * failure. | |
282 | * | |
283 | */ | |
284 | int seccomp_arch_add(scmp_filter_ctx ctx, uint32_t arch_token); | |
285 | ||
286 | /** | |
287 | * Removes an architecture from the filter | |
288 | * @param ctx the filter context | |
289 | * @param arch_token the architecture token, e.g. SCMP_ARCH_* | |
290 | * | |
291 | * This function removes an architecture from the given seccomp filter context. | |
292 | * If the architecture token is SCMP_ARCH_NATIVE then the native architecture | |
293 | * will be assumed. Returns zero on success, negative values on failure. | |
294 | * | |
295 | */ | |
296 | int seccomp_arch_remove(scmp_filter_ctx ctx, uint32_t arch_token); | |
297 | ||
298 | /** | |
299 | * Loads the filter into the kernel | |
300 | * @param ctx the filter context | |
301 | * | |
302 | * This function loads the given seccomp filter context into the kernel. If | |
303 | * the filter was loaded correctly, the kernel will be enforcing the filter | |
304 | * when this function returns. Returns zero on success, negative values on | |
305 | * error. | |
306 | * | |
307 | */ | |
308 | int seccomp_load(const scmp_filter_ctx ctx); | |
309 | ||
310 | /** | |
311 | * Get the value of a filter attribute | |
312 | * @param ctx the filter context | |
313 | * @param attr the filter attribute name | |
314 | * @param value the filter attribute value | |
315 | * | |
316 | * This function fetches the value of the given attribute name and returns it | |
317 | * via @value. Returns zero on success, negative values on failure. | |
318 | * | |
319 | */ | |
320 | int seccomp_attr_get(const scmp_filter_ctx ctx, | |
321 | enum scmp_filter_attr attr, uint32_t *value); | |
322 | ||
323 | /** | |
324 | * Set the value of a filter attribute | |
325 | * @param ctx the filter context | |
326 | * @param attr the filter attribute name | |
327 | * @param value the filter attribute value | |
328 | * | |
329 | * This function sets the value of the given attribute. Returns zero on | |
330 | * success, negative values on failure. | |
331 | * | |
332 | */ | |
333 | int seccomp_attr_set(scmp_filter_ctx ctx, | |
334 | enum scmp_filter_attr attr, uint32_t value); | |
335 | ||
336 | /** | |
337 | * Resolve a syscall number to a name | |
338 | * @param arch_token the architecture token, e.g. SCMP_ARCH_* | |
339 | * @param num the syscall number | |
340 | * | |
341 | * Resolve the given syscall number to the syscall name for the given | |
342 | * architecture; it is up to the caller to free the returned string. Returns | |
343 | * the syscall name on success, NULL on failure. | |
344 | * | |
345 | */ | |
346 | char *seccomp_syscall_resolve_num_arch(uint32_t arch_token, int num); | |
347 | ||
348 | /** | |
349 | * Resolve a syscall name to a number | |
350 | * @param arch_token the architecture token, e.g. SCMP_ARCH_* | |
351 | * @param name the syscall name | |
352 | * | |
353 | * Resolve the given syscall name to the syscall number for the given | |
354 | * architecture. Returns the syscall number on success, including negative | |
355 | * pseudo syscall numbers (e.g. __PNR_*); returns __NR_SCMP_ERROR on failure. | |
356 | * | |
357 | */ | |
358 | int seccomp_syscall_resolve_name_arch(uint32_t arch_token, const char *name); | |
359 | ||
360 | /** | |
361 | * Resolve a syscall name to a number | |
362 | * @param name the syscall name | |
363 | * | |
364 | * Resolve the given syscall name to the syscall number. Returns the syscall | |
365 | * number on success, including negative pseudo syscall numbers (e.g. __PNR_*); | |
366 | * returns __NR_SCMP_ERROR on failure. | |
367 | * | |
368 | */ | |
369 | int seccomp_syscall_resolve_name(const char *name); | |
370 | ||
371 | /** | |
372 | * Set the priority of a given syscall | |
373 | * @param ctx the filter context | |
374 | * @param syscall the syscall number | |
375 | * @param priority priority value, higher value == higher priority | |
376 | * | |
377 | * This function sets the priority of the given syscall; this value is used | |
378 | * when generating the seccomp filter code such that higher priority syscalls | |
379 | * will incur less filter code overhead than the lower priority syscalls in the | |
380 | * filter. Returns zero on success, negative values on failure. | |
381 | * | |
382 | */ | |
383 | int seccomp_syscall_priority(scmp_filter_ctx ctx, | |
384 | int syscall, uint8_t priority); | |
385 | ||
386 | /** | |
387 | * Add a new rule to the filter | |
388 | * @param ctx the filter context | |
389 | * @param action the filter action | |
390 | * @param syscall the syscall number | |
391 | * @param arg_cnt the number of argument filters in the argument filter chain | |
392 | * @param ... scmp_arg_cmp structs (use of SCMP_ARG_CMP() recommended) | |
393 | * | |
394 | * This function adds a series of new argument/value checks to the seccomp | |
395 | * filter for the given syscall; multiple argument/value checks can be | |
396 | * specified and they will be chained together (AND'd together) in the filter. | |
397 | * If the specified rule needs to be adjusted due to architecture specifics it | |
398 | * will be adjusted without notification. Returns zero on success, negative | |
399 | * values on failure. | |
400 | * | |
401 | */ | |
402 | int seccomp_rule_add(scmp_filter_ctx ctx, | |
403 | uint32_t action, int syscall, unsigned int arg_cnt, ...); | |
404 | ||
405 | ||
406 | /** | |
407 | * Add a new rule to the filter | |
408 | * @param ctx the filter context | |
409 | * @param action the filter action | |
410 | * @param syscall the syscall number | |
411 | * @param arg_cnt the number of elements in the arg_array parameter | |
412 | * @param arg_array array of scmp_arg_cmp structs | |
413 | * | |
414 | * This function adds a series of new argument/value checks to the seccomp | |
415 | * filter for the given syscall; multiple argument/value checks can be | |
416 | * specified and they will be chained together (AND'd together) in the filter. | |
417 | * If the specified rule needs to be adjusted due to architecture specifics it | |
418 | * will be adjusted without notification. Returns zero on success, negative | |
419 | * values on failure. | |
420 | * | |
421 | */ | |
422 | int seccomp_rule_add_array(scmp_filter_ctx ctx, | |
423 | uint32_t action, int syscall, unsigned int arg_cnt, | |
424 | const struct scmp_arg_cmp *arg_array); | |
425 | ||
426 | /** | |
427 | * Add a new rule to the filter | |
428 | * @param ctx the filter context | |
429 | * @param action the filter action | |
430 | * @param syscall the syscall number | |
431 | * @param arg_cnt the number of argument filters in the argument filter chain | |
432 | * @param ... scmp_arg_cmp structs (use of SCMP_ARG_CMP() recommended) | |
433 | * | |
434 | * This function adds a series of new argument/value checks to the seccomp | |
435 | * filter for the given syscall; multiple argument/value checks can be | |
436 | * specified and they will be chained together (AND'd together) in the filter. | |
437 | * If the specified rule can not be represented on the architecture the | |
438 | * function will fail. Returns zero on success, negative values on failure. | |
439 | * | |
440 | */ | |
441 | int seccomp_rule_add_exact(scmp_filter_ctx ctx, uint32_t action, | |
442 | int syscall, unsigned int arg_cnt, ...); | |
443 | ||
444 | /** | |
445 | * Add a new rule to the filter | |
446 | * @param ctx the filter context | |
447 | * @param action the filter action | |
448 | * @param syscall the syscall number | |
449 | * @param arg_cnt the number of elements in the arg_array parameter | |
450 | * @param arg_array array of scmp_arg_cmp structs | |
451 | * | |
452 | * This function adds a series of new argument/value checks to the seccomp | |
453 | * filter for the given syscall; multiple argument/value checks can be | |
454 | * specified and they will be chained together (AND'd together) in the filter. | |
455 | * If the specified rule can not be represented on the architecture the | |
456 | * function will fail. Returns zero on success, negative values on failure. | |
457 | * | |
458 | */ | |
459 | int seccomp_rule_add_exact_array(scmp_filter_ctx ctx, | |
460 | uint32_t action, int syscall, | |
461 | unsigned int arg_cnt, | |
462 | const struct scmp_arg_cmp *arg_array); | |
463 | ||
464 | /** | |
465 | * Generate seccomp Pseudo Filter Code (PFC) and export it to a file | |
466 | * @param ctx the filter context | |
467 | * @param fd the destination fd | |
468 | * | |
469 | * This function generates seccomp Pseudo Filter Code (PFC) and writes it to | |
470 | * the given fd. Returns zero on success, negative values on failure. | |
471 | * | |
472 | */ | |
473 | int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd); | |
474 | ||
475 | /** | |
476 | * Generate seccomp Berkley Packet Filter (BPF) code and export it to a file | |
477 | * @param ctx the filter context | |
478 | * @param fd the destination fd | |
479 | * | |
480 | * This function generates seccomp Berkley Packer Filter (BPF) code and writes | |
481 | * it to the given fd. Returns zero on success, negative values on failure. | |
482 | * | |
483 | */ | |
484 | int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd); | |
485 | ||
486 | /* | |
487 | * pseudo syscall definitions | |
488 | */ | |
489 | ||
490 | /* NOTE - pseudo syscall values {-1..-99} are reserved */ | |
491 | #define __NR_SCMP_ERROR -1 | |
492 | ||
493 | /* socket syscalls */ | |
494 | ||
495 | #define __PNR_socket -101 | |
496 | #ifndef __NR_socket | |
497 | #define __NR_socket __PNR_socket | |
498 | #endif /* __NR_socket */ | |
499 | ||
500 | #define __PNR_bind -102 | |
501 | #ifndef __NR_bind | |
502 | #define __NR_bind __PNR_bind | |
503 | #endif /* __NR_bind */ | |
504 | ||
505 | #define __PNR_connect -103 | |
506 | #ifndef __NR_connect | |
507 | #define __NR_connect __PNR_connect | |
508 | #endif /* __NR_connect */ | |
509 | ||
510 | #define __PNR_listen -104 | |
511 | #ifndef __NR_listen | |
512 | #define __NR_listen __PNR_listen | |
513 | #endif /* __NR_listen */ | |
514 | ||
515 | #define __PNR_accept -105 | |
516 | #ifndef __NR_accept | |
517 | #define __NR_accept __PNR_accept | |
518 | #endif /* __NR_accept */ | |
519 | ||
520 | #define __PNR_getsockname -106 | |
521 | #ifndef __NR_getsockname | |
522 | #define __NR_getsockname __PNR_getsockname | |
523 | #endif /* __NR_getsockname */ | |
524 | ||
525 | #define __PNR_getpeername -107 | |
526 | #ifndef __NR_getpeername | |
527 | #define __NR_getpeername __PNR_getpeername | |
528 | #endif /* __NR_getpeername */ | |
529 | ||
530 | #define __PNR_socketpair -108 | |
531 | #ifndef __NR_socketpair | |
532 | #define __NR_socketpair __PNR_socketpair | |
533 | #endif /* __NR_socketpair */ | |
534 | ||
535 | #define __PNR_send -109 | |
536 | #ifndef __NR_send | |
537 | #define __NR_send __PNR_send | |
538 | #endif /* __NR_send */ | |
539 | ||
540 | #define __PNR_recv -110 | |
541 | #ifndef __NR_recv | |
542 | #define __NR_recv __PNR_recv | |
543 | #endif /* __NR_recv */ | |
544 | ||
545 | #define __PNR_sendto -111 | |
546 | #ifndef __NR_sendto | |
547 | #define __NR_sendto __PNR_sendto | |
548 | #endif /* __NR_sendto */ | |
549 | ||
550 | #define __PNR_recvfrom -112 | |
551 | #ifndef __NR_recvfrom | |
552 | #define __NR_recvfrom __PNR_recvfrom | |
553 | #endif /* __NR_recvfrom */ | |
554 | ||
555 | #define __PNR_shutdown -113 | |
556 | #ifndef __NR_shutdown | |
557 | #define __NR_shutdown __PNR_shutdown | |
558 | #endif /* __NR_shutdown */ | |
559 | ||
560 | #define __PNR_setsockopt -114 | |
561 | #ifndef __NR_setsockopt | |
562 | #define __NR_setsockopt __PNR_setsockopt | |
563 | #endif /* __NR_getsockopt */ | |
564 | ||
565 | #define __PNR_getsockopt -115 | |
566 | #ifndef __NR_getsockopt | |
567 | #define __NR_getsockopt __PNR_getsockopt | |
568 | #endif /* __NR_getsockopt */ | |
569 | ||
570 | #define __PNR_sendmsg -116 | |
571 | #ifndef __NR_sendmsg | |
572 | #define __NR_sendmsg __PNR_sendmsg | |
573 | #endif /* __NR_sendmsg */ | |
574 | ||
575 | #define __PNR_recvmsg -117 | |
576 | #ifndef __NR_recvmsg | |
577 | #define __NR_recvmsg __PNR_recvmsg | |
578 | #endif /* __NR_recvmsg */ | |
579 | ||
580 | #define __PNR_accept4 -118 | |
581 | #ifndef __NR_accept4 | |
582 | #define __NR_accept4 __PNR_accept4 | |
583 | #endif /* __NR_accept4 */ | |
584 | ||
585 | #define __PNR_recvmmsg -119 | |
586 | #ifndef __NR_recvmmsg | |
587 | #define __NR_recvmmsg __PNR_recvmmsg | |
588 | #endif /* __NR_recvmmsg */ | |
589 | ||
590 | #define __PNR_sendmmsg -120 | |
591 | #ifndef __NR_sendmmsg | |
592 | #define __NR_sendmmsg __PNR_sendmmsg | |
593 | #endif /* __NR_sendmmsg */ | |
594 | ||
595 | /* ipc syscalls */ | |
596 | ||
597 | #define __PNR_semop -201 | |
598 | #ifndef __NR_semop | |
599 | #define __NR_semop __PNR_semop | |
600 | #endif /* __NR_semop */ | |
601 | ||
602 | #define __PNR_semget -202 | |
603 | #ifndef __NR_semget | |
604 | #define __NR_semget __PNR_semget | |
605 | #endif /* __NR_semget */ | |
606 | ||
607 | #define __PNR_semctl -203 | |
608 | #ifndef __NR_semctl | |
609 | #define __NR_semctl __PNR_semctl | |
610 | #endif /* __NR_semctl */ | |
611 | ||
612 | #define __PNR_semtimedop -204 | |
613 | #ifndef __NR_semtimedop | |
614 | #define __NR_semtimedop __PNR_semtimedop | |
615 | #endif /* __NR_semtime */ | |
616 | ||
617 | #define __PNR_msgsnd -211 | |
618 | #ifndef __NR_msgsnd | |
619 | #define __NR_msgsnd __PNR_msgsnd | |
620 | #endif /* __NR_msgsnd */ | |
621 | ||
622 | #define __PNR_msgrcv -212 | |
623 | #ifndef __NR_msgrcv | |
624 | #define __NR_msgrcv __PNR_msgrcv | |
625 | #endif /* __NR_msgrcv */ | |
626 | ||
627 | #define __PNR_msgget -213 | |
628 | #ifndef __NR_msgget | |
629 | #define __NR_msgget __PNR_msgget | |
630 | #endif /* __NR_msgget */ | |
631 | ||
632 | #define __PNR_msgctl -214 | |
633 | #ifndef __NR_msgctl | |
634 | #define __NR_msgctl __PNR_msgctl | |
635 | #endif /* __NR_msgctl */ | |
636 | ||
637 | #define __PNR_shmat -221 | |
638 | #ifndef __NR_shmat | |
639 | #define __NR_shmat __PNR_shmat | |
640 | #endif /* __NR_shmat */ | |
641 | ||
642 | #define __PNR_shmdt -222 | |
643 | #ifndef __NR_shmdt | |
644 | #define __NR_shmdt __PNR_shmdt | |
645 | #endif /* __NR_shmdt */ | |
646 | ||
647 | #define __PNR_shmget -223 | |
648 | #ifndef __NR_shmget | |
649 | #define __NR_shmget __PNR_shmget | |
650 | #endif /* __NR_shmget */ | |
651 | ||
652 | #define __PNR_shmctl -224 | |
653 | #ifndef __NR_shmctl | |
654 | #define __NR_shmctl __PNR_shmctl | |
655 | #endif /* __NR_shmctl */ | |
656 | ||
657 | /* single syscalls */ | |
658 | ||
659 | #define __PNR_arch_prctl -10001 | |
660 | #ifndef __NR_arch_prctl | |
661 | #define __NR_arch_prctl __PNR_arch_prctl | |
662 | #endif /* __NR_arch_prctl */ | |
663 | ||
664 | #define __PNR_bdflush -10002 | |
665 | #ifndef __NR_bdflush | |
666 | #define __NR_bdflush __PNR_bdflush | |
667 | #endif /* __NR_bdflush */ | |
668 | ||
669 | #define __PNR_break -10003 | |
670 | #ifndef __NR_break | |
671 | #define __NR_break __PNR_break | |
672 | #endif /* __NR_break */ | |
673 | ||
674 | #define __PNR_chown32 -10004 | |
675 | #ifndef __NR_chown32 | |
676 | #define __NR_chown32 __PNR_chown32 | |
677 | #endif /* __NR_chown32 */ | |
678 | ||
679 | #define __PNR_epoll_ctl_old -10005 | |
680 | #ifndef __NR_epoll_ctl_old | |
681 | #define __NR_epoll_ctl_old __PNR_epoll_ctl_old | |
682 | #endif /* __NR_epoll_ctl_old */ | |
683 | ||
684 | #define __PNR_epoll_wait_old -10006 | |
685 | #ifndef __NR_epoll_wait_old | |
686 | #define __NR_epoll_wait_old __PNR_epoll_wait_old | |
687 | #endif /* __NR_epoll_wait_old */ | |
688 | ||
689 | #define __PNR_fadvise64_64 -10007 | |
690 | #ifndef __NR_fadvise64_64 | |
691 | #define __NR_fadvise64_64 __PNR_fadvise64_64 | |
692 | #endif /* __NR_fadvise64_64 */ | |
693 | ||
694 | #define __PNR_fchown32 -10008 | |
695 | #ifndef __NR_fchown32 | |
696 | #define __NR_fchown32 __PNR_fchown32 | |
697 | #endif /* __NR_fchown32 */ | |
698 | ||
699 | #define __PNR_fcntl64 -10009 | |
700 | #ifndef __NR_fcntl64 | |
701 | #define __NR_fcntl64 __PNR_fcntl64 | |
702 | #endif /* __NR_fcntl64 */ | |
703 | ||
704 | #define __PNR_fstat64 -10010 | |
705 | #ifndef __NR_fstat64 | |
706 | #define __NR_fstat64 __PNR_fstat64 | |
707 | #endif /* __NR_fstat64 */ | |
708 | ||
709 | #define __PNR_fstatat64 -10011 | |
710 | #ifndef __NR_fstatat64 | |
711 | #define __NR_fstatat64 __PNR_fstatat64 | |
712 | #endif /* __NR_fstatat64 */ | |
713 | ||
714 | #define __PNR_fstatfs64 -10012 | |
715 | #ifndef __NR_fstatfs64 | |
716 | #define __NR_fstatfs64 __PNR_fstatfs64 | |
717 | #endif /* __NR_fstatfs64 */ | |
718 | ||
719 | #define __PNR_ftime -10013 | |
720 | #ifndef __NR_ftime | |
721 | #define __NR_ftime __PNR_ftime | |
722 | #endif /* __NR_ftime */ | |
723 | ||
724 | #define __PNR_ftruncate64 -10014 | |
725 | #ifndef __NR_ftruncate64 | |
726 | #define __NR_ftruncate64 __PNR_ftruncate64 | |
727 | #endif /* __NR_ftruncate64 */ | |
728 | ||
729 | #define __PNR_getegid32 -10015 | |
730 | #ifndef __NR_getegid32 | |
731 | #define __NR_getegid32 __PNR_getegid32 | |
732 | #endif /* __NR_getegid32 */ | |
733 | ||
734 | #define __PNR_geteuid32 -10016 | |
735 | #ifndef __NR_geteuid32 | |
736 | #define __NR_geteuid32 __PNR_geteuid32 | |
737 | #endif /* __NR_geteuid32 */ | |
738 | ||
739 | #define __PNR_getgid32 -10017 | |
740 | #ifndef __NR_getgid32 | |
741 | #define __NR_getgid32 __PNR_getgid32 | |
742 | #endif /* __NR_getgid32 */ | |
743 | ||
744 | #define __PNR_getgroups32 -10018 | |
745 | #ifndef __NR_getgroups32 | |
746 | #define __NR_getgroups32 __PNR_getgroups32 | |
747 | #endif /* __NR_getgroups32 */ | |
748 | ||
749 | #define __PNR_getresgid32 -10019 | |
750 | #ifndef __NR_getresgid32 | |
751 | #define __NR_getresgid32 __PNR_getresgid32 | |
752 | #endif /* __NR_getresgid32 */ | |
753 | ||
754 | #define __PNR_getresuid32 -10020 | |
755 | #ifndef __NR_getresuid32 | |
756 | #define __NR_getresuid32 __PNR_getresuid32 | |
757 | #endif /* __NR_getresuid32 */ | |
758 | ||
759 | #define __PNR_getuid32 -10021 | |
760 | #ifndef __NR_getuid32 | |
761 | #define __NR_getuid32 __PNR_getuid32 | |
762 | #endif /* __NR_getuid32 */ | |
763 | ||
764 | #define __PNR_gtty -10022 | |
765 | #ifndef __NR_gtty | |
766 | #define __NR_gtty __PNR_gtty | |
767 | #endif /* __NR_gtty */ | |
768 | ||
769 | #define __PNR_idle -10023 | |
770 | #ifndef __NR_idle | |
771 | #define __NR_idle __PNR_idle | |
772 | #endif /* __NR_idle */ | |
773 | ||
774 | #define __PNR_ipc -10024 | |
775 | #ifndef __NR_ipc | |
776 | #define __NR_ipc __PNR_ipc | |
777 | #endif /* __NR_ipc */ | |
778 | ||
779 | #define __PNR_lchown32 -10025 | |
780 | #ifndef __NR_lchown32 | |
781 | #define __NR_lchown32 __PNR_lchown32 | |
782 | #endif /* __NR_lchown32 */ | |
783 | ||
784 | #define __PNR__llseek -10026 | |
785 | #ifndef __NR__llseek | |
786 | #define __NR__llseek __PNR__llseek | |
787 | #endif /* __NR__llseek */ | |
788 | ||
789 | #define __PNR_lock -10027 | |
790 | #ifndef __NR_lock | |
791 | #define __NR_lock __PNR_lock | |
792 | #endif /* __NR_lock */ | |
793 | ||
794 | #define __PNR_lstat64 -10028 | |
795 | #ifndef __NR_lstat64 | |
796 | #define __NR_lstat64 __PNR_lstat64 | |
797 | #endif /* __NR_lstat64 */ | |
798 | ||
799 | #define __PNR_mmap2 -10029 | |
800 | #ifndef __NR_mmap2 | |
801 | #define __NR_mmap2 __PNR_mmap2 | |
802 | #endif /* __NR_mmap2 */ | |
803 | ||
804 | #define __PNR_mpx -10030 | |
805 | #ifndef __NR_mpx | |
806 | #define __NR_mpx __PNR_mpx | |
807 | #endif /* __NR_mpx */ | |
808 | ||
809 | #define __PNR_newfstatat -10031 | |
810 | #ifndef __NR_newfstatat | |
811 | #define __NR_newfstatat __PNR_newfstatat | |
812 | #endif /* __NR_newfstatat */ | |
813 | ||
814 | #define __PNR__newselect -10032 | |
815 | #ifndef __NR__newselect | |
816 | #define __NR__newselect __PNR__newselect | |
817 | #endif /* __NR__newselect */ | |
818 | ||
819 | #define __PNR_nice -10033 | |
820 | #ifndef __NR_nice | |
821 | #define __NR_nice __PNR_nice | |
822 | #endif /* __NR_nice */ | |
823 | ||
824 | #define __PNR_oldfstat -10034 | |
825 | #ifndef __NR_oldfstat | |
826 | #define __NR_oldfstat __PNR_oldfstat | |
827 | #endif /* __NR_oldfstat */ | |
828 | ||
829 | #define __PNR_oldlstat -10035 | |
830 | #ifndef __NR_oldlstat | |
831 | #define __NR_oldlstat __PNR_oldlstat | |
832 | #endif /* __NR_oldlstat */ | |
833 | ||
834 | #define __PNR_oldolduname -10036 | |
835 | #ifndef __NR_oldolduname | |
836 | #define __NR_oldolduname __PNR_oldolduname | |
837 | #endif /* __NR_oldolduname */ | |
838 | ||
839 | #define __PNR_oldstat -10037 | |
840 | #ifndef __NR_oldstat | |
841 | #define __NR_oldstat __PNR_oldstat | |
842 | #endif /* __NR_oldstat */ | |
843 | ||
844 | #define __PNR_olduname -10038 | |
845 | #ifndef __NR_olduname | |
846 | #define __NR_olduname __PNR_olduname | |
847 | #endif /* __NR_olduname */ | |
848 | ||
849 | #define __PNR_prof -10039 | |
850 | #ifndef __NR_prof | |
851 | #define __NR_prof __PNR_prof | |
852 | #endif /* __NR_prof */ | |
853 | ||
854 | #define __PNR_profil -10040 | |
855 | #ifndef __NR_profil | |
856 | #define __NR_profil __PNR_profil | |
857 | #endif /* __NR_profil */ | |
858 | ||
859 | #define __PNR_readdir -10041 | |
860 | #ifndef __NR_readdir | |
861 | #define __NR_readdir __PNR_readdir | |
862 | #endif /* __NR_readdir */ | |
863 | ||
864 | #define __PNR_security -10042 | |
865 | #ifndef __NR_security | |
866 | #define __NR_security __PNR_security | |
867 | #endif /* __NR_security */ | |
868 | ||
869 | #define __PNR_sendfile64 -10043 | |
870 | #ifndef __NR_sendfile64 | |
871 | #define __NR_sendfile64 __PNR_sendfile64 | |
872 | #endif /* __NR_sendfile64 */ | |
873 | ||
874 | #define __PNR_setfsgid32 -10044 | |
875 | #ifndef __NR_setfsgid32 | |
876 | #define __NR_setfsgid32 __PNR_setfsgid32 | |
877 | #endif /* __NR_setfsgid32 */ | |
878 | ||
879 | #define __PNR_setfsuid32 -10045 | |
880 | #ifndef __NR_setfsuid32 | |
881 | #define __NR_setfsuid32 __PNR_setfsuid32 | |
882 | #endif /* __NR_setfsuid32 */ | |
883 | ||
884 | #define __PNR_setgid32 -10046 | |
885 | #ifndef __NR_setgid32 | |
886 | #define __NR_setgid32 __PNR_setgid32 | |
887 | #endif /* __NR_setgid32 */ | |
888 | ||
889 | #define __PNR_setgroups32 -10047 | |
890 | #ifndef __NR_setgroups32 | |
891 | #define __NR_setgroups32 __PNR_setgroups32 | |
892 | #endif /* __NR_setgroups32 */ | |
893 | ||
894 | #define __PNR_setregid32 -10048 | |
895 | #ifndef __NR_setregid32 | |
896 | #define __NR_setregid32 __PNR_setregid32 | |
897 | #endif /* __NR_setregid32 */ | |
898 | ||
899 | #define __PNR_setresgid32 -10049 | |
900 | #ifndef __NR_setresgid32 | |
901 | #define __NR_setresgid32 __PNR_setresgid32 | |
902 | #endif /* __NR_setresgid32 */ | |
903 | ||
904 | #define __PNR_setresuid32 -10050 | |
905 | #ifndef __NR_setresuid32 | |
906 | #define __NR_setresuid32 __PNR_setresuid32 | |
907 | #endif /* __NR_setresuid32 */ | |
908 | ||
909 | #define __PNR_setreuid32 -10051 | |
910 | #ifndef __NR_setreuid32 | |
911 | #define __NR_setreuid32 __PNR_setreuid32 | |
912 | #endif /* __NR_setreuid32 */ | |
913 | ||
914 | #define __PNR_setuid32 -10052 | |
915 | #ifndef __NR_setuid32 | |
916 | #define __NR_setuid32 __PNR_setuid32 | |
917 | #endif /* __NR_setuid32 */ | |
918 | ||
919 | #define __PNR_sgetmask -10053 | |
920 | #ifndef __NR_sgetmask | |
921 | #define __NR_sgetmask __PNR_sgetmask | |
922 | #endif /* __NR_sgetmask */ | |
923 | ||
924 | #define __PNR_sigaction -10054 | |
925 | #ifndef __NR_sigaction | |
926 | #define __NR_sigaction __PNR_sigaction | |
927 | #endif /* __NR_sigaction */ | |
928 | ||
929 | #define __PNR_signal -10055 | |
930 | #ifndef __NR_signal | |
931 | #define __NR_signal __PNR_signal | |
932 | #endif /* __NR_signal */ | |
933 | ||
934 | #define __PNR_sigpending -10056 | |
935 | #ifndef __NR_sigpending | |
936 | #define __NR_sigpending __PNR_sigpending | |
937 | #endif /* __NR_sigpending */ | |
938 | ||
939 | #define __PNR_sigprocmask -10057 | |
940 | #ifndef __NR_sigprocmask | |
941 | #define __NR_sigprocmask __PNR_sigprocmask | |
942 | #endif /* __NR_sigprocmask */ | |
943 | ||
944 | #define __PNR_sigreturn -10058 | |
945 | #ifndef __NR_sigreturn | |
946 | #define __NR_sigreturn __PNR_sigreturn | |
947 | #endif /* __NR_sigreturn */ | |
948 | ||
949 | #define __PNR_sigsuspend -10059 | |
950 | #ifndef __NR_sigsuspend | |
951 | #define __NR_sigsuspend __PNR_sigsuspend | |
952 | #endif /* __NR_sigsuspend */ | |
953 | ||
954 | #define __PNR_socketcall -10060 | |
955 | #ifndef __NR_socketcall | |
956 | #define __NR_socketcall __PNR_socketcall | |
957 | #endif /* __NR_socketcall */ | |
958 | ||
959 | #define __PNR_ssetmask -10061 | |
960 | #ifndef __NR_ssetmask | |
961 | #define __NR_ssetmask __PNR_ssetmask | |
962 | #endif /* __NR_ssetmask */ | |
963 | ||
964 | #define __PNR_stat64 -10062 | |
965 | #ifndef __NR_stat64 | |
966 | #define __NR_stat64 __PNR_stat64 | |
967 | #endif /* __NR_stat64 */ | |
968 | ||
969 | #define __PNR_statfs64 -10063 | |
970 | #ifndef __NR_statfs64 | |
971 | #define __NR_statfs64 __PNR_statfs64 | |
972 | #endif /* __NR_statfs64 */ | |
973 | ||
974 | #define __PNR_stime -10064 | |
975 | #ifndef __NR_stime | |
976 | #define __NR_stime __PNR_stime | |
977 | #endif /* __NR_stime */ | |
978 | ||
979 | #define __PNR_stty -10065 | |
980 | #ifndef __NR_stty | |
981 | #define __NR_stty __PNR_stty | |
982 | #endif /* __NR_stty */ | |
983 | ||
984 | #define __PNR_truncate64 -10066 | |
985 | #ifndef __NR_truncate64 | |
986 | #define __NR_truncate64 __PNR_truncate64 | |
987 | #endif /* __NR_truncate64 */ | |
988 | ||
989 | #define __PNR_tuxcall -10067 | |
990 | #ifndef __NR_tuxcall | |
991 | #define __NR_tuxcall __PNR_tuxcall | |
992 | #endif /* __NR_tuxcall */ | |
993 | ||
994 | #define __PNR_ugetrlimit -10068 | |
995 | #ifndef __NR_ugetrlimit | |
996 | #define __NR_ugetrlimit __PNR_ugetrlimit | |
997 | #endif /* __NR_ugetrlimit */ | |
998 | ||
999 | #define __PNR_ulimit -10069 | |
1000 | #ifndef __NR_ulimit | |
1001 | #define __NR_ulimit __PNR_ulimit | |
1002 | #endif /* __NR_ulimit */ | |
1003 | ||
1004 | #define __PNR_umount -10070 | |
1005 | #ifndef __NR_umount | |
1006 | #define __NR_umount __PNR_umount | |
1007 | #endif /* __NR_umount */ | |
1008 | ||
1009 | #define __PNR_vm86 -10071 | |
1010 | #ifndef __NR_vm86 | |
1011 | #define __NR_vm86 __PNR_vm86 | |
1012 | #endif /* __NR_vm86 */ | |
1013 | ||
1014 | #define __PNR_vm86old -10072 | |
1015 | #ifndef __NR_vm86old | |
1016 | #define __NR_vm86old __PNR_vm86old | |
1017 | #endif /* __NR_vm86old */ | |
1018 | ||
1019 | #define __PNR_waitpid -10073 | |
1020 | #ifndef __NR_waitpid | |
1021 | #define __NR_waitpid __PNR_waitpid | |
1022 | #endif /* __NR_waitpid */ | |
1023 | ||
1024 | #define __PNR_create_module -10074 | |
1025 | #ifndef __NR_create_module | |
1026 | #define __NR_create_module __PNR_create_module | |
1027 | #endif /* __NR_create_module */ | |
1028 | ||
1029 | #define __PNR_get_kernel_syms -10075 | |
1030 | #ifndef __NR_get_kernel_syms | |
1031 | #define __NR_get_kernel_syms __PNR_get_kernel_syms | |
1032 | #endif /* __NR_get_kernel_syms */ | |
1033 | ||
1034 | #define __PNR_get_thread_area -10076 | |
1035 | #ifndef __NR_get_thread_area | |
1036 | #define __NR_get_thread_area __PNR_get_thread_area | |
1037 | #endif /* __NR_get_thread_area */ | |
1038 | ||
1039 | #define __PNR_nfsservctl -10077 | |
1040 | #ifndef __NR_nfsservctl | |
1041 | #define __NR_nfsservctl __PNR_nfsservctl | |
1042 | #endif /* __NR_nfsservctl */ | |
1043 | ||
1044 | #define __PNR_query_module -10078 | |
1045 | #ifndef __NR_query_module | |
1046 | #define __NR_query_module __PNR_query_module | |
1047 | #endif /* __NR_query_module */ | |
1048 | ||
1049 | #define __PNR_set_thread_area -10079 | |
1050 | #ifndef __NR_set_thread_area | |
1051 | #define __NR_set_thread_area __PNR_set_thread_area | |
1052 | #endif /* __NR_set_thread_area */ | |
1053 | ||
1054 | #define __PNR__sysctl -10080 | |
1055 | #ifndef __NR__sysctl | |
1056 | #define __NR__sysctl __PNR__sysctl | |
1057 | #endif /* __NR__sysctl */ | |
1058 | ||
1059 | #define __PNR_uselib -10081 | |
1060 | #ifndef __NR_uselib | |
1061 | #define __NR_uselib __PNR_uselib | |
1062 | #endif /* __NR_uselib */ | |
1063 | ||
1064 | #define __PNR_vserver -10082 | |
1065 | #ifndef __NR_vserver | |
1066 | #define __NR_vserver __PNR_vserver | |
1067 | #endif /* __NR_vserver */ | |
1068 | ||
1069 | #define __PNR_arm_fadvise64_64 -10083 | |
1070 | #ifndef __NR_arm_fadvise64_64 | |
1071 | #define __NR_arm_fadvise64_64 __PNR_arm_fadvise64_64 | |
1072 | #endif /* __NR_arm_fadvise64_64 */ | |
1073 | ||
1074 | #define __PNR_arm_sync_file_range -10084 | |
1075 | #ifndef __NR_arm_sync_file_range | |
1076 | #define __NR_arm_sync_file_range __PNR_arm_sync_file_range | |
1077 | #endif /* __NR_arm_sync_file_range */ | |
1078 | ||
1079 | #define __PNR_finit_module -10085 | |
1080 | #ifndef __NR_finit_module | |
1081 | #define __NR_finit_module __PNR_finit_module | |
1082 | #endif /* __NR_finit_module */ | |
1083 | ||
1084 | #define __PNR_pciconfig_iobase -10086 | |
1085 | #ifndef __NR_pciconfig_iobase | |
1086 | #define __NR_pciconfig_iobase __PNR_pciconfig_iobase | |
1087 | #endif /* __NR_pciconfig_iobase */ | |
1088 | ||
1089 | #define __PNR_pciconfig_read -10087 | |
1090 | #ifndef __NR_pciconfig_read | |
1091 | #define __NR_pciconfig_read __PNR_pciconfig_read | |
1092 | #endif /* __NR_pciconfig_read */ | |
1093 | ||
1094 | #define __PNR_pciconfig_write -10088 | |
1095 | #ifndef __NR_pciconfig_write | |
1096 | #define __NR_pciconfig_write __PNR_pciconfig_write | |
1097 | #endif /* __NR_pciconfig_write */ | |
1098 | ||
1099 | #define __PNR_sync_file_range2 -10089 | |
1100 | #ifndef __NR_sync_file_range2 | |
1101 | #define __NR_sync_file_range2 __PNR_sync_file_range2 | |
1102 | #endif /* __NR_sync_file_range2 */ | |
1103 | ||
1104 | #define __PNR_syscall -10090 | |
1105 | #ifndef __NR_syscall | |
1106 | #define __NR_syscall __PNR_syscall | |
1107 | #endif /* __NR_syscall */ | |
1108 | ||
1109 | #define __PNR_afs_syscall -10091 | |
1110 | #ifndef __NR_afs_syscall | |
1111 | #define __NR_afs_syscall __PNR_afs_syscall | |
1112 | #endif /* __NR_afs_syscall */ | |
1113 | ||
1114 | #define __PNR_fadvise64 -10092 | |
1115 | #ifndef __NR_fadvise64 | |
1116 | #define __NR_fadvise64 __PNR_fadvise64 | |
1117 | #endif /* __NR_fadvise64 */ | |
1118 | ||
1119 | #define __PNR_getpmsg -10093 | |
1120 | #ifndef __NR_getpmsg | |
1121 | #define __NR_getpmsg __PNR_getpmsg | |
1122 | #endif /* __NR_getpmsg */ | |
1123 | ||
1124 | #define __PNR_ioperm -10094 | |
1125 | #ifndef __NR_ioperm | |
1126 | #define __NR_ioperm __PNR_ioperm | |
1127 | #endif /* __NR_ioperm */ | |
1128 | ||
1129 | #define __PNR_iopl -10095 | |
1130 | #ifndef __NR_iopl | |
1131 | #define __NR_iopl __PNR_iopl | |
1132 | #endif /* __NR_iopl */ | |
1133 | ||
1134 | #define __PNR_kcmp -10096 | |
1135 | #ifndef __NR_kcmp | |
1136 | #define __NR_kcmp __PNR_kcmp | |
1137 | #endif /* __NR_kcmp */ | |
1138 | ||
1139 | #define __PNR_migrate_pages -10097 | |
1140 | #ifndef __NR_migrate_pages | |
1141 | #define __NR_migrate_pages __PNR_migrate_pages | |
1142 | #endif /* __NR_migrate_pages */ | |
1143 | ||
1144 | #define __PNR_modify_ldt -10098 | |
1145 | #ifndef __NR_modify_ldt | |
1146 | #define __NR_modify_ldt __PNR_modify_ldt | |
1147 | #endif /* __NR_modify_ldt */ | |
1148 | ||
1149 | #define __PNR_putpmsg -10099 | |
1150 | #ifndef __NR_putpmsg | |
1151 | #define __NR_putpmsg __PNR_putpmsg | |
1152 | #endif /* __NR_putpmsg */ | |
1153 | ||
1154 | #define __PNR_sync_file_range -10100 | |
1155 | #ifndef __NR_sync_file_range | |
1156 | #define __NR_sync_file_range __PNR_sync_file_range | |
1157 | #endif /* __NR_sync_file_range */ | |
1158 | ||
1159 | #ifdef __cplusplus | |
1160 | } | |
1161 | #endif | |
1162 | ||
1163 | #endif |
0 | # | |
1 | # Enhanced Seccomp Library Installation Defaults | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | INSTALL_PREFIX ?= $(CONF_INSTALL_PREFIX) | |
22 | ||
23 | INSTALL_SBIN_DIR ?= $(DESTDIR)/$(INSTALL_PREFIX)/sbin | |
24 | INSTALL_BIN_DIR ?= $(DESTDIR)/$(INSTALL_PREFIX)/bin | |
25 | INSTALL_LIB_DIR ?= $(DESTDIR)/$(CONF_INSTALL_LIBDIR) | |
26 | INSTALL_INC_DIR ?= $(DESTDIR)/$(INSTALL_PREFIX)/include | |
27 | INSTALL_MAN_DIR ?= $(DESTDIR)/$(INSTALL_PREFIX)/share/man | |
28 | ||
29 | INSTALL_OWNER ?= $$(id -u) | |
30 | INSTALL_GROUP ?= $$(id -g) |
0 | # | |
1 | # Enhanced Seccomp Library pkg-config Configuration | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | prefix=%%INSTALL_PREFIX%% | |
22 | libdir=%%INSTALL_LIBDIR%% | |
23 | includedir=${prefix}/include | |
24 | ||
25 | Name: libseccomp | |
26 | Description: The enhanced seccomp library | |
27 | URL: http://libseccomp.sf.net | |
28 | Version: %%VERSION_RELEASE%% | |
29 | Cflags: -I${includedir} | |
30 | Libs: -L${libdir} -lseccomp |
0 | # | |
1 | # Enhanced Seccomp Library Build Macros | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | SHELL = /bin/bash | |
22 | ||
23 | # | |
24 | # simple /bin/bash script to find the top of the tree | |
25 | # | |
26 | ||
27 | TOPDIR := $(shell \ | |
28 | ftd() { \ | |
29 | cd $$1; \ | |
30 | if [[ -r "macros.mk" ]]; then \ | |
31 | pwd; \ | |
32 | else \ | |
33 | ftd "../"; \ | |
34 | fi \ | |
35 | }; \ | |
36 | ftd .) | |
37 | ||
38 | # | |
39 | # build configuration | |
40 | # | |
41 | ||
42 | V ?= 0 | |
43 | ||
44 | CPPFLAGS += -I$(TOPDIR) -I$(TOPDIR)/include | |
45 | LIBFLAGS = | |
46 | ||
47 | CFLAGS ?= -Wl,-z,relro -Wall -O0 -g -fvisibility=hidden | |
48 | CFLAGS += -fPIC | |
49 | PYCFLAGS ?= -fvisibility=default | |
50 | LDFLAGS ?= -z relro -g | |
51 | ||
52 | # | |
53 | # build tools | |
54 | # | |
55 | ||
56 | LN ?= ln | |
57 | MV ?= mv | |
58 | CAT ?= cat | |
59 | ECHO ?= echo | |
60 | TAR ?= tar | |
61 | MKDIR ?= mkdir | |
62 | ||
63 | SED ?= sed | |
64 | AWK ?= awk | |
65 | ||
66 | PYTHON ?= /usr/bin/env python | |
67 | ||
68 | # we require gcc specific functionality | |
69 | GCC ?= gcc | |
70 | ||
71 | INSTALL ?= install | |
72 | ||
73 | ifeq ($(V),0) | |
74 | MAKE += --quiet --no-print-directory | |
75 | ECHO_INFO ?= $(ECHO) ">> INFO:" | |
76 | else | |
77 | ECHO_INFO ?= /bin/true || $(ECHO) ">> INFO:" | |
78 | endif | |
79 | ||
80 | # | |
81 | # auto dependencies | |
82 | # | |
83 | ||
84 | MAKEDEP = @$(GCC) $(CPPFLAGS) -MM -MF $(patsubst %.o,%.d,$@) $<; | |
85 | MAKEDEP_EXEC = \ | |
86 | @$(GCC) $(CPPFLAGS) -MM -MT $(patsubst %.d,%,$@) \ | |
87 | -MF $@ $(patsubst %.d,%.c,$@); | |
88 | ||
89 | ADDDEP = \ | |
90 | @adddep_func() { \ | |
91 | $(MV) $$1 $$1.dtmp; \ | |
92 | $(CAT) $$1.dtmp | $(SED) -e 's/\([^\]\)$$/\1 \\/' | \ | |
93 | ( $(CAT) - && $(ECHO) " $$2" ) > $$1; \ | |
94 | $(RM) -f $@.dtmp; \ | |
95 | }; \ | |
96 | adddep_func | |
97 | ||
98 | # | |
99 | # build constants | |
100 | # | |
101 | ||
102 | VERSION_HDR = version.h | |
103 | ||
104 | # | |
105 | # build macros | |
106 | # | |
107 | ||
108 | PY_DISTUTILS = \ | |
109 | VERSION_RELEASE="$(VERSION_RELEASE)" \ | |
110 | CFLAGS="$(CFLAGS) $(CPPFLAGS) $(PYCFLAGS)" LDFLAGS="$(LDFLAGS)" \ | |
111 | $(PYTHON) ./setup.py | |
112 | ||
113 | ifeq ($(V),0) | |
114 | PY_BUILD = @echo " PYTHON build"; | |
115 | endif | |
116 | PY_BUILD += $(PY_DISTUTILS) | |
117 | ifeq ($(V),0) | |
118 | PY_BUILD += -q | |
119 | endif | |
120 | PY_BUILD += build | |
121 | ||
122 | ifeq ($(V),0) | |
123 | PY_INSTALL = @echo " PYTHON install"; | |
124 | endif | |
125 | PY_INSTALL += $(PY_DISTUTILS) | |
126 | ifeq ($(V),0) | |
127 | PY_INSTALL += -q | |
128 | endif | |
129 | PY_INSTALL += install | |
130 | ||
131 | ifeq ($(V),0) | |
132 | COMPILE = @echo " CC $@"; | |
133 | endif | |
134 | COMPILE += $(GCC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<; | |
135 | ||
136 | ifeq ($(V),0) | |
137 | COMPILE_EXEC = @echo " CC $@"; | |
138 | endif | |
139 | COMPILE_EXEC += $(GCC) $(CFLAGS) $(CPPFLAGS) -o $@ $< $(LDFLAGS); | |
140 | ||
141 | ifeq ($(V),0) | |
142 | ARCHIVE = @echo " AR $@"; | |
143 | endif | |
144 | ARCHIVE += $(AR) -cru $@ $?; | |
145 | ||
146 | ifeq ($(V),0) | |
147 | LINK_EXEC = @echo " LD $@"; | |
148 | endif | |
149 | LINK_EXEC += $(GCC) $(LDFLAGS) -o $@ $^ $(LIBFLAGS); | |
150 | ||
151 | ifeq ($(V),0) | |
152 | LINK_LIB = @echo " LD $@" \ | |
153 | "($(patsubst %.so.$(VERSION_RELEASE),%.so.$(VERSION_MAJOR),$@))"; | |
154 | endif | |
155 | LINK_LIB += $(GCC) $(LDFLAGS) -o $@ $^ -shared \ | |
156 | -Wl,-soname=$(patsubst %.so.$(VERSION_RELEASE),%.so.$(VERSION_MAJOR),$@) | |
157 | ||
158 | # | |
159 | # install macros | |
160 | # | |
161 | ||
162 | ifeq ($(V),0) | |
163 | INSTALL_LIB_MACRO = @echo " INSTALL $^ ($(INSTALL_LIB_DIR)/$^)"; | |
164 | endif | |
165 | INSTALL_LIB_MACRO += \ | |
166 | basename=$$(echo $^ | sed -e 's/.so.*$$/.so/'); \ | |
167 | soname=$$(objdump -p $^ | grep "SONAME" | awk '{print $$2}'); \ | |
168 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) \ | |
169 | -d "$(INSTALL_LIB_DIR)"; \ | |
170 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) -m 0755 \ | |
171 | $^ "$(INSTALL_LIB_DIR)"; \ | |
172 | (cd "$(INSTALL_LIB_DIR)"; $(RM) $$soname); \ | |
173 | (cd "$(INSTALL_LIB_DIR)"; $(LN) -s $^ $$soname); \ | |
174 | (cd "$(INSTALL_LIB_DIR)"; $(RM) $$basname); \ | |
175 | (cd "$(INSTALL_LIB_DIR)"; $(LN) -s $^ $$basename); | |
176 | ||
177 | ifeq ($(V),0) | |
178 | INSTALL_BIN_MACRO = @echo " INSTALL $^ ($(INSTALL_BIN_DIR)/$^)"; | |
179 | endif | |
180 | INSTALL_BIN_MACRO += \ | |
181 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) \ | |
182 | -d "$(INSTALL_BIN_DIR)"; \ | |
183 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) -m 0755 \ | |
184 | $^ "$(INSTALL_BIN_DIR)"; | |
185 | ||
186 | ifeq ($(V),0) | |
187 | INSTALL_PC_MACRO = \ | |
188 | @echo " INSTALL $$(cat /proc/$$$$/cmdline | awk '{print $$(NF)}')" \ | |
189 | " ($(INSTALL_LIB_DIR)/pkgconfig)"; | |
190 | endif | |
191 | INSTALL_PC_MACRO += \ | |
192 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) \ | |
193 | -d "$(INSTALL_LIB_DIR)/pkgconfig"; \ | |
194 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) -m 0644 \ | |
195 | "$$(cat /proc/$$$$/cmdline | awk '{print $$(NF)}')" \ | |
196 | "$(INSTALL_LIB_DIR)/pkgconfig"; \# | |
197 | ||
198 | ifeq ($(V),0) | |
199 | INSTALL_INC_MACRO = @echo " INSTALL $^ ($(INSTALL_INC_DIR))"; | |
200 | endif | |
201 | INSTALL_INC_MACRO += \ | |
202 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) \ | |
203 | -d "$(INSTALL_INC_DIR)"; \ | |
204 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) -m 0644 \ | |
205 | $^ "$(INSTALL_INC_DIR)"; | |
206 | ||
207 | ifeq ($(V),0) | |
208 | INSTALL_MAN1_MACRO = \ | |
209 | @echo " INSTALL manpages ($(INSTALL_MAN_DIR)/man1)"; | |
210 | endif | |
211 | INSTALL_MAN1_MACRO += \ | |
212 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) \ | |
213 | -d "$(INSTALL_MAN_DIR)/man1"; \ | |
214 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) -m 0644 \ | |
215 | $^ "$(INSTALL_MAN_DIR)/man1"; | |
216 | ||
217 | ifeq ($(V),0) | |
218 | INSTALL_MAN3_MACRO = \ | |
219 | @echo " INSTALL manpages ($(INSTALL_MAN_DIR)/man3)"; | |
220 | endif | |
221 | INSTALL_MAN3_MACRO += \ | |
222 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) \ | |
223 | -d "$(INSTALL_MAN_DIR)/man3"; \ | |
224 | $(INSTALL) -o $(INSTALL_OWNER) -g $(INSTALL_GROUP) -m 0644 \ | |
225 | $^ "$(INSTALL_MAN_DIR)/man3"; | |
226 | ||
227 | # | |
228 | # default build targets | |
229 | # | |
230 | ||
231 | %.o: %.c | |
232 | $(MAKEDEP) | |
233 | $(COMPILE) |
0 | # | |
1 | # Enhanced Seccomp Library Makefile | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | # | |
22 | # macros | |
23 | # | |
24 | ||
25 | include ../macros.mk | |
26 | ||
27 | # | |
28 | # configuration | |
29 | # | |
30 | ||
31 | include $(TOPDIR)/version_info.mk | |
32 | include $(TOPDIR)/configure.mk | |
33 | include $(TOPDIR)/install.mk | |
34 | ||
35 | LIB_STATIC = libseccomp.a | |
36 | LIB_SHARED = libseccomp.so.$(VERSION_RELEASE) | |
37 | ||
38 | OBJS = \ | |
39 | api.o db.o arch.o \ | |
40 | arch-x86.o arch-x86-syscalls.o \ | |
41 | arch-x86_64.o arch-x86_64-syscalls.o \ | |
42 | arch-x32.o arch-x32-syscalls.o \ | |
43 | arch-arm.o arch-arm-syscalls.o \ | |
44 | hash.o \ | |
45 | gen_pfc.o gen_bpf.o | |
46 | ||
47 | DEPS = $(OBJS:%.o=%.d) | |
48 | ||
49 | # | |
50 | # bindings configuration | |
51 | # | |
52 | ||
53 | BINDINGS = | |
54 | ||
55 | ifeq ($(CONF_BINDINGS_PYTHON), 1) | |
56 | BINDINGS += python | |
57 | endif | |
58 | ||
59 | # | |
60 | # targets | |
61 | # | |
62 | ||
63 | .PHONY: all install clean python | |
64 | ||
65 | all: $(LIB_STATIC) $(LIB_SHARED) $(BINDINGS) | |
66 | ||
67 | -include $(DEPS) | |
68 | ||
69 | $(LIB_STATIC): $(OBJS) | |
70 | $(ARCHIVE) | |
71 | ||
72 | $(LIB_SHARED): $(OBJS) | |
73 | $(LINK_LIB) | |
74 | ||
75 | python: $(LIB_STATIC) | |
76 | @$(ECHO_INFO) "building in directory $@/ ..." | |
77 | @$(MAKE) -C $@ | |
78 | ||
79 | install: $(LIB_SHARED) | |
80 | $(INSTALL_LIB_MACRO) | |
81 | @for dir in $(BINDINGS); do \ | |
82 | $(ECHO) ">> INFO: installing from $$dir/"; \ | |
83 | $(MAKE) -C $$dir install; \ | |
84 | done | |
85 | ||
86 | clean: | |
87 | $(RM) $(DEPS) $(OBJS) $(LIB_STATIC) libseccomp.so.* | |
88 | @for dir in python; do \ | |
89 | $(MAKE) -C $$dir clean; \ | |
90 | done | |
91 |
0 | /** | |
1 | * Seccomp Library API | |
2 | * | |
3 | * Copyright (c) 2012,2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <endian.h> | |
22 | #include <errno.h> | |
23 | #include <inttypes.h> | |
24 | #include <unistd.h> | |
25 | #include <stdarg.h> | |
26 | #include <stdlib.h> | |
27 | #include <string.h> | |
28 | #include <stdbool.h> | |
29 | #include <sys/prctl.h> | |
30 | ||
31 | #include <seccomp.h> | |
32 | ||
33 | #include "arch.h" | |
34 | #include "db.h" | |
35 | #include "gen_pfc.h" | |
36 | #include "gen_bpf.h" | |
37 | #include "system.h" | |
38 | ||
39 | #define API __attribute__((visibility("default"))) | |
40 | ||
41 | /** | |
42 | * Validate a filter context | |
43 | * @param ctx the filter context | |
44 | * | |
45 | * Attempt to validate the provided filter context. Returns zero if the | |
46 | * context is valid, negative values on failure. | |
47 | * | |
48 | */ | |
49 | static int _ctx_valid(const scmp_filter_ctx *ctx) | |
50 | { | |
51 | return db_col_valid((struct db_filter_col *)ctx); | |
52 | } | |
53 | ||
54 | /** | |
55 | * Validate a syscall number | |
56 | * @param syscall the syscall number | |
57 | * | |
58 | * Attempt to perform basic syscall number validation. Returns zero of the | |
59 | * syscall appears valid, negative values on failure. | |
60 | * | |
61 | */ | |
62 | static int _syscall_valid(int syscall) | |
63 | { | |
64 | if (syscall <= -1 && syscall >= -99) | |
65 | return -EINVAL; | |
66 | return 0; | |
67 | } | |
68 | ||
69 | /* NOTE - function header comment in include/seccomp.h */ | |
70 | API scmp_filter_ctx seccomp_init(uint32_t def_action) | |
71 | { | |
72 | struct db_filter_col *col; | |
73 | struct db_filter *db; | |
74 | ||
75 | if (db_action_valid(def_action) < 0) | |
76 | return NULL; | |
77 | ||
78 | col = db_col_init(def_action); | |
79 | if (col == NULL) | |
80 | return NULL; | |
81 | db = db_init(arch_def_native); | |
82 | if (db == NULL) | |
83 | goto init_failure_col; | |
84 | ||
85 | if (db_col_db_add(col, db) < 0) | |
86 | goto init_failure_db; | |
87 | ||
88 | return col; | |
89 | ||
90 | init_failure_db: | |
91 | db_release(db); | |
92 | init_failure_col: | |
93 | db_col_release(col); | |
94 | return NULL; | |
95 | } | |
96 | ||
97 | /* NOTE - function header comment in include/seccomp.h */ | |
98 | API int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action) | |
99 | { | |
100 | int rc; | |
101 | struct db_filter_col *col = (struct db_filter_col *)ctx; | |
102 | struct db_filter *db; | |
103 | ||
104 | if (db_col_valid(col) || db_action_valid(def_action) < 0) | |
105 | return -EINVAL; | |
106 | ||
107 | db_col_reset(col, def_action); | |
108 | ||
109 | db = db_init(arch_def_native); | |
110 | if (db == NULL) | |
111 | return -ENOMEM; | |
112 | rc = db_col_db_add(col, db); | |
113 | if (rc < 0) | |
114 | db_release(db); | |
115 | ||
116 | return rc; | |
117 | } | |
118 | ||
119 | /* NOTE - function header comment in include/seccomp.h */ | |
120 | API void seccomp_release(scmp_filter_ctx ctx) | |
121 | { | |
122 | if (_ctx_valid(ctx)) | |
123 | return; | |
124 | ||
125 | db_col_release((struct db_filter_col *)ctx); | |
126 | } | |
127 | ||
128 | /* NOTE - function header comment in include/seccomp.h */ | |
129 | API int seccomp_merge(scmp_filter_ctx ctx_dst, | |
130 | scmp_filter_ctx ctx_src) | |
131 | { | |
132 | struct db_filter_col *col_dst = (struct db_filter_col *)ctx_dst; | |
133 | struct db_filter_col *col_src = (struct db_filter_col *)ctx_src; | |
134 | ||
135 | if (db_col_valid(col_dst) || db_col_valid(col_src)) | |
136 | return -EINVAL; | |
137 | ||
138 | /* NOTE: only the default action and NNP settings must match */ | |
139 | if ((col_dst->attr.act_default != col_src->attr.act_default) || | |
140 | (col_dst->attr.nnp_enable != col_src->attr.nnp_enable)) | |
141 | return -EINVAL; | |
142 | ||
143 | return db_col_merge(col_dst, col_src); | |
144 | } | |
145 | ||
146 | /* NOTE - function header comment in include/seccomp.h */ | |
147 | API uint32_t seccomp_arch_native(void) | |
148 | { | |
149 | return arch_def_native->token; | |
150 | } | |
151 | ||
152 | /* NOTE - function header comment in include/seccomp.h */ | |
153 | API int seccomp_arch_exist(const scmp_filter_ctx ctx, | |
154 | uint32_t arch_token) | |
155 | { | |
156 | struct db_filter_col *col = (struct db_filter_col *)ctx; | |
157 | ||
158 | if (arch_token == 0) | |
159 | arch_token = arch_def_native->token; | |
160 | ||
161 | if (arch_valid(arch_token)) | |
162 | return -EINVAL; | |
163 | ||
164 | return (db_col_arch_exist(col, arch_token) ? 0 : -EEXIST); | |
165 | } | |
166 | ||
167 | /* NOTE - function header comment in include/seccomp.h */ | |
168 | API int seccomp_arch_add(scmp_filter_ctx ctx, uint32_t arch_token) | |
169 | { | |
170 | int rc; | |
171 | const struct arch_def *arch; | |
172 | struct db_filter *db; | |
173 | struct db_filter_col *col = (struct db_filter_col *)ctx; | |
174 | ||
175 | if (arch_token == 0) | |
176 | arch_token = arch_def_native->token; | |
177 | ||
178 | if (arch_valid(arch_token)) | |
179 | return -EINVAL; | |
180 | if (db_col_arch_exist(col, arch_token)) | |
181 | return -EEXIST; | |
182 | ||
183 | arch = arch_def_lookup(arch_token); | |
184 | if (arch == NULL) | |
185 | return -EFAULT; | |
186 | db = db_init(arch); | |
187 | if (db == NULL) | |
188 | return -ENOMEM; | |
189 | rc = db_col_db_add(col, db); | |
190 | if (rc < 0) | |
191 | db_release(db); | |
192 | ||
193 | return rc; | |
194 | } | |
195 | ||
196 | /* NOTE - function header comment in include/seccomp.h */ | |
197 | API int seccomp_arch_remove(scmp_filter_ctx ctx, uint32_t arch_token) | |
198 | { | |
199 | struct db_filter_col *col = (struct db_filter_col *)ctx; | |
200 | ||
201 | if (arch_token == 0) | |
202 | arch_token = arch_def_native->token; | |
203 | ||
204 | if (arch_valid(arch_token)) | |
205 | return -EINVAL; | |
206 | if (db_col_arch_exist(col, arch_token) != -EEXIST) | |
207 | return -EEXIST; | |
208 | ||
209 | return db_col_db_remove(col, arch_token); | |
210 | } | |
211 | ||
212 | /* NOTE - function header comment in include/seccomp.h */ | |
213 | API int seccomp_load(const scmp_filter_ctx ctx) | |
214 | { | |
215 | int rc; | |
216 | struct db_filter_col *col; | |
217 | struct bpf_program *program; | |
218 | ||
219 | if (_ctx_valid(ctx)) | |
220 | return -EINVAL; | |
221 | col = (struct db_filter_col *)ctx; | |
222 | ||
223 | program = gen_bpf_generate((struct db_filter_col *)ctx); | |
224 | if (program == NULL) | |
225 | return -ENOMEM; | |
226 | /* attempt to set NO_NEW_PRIVS */ | |
227 | if (col->attr.nnp_enable) { | |
228 | rc = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | |
229 | if (rc < 0) | |
230 | return -errno; | |
231 | } | |
232 | /* load the filter into the kernel */ | |
233 | rc = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, program); | |
234 | gen_bpf_release(program); | |
235 | if (rc < 0) | |
236 | return -errno; | |
237 | ||
238 | return 0; | |
239 | } | |
240 | ||
241 | /* NOTE - function header comment in include/seccomp.h */ | |
242 | API int seccomp_attr_get(const scmp_filter_ctx ctx, | |
243 | enum scmp_filter_attr attr, uint32_t *value) | |
244 | { | |
245 | if (_ctx_valid(ctx)) | |
246 | return -EINVAL; | |
247 | ||
248 | return db_col_attr_get((const struct db_filter_col *)ctx, attr, value); | |
249 | } | |
250 | ||
251 | /* NOTE - function header comment in include/seccomp.h */ | |
252 | API int seccomp_attr_set(scmp_filter_ctx ctx, | |
253 | enum scmp_filter_attr attr, uint32_t value) | |
254 | { | |
255 | if (_ctx_valid(ctx)) | |
256 | return -EINVAL; | |
257 | ||
258 | return db_col_attr_set((struct db_filter_col *)ctx, attr, value); | |
259 | } | |
260 | ||
261 | /* NOTE - function header comment in include/seccomp.h */ | |
262 | API char *seccomp_syscall_resolve_num_arch(uint32_t arch_token, int num) | |
263 | { | |
264 | const struct arch_def *arch; | |
265 | const char *name; | |
266 | ||
267 | if (arch_token == 0) | |
268 | arch_token = arch_def_native->token; | |
269 | if (arch_valid(arch_token)) | |
270 | return NULL; | |
271 | arch = arch_def_lookup(arch_token); | |
272 | if (arch == NULL) | |
273 | return NULL; | |
274 | ||
275 | name = arch_syscall_resolve_num(arch, num); | |
276 | if (name == NULL) | |
277 | return NULL; | |
278 | ||
279 | return strdup(name); | |
280 | } | |
281 | ||
282 | /* NOTE - function header comment in include/seccomp.h */ | |
283 | API int seccomp_syscall_resolve_name_arch(uint32_t arch_token, const char *name) | |
284 | { | |
285 | const struct arch_def *arch; | |
286 | ||
287 | if (name == NULL) | |
288 | return -EINVAL; | |
289 | ||
290 | if (arch_token == 0) | |
291 | arch_token = arch_def_native->token; | |
292 | if (arch_valid(arch_token)) | |
293 | return -EINVAL; | |
294 | arch = arch_def_lookup(arch_token); | |
295 | if (arch == NULL) | |
296 | return -EFAULT; | |
297 | ||
298 | return arch_syscall_resolve_name(arch, name); | |
299 | } | |
300 | ||
301 | /* NOTE - function header comment in include/seccomp.h */ | |
302 | API int seccomp_syscall_resolve_name(const char *name) | |
303 | { | |
304 | return seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE, name); | |
305 | } | |
306 | ||
307 | /* NOTE - function header comment in include/seccomp.h */ | |
308 | API int seccomp_syscall_priority(scmp_filter_ctx ctx, | |
309 | int syscall, uint8_t priority) | |
310 | { | |
311 | int rc = 0, rc_tmp; | |
312 | unsigned int iter; | |
313 | int sc_tmp; | |
314 | struct db_filter_col *col; | |
315 | struct db_filter *filter; | |
316 | ||
317 | if (_ctx_valid(ctx) || _syscall_valid(syscall)) | |
318 | return -EINVAL; | |
319 | col = (struct db_filter_col *)ctx; | |
320 | ||
321 | for (iter = 0; iter < col->filter_cnt; iter++) { | |
322 | filter = col->filters[iter]; | |
323 | sc_tmp = syscall; | |
324 | ||
325 | rc_tmp = arch_syscall_translate(filter->arch, &sc_tmp); | |
326 | if (rc_tmp < 0) | |
327 | goto syscall_priority_failure; | |
328 | ||
329 | /* if this is a pseudo syscall (syscall < 0) then we need to | |
330 | * rewrite the syscall for some arch specific reason */ | |
331 | if (sc_tmp < 0) { | |
332 | /* we set this as a strict op - we don't really care | |
333 | * since priorities are a "best effort" thing - as we | |
334 | * want to catch the -EDOM error and bail on this | |
335 | * architecture */ | |
336 | rc_tmp = arch_syscall_rewrite(filter->arch, 1, &sc_tmp); | |
337 | if (rc_tmp == -EDOM) | |
338 | continue; | |
339 | if (rc_tmp < 0) | |
340 | goto syscall_priority_failure; | |
341 | } | |
342 | ||
343 | rc_tmp = db_syscall_priority(filter, sc_tmp, priority); | |
344 | ||
345 | syscall_priority_failure: | |
346 | if (rc == 0 && rc_tmp < 0) | |
347 | rc = rc_tmp; | |
348 | } | |
349 | ||
350 | return rc; | |
351 | } | |
352 | ||
353 | /** | |
354 | * Add a new rule to the current filter | |
355 | * @param col the filter collection | |
356 | * @param strict the strict flag | |
357 | * @param action the filter action | |
358 | * @param syscall the syscall number | |
359 | * @param arg_cnt the number of argument filters in the argument filter chain | |
360 | * @param arg_list the argument filter chain, (uint, enum scmp_compare, ulong) | |
361 | * | |
362 | * This function adds a new argument/comparison/value to the seccomp filter for | |
363 | * a syscall; multiple arguments can be specified and they will be chained | |
364 | * together (essentially AND'd together) in the filter. When the strict flag | |
365 | * is true the function will fail if the exact rule can not be added to the | |
366 | * filter, if the strict flag is false the function will not fail if the | |
367 | * function needs to adjust the rule due to architecture specifics. Returns | |
368 | * zero on success, negative values on failure. | |
369 | * | |
370 | */ | |
371 | static int _seccomp_rule_add(struct db_filter_col *col, | |
372 | bool strict, uint32_t action, int syscall, | |
373 | unsigned int arg_cnt, | |
374 | const struct scmp_arg_cmp *arg_array) | |
375 | { | |
376 | int rc = 0, rc_tmp; | |
377 | int sc_tmp; | |
378 | unsigned int iter; | |
379 | unsigned int chain_len; | |
380 | unsigned int arg_num; | |
381 | size_t chain_size; | |
382 | struct db_filter *filter; | |
383 | struct db_api_arg *chain = NULL, *chain_tmp; | |
384 | struct scmp_arg_cmp arg_data; | |
385 | ||
386 | if (arg_cnt > 0 && arg_array == NULL) | |
387 | return -EINVAL; | |
388 | ||
389 | if (db_col_valid(col) || _syscall_valid(syscall)) | |
390 | return -EINVAL; | |
391 | ||
392 | rc = db_action_valid(action); | |
393 | if (rc < 0) | |
394 | return rc; | |
395 | if (action == col->attr.act_default) | |
396 | return -EPERM; | |
397 | ||
398 | if (strict && col->filter_cnt > 1) | |
399 | return -EOPNOTSUPP; | |
400 | ||
401 | /* collect the arguments for the filter rule */ | |
402 | chain_len = ARG_COUNT_MAX; | |
403 | chain_size = sizeof(*chain) * chain_len; | |
404 | chain = malloc(chain_size); | |
405 | if (chain == NULL) | |
406 | return -ENOMEM; | |
407 | memset(chain, 0, chain_size); | |
408 | for (iter = 0; iter < arg_cnt; iter++) { | |
409 | arg_data = arg_array[iter]; | |
410 | arg_num = arg_data.arg; | |
411 | if (arg_num < chain_len && chain[arg_num].valid == 0) { | |
412 | chain[arg_num].valid = 1; | |
413 | chain[arg_num].arg = arg_num; | |
414 | chain[arg_num].op = arg_data.op; | |
415 | /* XXX - we should check datum/mask size against the | |
416 | * arch definition, e.g. 64 bit datum on x86 */ | |
417 | switch (chain[arg_num].op) { | |
418 | case SCMP_CMP_NE: | |
419 | case SCMP_CMP_LT: | |
420 | case SCMP_CMP_LE: | |
421 | case SCMP_CMP_EQ: | |
422 | case SCMP_CMP_GE: | |
423 | case SCMP_CMP_GT: | |
424 | chain[arg_num].mask = DATUM_MAX; | |
425 | chain[arg_num].datum = arg_data.datum_a; | |
426 | break; | |
427 | case SCMP_CMP_MASKED_EQ: | |
428 | chain[arg_num].mask = arg_data.datum_a; | |
429 | chain[arg_num].datum = arg_data.datum_b; | |
430 | break; | |
431 | default: | |
432 | rc = -EINVAL; | |
433 | goto rule_add_return; | |
434 | } | |
435 | } else { | |
436 | rc = -EINVAL; | |
437 | goto rule_add_return; | |
438 | } | |
439 | } | |
440 | ||
441 | for (iter = 0; iter < col->filter_cnt; iter++) { | |
442 | filter = col->filters[iter]; | |
443 | sc_tmp = syscall; | |
444 | ||
445 | rc_tmp = arch_syscall_translate(filter->arch, &sc_tmp); | |
446 | if (rc_tmp < 0) | |
447 | goto rule_add_failure; | |
448 | ||
449 | /* if this is a pseudo syscall (syscall < 0) then we need to | |
450 | * rewrite the rule for some arch specific reason */ | |
451 | if (sc_tmp < 0) { | |
452 | /* make a private copy of the chain */ | |
453 | chain_tmp = malloc(chain_size); | |
454 | if (chain_tmp == NULL) { | |
455 | rc = -ENOMEM; | |
456 | goto rule_add_failure; | |
457 | } | |
458 | memcpy(chain_tmp, chain, chain_size); | |
459 | ||
460 | /* mangle the private chain copy */ | |
461 | rc_tmp = arch_filter_rewrite(filter->arch, strict, | |
462 | &sc_tmp, chain_tmp); | |
463 | if ((rc == -EDOM) && (!strict)) { | |
464 | free(chain_tmp); | |
465 | continue; | |
466 | } | |
467 | if (rc_tmp < 0) { | |
468 | free(chain_tmp); | |
469 | goto rule_add_failure; | |
470 | } | |
471 | ||
472 | /* add the new rule to the existing filter */ | |
473 | rc_tmp = db_rule_add(filter, action, sc_tmp, chain_tmp); | |
474 | free(chain_tmp); | |
475 | } else | |
476 | /* add the new rule to the existing filter */ | |
477 | rc_tmp = db_rule_add(filter, action, sc_tmp, chain); | |
478 | ||
479 | rule_add_failure: | |
480 | if (rc == 0 && rc_tmp < 0) | |
481 | rc = rc_tmp; | |
482 | } | |
483 | ||
484 | rule_add_return: | |
485 | if (chain != NULL) | |
486 | free(chain); | |
487 | return rc; | |
488 | } | |
489 | ||
490 | /* NOTE - function header comment in include/seccomp.h */ | |
491 | API int seccomp_rule_add_array(scmp_filter_ctx ctx, | |
492 | uint32_t action, int syscall, | |
493 | unsigned int arg_cnt, | |
494 | const struct scmp_arg_cmp *arg_array) | |
495 | { | |
496 | if (arg_cnt < 0 || arg_cnt > ARG_COUNT_MAX) | |
497 | return -EINVAL; | |
498 | ||
499 | return _seccomp_rule_add((struct db_filter_col *)ctx, | |
500 | 0, action, syscall, arg_cnt, arg_array); | |
501 | } | |
502 | ||
503 | /* NOTE - function header comment in include/seccomp.h */ | |
504 | API int seccomp_rule_add(scmp_filter_ctx ctx, | |
505 | uint32_t action, int syscall, | |
506 | unsigned int arg_cnt, ...) | |
507 | { | |
508 | int rc; | |
509 | int iter; | |
510 | struct scmp_arg_cmp arg_array[ARG_COUNT_MAX]; | |
511 | va_list arg_list; | |
512 | ||
513 | if (arg_cnt < 0 || arg_cnt > ARG_COUNT_MAX) | |
514 | return -EINVAL; | |
515 | ||
516 | va_start(arg_list, arg_cnt); | |
517 | for (iter = 0; iter < arg_cnt; ++iter) | |
518 | arg_array[iter] = va_arg(arg_list, struct scmp_arg_cmp); | |
519 | rc = seccomp_rule_add_array(ctx, action, syscall, arg_cnt, arg_array); | |
520 | va_end(arg_list); | |
521 | ||
522 | return rc; | |
523 | } | |
524 | ||
525 | /* NOTE - function header comment in include/seccomp.h */ | |
526 | API int seccomp_rule_add_exact_array(scmp_filter_ctx ctx, | |
527 | uint32_t action, int syscall, | |
528 | unsigned int arg_cnt, | |
529 | const struct scmp_arg_cmp *arg_array) | |
530 | { | |
531 | if (arg_cnt < 0 || arg_cnt > ARG_COUNT_MAX) | |
532 | return -EINVAL; | |
533 | ||
534 | return _seccomp_rule_add((struct db_filter_col *)ctx, | |
535 | 1, action, syscall, arg_cnt, arg_array); | |
536 | } | |
537 | ||
538 | /* NOTE - function header comment in include/seccomp.h */ | |
539 | API int seccomp_rule_add_exact(scmp_filter_ctx ctx, | |
540 | uint32_t action, int syscall, | |
541 | unsigned int arg_cnt, ...) | |
542 | { | |
543 | int rc; | |
544 | int iter; | |
545 | struct scmp_arg_cmp arg_array[ARG_COUNT_MAX]; | |
546 | va_list arg_list; | |
547 | ||
548 | if (arg_cnt < 0 || arg_cnt > ARG_COUNT_MAX) | |
549 | return -EINVAL; | |
550 | ||
551 | va_start(arg_list, arg_cnt); | |
552 | for (iter = 0; iter < arg_cnt; ++iter) | |
553 | arg_array[iter] = va_arg(arg_list, struct scmp_arg_cmp); | |
554 | rc = seccomp_rule_add_exact_array(ctx, | |
555 | action, syscall, arg_cnt, arg_array); | |
556 | va_end(arg_list); | |
557 | ||
558 | return rc; | |
559 | } | |
560 | ||
561 | /* NOTE - function header comment in include/seccomp.h */ | |
562 | API int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd) | |
563 | { | |
564 | if (_ctx_valid(ctx)) | |
565 | return -EINVAL; | |
566 | ||
567 | return gen_pfc_generate((struct db_filter_col *)ctx, fd); | |
568 | } | |
569 | ||
570 | /* NOTE - function header comment in include/seccomp.h */ | |
571 | API int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd) | |
572 | { | |
573 | int rc; | |
574 | struct bpf_program *program; | |
575 | ||
576 | if (_ctx_valid(ctx)) | |
577 | return -EINVAL; | |
578 | ||
579 | program = gen_bpf_generate((struct db_filter_col *)ctx); | |
580 | if (program == NULL) | |
581 | return -ENOMEM; | |
582 | rc = write(fd, program->blks, BPF_PGM_SIZE(program)); | |
583 | gen_bpf_release(program); | |
584 | if (rc < 0) | |
585 | return -errno; | |
586 | ||
587 | return 0; | |
588 | } |
0 | /** | |
1 | * Enhanced Seccomp ARM Syscall Table | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <string.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "arch.h" | |
26 | #include "arch-arm.h" | |
27 | ||
28 | #define __NR_OABI_SYSCALL_BASE 0x900000 | |
29 | ||
30 | /* NOTE: we currently only support the ARM EABI, more info at the URL below: | |
31 | * -> http://wiki.embeddedarm.com/wiki/EABI_vs_OABI */ | |
32 | #if 1 | |
33 | #define __NR_SYSCALL_BASE 0 | |
34 | #else | |
35 | #define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE | |
36 | #endif | |
37 | ||
38 | /* NOTE: based on Linux 3.8.0-rc5 */ | |
39 | const struct arch_syscall_def arm_syscall_table[] = { \ | |
40 | /* NOTE: arm_sync_file_range() and sync_file_range2() share values */ | |
41 | { "accept", (__NR_SYSCALL_BASE + 285) }, | |
42 | { "accept4", (__NR_SYSCALL_BASE + 366) }, | |
43 | { "access", (__NR_SYSCALL_BASE + 33) }, | |
44 | { "acct", (__NR_SYSCALL_BASE + 51) }, | |
45 | { "add_key", (__NR_SYSCALL_BASE + 309) }, | |
46 | { "adjtimex", (__NR_SYSCALL_BASE + 124) }, | |
47 | { "afs_syscall", __PNR_afs_syscall }, | |
48 | { "alarm", (__NR_SYSCALL_BASE + 27) }, | |
49 | { "arm_fadvise64_64", (__NR_SYSCALL_BASE + 270) }, | |
50 | { "arm_sync_file_range", (__NR_SYSCALL_BASE + 341) }, | |
51 | { "arch_prctl", __PNR_arch_prctl }, | |
52 | { "bdflush", (__NR_SYSCALL_BASE + 134) }, | |
53 | { "bind", (__NR_SYSCALL_BASE + 282) }, | |
54 | { "break", __PNR_break }, | |
55 | { "brk", (__NR_SYSCALL_BASE + 45) }, | |
56 | { "capget", (__NR_SYSCALL_BASE + 184) }, | |
57 | { "capset", (__NR_SYSCALL_BASE + 185) }, | |
58 | { "chdir", (__NR_SYSCALL_BASE + 12) }, | |
59 | { "chmod", (__NR_SYSCALL_BASE + 15) }, | |
60 | { "chown", (__NR_SYSCALL_BASE + 182) }, | |
61 | { "chown32", (__NR_SYSCALL_BASE + 212) }, | |
62 | { "chroot", (__NR_SYSCALL_BASE + 61) }, | |
63 | { "clock_adjtime", (__NR_SYSCALL_BASE + 372) }, | |
64 | { "clock_getres", (__NR_SYSCALL_BASE + 264) }, | |
65 | { "clock_gettime", (__NR_SYSCALL_BASE + 263) }, | |
66 | { "clock_nanosleep", (__NR_SYSCALL_BASE + 265) }, | |
67 | { "clock_settime", (__NR_SYSCALL_BASE + 262) }, | |
68 | { "clone", (__NR_SYSCALL_BASE + 120) }, | |
69 | { "close", (__NR_SYSCALL_BASE + 6) }, | |
70 | { "connect", (__NR_SYSCALL_BASE + 283) }, | |
71 | { "creat", (__NR_SYSCALL_BASE + 8) }, | |
72 | { "create_module", __PNR_create_module }, | |
73 | { "delete_module", (__NR_SYSCALL_BASE + 129) }, | |
74 | { "dup", (__NR_SYSCALL_BASE + 41) }, | |
75 | { "dup2", (__NR_SYSCALL_BASE + 63) }, | |
76 | { "dup3", (__NR_SYSCALL_BASE + 358) }, | |
77 | { "epoll_create", (__NR_SYSCALL_BASE + 250) }, | |
78 | { "epoll_create1", (__NR_SYSCALL_BASE + 357) }, | |
79 | { "epoll_ctl", (__NR_SYSCALL_BASE + 251) }, | |
80 | { "epoll_ctl_old", __PNR_epoll_ctl_old }, | |
81 | { "epoll_pwait", (__NR_SYSCALL_BASE + 346) }, | |
82 | { "epoll_wait", (__NR_SYSCALL_BASE + 252) }, | |
83 | { "epoll_wait_old", __PNR_epoll_wait_old }, | |
84 | { "eventfd", (__NR_SYSCALL_BASE + 351) }, | |
85 | { "eventfd2", (__NR_SYSCALL_BASE + 356) }, | |
86 | { "execve", (__NR_SYSCALL_BASE + 11) }, | |
87 | { "exit", (__NR_SYSCALL_BASE + 1) }, | |
88 | { "exit_group", (__NR_SYSCALL_BASE + 248) }, | |
89 | { "faccessat", (__NR_SYSCALL_BASE + 334) }, | |
90 | { "fadvise64", __PNR_fadvise64 }, | |
91 | { "fadvise64_64", __PNR_fadvise64_64 }, | |
92 | { "fallocate", (__NR_SYSCALL_BASE + 352) }, | |
93 | { "fanotify_init", (__NR_SYSCALL_BASE + 367) }, | |
94 | { "fanotify_mark", (__NR_SYSCALL_BASE + 368) }, | |
95 | { "fchdir", (__NR_SYSCALL_BASE + 133) }, | |
96 | { "fchmod", (__NR_SYSCALL_BASE + 94) }, | |
97 | { "fchmodat", (__NR_SYSCALL_BASE + 333) }, | |
98 | { "fchown", (__NR_SYSCALL_BASE + 95) }, | |
99 | { "fchown32", (__NR_SYSCALL_BASE + 207) }, | |
100 | { "fchownat", (__NR_SYSCALL_BASE + 325) }, | |
101 | { "fcntl", (__NR_SYSCALL_BASE + 55) }, | |
102 | { "fcntl64", (__NR_SYSCALL_BASE + 221) }, | |
103 | { "fdatasync", (__NR_SYSCALL_BASE + 148) }, | |
104 | { "fgetxattr", (__NR_SYSCALL_BASE + 231) }, | |
105 | { "finit_module", (__NR_SYSCALL_BASE + 379) }, | |
106 | { "flistxattr", (__NR_SYSCALL_BASE + 234) }, | |
107 | { "flock", (__NR_SYSCALL_BASE + 143) }, | |
108 | { "fork", (__NR_SYSCALL_BASE + 2) }, | |
109 | { "fremovexattr", (__NR_SYSCALL_BASE + 237) }, | |
110 | { "fsetxattr", (__NR_SYSCALL_BASE + 228) }, | |
111 | { "fstat", (__NR_SYSCALL_BASE + 108) }, | |
112 | { "fstat64", (__NR_SYSCALL_BASE + 197) }, | |
113 | { "fstatat64", (__NR_SYSCALL_BASE + 327) }, | |
114 | { "fstatfs", (__NR_SYSCALL_BASE + 100) }, | |
115 | { "fstatfs64", (__NR_SYSCALL_BASE + 267) }, | |
116 | { "fsync", (__NR_SYSCALL_BASE + 118) }, | |
117 | { "ftime", __PNR_ftime }, | |
118 | { "ftruncate", (__NR_SYSCALL_BASE + 93) }, | |
119 | { "ftruncate64", (__NR_SYSCALL_BASE + 194) }, | |
120 | { "futex", (__NR_SYSCALL_BASE + 240) }, | |
121 | { "futimesat", (__NR_SYSCALL_BASE + 326) }, | |
122 | { "get_kernel_syms", __PNR_get_kernel_syms }, | |
123 | { "get_mempolicy", (__NR_SYSCALL_BASE + 320) }, | |
124 | { "get_robust_list", (__NR_SYSCALL_BASE + 339) }, | |
125 | { "get_thread_area", __PNR_get_thread_area }, | |
126 | { "getcpu", (__NR_SYSCALL_BASE + 345) }, | |
127 | { "getcwd", (__NR_SYSCALL_BASE + 183) }, | |
128 | { "getdents", (__NR_SYSCALL_BASE + 141) }, | |
129 | { "getdents64", (__NR_SYSCALL_BASE + 217) }, | |
130 | { "getegid", (__NR_SYSCALL_BASE + 50) }, | |
131 | { "getegid32", (__NR_SYSCALL_BASE + 202) }, | |
132 | { "geteuid", (__NR_SYSCALL_BASE + 49) }, | |
133 | { "geteuid32", (__NR_SYSCALL_BASE + 201) }, | |
134 | { "getgid", (__NR_SYSCALL_BASE + 47) }, | |
135 | { "getgid32", (__NR_SYSCALL_BASE + 200) }, | |
136 | { "getgroups", (__NR_SYSCALL_BASE + 80) }, | |
137 | { "getgroups32", (__NR_SYSCALL_BASE + 205) }, | |
138 | { "getitimer", (__NR_SYSCALL_BASE + 105) }, | |
139 | { "getpeername", (__NR_SYSCALL_BASE + 287) }, | |
140 | { "getpgid", (__NR_SYSCALL_BASE + 132) }, | |
141 | { "getpgrp", (__NR_SYSCALL_BASE + 65) }, | |
142 | { "getpid", (__NR_SYSCALL_BASE + 20) }, | |
143 | { "getpmsg", __PNR_getpmsg }, | |
144 | { "getppid", (__NR_SYSCALL_BASE + 64) }, | |
145 | { "getpriority", (__NR_SYSCALL_BASE + 96) }, | |
146 | { "getresgid", (__NR_SYSCALL_BASE + 171) }, | |
147 | { "getresgid32", (__NR_SYSCALL_BASE + 211) }, | |
148 | { "getresuid", (__NR_SYSCALL_BASE + 165) }, | |
149 | { "getresuid32", (__NR_SYSCALL_BASE + 209) }, | |
150 | { "getrlimit", (__NR_SYSCALL_BASE + 76) }, | |
151 | { "getrusage", (__NR_SYSCALL_BASE + 77) }, | |
152 | { "getsid", (__NR_SYSCALL_BASE + 147) }, | |
153 | { "getsockname", (__NR_SYSCALL_BASE + 286) }, | |
154 | { "getsockopt", (__NR_SYSCALL_BASE + 295) }, | |
155 | { "gettid", (__NR_SYSCALL_BASE + 224) }, | |
156 | { "gettimeofday", (__NR_SYSCALL_BASE + 78) }, | |
157 | { "getuid", (__NR_SYSCALL_BASE + 24) }, | |
158 | { "getuid32", (__NR_SYSCALL_BASE + 199) }, | |
159 | { "getxattr", (__NR_SYSCALL_BASE + 229) }, | |
160 | { "gtty", __PNR_gtty }, | |
161 | { "idle", __PNR_idle }, | |
162 | { "init_module", (__NR_SYSCALL_BASE + 128) }, | |
163 | { "inotify_add_watch", (__NR_SYSCALL_BASE + 317) }, | |
164 | { "inotify_init", (__NR_SYSCALL_BASE + 316) }, | |
165 | { "inotify_init1", (__NR_SYSCALL_BASE + 360) }, | |
166 | { "inotify_rm_watch", (__NR_SYSCALL_BASE + 318) }, | |
167 | { "io_cancel", (__NR_SYSCALL_BASE + 247) }, | |
168 | { "io_destroy", (__NR_SYSCALL_BASE + 244) }, | |
169 | { "io_getevents", (__NR_SYSCALL_BASE + 245) }, | |
170 | { "io_setup", (__NR_SYSCALL_BASE + 243) }, | |
171 | { "io_submit", (__NR_SYSCALL_BASE + 246) }, | |
172 | { "ioctl", (__NR_SYSCALL_BASE + 54) }, | |
173 | { "ioperm", __PNR_ioperm }, | |
174 | { "iopl", __PNR_iopl }, | |
175 | { "ioprio_get", (__NR_SYSCALL_BASE + 315) }, | |
176 | { "ioprio_set", (__NR_SYSCALL_BASE + 314) }, | |
177 | { "ipc", (__NR_SYSCALL_BASE + 117) }, | |
178 | { "kcmp", __PNR_kcmp }, | |
179 | { "kexec_load", (__NR_SYSCALL_BASE + 347) }, | |
180 | { "keyctl", (__NR_SYSCALL_BASE + 311) }, | |
181 | { "kill", (__NR_SYSCALL_BASE + 37) }, | |
182 | { "lchown", (__NR_SYSCALL_BASE + 16) }, | |
183 | { "lchown32", (__NR_SYSCALL_BASE + 198) }, | |
184 | { "lgetxattr", (__NR_SYSCALL_BASE + 230) }, | |
185 | { "link", (__NR_SYSCALL_BASE + 9) }, | |
186 | { "linkat", (__NR_SYSCALL_BASE + 330) }, | |
187 | { "listen", (__NR_SYSCALL_BASE + 284) }, | |
188 | { "listxattr", (__NR_SYSCALL_BASE + 232) }, | |
189 | { "llistxattr", (__NR_SYSCALL_BASE + 233) }, | |
190 | { "_llseek", (__NR_SYSCALL_BASE + 140) }, | |
191 | { "lock", __PNR_lock }, | |
192 | { "lookup_dcookie", (__NR_SYSCALL_BASE + 249) }, | |
193 | { "lremovexattr", (__NR_SYSCALL_BASE + 236) }, | |
194 | { "lseek", (__NR_SYSCALL_BASE + 19) }, | |
195 | { "lsetxattr", (__NR_SYSCALL_BASE + 227) }, | |
196 | { "lstat", (__NR_SYSCALL_BASE + 107) }, | |
197 | { "lstat64", (__NR_SYSCALL_BASE + 196) }, | |
198 | { "madvise", (__NR_SYSCALL_BASE + 220) }, | |
199 | { "mbind", (__NR_SYSCALL_BASE + 319) }, | |
200 | { "migrate_pages", __PNR_migrate_pages }, | |
201 | { "mincore", (__NR_SYSCALL_BASE + 219) }, | |
202 | { "mkdir", (__NR_SYSCALL_BASE + 39) }, | |
203 | { "mkdirat", (__NR_SYSCALL_BASE + 323) }, | |
204 | { "mknod", (__NR_SYSCALL_BASE + 14) }, | |
205 | { "mknodat", (__NR_SYSCALL_BASE + 324) }, | |
206 | { "mlock", (__NR_SYSCALL_BASE + 150) }, | |
207 | { "mlockall", (__NR_SYSCALL_BASE + 152) }, | |
208 | { "mmap", (__NR_SYSCALL_BASE + 90) }, | |
209 | { "mmap2", (__NR_SYSCALL_BASE + 192) }, | |
210 | { "modify_ldt", __PNR_modify_ldt }, | |
211 | { "mount", (__NR_SYSCALL_BASE + 21) }, | |
212 | { "move_pages", (__NR_SYSCALL_BASE + 344) }, | |
213 | { "mprotect", (__NR_SYSCALL_BASE + 125) }, | |
214 | { "mpx", __PNR_mpx }, | |
215 | { "mq_getsetattr", (__NR_SYSCALL_BASE + 279) }, | |
216 | { "mq_notify", (__NR_SYSCALL_BASE + 278) }, | |
217 | { "mq_open", (__NR_SYSCALL_BASE + 274) }, | |
218 | { "mq_timedreceive", (__NR_SYSCALL_BASE + 277) }, | |
219 | { "mq_timedsend", (__NR_SYSCALL_BASE + 276) }, | |
220 | { "mq_unlink", (__NR_SYSCALL_BASE + 275) }, | |
221 | { "mremap", (__NR_SYSCALL_BASE + 163) }, | |
222 | { "msgctl", (__NR_SYSCALL_BASE + 304) }, | |
223 | { "msgget", (__NR_SYSCALL_BASE + 303) }, | |
224 | { "msgrcv", (__NR_SYSCALL_BASE + 302) }, | |
225 | { "msgsnd", (__NR_SYSCALL_BASE + 301) }, | |
226 | { "msync", (__NR_SYSCALL_BASE + 144) }, | |
227 | { "munlock", (__NR_SYSCALL_BASE + 151) }, | |
228 | { "munlockall", (__NR_SYSCALL_BASE + 153) }, | |
229 | { "munmap", (__NR_SYSCALL_BASE + 91) }, | |
230 | { "name_to_handle_at", (__NR_SYSCALL_BASE + 370) }, | |
231 | { "nanosleep", (__NR_SYSCALL_BASE + 162) }, | |
232 | { "_newselect", (__NR_SYSCALL_BASE + 142) }, | |
233 | { "newfstatat", __PNR_newfstatat }, | |
234 | { "nfsservctl", (__NR_SYSCALL_BASE + 169) }, | |
235 | { "nice", (__NR_SYSCALL_BASE + 34) }, | |
236 | { "oldfstat", __PNR_oldfstat }, | |
237 | { "oldlstat", __PNR_oldlstat }, | |
238 | { "oldolduname", __PNR_oldolduname }, | |
239 | { "oldstat", __PNR_oldstat }, | |
240 | { "olduname", __PNR_olduname }, | |
241 | { "open", (__NR_SYSCALL_BASE + 5) }, | |
242 | { "open_by_handle_at", (__NR_SYSCALL_BASE + 371) }, | |
243 | { "openat", (__NR_SYSCALL_BASE + 322) }, | |
244 | { "pause", (__NR_SYSCALL_BASE + 29) }, | |
245 | { "pciconfig_iobase", (__NR_SYSCALL_BASE + 271) }, | |
246 | { "pciconfig_read", (__NR_SYSCALL_BASE + 272) }, | |
247 | { "pciconfig_write", (__NR_SYSCALL_BASE + 273) }, | |
248 | { "perf_event_open", (__NR_SYSCALL_BASE + 364) }, | |
249 | { "personality", (__NR_SYSCALL_BASE + 136) }, | |
250 | { "pipe", (__NR_SYSCALL_BASE + 42) }, | |
251 | { "pipe2", (__NR_SYSCALL_BASE + 359) }, | |
252 | { "pivot_root", (__NR_SYSCALL_BASE + 218) }, | |
253 | { "poll", (__NR_SYSCALL_BASE + 168) }, | |
254 | { "ppoll", (__NR_SYSCALL_BASE + 336) }, | |
255 | { "prctl", (__NR_SYSCALL_BASE + 172) }, | |
256 | { "pread64", (__NR_SYSCALL_BASE + 180) }, | |
257 | { "preadv", (__NR_SYSCALL_BASE + 361) }, | |
258 | { "prlimit64", (__NR_SYSCALL_BASE + 369) }, | |
259 | { "process_vm_readv", (__NR_SYSCALL_BASE + 376) }, | |
260 | { "process_vm_writev", (__NR_SYSCALL_BASE + 377) }, | |
261 | { "prof", __PNR_prof }, | |
262 | { "profil", __PNR_profil }, | |
263 | { "pselect6", (__NR_SYSCALL_BASE + 335) }, | |
264 | { "ptrace", (__NR_SYSCALL_BASE + 26) }, | |
265 | { "putpmsg", __PNR_putpmsg }, | |
266 | { "pwrite64", (__NR_SYSCALL_BASE + 181) }, | |
267 | { "pwritev", (__NR_SYSCALL_BASE + 362) }, | |
268 | { "query_module", __PNR_query_module }, | |
269 | { "quotactl", (__NR_SYSCALL_BASE + 131) }, | |
270 | { "read", (__NR_SYSCALL_BASE + 3) }, | |
271 | { "readahead", (__NR_SYSCALL_BASE + 225) }, | |
272 | { "readdir", (__NR_SYSCALL_BASE + 89) }, | |
273 | { "readlink", (__NR_SYSCALL_BASE + 85) }, | |
274 | { "readlinkat", (__NR_SYSCALL_BASE + 332) }, | |
275 | { "readv", (__NR_SYSCALL_BASE + 145) }, | |
276 | { "reboot", (__NR_SYSCALL_BASE + 88) }, | |
277 | { "recv", (__NR_SYSCALL_BASE + 291) }, | |
278 | { "recvfrom", (__NR_SYSCALL_BASE + 292) }, | |
279 | { "recvmmsg", (__NR_SYSCALL_BASE + 365) }, | |
280 | { "recvmsg", (__NR_SYSCALL_BASE + 297) }, | |
281 | { "remap_file_pages", (__NR_SYSCALL_BASE + 253) }, | |
282 | { "removexattr", (__NR_SYSCALL_BASE + 235) }, | |
283 | { "rename", (__NR_SYSCALL_BASE + 38) }, | |
284 | { "renameat", (__NR_SYSCALL_BASE + 329) }, | |
285 | { "request_key", (__NR_SYSCALL_BASE + 310) }, | |
286 | { "restart_syscall", (__NR_SYSCALL_BASE + 0) }, | |
287 | { "rmdir", (__NR_SYSCALL_BASE + 40) }, | |
288 | { "rt_sigaction", (__NR_SYSCALL_BASE + 174) }, | |
289 | { "rt_sigpending", (__NR_SYSCALL_BASE + 176) }, | |
290 | { "rt_sigprocmask", (__NR_SYSCALL_BASE + 175) }, | |
291 | { "rt_sigqueueinfo", (__NR_SYSCALL_BASE + 178) }, | |
292 | { "rt_sigreturn", (__NR_SYSCALL_BASE + 173) }, | |
293 | { "rt_sigsuspend", (__NR_SYSCALL_BASE + 179) }, | |
294 | { "rt_sigtimedwait", (__NR_SYSCALL_BASE + 177) }, | |
295 | { "rt_tgsigqueueinfo", (__NR_SYSCALL_BASE + 363) }, | |
296 | { "sched_get_priority_max", (__NR_SYSCALL_BASE + 159) }, | |
297 | { "sched_get_priority_min", (__NR_SYSCALL_BASE + 160) }, | |
298 | { "sched_getaffinity", (__NR_SYSCALL_BASE + 242) }, | |
299 | { "sched_getparam", (__NR_SYSCALL_BASE + 155) }, | |
300 | { "sched_getscheduler", (__NR_SYSCALL_BASE + 157) }, | |
301 | { "sched_rr_get_interval", (__NR_SYSCALL_BASE + 161) }, | |
302 | { "sched_setaffinity", (__NR_SYSCALL_BASE + 241) }, | |
303 | { "sched_setparam", (__NR_SYSCALL_BASE + 154) }, | |
304 | { "sched_setscheduler", (__NR_SYSCALL_BASE + 156) }, | |
305 | { "sched_yield", (__NR_SYSCALL_BASE + 158) }, | |
306 | { "security", __PNR_security }, | |
307 | { "select", (__NR_SYSCALL_BASE + 82) }, | |
308 | { "semctl", (__NR_SYSCALL_BASE + 300) }, | |
309 | { "semget", (__NR_SYSCALL_BASE + 299) }, | |
310 | { "semop", (__NR_SYSCALL_BASE + 298) }, | |
311 | { "semtimedop", (__NR_SYSCALL_BASE + 312) }, | |
312 | { "send", (__NR_SYSCALL_BASE + 289) }, | |
313 | { "sendfile", (__NR_SYSCALL_BASE + 187) }, | |
314 | { "sendfile64", (__NR_SYSCALL_BASE + 239) }, | |
315 | { "sendmmsg", (__NR_SYSCALL_BASE + 374) }, | |
316 | { "sendmsg", (__NR_SYSCALL_BASE + 296) }, | |
317 | { "sendto", (__NR_SYSCALL_BASE + 290) }, | |
318 | { "set_mempolicy", (__NR_SYSCALL_BASE + 321) }, | |
319 | { "set_robust_list", (__NR_SYSCALL_BASE + 338) }, | |
320 | { "set_thread_area", __PNR_set_thread_area }, | |
321 | { "set_tid_address", (__NR_SYSCALL_BASE + 256) }, | |
322 | { "setdomainname", (__NR_SYSCALL_BASE + 121) }, | |
323 | { "setfsgid", (__NR_SYSCALL_BASE + 139) }, | |
324 | { "setfsgid32", (__NR_SYSCALL_BASE + 216) }, | |
325 | { "setfsuid", (__NR_SYSCALL_BASE + 138) }, | |
326 | { "setfsuid32", (__NR_SYSCALL_BASE + 215) }, | |
327 | { "setgid", (__NR_SYSCALL_BASE + 46) }, | |
328 | { "setgid32", (__NR_SYSCALL_BASE + 214) }, | |
329 | { "setgroups", (__NR_SYSCALL_BASE + 81) }, | |
330 | { "setgroups32", (__NR_SYSCALL_BASE + 206) }, | |
331 | { "sethostname", (__NR_SYSCALL_BASE + 74) }, | |
332 | { "setitimer", (__NR_SYSCALL_BASE + 104) }, | |
333 | { "setns", (__NR_SYSCALL_BASE + 375) }, | |
334 | { "setpgid", (__NR_SYSCALL_BASE + 57) }, | |
335 | { "setpriority", (__NR_SYSCALL_BASE + 97) }, | |
336 | { "setregid", (__NR_SYSCALL_BASE + 71) }, | |
337 | { "setregid32", (__NR_SYSCALL_BASE + 204) }, | |
338 | { "setresgid", (__NR_SYSCALL_BASE + 170) }, | |
339 | { "setresgid32", (__NR_SYSCALL_BASE + 210) }, | |
340 | { "setresuid", (__NR_SYSCALL_BASE + 164) }, | |
341 | { "setresuid32", (__NR_SYSCALL_BASE + 208) }, | |
342 | { "setreuid", (__NR_SYSCALL_BASE + 70) }, | |
343 | { "setreuid32", (__NR_SYSCALL_BASE + 203) }, | |
344 | { "setrlimit", (__NR_SYSCALL_BASE + 75) }, | |
345 | { "setsid", (__NR_SYSCALL_BASE + 66) }, | |
346 | { "setsockopt", (__NR_SYSCALL_BASE + 294) }, | |
347 | { "settimeofday", (__NR_SYSCALL_BASE + 79) }, | |
348 | { "setuid", (__NR_SYSCALL_BASE + 23) }, | |
349 | { "setuid32", (__NR_SYSCALL_BASE + 213) }, | |
350 | { "setxattr", (__NR_SYSCALL_BASE + 226) }, | |
351 | { "sgetmask", __PNR_sgetmask }, | |
352 | { "shmat", (__NR_SYSCALL_BASE + 305) }, | |
353 | { "shmctl", (__NR_SYSCALL_BASE + 308) }, | |
354 | { "shmdt", (__NR_SYSCALL_BASE + 306) }, | |
355 | { "shmget", (__NR_SYSCALL_BASE + 307) }, | |
356 | { "shutdown", (__NR_SYSCALL_BASE + 293) }, | |
357 | { "sigaction", (__NR_SYSCALL_BASE + 67) }, | |
358 | { "sigaltstack", (__NR_SYSCALL_BASE + 186) }, | |
359 | { "signal", __PNR_signal }, | |
360 | { "signalfd", (__NR_SYSCALL_BASE + 349) }, | |
361 | { "signalfd4", (__NR_SYSCALL_BASE + 355) }, | |
362 | { "sigpending", (__NR_SYSCALL_BASE + 73) }, | |
363 | { "sigprocmask", (__NR_SYSCALL_BASE + 126) }, | |
364 | { "sigreturn", (__NR_SYSCALL_BASE + 119) }, | |
365 | { "sigsuspend", (__NR_SYSCALL_BASE + 72) }, | |
366 | { "socket", (__NR_SYSCALL_BASE + 281) }, | |
367 | { "socketcall", (__NR_SYSCALL_BASE + 102) }, | |
368 | { "socketpair", (__NR_SYSCALL_BASE + 288) }, | |
369 | { "splice", (__NR_SYSCALL_BASE + 340) }, | |
370 | { "ssetmask", __PNR_ssetmask }, | |
371 | { "stat", (__NR_SYSCALL_BASE + 106) }, | |
372 | { "stat64", (__NR_SYSCALL_BASE + 195) }, | |
373 | { "statfs", (__NR_SYSCALL_BASE + 99) }, | |
374 | { "statfs64", (__NR_SYSCALL_BASE + 266) }, | |
375 | { "stime", (__NR_SYSCALL_BASE + 25) }, | |
376 | { "stty", __PNR_stty }, | |
377 | { "swapoff", (__NR_SYSCALL_BASE + 115) }, | |
378 | { "swapon", (__NR_SYSCALL_BASE + 87) }, | |
379 | { "symlink", (__NR_SYSCALL_BASE + 83) }, | |
380 | { "symlinkat", (__NR_SYSCALL_BASE + 331) }, | |
381 | { "sync", (__NR_SYSCALL_BASE + 36) }, | |
382 | { "sync_file_range", __PNR_sync_file_range }, | |
383 | { "sync_file_range2", (__NR_SYSCALL_BASE + 341) }, | |
384 | { "syncfs", (__NR_SYSCALL_BASE + 373) }, | |
385 | { "syscall", (__NR_SYSCALL_BASE + 113) }, | |
386 | { "_sysctl", (__NR_SYSCALL_BASE + 149) }, | |
387 | { "sysfs", (__NR_SYSCALL_BASE + 135) }, | |
388 | { "sysinfo", (__NR_SYSCALL_BASE + 116) }, | |
389 | { "syslog", (__NR_SYSCALL_BASE + 103) }, | |
390 | { "tee", (__NR_SYSCALL_BASE + 342) }, | |
391 | { "tgkill", (__NR_SYSCALL_BASE + 268) }, | |
392 | { "time", (__NR_SYSCALL_BASE + 13) }, | |
393 | { "timer_create", (__NR_SYSCALL_BASE + 257) }, | |
394 | { "timer_delete", (__NR_SYSCALL_BASE + 261) }, | |
395 | { "timer_getoverrun", (__NR_SYSCALL_BASE + 260) }, | |
396 | { "timer_gettime", (__NR_SYSCALL_BASE + 259) }, | |
397 | { "timer_settime", (__NR_SYSCALL_BASE + 258) }, | |
398 | { "timerfd_create", (__NR_SYSCALL_BASE + 350) }, | |
399 | { "timerfd_gettime", (__NR_SYSCALL_BASE + 354) }, | |
400 | { "timerfd_settime", (__NR_SYSCALL_BASE + 353) }, | |
401 | { "times", (__NR_SYSCALL_BASE + 43) }, | |
402 | { "tkill", (__NR_SYSCALL_BASE + 238) }, | |
403 | { "truncate", (__NR_SYSCALL_BASE + 92) }, | |
404 | { "truncate64", (__NR_SYSCALL_BASE + 193) }, | |
405 | { "tuxcall", __PNR_tuxcall }, | |
406 | { "ugetrlimit", (__NR_SYSCALL_BASE + 191) }, | |
407 | { "ulimit", __PNR_ulimit }, | |
408 | { "umask", (__NR_SYSCALL_BASE + 60) }, | |
409 | { "umount", (__NR_SYSCALL_BASE + 22) }, | |
410 | { "umount2", (__NR_SYSCALL_BASE + 52) }, | |
411 | { "uname", (__NR_SYSCALL_BASE + 122) }, | |
412 | { "unlink", (__NR_SYSCALL_BASE + 10) }, | |
413 | { "unlinkat", (__NR_SYSCALL_BASE + 328) }, | |
414 | { "unshare", (__NR_SYSCALL_BASE + 337) }, | |
415 | { "uselib", (__NR_SYSCALL_BASE + 86) }, | |
416 | { "ustat", (__NR_SYSCALL_BASE + 62) }, | |
417 | { "utime", (__NR_SYSCALL_BASE + 30) }, | |
418 | { "utimensat", (__NR_SYSCALL_BASE + 348) }, | |
419 | { "utimes", (__NR_SYSCALL_BASE + 269) }, | |
420 | { "vfork", (__NR_SYSCALL_BASE + 190) }, | |
421 | { "vhangup", (__NR_SYSCALL_BASE + 111) }, | |
422 | { "vm86", __PNR_vm86 }, | |
423 | { "vm86old", __PNR_vm86old }, | |
424 | { "vmsplice", (__NR_SYSCALL_BASE + 343) }, | |
425 | { "vserver", (__NR_SYSCALL_BASE + 313) }, | |
426 | { "wait4", (__NR_SYSCALL_BASE + 114) }, | |
427 | { "waitid", (__NR_SYSCALL_BASE + 280) }, | |
428 | { "waitpid", __PNR_waitpid }, | |
429 | { "write", (__NR_SYSCALL_BASE + 4) }, | |
430 | { "writev", (__NR_SYSCALL_BASE + 146) }, | |
431 | { NULL, __NR_SCMP_ERROR }, | |
432 | }; | |
433 | ||
434 | /** | |
435 | * Resolve a syscall name to a number | |
436 | * @param name the syscall name | |
437 | * | |
438 | * Resolve the given syscall name to the syscall number using the syscall table. | |
439 | * Returns the syscall number on success, including negative pseudo syscall | |
440 | * numbers; returns __NR_SCMP_ERROR on failure. | |
441 | * | |
442 | */ | |
443 | int arm_syscall_resolve_name(const char *name) | |
444 | { | |
445 | unsigned int iter; | |
446 | const struct arch_syscall_def *table = arm_syscall_table; | |
447 | ||
448 | /* XXX - plenty of room for future improvement here */ | |
449 | for (iter = 0; table[iter].name != NULL; iter++) { | |
450 | if (strcmp(name, table[iter].name) == 0) | |
451 | return table[iter].num; | |
452 | } | |
453 | ||
454 | return __NR_SCMP_ERROR; | |
455 | } | |
456 | ||
457 | /** | |
458 | * Resolve a syscall number to a name | |
459 | * @param num the syscall number | |
460 | * | |
461 | * Resolve the given syscall number to the syscall name using the syscall table. | |
462 | * Returns a pointer to the syscall name string on success, including pseudo | |
463 | * syscall names; returns NULL on failure. | |
464 | * | |
465 | */ | |
466 | const char *arm_syscall_resolve_num(int num) | |
467 | { | |
468 | unsigned int iter; | |
469 | const struct arch_syscall_def *table = arm_syscall_table; | |
470 | ||
471 | /* XXX - plenty of room for future improvement here */ | |
472 | for (iter = 0; table[iter].num != __NR_SCMP_ERROR; iter++) { | |
473 | if (num == table[iter].num) | |
474 | return table[iter].name; | |
475 | } | |
476 | ||
477 | return NULL; | |
478 | } |
0 | /** | |
1 | * Enhanced Seccomp ARM Specific Code | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <stdlib.h> | |
22 | #include <errno.h> | |
23 | #include <linux/audit.h> | |
24 | ||
25 | #include "arch.h" | |
26 | #include "arch-arm.h" | |
27 | ||
28 | const struct arch_def arch_def_arm = { | |
29 | .token = SCMP_ARCH_ARM, | |
30 | .token_bpf = AUDIT_ARCH_ARM, | |
31 | .size = ARCH_SIZE_32, | |
32 | .endian = ARCH_ENDIAN_LITTLE, | |
33 | }; |
0 | /** | |
1 | * Enhanced Seccomp ARM Specific Code | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #ifndef _ARCH_ARM_H | |
22 | #define _ARCH_ARM_H | |
23 | ||
24 | #include <inttypes.h> | |
25 | ||
26 | #include "arch.h" | |
27 | #include "system.h" | |
28 | ||
29 | #define arm_arg_count_max 6 | |
30 | ||
31 | extern const struct arch_def arch_def_arm; | |
32 | ||
33 | int arm_syscall_resolve_name(const char *name); | |
34 | const char *arm_syscall_resolve_num(int num); | |
35 | ||
36 | #endif |
0 | /** | |
1 | * Enhanced Seccomp x32 Syscall Table | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <string.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "arch.h" | |
26 | #include "arch-x86_64.h" | |
27 | #include "arch-x32.h" | |
28 | ||
29 | /** | |
30 | * Resolve a syscall name to a number | |
31 | * @param name the syscall name | |
32 | * | |
33 | * Resolve the given syscall name to the syscall number using the syscall table. | |
34 | * Returns the syscall number on success, including negative pseudo syscall | |
35 | * numbers; returns __NR_SCMP_ERROR on failure. | |
36 | * | |
37 | */ | |
38 | int x32_syscall_resolve_name(const char *name) | |
39 | { | |
40 | int syscall; | |
41 | ||
42 | syscall = x86_64_syscall_resolve_name(name); | |
43 | if (syscall >= 0) | |
44 | syscall |= X32_SYSCALL_BIT; | |
45 | ||
46 | return syscall; | |
47 | } | |
48 | ||
49 | /** | |
50 | * Resolve a syscall number to a name | |
51 | * @param num the syscall number | |
52 | * | |
53 | * Resolve the given syscall number to the syscall name using the syscall table. | |
54 | * Returns a pointer to the syscall name string on success, including pseudo | |
55 | * syscall names; returns NULL on failure. | |
56 | * | |
57 | */ | |
58 | const char *x32_syscall_resolve_num(int num) | |
59 | { | |
60 | int syscall = num; | |
61 | ||
62 | if (syscall >= 0) | |
63 | syscall &= (~X32_SYSCALL_BIT); | |
64 | ||
65 | return x86_64_syscall_resolve_num(syscall); | |
66 | } |
0 | /** | |
1 | * Enhanced Seccomp x32 Specific Code | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <stdlib.h> | |
22 | #include <errno.h> | |
23 | #include <linux/audit.h> | |
24 | ||
25 | #include "arch.h" | |
26 | #include "arch-x32.h" | |
27 | ||
28 | const struct arch_def arch_def_x32 = { | |
29 | .token = SCMP_ARCH_X32, | |
30 | /* NOTE: this seems odd but the kernel treats x32 like x86_64 here */ | |
31 | .token_bpf = AUDIT_ARCH_X86_64, | |
32 | .size = ARCH_SIZE_32, | |
33 | .endian = ARCH_ENDIAN_LITTLE, | |
34 | }; |
0 | /** | |
1 | * Enhanced Seccomp x32 Specific Code | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #ifndef _ARCH_X32_H | |
22 | #define _ARCH_X32_H | |
23 | ||
24 | #include <inttypes.h> | |
25 | ||
26 | #include "arch.h" | |
27 | #include "system.h" | |
28 | ||
29 | #define X32_SYSCALL_BIT 0x40000000 | |
30 | ||
31 | #define x32_arg_count_max 6 | |
32 | ||
33 | extern const struct arch_def arch_def_x32; | |
34 | ||
35 | int x32_syscall_resolve_name(const char *name); | |
36 | const char *x32_syscall_resolve_num(int num); | |
37 | ||
38 | #endif |
0 | /** | |
1 | * Enhanced Seccomp x86 Syscall Table | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <string.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "arch.h" | |
26 | #include "arch-x86.h" | |
27 | ||
28 | /* NOTE: based on Linux 3.4.7 */ | |
29 | static const struct arch_syscall_def x86_syscall_table[] = { \ | |
30 | { "accept", __PNR_accept }, | |
31 | { "accept4", __PNR_accept4 }, | |
32 | { "access", 33 }, | |
33 | { "acct", 51 }, | |
34 | { "add_key", 286 }, | |
35 | { "adjtimex", 124 }, | |
36 | { "afs_syscall", 137 }, | |
37 | { "alarm", 27 }, | |
38 | { "arm_fadvise64_64", __PNR_arm_fadvise64_64 }, | |
39 | { "arm_sync_file_range", __PNR_arm_sync_file_range }, | |
40 | { "arch_prctl", __PNR_arch_prctl }, | |
41 | { "bdflush", 134 }, | |
42 | { "bind", __PNR_bind }, | |
43 | { "break", 17 }, | |
44 | { "brk", 45 }, | |
45 | { "capget", 184 }, | |
46 | { "capset", 185 }, | |
47 | { "chdir", 12 }, | |
48 | { "chmod", 15 }, | |
49 | { "chown", 182 }, | |
50 | { "chown32", 212 }, | |
51 | { "chroot", 61 }, | |
52 | { "clock_adjtime", 343 }, | |
53 | { "clock_getres", 266 }, | |
54 | { "clock_gettime", 265 }, | |
55 | { "clock_nanosleep", 267 }, | |
56 | { "clock_settime", 264 }, | |
57 | { "clone", 120 }, | |
58 | { "close", 6 }, | |
59 | { "connect", __PNR_connect }, | |
60 | { "creat", 8 }, | |
61 | { "create_module", 127 }, | |
62 | { "delete_module", 129 }, | |
63 | { "dup", 41 }, | |
64 | { "dup2", 63 }, | |
65 | { "dup3", 330 }, | |
66 | { "epoll_create", 254 }, | |
67 | { "epoll_create1", 329 }, | |
68 | { "epoll_ctl", 255 }, | |
69 | { "epoll_ctl_old", __PNR_epoll_ctl_old }, | |
70 | { "epoll_pwait", 319 }, | |
71 | { "epoll_wait", 256 }, | |
72 | { "epoll_wait_old", __PNR_epoll_wait_old }, | |
73 | { "eventfd", 323 }, | |
74 | { "eventfd2", 328 }, | |
75 | { "execve", 11 }, | |
76 | { "exit", 1 }, | |
77 | { "exit_group", 252 }, | |
78 | { "faccessat", 307 }, | |
79 | { "fadvise64", 250 }, | |
80 | { "fadvise64_64", 272 }, | |
81 | { "fallocate", 324 }, | |
82 | { "fanotify_init", 338 }, | |
83 | { "fanotify_mark", 339 }, | |
84 | { "fchdir", 133 }, | |
85 | { "fchmod", 94 }, | |
86 | { "fchmodat", 306 }, | |
87 | { "fchown", 95 }, | |
88 | { "fchown32", 207 }, | |
89 | { "fchownat", 298 }, | |
90 | { "fcntl", 55 }, | |
91 | { "fcntl64", 221 }, | |
92 | { "fdatasync", 148 }, | |
93 | { "fgetxattr", 231 }, | |
94 | { "finit_module", __PNR_finit_module }, | |
95 | { "flistxattr", 234 }, | |
96 | { "flock", 143 }, | |
97 | { "fork", 2 }, | |
98 | { "fremovexattr", 237 }, | |
99 | { "fsetxattr", 228 }, | |
100 | { "fstat", 108 }, | |
101 | { "fstat64", 197 }, | |
102 | { "fstatat64", 300 }, | |
103 | { "fstatfs", 100 }, | |
104 | { "fstatfs64", 269 }, | |
105 | { "fsync", 118 }, | |
106 | { "ftime", 35 }, | |
107 | { "ftruncate", 93 }, | |
108 | { "ftruncate64", 194 }, | |
109 | { "futex", 240 }, | |
110 | { "futimesat", 299 }, | |
111 | { "get_kernel_syms", 130 }, | |
112 | { "get_mempolicy", 275 }, | |
113 | { "get_robust_list", 312 }, | |
114 | { "get_thread_area", 244 }, | |
115 | { "getcpu", 318 }, | |
116 | { "getcwd", 183 }, | |
117 | { "getdents", 141 }, | |
118 | { "getdents64", 220 }, | |
119 | { "getegid", 50 }, | |
120 | { "getegid32", 202 }, | |
121 | { "geteuid", 49 }, | |
122 | { "geteuid32", 201 }, | |
123 | { "getgid", 47 }, | |
124 | { "getgid32", 200 }, | |
125 | { "getgroups", 80 }, | |
126 | { "getgroups32", 205 }, | |
127 | { "getitimer", 105 }, | |
128 | { "getpeername", __PNR_getpeername }, | |
129 | { "getpgid", 132 }, | |
130 | { "getpgrp", 65 }, | |
131 | { "getpid", 20 }, | |
132 | { "getpmsg", 188 }, | |
133 | { "getppid", 64 }, | |
134 | { "getpriority", 96 }, | |
135 | { "getresgid", 171 }, | |
136 | { "getresgid32", 211 }, | |
137 | { "getresuid", 165 }, | |
138 | { "getresuid32", 209 }, | |
139 | { "getrlimit", 76 }, | |
140 | { "getrusage", 77 }, | |
141 | { "getsid", 147 }, | |
142 | { "getsockname", __PNR_getsockname }, | |
143 | { "getsockopt", __PNR_getsockopt }, | |
144 | { "gettid", 224 }, | |
145 | { "gettimeofday", 78 }, | |
146 | { "getuid", 24 }, | |
147 | { "getuid32", 199 }, | |
148 | { "getxattr", 229 }, | |
149 | { "gtty", 32 }, | |
150 | { "idle", 112 }, | |
151 | { "init_module", 128 }, | |
152 | { "inotify_add_watch", 292 }, | |
153 | { "inotify_init", 291 }, | |
154 | { "inotify_init1", 332 }, | |
155 | { "inotify_rm_watch", 293 }, | |
156 | { "io_cancel", 249 }, | |
157 | { "io_destroy", 246 }, | |
158 | { "io_getevents", 247 }, | |
159 | { "io_setup", 245 }, | |
160 | { "io_submit", 248 }, | |
161 | { "ioctl", 54 }, | |
162 | { "ioperm", 101 }, | |
163 | { "iopl", 110 }, | |
164 | { "ioprio_get", 290 }, | |
165 | { "ioprio_set", 289 }, | |
166 | { "ipc", 117 }, | |
167 | { "kcmp", 349 }, | |
168 | { "kexec_load", 283 }, | |
169 | { "keyctl", 288 }, | |
170 | { "kill", 37 }, | |
171 | { "lchown", 16 }, | |
172 | { "lchown32", 198 }, | |
173 | { "lgetxattr", 230 }, | |
174 | { "link", 9 }, | |
175 | { "linkat", 303 }, | |
176 | { "listen", __PNR_listen }, | |
177 | { "listxattr", 232 }, | |
178 | { "llistxattr", 233 }, | |
179 | { "_llseek", 140 }, | |
180 | { "lock", 53 }, | |
181 | { "lookup_dcookie", 253 }, | |
182 | { "lremovexattr", 236 }, | |
183 | { "lseek", 19 }, | |
184 | { "lsetxattr", 227 }, | |
185 | { "lstat", 107 }, | |
186 | { "lstat64", 196 }, | |
187 | { "madvise", 219 }, | |
188 | { "mbind", 274 }, | |
189 | { "migrate_pages", 294 }, | |
190 | { "mincore", 218 }, | |
191 | { "mkdir", 39 }, | |
192 | { "mkdirat", 296 }, | |
193 | { "mknod", 14 }, | |
194 | { "mknodat", 297 }, | |
195 | { "mlock", 150 }, | |
196 | { "mlockall", 152 }, | |
197 | { "mmap", 90 }, | |
198 | { "mmap2", 192 }, | |
199 | { "modify_ldt", 123 }, | |
200 | { "mount", 21 }, | |
201 | { "move_pages", 317 }, | |
202 | { "mprotect", 125 }, | |
203 | { "mpx", 56 }, | |
204 | { "mq_getsetattr", 282 }, | |
205 | { "mq_notify", 281 }, | |
206 | { "mq_open", 277 }, | |
207 | { "mq_timedreceive", 280 }, | |
208 | { "mq_timedsend", 279 }, | |
209 | { "mq_unlink", 278 }, | |
210 | { "mremap", 163 }, | |
211 | { "msgctl", __PNR_msgctl }, | |
212 | { "msgget", __PNR_msgget }, | |
213 | { "msgrcv", __PNR_msgrcv }, | |
214 | { "msgsnd", __PNR_msgsnd }, | |
215 | { "msync", 144 }, | |
216 | { "munlock", 151 }, | |
217 | { "munlockall", 153 }, | |
218 | { "munmap", 91 }, | |
219 | { "name_to_handle_at", 341 }, | |
220 | { "nanosleep", 162 }, | |
221 | { "_newselect", 142 }, | |
222 | { "newfstatat", __PNR_newfstatat }, | |
223 | { "nfsservctl", 169 }, | |
224 | { "nice", 34 }, | |
225 | { "oldfstat", 28 }, | |
226 | { "oldlstat", 84 }, | |
227 | { "oldolduname", 59 }, | |
228 | { "oldstat", 18 }, | |
229 | { "olduname", 109 }, | |
230 | { "open", 5 }, | |
231 | { "open_by_handle_at", 342 }, | |
232 | { "openat", 295 }, | |
233 | { "pause", 29 }, | |
234 | { "pciconfig_iobase", __PNR_pciconfig_iobase }, | |
235 | { "pciconfig_read", __PNR_pciconfig_read }, | |
236 | { "pciconfig_write", __PNR_pciconfig_write }, | |
237 | { "perf_event_open", 336 }, | |
238 | { "personality", 136 }, | |
239 | { "pipe", 42 }, | |
240 | { "pipe2", 331 }, | |
241 | { "pivot_root", 217 }, | |
242 | { "poll", 168 }, | |
243 | { "ppoll", 309 }, | |
244 | { "prctl", 172 }, | |
245 | { "pread64", 180 }, | |
246 | { "preadv", 333 }, | |
247 | { "prlimit64", 340 }, | |
248 | { "process_vm_readv", 347 }, | |
249 | { "process_vm_writev", 348 }, | |
250 | { "prof", 44 }, | |
251 | { "profil", 98 }, | |
252 | { "pselect6", 308 }, | |
253 | { "ptrace", 26 }, | |
254 | { "putpmsg", 189 }, | |
255 | { "pwrite64", 181 }, | |
256 | { "pwritev", 334 }, | |
257 | { "query_module", 167 }, | |
258 | { "quotactl", 131 }, | |
259 | { "read", 3 }, | |
260 | { "readahead", 225 }, | |
261 | { "readdir", 89 }, | |
262 | { "readlink", 85 }, | |
263 | { "readlinkat", 305 }, | |
264 | { "readv", 145 }, | |
265 | { "reboot", 88 }, | |
266 | { "recv", __PNR_recv }, | |
267 | { "recvfrom", __PNR_recvfrom }, | |
268 | { "recvmmsg", 337 }, | |
269 | { "recvmsg", __PNR_recvmsg }, | |
270 | { "remap_file_pages", 257 }, | |
271 | { "removexattr", 235 }, | |
272 | { "rename", 38 }, | |
273 | { "renameat", 302 }, | |
274 | { "request_key", 287 }, | |
275 | { "restart_syscall", 0 }, | |
276 | { "rmdir", 40 }, | |
277 | { "rt_sigaction", 174 }, | |
278 | { "rt_sigpending", 176 }, | |
279 | { "rt_sigprocmask", 175 }, | |
280 | { "rt_sigqueueinfo", 178 }, | |
281 | { "rt_sigreturn", 173 }, | |
282 | { "rt_sigsuspend", 179 }, | |
283 | { "rt_sigtimedwait", 177 }, | |
284 | { "rt_tgsigqueueinfo", 335 }, | |
285 | { "sched_get_priority_max", 159 }, | |
286 | { "sched_get_priority_min", 160 }, | |
287 | { "sched_getaffinity", 242 }, | |
288 | { "sched_getparam", 155 }, | |
289 | { "sched_getscheduler", 157 }, | |
290 | { "sched_rr_get_interval", 161 }, | |
291 | { "sched_setaffinity", 241 }, | |
292 | { "sched_setparam", 154 }, | |
293 | { "sched_setscheduler", 156 }, | |
294 | { "sched_yield", 158 }, | |
295 | { "security", __PNR_security }, | |
296 | { "select", 82 }, | |
297 | { "semctl", __PNR_semctl }, | |
298 | { "semget", __PNR_semget }, | |
299 | { "semop", __PNR_semop }, | |
300 | { "semtimedop", __PNR_semtimedop }, | |
301 | { "send", __PNR_send }, | |
302 | { "sendfile", 187 }, | |
303 | { "sendfile64", 239 }, | |
304 | { "sendmmsg", 345 }, | |
305 | { "sendmsg", __PNR_sendmsg }, | |
306 | { "sendto", __PNR_sendto }, | |
307 | { "set_mempolicy", 276 }, | |
308 | { "set_robust_list", 311 }, | |
309 | { "set_thread_area", 243 }, | |
310 | { "set_tid_address", 258 }, | |
311 | { "setdomainname", 121 }, | |
312 | { "setfsgid", 139 }, | |
313 | { "setfsgid32", 216 }, | |
314 | { "setfsuid", 138 }, | |
315 | { "setfsuid32", 215 }, | |
316 | { "setgid", 46 }, | |
317 | { "setgid32", 214 }, | |
318 | { "setgroups", 81 }, | |
319 | { "setgroups32", 206 }, | |
320 | { "sethostname", 74 }, | |
321 | { "setitimer", 104 }, | |
322 | { "setns", 346 }, | |
323 | { "setpgid", 57 }, | |
324 | { "setpriority", 97 }, | |
325 | { "setregid", 71 }, | |
326 | { "setregid32", 204 }, | |
327 | { "setresgid", 170 }, | |
328 | { "setresgid32", 210 }, | |
329 | { "setresuid", 164 }, | |
330 | { "setresuid32", 208 }, | |
331 | { "setreuid", 70 }, | |
332 | { "setreuid32", 203 }, | |
333 | { "setrlimit", 75 }, | |
334 | { "setsid", 66 }, | |
335 | { "setsockopt", __PNR_setsockopt }, | |
336 | { "settimeofday", 79 }, | |
337 | { "setuid", 23 }, | |
338 | { "setuid32", 213 }, | |
339 | { "setxattr", 226 }, | |
340 | { "sgetmask", 68 }, | |
341 | { "shmat", __PNR_shmat }, | |
342 | { "shmctl", __PNR_shmctl }, | |
343 | { "shmdt", __PNR_shmdt }, | |
344 | { "shmget", __PNR_shmget }, | |
345 | { "shutdown", __PNR_shutdown }, | |
346 | { "sigaction", 67 }, | |
347 | { "sigaltstack", 186 }, | |
348 | { "signal", 48 }, | |
349 | { "signalfd", 321 }, | |
350 | { "signalfd4", 327 }, | |
351 | { "sigpending", 73 }, | |
352 | { "sigprocmask", 126 }, | |
353 | { "sigreturn", 119 }, | |
354 | { "sigsuspend", 72 }, | |
355 | { "socket", __PNR_socket }, | |
356 | { "socketcall", 102 }, | |
357 | { "socketpair", __PNR_socketpair }, | |
358 | { "splice", 313 }, | |
359 | { "ssetmask", 69 }, | |
360 | { "stat", 106 }, | |
361 | { "stat64", 195 }, | |
362 | { "statfs", 99 }, | |
363 | { "statfs64", 268 }, | |
364 | { "stime", 25 }, | |
365 | { "stty", 31 }, | |
366 | { "swapoff", 115 }, | |
367 | { "swapon", 87 }, | |
368 | { "symlink", 83 }, | |
369 | { "symlinkat", 304 }, | |
370 | { "sync", 36 }, | |
371 | { "sync_file_range", 314 }, | |
372 | { "sync_file_range2", __PNR_sync_file_range2 }, | |
373 | { "syncfs", 344 }, | |
374 | { "syscall", __PNR_syscall }, | |
375 | { "_sysctl", 149 }, | |
376 | { "sysfs", 135 }, | |
377 | { "sysinfo", 116 }, | |
378 | { "syslog", 103 }, | |
379 | { "tee", 315 }, | |
380 | { "tgkill", 270 }, | |
381 | { "time", 13 }, | |
382 | { "timer_create", 259 }, | |
383 | { "timer_delete", 263 }, | |
384 | { "timer_getoverrun", 262 }, | |
385 | { "timer_gettime", 261 }, | |
386 | { "timer_settime", 260 }, | |
387 | { "timerfd_create", 322 }, | |
388 | { "timerfd_gettime", 326 }, | |
389 | { "timerfd_settime", 325 }, | |
390 | { "times", 43 }, | |
391 | { "tkill", 238 }, | |
392 | { "truncate", 92 }, | |
393 | { "truncate64", 193 }, | |
394 | { "tuxcall", __PNR_tuxcall }, | |
395 | { "ugetrlimit", 191 }, | |
396 | { "ulimit", 58 }, | |
397 | { "umask", 60 }, | |
398 | { "umount", 22 }, | |
399 | { "umount2", 52 }, | |
400 | { "uname", 122 }, | |
401 | { "unlink", 10 }, | |
402 | { "unlinkat", 301 }, | |
403 | { "unshare", 310 }, | |
404 | { "uselib", 86 }, | |
405 | { "ustat", 62 }, | |
406 | { "utime", 30 }, | |
407 | { "utimensat", 320 }, | |
408 | { "utimes", 271 }, | |
409 | { "vfork", 190 }, | |
410 | { "vhangup", 111 }, | |
411 | { "vm86", 166 }, | |
412 | { "vm86old", 113 }, | |
413 | { "vmsplice", 316 }, | |
414 | { "vserver", 273 }, | |
415 | { "wait4", 114 }, | |
416 | { "waitid", 284 }, | |
417 | { "waitpid", 7 }, | |
418 | { "write", 4 }, | |
419 | { "writev", 146 }, | |
420 | { NULL, __NR_SCMP_ERROR }, | |
421 | }; | |
422 | ||
423 | /** | |
424 | * Resolve a syscall name to a number | |
425 | * @param name the syscall name | |
426 | * | |
427 | * Resolve the given syscall name to the syscall number using the syscall table. | |
428 | * Returns the syscall number on success, including negative pseudo syscall | |
429 | * numbers; returns __NR_SCMP_ERROR on failure. | |
430 | * | |
431 | */ | |
432 | int x86_syscall_resolve_name(const char *name) | |
433 | { | |
434 | unsigned int iter; | |
435 | const struct arch_syscall_def *table = x86_syscall_table; | |
436 | ||
437 | /* XXX - plenty of room for future improvement here */ | |
438 | for (iter = 0; table[iter].name != NULL; iter++) { | |
439 | if (strcmp(name, table[iter].name) == 0) | |
440 | return table[iter].num; | |
441 | } | |
442 | ||
443 | return __NR_SCMP_ERROR; | |
444 | } | |
445 | ||
446 | /** | |
447 | * Resolve a syscall number to a name | |
448 | * @param num the syscall number | |
449 | * | |
450 | * Resolve the given syscall number to the syscall name using the syscall table. | |
451 | * Returns a pointer to the syscall name string on success, including pseudo | |
452 | * syscall names; returns NULL on failure. | |
453 | * | |
454 | */ | |
455 | const char *x86_syscall_resolve_num(int num) | |
456 | { | |
457 | unsigned int iter; | |
458 | const struct arch_syscall_def *table = x86_syscall_table; | |
459 | ||
460 | /* XXX - plenty of room for future improvement here */ | |
461 | for (iter = 0; table[iter].num != __NR_SCMP_ERROR; iter++) { | |
462 | if (num == table[iter].num) | |
463 | return table[iter].name; | |
464 | } | |
465 | ||
466 | return NULL; | |
467 | } |
0 | /** | |
1 | * Enhanced Seccomp x86 Specific Code | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <stdlib.h> | |
22 | #include <errno.h> | |
23 | #include <linux/audit.h> | |
24 | ||
25 | #include "arch.h" | |
26 | #include "arch-x86.h" | |
27 | ||
28 | /* x86 syscall numbers */ | |
29 | #define __x86_NR_socketcall 102 | |
30 | #define __x86_NR_ipc 117 | |
31 | ||
32 | const struct arch_def arch_def_x86 = { | |
33 | .token = SCMP_ARCH_X86, | |
34 | .token_bpf = AUDIT_ARCH_I386, | |
35 | .size = ARCH_SIZE_32, | |
36 | .endian = ARCH_ENDIAN_LITTLE, | |
37 | }; | |
38 | ||
39 | /** | |
40 | * Rewrite a syscall value to match the architecture | |
41 | * @param arch the architecture definition | |
42 | * @param strict strict flag | |
43 | * @param syscall the syscall number | |
44 | * | |
45 | * Syscalls can vary across different architectures so this function rewrites | |
46 | * the syscall into the correct value for the specified architecture. If | |
47 | * @strict is true then the function will fail if the syscall can not be | |
48 | * preservered, however, if @strict is false the function will do a "best | |
49 | * effort" rewrite and not fail. Returns zero on success, negative values on | |
50 | * failure. | |
51 | * | |
52 | */ | |
53 | int x86_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall) | |
54 | { | |
55 | if ((*syscall) <= -100 && (*syscall) >= -117) | |
56 | *syscall = __x86_NR_socketcall; | |
57 | else if ((*syscall) <= -200 && (*syscall) >= -211) | |
58 | *syscall = __x86_NR_ipc; | |
59 | else if (((*syscall) < 0) && (strict)) | |
60 | return -EDOM; | |
61 | ||
62 | return 0; | |
63 | } | |
64 | ||
65 | /** | |
66 | * Rewrite a filter rule to match the architecture specifics | |
67 | * @param arch the architecture definition | |
68 | * @param strict strict flag | |
69 | * @param syscall the syscall number | |
70 | * @param chain the argument filter chain | |
71 | * | |
72 | * Syscalls can vary across different architectures so this function handles | |
73 | * the necessary seccomp rule rewrites to ensure the right thing is done | |
74 | * regardless of the rule or architecture. If @strict is true then the | |
75 | * function will fail if the entire filter can not be preservered, however, | |
76 | * if @strict is false the function will do a "best effort" rewrite and not | |
77 | * fail. Returns zero on success, negative values on failure. | |
78 | * | |
79 | */ | |
80 | int x86_filter_rewrite(const struct arch_def *arch, bool strict, | |
81 | int *syscall, struct db_api_arg *chain) | |
82 | { | |
83 | unsigned int iter; | |
84 | ||
85 | if ((*syscall) <= -100 && (*syscall) >= -117) { | |
86 | for (iter = 0; iter < x86_arg_count_max; iter++) { | |
87 | if ((chain[iter].valid != 0) && (strict)) | |
88 | return -EINVAL; | |
89 | } | |
90 | chain[0].arg = 0; | |
91 | chain[0].op = SCMP_CMP_EQ; | |
92 | chain[0].mask = DATUM_MAX; | |
93 | chain[0].datum = abs(*syscall) % 100; | |
94 | chain[0].valid = 1; | |
95 | *syscall = __x86_NR_socketcall; | |
96 | } else if ((*syscall) <= -200 && (*syscall) >= -211) { | |
97 | for (iter = 0; iter < x86_arg_count_max; iter++) { | |
98 | if ((chain[iter].valid != 0) && (strict)) | |
99 | return -EINVAL; | |
100 | } | |
101 | chain[0].arg = 0; | |
102 | chain[0].op = SCMP_CMP_EQ; | |
103 | chain[0].mask = DATUM_MAX; | |
104 | chain[0].datum = abs(*syscall) % 200; | |
105 | chain[0].valid = 1; | |
106 | *syscall = __x86_NR_ipc; | |
107 | } else if (((*syscall) < 0) && (strict)) | |
108 | return -EDOM; | |
109 | ||
110 | return 0; | |
111 | } |
0 | /** | |
1 | * Enhanced Seccomp x86 Specific Code | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #ifndef _ARCH_X86_H | |
22 | #define _ARCH_X86_H | |
23 | ||
24 | #include <stdbool.h> | |
25 | ||
26 | #include "arch.h" | |
27 | #include "db.h" | |
28 | #include "system.h" | |
29 | ||
30 | #define x86_arg_count_max 6 | |
31 | ||
32 | extern const struct arch_def arch_def_x86; | |
33 | ||
34 | int x86_syscall_resolve_name(const char *name); | |
35 | const char *x86_syscall_resolve_num(int num); | |
36 | ||
37 | int x86_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall); | |
38 | ||
39 | int x86_filter_rewrite(const struct arch_def *arch, bool strict, | |
40 | int *syscall, struct db_api_arg *chain); | |
41 | ||
42 | #endif |
0 | /** | |
1 | * Enhanced Seccomp x86_64 Syscall Table | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <string.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "arch.h" | |
26 | #include "arch-x86_64.h" | |
27 | ||
28 | /* NOTE: based on Linux 3.4.7 */ | |
29 | const struct arch_syscall_def x86_64_syscall_table[] = { \ | |
30 | { "accept", 43 }, | |
31 | { "accept4", 288 }, | |
32 | { "access", 21 }, | |
33 | { "acct", 163 }, | |
34 | { "add_key", 248 }, | |
35 | { "adjtimex", 159 }, | |
36 | { "afs_syscall", 183 }, | |
37 | { "alarm", 37 }, | |
38 | { "arm_fadvise64_64", __PNR_arm_fadvise64_64 }, | |
39 | { "arm_sync_file_range", __PNR_arm_sync_file_range }, | |
40 | { "arch_prctl", 158 }, | |
41 | { "bdflush", __PNR_bdflush }, | |
42 | { "bind", 49 }, | |
43 | { "break", __PNR_break }, | |
44 | { "brk", 12 }, | |
45 | { "capget", 125 }, | |
46 | { "capset", 126 }, | |
47 | { "chdir", 80 }, | |
48 | { "chmod", 90 }, | |
49 | { "chown", 92 }, | |
50 | { "chown32", __PNR_chown32 }, | |
51 | { "chroot", 161 }, | |
52 | { "clock_adjtime", 305 }, | |
53 | { "clock_getres", 229 }, | |
54 | { "clock_gettime", 228 }, | |
55 | { "clock_nanosleep", 230 }, | |
56 | { "clock_settime", 227 }, | |
57 | { "clone", 56 }, | |
58 | { "close", 3 }, | |
59 | { "connect", 42 }, | |
60 | { "creat", 85 }, | |
61 | { "create_module", 174 }, | |
62 | { "delete_module", 176 }, | |
63 | { "dup", 32 }, | |
64 | { "dup2", 33 }, | |
65 | { "dup3", 292 }, | |
66 | { "epoll_create", 213 }, | |
67 | { "epoll_create1", 291 }, | |
68 | { "epoll_ctl", 233 }, | |
69 | { "epoll_ctl_old", 214 }, | |
70 | { "epoll_pwait", 281 }, | |
71 | { "epoll_wait", 232 }, | |
72 | { "epoll_wait_old", 215 }, | |
73 | { "eventfd", 284 }, | |
74 | { "eventfd2", 290 }, | |
75 | { "execve", 59 }, | |
76 | { "exit", 60 }, | |
77 | { "exit_group", 231 }, | |
78 | { "faccessat", 269 }, | |
79 | { "fadvise64", 221 }, | |
80 | { "fadvise64_64", __PNR_fadvise64_64 }, | |
81 | { "fallocate", 285 }, | |
82 | { "fanotify_init", 300 }, | |
83 | { "fanotify_mark", 301 }, | |
84 | { "fchdir", 81 }, | |
85 | { "fchmod", 91 }, | |
86 | { "fchmodat", 268 }, | |
87 | { "fchown", 93 }, | |
88 | { "fchown32", __PNR_fchown32 }, | |
89 | { "fchownat", 260 }, | |
90 | { "fcntl", 72 }, | |
91 | { "fcntl64", __PNR_fcntl64 }, | |
92 | { "fdatasync", 75 }, | |
93 | { "fgetxattr", 193 }, | |
94 | { "finit_module", __PNR_finit_module }, | |
95 | { "flistxattr", 196 }, | |
96 | { "flock", 73 }, | |
97 | { "fork", 57 }, | |
98 | { "fremovexattr", 199 }, | |
99 | { "fsetxattr", 190 }, | |
100 | { "fstat", 5 }, | |
101 | { "fstat64", __PNR_fstat64 }, | |
102 | { "fstatat64", __PNR_fstatat64 }, | |
103 | { "fstatfs", 138 }, | |
104 | { "fstatfs64", __PNR_fstatfs64 }, | |
105 | { "fsync", 74 }, | |
106 | { "ftime", __PNR_ftime }, | |
107 | { "ftruncate", 77 }, | |
108 | { "ftruncate64", __PNR_ftruncate64 }, | |
109 | { "futex", 202 }, | |
110 | { "futimesat", 261 }, | |
111 | { "get_kernel_syms", 177 }, | |
112 | { "get_mempolicy", 239 }, | |
113 | { "get_robust_list", 274 }, | |
114 | { "get_thread_area", 211 }, | |
115 | { "getcpu", 309 }, | |
116 | { "getcwd", 79 }, | |
117 | { "getdents", 78 }, | |
118 | { "getdents64", 217 }, | |
119 | { "getegid", 108 }, | |
120 | { "getegid32", __PNR_getegid32 }, | |
121 | { "geteuid", 107 }, | |
122 | { "geteuid32", __PNR_geteuid32 }, | |
123 | { "getgid", 104 }, | |
124 | { "getgid32", __PNR_getgid32 }, | |
125 | { "getgroups", 115 }, | |
126 | { "getgroups32", __PNR_getgroups32 }, | |
127 | { "getitimer", 36 }, | |
128 | { "getpeername", 52 }, | |
129 | { "getpgid", 121 }, | |
130 | { "getpgrp", 111 }, | |
131 | { "getpid", 39 }, | |
132 | { "getpmsg", 181 }, | |
133 | { "getppid", 110 }, | |
134 | { "getpriority", 140 }, | |
135 | { "getresgid", 120 }, | |
136 | { "getresgid32", __PNR_getresgid32 }, | |
137 | { "getresuid", 118 }, | |
138 | { "getresuid32", __PNR_getresuid32 }, | |
139 | { "getrlimit", 97 }, | |
140 | { "getrusage", 98 }, | |
141 | { "getsid", 124 }, | |
142 | { "getsockname", 51 }, | |
143 | { "getsockopt", 55 }, | |
144 | { "gettid", 186 }, | |
145 | { "gettimeofday", 96 }, | |
146 | { "getuid", 102 }, | |
147 | { "getuid32", __PNR_getuid32 }, | |
148 | { "getxattr", 191 }, | |
149 | { "gtty", __PNR_gtty }, | |
150 | { "idle", __PNR_idle }, | |
151 | { "init_module", 175 }, | |
152 | { "inotify_add_watch", 254 }, | |
153 | { "inotify_init", 253 }, | |
154 | { "inotify_init1", 294 }, | |
155 | { "inotify_rm_watch", 255 }, | |
156 | { "io_cancel", 210 }, | |
157 | { "io_destroy", 207 }, | |
158 | { "io_getevents", 208 }, | |
159 | { "io_setup", 206 }, | |
160 | { "io_submit", 209 }, | |
161 | { "ioctl", 16 }, | |
162 | { "ioperm", 173 }, | |
163 | { "iopl", 172 }, | |
164 | { "ioprio_get", 252 }, | |
165 | { "ioprio_set", 251 }, | |
166 | { "ipc", __PNR_ipc }, | |
167 | { "kcmp", 312 }, | |
168 | { "kexec_load", 246 }, | |
169 | { "keyctl", 250 }, | |
170 | { "kill", 62 }, | |
171 | { "lchown", 94 }, | |
172 | { "lchown32", __PNR_lchown32 }, | |
173 | { "lgetxattr", 192 }, | |
174 | { "link", 86 }, | |
175 | { "linkat", 265 }, | |
176 | { "listen", 50 }, | |
177 | { "listxattr", 194 }, | |
178 | { "llistxattr", 195 }, | |
179 | { "_llseek", __PNR__llseek }, | |
180 | { "lock", __PNR_lock }, | |
181 | { "lookup_dcookie", 212 }, | |
182 | { "lremovexattr", 198 }, | |
183 | { "lseek", 8 }, | |
184 | { "lsetxattr", 189 }, | |
185 | { "lstat", 6 }, | |
186 | { "lstat64", __PNR_lstat64 }, | |
187 | { "madvise", 28 }, | |
188 | { "mbind", 237 }, | |
189 | { "migrate_pages", 256 }, | |
190 | { "mincore", 27 }, | |
191 | { "mkdir", 83 }, | |
192 | { "mkdirat", 258 }, | |
193 | { "mknod", 133 }, | |
194 | { "mknodat", 259 }, | |
195 | { "mlock", 149 }, | |
196 | { "mlockall", 151 }, | |
197 | { "mmap", 9 }, | |
198 | { "mmap2", __PNR_mmap2 }, | |
199 | { "modify_ldt", 154 }, | |
200 | { "mount", 165 }, | |
201 | { "move_pages", 279 }, | |
202 | { "mprotect", 10 }, | |
203 | { "mpx", __PNR_mpx }, | |
204 | { "mq_getsetattr", 245 }, | |
205 | { "mq_notify", 244 }, | |
206 | { "mq_open", 240 }, | |
207 | { "mq_timedreceive", 243 }, | |
208 | { "mq_timedsend", 242 }, | |
209 | { "mq_unlink", 241 }, | |
210 | { "mremap", 25 }, | |
211 | { "msgctl", 71 }, | |
212 | { "msgget", 68 }, | |
213 | { "msgrcv", 70 }, | |
214 | { "msgsnd", 69 }, | |
215 | { "msync", 26 }, | |
216 | { "munlock", 150 }, | |
217 | { "munlockall", 152 }, | |
218 | { "munmap", 11 }, | |
219 | { "name_to_handle_at", 303 }, | |
220 | { "nanosleep", 35 }, | |
221 | { "_newselect", __PNR__newselect }, | |
222 | { "newfstatat", 262 }, | |
223 | { "nfsservctl", 180 }, | |
224 | { "nice", __PNR_nice }, | |
225 | { "oldfstat", __PNR_oldfstat }, | |
226 | { "oldlstat", __PNR_oldlstat }, | |
227 | { "oldolduname", __PNR_oldolduname }, | |
228 | { "oldstat", __PNR_oldstat }, | |
229 | { "olduname", __PNR_olduname }, | |
230 | { "open", 2 }, | |
231 | { "open_by_handle_at", 304 }, | |
232 | { "openat", 257 }, | |
233 | { "pause", 34 }, | |
234 | { "pciconfig_iobase", __PNR_pciconfig_iobase }, | |
235 | { "pciconfig_read", __PNR_pciconfig_read }, | |
236 | { "pciconfig_write", __PNR_pciconfig_write }, | |
237 | { "perf_event_open", 298 }, | |
238 | { "personality", 135 }, | |
239 | { "pipe", 22 }, | |
240 | { "pipe2", 293 }, | |
241 | { "pivot_root", 155 }, | |
242 | { "poll", 7 }, | |
243 | { "ppoll", 271 }, | |
244 | { "prctl", 157 }, | |
245 | { "pread64", 17 }, | |
246 | { "preadv", 295 }, | |
247 | { "prlimit64", 302 }, | |
248 | { "process_vm_readv", 310 }, | |
249 | { "process_vm_writev", 311 }, | |
250 | { "prof", __PNR_prof }, | |
251 | { "profil", __PNR_profil }, | |
252 | { "pselect6", 270 }, | |
253 | { "ptrace", 101 }, | |
254 | { "putpmsg", 182 }, | |
255 | { "pwrite64", 18 }, | |
256 | { "pwritev", 296 }, | |
257 | { "query_module", 178 }, | |
258 | { "quotactl", 179 }, | |
259 | { "read", 0 }, | |
260 | { "readahead", 187 }, | |
261 | { "readdir", __PNR_readdir }, | |
262 | { "readlink", 89 }, | |
263 | { "readlinkat", 267 }, | |
264 | { "readv", 19 }, | |
265 | { "reboot", 169 }, | |
266 | { "recv", __PNR_recv }, | |
267 | { "recvfrom", 45 }, | |
268 | { "recvmmsg", 299 }, | |
269 | { "recvmsg", 47 }, | |
270 | { "remap_file_pages", 216 }, | |
271 | { "removexattr", 197 }, | |
272 | { "rename", 82 }, | |
273 | { "renameat", 264 }, | |
274 | { "request_key", 249 }, | |
275 | { "restart_syscall", 219 }, | |
276 | { "rmdir", 84 }, | |
277 | { "rt_sigaction", 13 }, | |
278 | { "rt_sigpending", 127 }, | |
279 | { "rt_sigprocmask", 14 }, | |
280 | { "rt_sigqueueinfo", 129 }, | |
281 | { "rt_sigreturn", 15 }, | |
282 | { "rt_sigsuspend", 130 }, | |
283 | { "rt_sigtimedwait", 128 }, | |
284 | { "rt_tgsigqueueinfo", 297 }, | |
285 | { "sched_get_priority_max", 146 }, | |
286 | { "sched_get_priority_min", 147 }, | |
287 | { "sched_getaffinity", 204 }, | |
288 | { "sched_getparam", 143 }, | |
289 | { "sched_getscheduler", 145 }, | |
290 | { "sched_rr_get_interval", 148 }, | |
291 | { "sched_setaffinity", 203 }, | |
292 | { "sched_setparam", 142 }, | |
293 | { "sched_setscheduler", 144 }, | |
294 | { "sched_yield", 24 }, | |
295 | { "security", 185 }, | |
296 | { "select", 23 }, | |
297 | { "semctl", 66 }, | |
298 | { "semget", 64 }, | |
299 | { "semop", 65 }, | |
300 | { "semtimedop", 220 }, | |
301 | { "send", __PNR_send }, | |
302 | { "sendfile", 40 }, | |
303 | { "sendfile64", __PNR_sendfile64 }, | |
304 | { "sendmmsg", 307 }, | |
305 | { "sendmsg", 46 }, | |
306 | { "sendto", 44 }, | |
307 | { "set_mempolicy", 238 }, | |
308 | { "set_robust_list", 273 }, | |
309 | { "set_thread_area", 205 }, | |
310 | { "set_tid_address", 218 }, | |
311 | { "setdomainname", 171 }, | |
312 | { "setfsgid", 123 }, | |
313 | { "setfsgid32", __PNR_setfsgid32 }, | |
314 | { "setfsuid", 122 }, | |
315 | { "setfsuid32", __PNR_setfsuid32 }, | |
316 | { "setgid", 106 }, | |
317 | { "setgid32", __PNR_setgid32 }, | |
318 | { "setgroups", 116 }, | |
319 | { "setgroups32", __PNR_setgroups32 }, | |
320 | { "sethostname", 170 }, | |
321 | { "setitimer", 38 }, | |
322 | { "setns", 308 }, | |
323 | { "setpgid", 109 }, | |
324 | { "setpriority", 141 }, | |
325 | { "setregid", 114 }, | |
326 | { "setregid32", __PNR_setregid32 }, | |
327 | { "setresgid", 119 }, | |
328 | { "setresgid32", __PNR_setresgid32 }, | |
329 | { "setresuid", 117 }, | |
330 | { "setresuid32", __PNR_setresuid32 }, | |
331 | { "setreuid", 113 }, | |
332 | { "setreuid32", __PNR_setreuid32 }, | |
333 | { "setrlimit", 160 }, | |
334 | { "setsid", 112 }, | |
335 | { "setsockopt", 54 }, | |
336 | { "settimeofday", 164 }, | |
337 | { "setuid", 105 }, | |
338 | { "setuid32", __PNR_setuid32 }, | |
339 | { "setxattr", 188 }, | |
340 | { "sgetmask", __PNR_sgetmask }, | |
341 | { "shmat", 30 }, | |
342 | { "shmctl", 31 }, | |
343 | { "shmdt", 67 }, | |
344 | { "shmget", 29 }, | |
345 | { "shutdown", 48 }, | |
346 | { "sigaction", __PNR_sigaction }, | |
347 | { "sigaltstack", 131 }, | |
348 | { "signal", __PNR_signal }, | |
349 | { "signalfd", 282 }, | |
350 | { "signalfd4", 289 }, | |
351 | { "sigpending", __PNR_sigpending }, | |
352 | { "sigprocmask", __PNR_sigprocmask }, | |
353 | { "sigreturn", __PNR_sigreturn }, | |
354 | { "sigsuspend", __PNR_sigsuspend }, | |
355 | { "socket", 41 }, | |
356 | { "socketcall", __PNR_socketcall }, | |
357 | { "socketpair", 53 }, | |
358 | { "splice", 275 }, | |
359 | { "ssetmask", __PNR_ssetmask }, | |
360 | { "stat", 4 }, | |
361 | { "stat64", __PNR_stat64 }, | |
362 | { "statfs", 137 }, | |
363 | { "statfs64", __PNR_statfs64 }, | |
364 | { "stime", __PNR_stime }, | |
365 | { "stty", __PNR_stty }, | |
366 | { "swapoff", 168 }, | |
367 | { "swapon", 167 }, | |
368 | { "symlink", 88 }, | |
369 | { "symlinkat", 266 }, | |
370 | { "sync", 162 }, | |
371 | { "sync_file_range", 277 }, | |
372 | { "sync_file_range2", __PNR_sync_file_range2 }, | |
373 | { "syncfs", 306 }, | |
374 | { "syscall", __PNR_syscall }, | |
375 | { "_sysctl", 156 }, | |
376 | { "sysfs", 139 }, | |
377 | { "sysinfo", 99 }, | |
378 | { "syslog", 103 }, | |
379 | { "tee", 276 }, | |
380 | { "tgkill", 234 }, | |
381 | { "time", 201 }, | |
382 | { "timer_create", 222 }, | |
383 | { "timer_delete", 226 }, | |
384 | { "timer_getoverrun", 225 }, | |
385 | { "timer_gettime", 224 }, | |
386 | { "timer_settime", 223 }, | |
387 | { "timerfd_create", 283 }, | |
388 | { "timerfd_gettime", 287 }, | |
389 | { "timerfd_settime", 286 }, | |
390 | { "times", 100 }, | |
391 | { "tkill", 200 }, | |
392 | { "truncate", 76 }, | |
393 | { "truncate64", __PNR_truncate64 }, | |
394 | { "tuxcall", 184 }, | |
395 | { "ugetrlimit", __PNR_ugetrlimit }, | |
396 | { "ulimit", __PNR_ulimit }, | |
397 | { "umask", 95 }, | |
398 | { "umount", __PNR_umount }, | |
399 | { "umount2", 166 }, | |
400 | { "uname", 63 }, | |
401 | { "unlink", 87 }, | |
402 | { "unlinkat", 263 }, | |
403 | { "unshare", 272 }, | |
404 | { "uselib", 134 }, | |
405 | { "ustat", 136 }, | |
406 | { "utime", 132 }, | |
407 | { "utimensat", 280 }, | |
408 | { "utimes", 235 }, | |
409 | { "vfork", 58 }, | |
410 | { "vhangup", 153 }, | |
411 | { "vm86", __PNR_vm86 }, | |
412 | { "vm86old", __PNR_vm86old }, | |
413 | { "vmsplice", 278 }, | |
414 | { "vserver", 236 }, | |
415 | { "wait4", 61 }, | |
416 | { "waitid", 247 }, | |
417 | { "waitpid", __PNR_waitpid }, | |
418 | { "write", 1 }, | |
419 | { "writev", 20 }, | |
420 | { NULL, __NR_SCMP_ERROR }, | |
421 | }; | |
422 | ||
423 | /** | |
424 | * Resolve a syscall name to a number | |
425 | * @param name the syscall name | |
426 | * | |
427 | * Resolve the given syscall name to the syscall number using the syscall table. | |
428 | * Returns the syscall number on success, including negative pseudo syscall | |
429 | * numbers; returns __NR_SCMP_ERROR on failure. | |
430 | * | |
431 | */ | |
432 | int x86_64_syscall_resolve_name(const char *name) | |
433 | { | |
434 | unsigned int iter; | |
435 | const struct arch_syscall_def *table = x86_64_syscall_table; | |
436 | ||
437 | /* XXX - plenty of room for future improvement here */ | |
438 | for (iter = 0; table[iter].name != NULL; iter++) { | |
439 | if (strcmp(name, table[iter].name) == 0) | |
440 | return table[iter].num; | |
441 | } | |
442 | ||
443 | return __NR_SCMP_ERROR; | |
444 | } | |
445 | ||
446 | /** | |
447 | * Resolve a syscall number to a name | |
448 | * @param num the syscall number | |
449 | * | |
450 | * Resolve the given syscall number to the syscall name using the syscall table. | |
451 | * Returns a pointer to the syscall name string on success, including pseudo | |
452 | * syscall names; returns NULL on failure. | |
453 | * | |
454 | */ | |
455 | const char *x86_64_syscall_resolve_num(int num) | |
456 | { | |
457 | unsigned int iter; | |
458 | const struct arch_syscall_def *table = x86_64_syscall_table; | |
459 | ||
460 | /* XXX - plenty of room for future improvement here */ | |
461 | for (iter = 0; table[iter].num != __NR_SCMP_ERROR; iter++) { | |
462 | if (num == table[iter].num) | |
463 | return table[iter].name; | |
464 | } | |
465 | ||
466 | return NULL; | |
467 | } |
0 | /** | |
1 | * Enhanced Seccomp x86_64 Specific Code | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <stdlib.h> | |
22 | #include <errno.h> | |
23 | #include <linux/audit.h> | |
24 | ||
25 | #include "arch.h" | |
26 | #include "arch-x86_64.h" | |
27 | ||
28 | const struct arch_def arch_def_x86_64 = { | |
29 | .token = SCMP_ARCH_X86_64, | |
30 | .token_bpf = AUDIT_ARCH_X86_64, | |
31 | .size = ARCH_SIZE_64, | |
32 | .endian = ARCH_ENDIAN_LITTLE, | |
33 | }; |
0 | /** | |
1 | * Enhanced Seccomp x86_64 Specific Code | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #ifndef _ARCH_x86_64_H | |
22 | #define _ARCH_x86_64_H | |
23 | ||
24 | #include <inttypes.h> | |
25 | ||
26 | #include "arch.h" | |
27 | #include "system.h" | |
28 | ||
29 | #define x86_64_arg_count_max 6 | |
30 | ||
31 | extern const struct arch_def arch_def_x86_64; | |
32 | ||
33 | #define x86_64_arg_offset_lo(x) (arch_arg_offset(x)) | |
34 | #define x86_64_arg_offset_hi(x) (arch_arg_offset(x) + 4) | |
35 | ||
36 | int x86_64_syscall_resolve_name(const char *name); | |
37 | const char *x86_64_syscall_resolve_num(int num); | |
38 | ||
39 | #endif |
0 | /** | |
1 | * Enhanced Seccomp Architecture/Machine Specific Code | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <elf.h> | |
22 | #include <errno.h> | |
23 | #include <stdlib.h> | |
24 | #include <string.h> | |
25 | #include <asm/bitsperlong.h> | |
26 | #include <linux/audit.h> | |
27 | #include <stdbool.h> | |
28 | ||
29 | #include <seccomp.h> | |
30 | ||
31 | #include "arch.h" | |
32 | #include "arch-x86.h" | |
33 | #include "arch-x86_64.h" | |
34 | #include "arch-x32.h" | |
35 | #include "arch-arm.h" | |
36 | #include "system.h" | |
37 | ||
38 | #if __i386__ | |
39 | const struct arch_def *arch_def_native = &arch_def_x86; | |
40 | #elif __x86_64__ | |
41 | #ifdef __ILP32__ | |
42 | const struct arch_def *arch_def_native = &arch_def_x32; | |
43 | #else | |
44 | const struct arch_def *arch_def_native = &arch_def_x86_64; | |
45 | #endif /* __ILP32__ */ | |
46 | #elif __arm__ | |
47 | const struct arch_def *arch_def_native = &arch_def_arm; | |
48 | #else | |
49 | #error the arch code needs to know about your machine type | |
50 | #endif /* machine type guess */ | |
51 | ||
52 | /** | |
53 | * Validate the architecture token | |
54 | * @param arch the architecture token | |
55 | * | |
56 | * Verify the given architecture token; return zero if valid, -EINVAL if not. | |
57 | * | |
58 | */ | |
59 | int arch_valid(uint32_t arch) | |
60 | { | |
61 | switch (arch) { | |
62 | case SCMP_ARCH_X86: | |
63 | case SCMP_ARCH_X86_64: | |
64 | case SCMP_ARCH_X32: | |
65 | case SCMP_ARCH_ARM: | |
66 | return 0; | |
67 | } | |
68 | ||
69 | return -EINVAL; | |
70 | } | |
71 | ||
72 | /** | |
73 | * Lookup the architecture definition | |
74 | * @param token the architecure token | |
75 | * | |
76 | * Return the matching architecture definition, returns NULL on failure. | |
77 | * | |
78 | */ | |
79 | const struct arch_def *arch_def_lookup(uint32_t token) | |
80 | { | |
81 | switch (token) { | |
82 | case SCMP_ARCH_X86: | |
83 | return &arch_def_x86; | |
84 | case SCMP_ARCH_X86_64: | |
85 | return &arch_def_x86_64; | |
86 | case SCMP_ARCH_X32: | |
87 | return &arch_def_x32; | |
88 | case SCMP_ARCH_ARM: | |
89 | return &arch_def_arm; | |
90 | } | |
91 | ||
92 | return NULL; | |
93 | } | |
94 | ||
95 | /** | |
96 | * Determine the maximum number of syscall arguments | |
97 | * @param arch the architecture definition | |
98 | * | |
99 | * Determine the maximum number of syscall arguments for the given architecture. | |
100 | * Returns the number of arguments on success, negative values on failure. | |
101 | * | |
102 | */ | |
103 | int arch_arg_count_max(const struct arch_def *arch) | |
104 | { | |
105 | switch (arch->token) { | |
106 | case SCMP_ARCH_X86: | |
107 | return x86_arg_count_max; | |
108 | case SCMP_ARCH_X86_64: | |
109 | return x86_64_arg_count_max; | |
110 | case SCMP_ARCH_X32: | |
111 | return x32_arg_count_max; | |
112 | case SCMP_ARCH_ARM: | |
113 | return arm_arg_count_max; | |
114 | } | |
115 | ||
116 | return -EDOM; | |
117 | } | |
118 | ||
119 | /** | |
120 | * Determine the argument offset for the lower 32 bits | |
121 | * @param arch the architecture definition | |
122 | * @param arg the argument number | |
123 | * | |
124 | * Determine the correct offset for the low 32 bits of the given argument based | |
125 | * on the architecture definition. Returns the offset on success, negative | |
126 | * values on failure. | |
127 | * | |
128 | */ | |
129 | int arch_arg_offset_lo(const struct arch_def *arch, unsigned int arg) | |
130 | { | |
131 | switch (arch->token) { | |
132 | case SCMP_ARCH_X86_64: | |
133 | return x86_64_arg_offset_lo(arg); | |
134 | default: | |
135 | return -EDOM; | |
136 | } | |
137 | } | |
138 | ||
139 | /** | |
140 | * Determine the argument offset for the high 32 bits | |
141 | * @param arch the architecture definition | |
142 | * @param arg the argument number | |
143 | * | |
144 | * Determine the correct offset for the high 32 bits of the given argument | |
145 | * based on the architecture definition. Returns the offset on success, | |
146 | * negative values on failure. | |
147 | * | |
148 | */ | |
149 | int arch_arg_offset_hi(const struct arch_def *arch, unsigned int arg) | |
150 | { | |
151 | switch (arch->token) { | |
152 | case SCMP_ARCH_X86_64: | |
153 | return x86_64_arg_offset_hi(arg); | |
154 | default: | |
155 | return -EDOM; | |
156 | } | |
157 | } | |
158 | ||
159 | /** | |
160 | * Resolve a syscall name to a number | |
161 | * @param arch the architecture definition | |
162 | * @param name the syscall name | |
163 | * | |
164 | * Resolve the given syscall name to the syscall number based on the given | |
165 | * architecture. Returns the syscall number on success, including negative | |
166 | * pseudo syscall numbers; returns __NR_SCMP_ERROR on failure. | |
167 | * | |
168 | */ | |
169 | int arch_syscall_resolve_name(const struct arch_def *arch, const char *name) | |
170 | { | |
171 | switch (arch->token) { | |
172 | case SCMP_ARCH_X86: | |
173 | return x86_syscall_resolve_name(name); | |
174 | case SCMP_ARCH_X86_64: | |
175 | return x86_64_syscall_resolve_name(name); | |
176 | case SCMP_ARCH_X32: | |
177 | return x32_syscall_resolve_name(name); | |
178 | case SCMP_ARCH_ARM: | |
179 | return arm_syscall_resolve_name(name); | |
180 | } | |
181 | ||
182 | return __NR_SCMP_ERROR; | |
183 | } | |
184 | ||
185 | /** | |
186 | * Resolve a syscall number to a name | |
187 | * @param arch the architecture definition | |
188 | * @param num the syscall number | |
189 | * | |
190 | * Resolve the given syscall number to the syscall name based on the given | |
191 | * architecture. Returns a pointer to the syscall name string on success, | |
192 | * including pseudo syscall names; returns NULL on failure. | |
193 | * | |
194 | */ | |
195 | const char *arch_syscall_resolve_num(const struct arch_def *arch, int num) | |
196 | { | |
197 | switch (arch->token) { | |
198 | case SCMP_ARCH_X86: | |
199 | return x86_syscall_resolve_num(num); | |
200 | case SCMP_ARCH_X86_64: | |
201 | return x86_64_syscall_resolve_num(num); | |
202 | case SCMP_ARCH_X32: | |
203 | return x32_syscall_resolve_num(num); | |
204 | case SCMP_ARCH_ARM: | |
205 | return arm_syscall_resolve_num(num); | |
206 | } | |
207 | ||
208 | return NULL; | |
209 | } | |
210 | ||
211 | /** | |
212 | * Translate the syscall number | |
213 | * @param arch the architecture definition | |
214 | * @param syscall the syscall number | |
215 | * | |
216 | * Translate the syscall number, in the context of the native architecure, to | |
217 | * the provided architecure. Returns zero on success, negative values on | |
218 | * failure. | |
219 | * | |
220 | */ | |
221 | int arch_syscall_translate(const struct arch_def *arch, int *syscall) | |
222 | { | |
223 | int sc_num; | |
224 | const char *sc_name; | |
225 | ||
226 | if (arch->token != arch_def_native->token) { | |
227 | sc_name = arch_syscall_resolve_num(arch_def_native, *syscall); | |
228 | if (sc_name == NULL) | |
229 | return -EFAULT; | |
230 | ||
231 | sc_num = arch_syscall_resolve_name(arch, sc_name); | |
232 | if (sc_num == __NR_SCMP_ERROR) | |
233 | return -EFAULT; | |
234 | ||
235 | *syscall = sc_num; | |
236 | } | |
237 | ||
238 | return 0; | |
239 | } | |
240 | ||
241 | /** | |
242 | * Rewrite a syscall value to match the architecture | |
243 | * @param arch the architecture definition | |
244 | * @param strict strict flag | |
245 | * @param syscall the syscall number | |
246 | * | |
247 | * Syscalls can vary across different architectures so this function rewrites | |
248 | * the syscall into the correct value for the specified architecture. If | |
249 | * @strict is true then the function will fail if the syscall can not be | |
250 | * preservered, however, if @strict is false the function will do a "best | |
251 | * effort" rewrite and not fail. Returns zero on success, negative values on | |
252 | * failure. | |
253 | * | |
254 | */ | |
255 | int arch_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall) | |
256 | { | |
257 | int sys = *syscall; | |
258 | ||
259 | if (sys >= 0) { | |
260 | /* we shouldn't be here - no rewrite needed */ | |
261 | return 0; | |
262 | } else if (sys < 0 && sys > -100) { | |
263 | /* reserved values */ | |
264 | return -EINVAL; | |
265 | } else if (sys <= -100 && sys > -10000) { | |
266 | /* rewritable syscalls */ | |
267 | switch (arch->token) { | |
268 | case SCMP_ARCH_X86: | |
269 | return x86_syscall_rewrite(arch, strict, syscall); | |
270 | } | |
271 | /* NOTE: we fall through to the default handling (strict?) if | |
272 | * we don't support any rewriting for the architecture */ | |
273 | } | |
274 | ||
275 | /* syscalls not defined on this architecture */ | |
276 | if (strict) | |
277 | return -EDOM; | |
278 | return 0; | |
279 | } | |
280 | ||
281 | /** | |
282 | * Rewrite a filter rule to match the architecture specifics | |
283 | * @param arch the architecture definition | |
284 | * @param strict strict flag | |
285 | * @param syscall the syscall number | |
286 | * @param chain the argument filter chain | |
287 | * | |
288 | * Syscalls can vary across different architectures so this function handles | |
289 | * the necessary seccomp rule rewrites to ensure the right thing is done | |
290 | * regardless of the rule or architecture. If @strict is true then the | |
291 | * function will fail if the entire filter can not be preservered, however, | |
292 | * if @strict is false the function will do a "best effort" rewrite and not | |
293 | * fail. Returns zero on success, negative values on failure. | |
294 | * | |
295 | */ | |
296 | int arch_filter_rewrite(const struct arch_def *arch, | |
297 | bool strict, int *syscall, struct db_api_arg *chain) | |
298 | { | |
299 | int sys = *syscall; | |
300 | ||
301 | if (sys >= 0) { | |
302 | /* we shouldn't be here - no rewrite needed */ | |
303 | return 0; | |
304 | } else if (sys < 0 && sys > -100) { | |
305 | /* reserved values */ | |
306 | return -EINVAL; | |
307 | } else if (sys <= -100 && sys > -10000) { | |
308 | /* rewritable syscalls */ | |
309 | switch (arch->token) { | |
310 | case SCMP_ARCH_X86: | |
311 | return x86_filter_rewrite(arch, strict, syscall, chain); | |
312 | } | |
313 | /* NOTE: we fall through to the default handling (strict?) if | |
314 | * we don't support any rewriting for the architecture */ | |
315 | } | |
316 | ||
317 | /* syscalls not defined on this architecture */ | |
318 | if (strict) | |
319 | return -EDOM; | |
320 | return 0; | |
321 | } |
0 | /** | |
1 | * Enhanced Seccomp Architecture/Machine Specific Code | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #ifndef _ARCH_H | |
22 | #define _ARCH_H | |
23 | ||
24 | #include <inttypes.h> | |
25 | #include <stddef.h> | |
26 | #include <stdbool.h> | |
27 | ||
28 | #include <seccomp.h> | |
29 | ||
30 | #include "system.h" | |
31 | ||
32 | struct db_api_arg; | |
33 | ||
34 | struct arch_def { | |
35 | uint32_t token; | |
36 | uint32_t token_bpf; | |
37 | enum { | |
38 | ARCH_SIZE_UNSPEC = 0, | |
39 | ARCH_SIZE_32 = 32, | |
40 | ARCH_SIZE_64 = 64, | |
41 | } size; | |
42 | enum { | |
43 | ARCH_ENDIAN_UNSPEC = 0, | |
44 | ARCH_ENDIAN_LITTLE, | |
45 | ARCH_ENDIAN_BIG, | |
46 | } endian; | |
47 | }; | |
48 | ||
49 | /* arch_def for the current architecture */ | |
50 | extern const struct arch_def *arch_def_native; | |
51 | ||
52 | /* NOTE: Syscall mappings can be found by running the following commands | |
53 | * on the specific architecture's include file: | |
54 | * # gcc -E -dM <file> | grep '__NR_' | |
55 | * where <file> in many cases is /usr/include/asm/unistd.h, however, | |
56 | * depending on the architecture you may need to use a different header. | |
57 | * Further, you can automatically format this list for use as a struct | |
58 | * initializer with the following command: | |
59 | * # gcc -E -dM <file> | grep '__NR_' | \ | |
60 | * sed -e 's/#define[ \t]\+__NR_//' | sort | \ | |
61 | * sed -e 's/\([^ \t]\+\)\([ \t]\+\)\([0-9]\+\)/\t{ \"\1\", \3 },/' | |
62 | * Finally, when creating a table/array of this structure, the final | |
63 | * sentinel entry should be "{ NULL, __NR_SCMP_ERROR }"; see the existing | |
64 | * tables as an example. | |
65 | */ | |
66 | struct arch_syscall_def { | |
67 | const char *name; | |
68 | unsigned int num; | |
69 | }; | |
70 | ||
71 | #define DATUM_MAX ((scmp_datum_t)-1) | |
72 | #define D64_LO(x) ((uint32_t)((uint64_t)(x) & 0x00000000ffffffff)) | |
73 | #define D64_HI(x) ((uint32_t)((uint64_t)(x) >> 32)) | |
74 | ||
75 | #define ARG_COUNT_MAX 6 | |
76 | ||
77 | int arch_valid(uint32_t arch); | |
78 | ||
79 | const struct arch_def *arch_def_lookup(uint32_t token); | |
80 | ||
81 | int arch_arg_count_max(const struct arch_def *arch); | |
82 | ||
83 | /** | |
84 | * Determine the argument offset | |
85 | * @param _arg the argument number | |
86 | * | |
87 | * Return the correct offset of the given argument. | |
88 | * | |
89 | */ | |
90 | #define arch_arg_offset(_arg) (offsetof(struct seccomp_data, args[_arg])) | |
91 | ||
92 | int arch_arg_offset_lo(const struct arch_def *arch, unsigned int arg); | |
93 | int arch_arg_offset_hi(const struct arch_def *arch, unsigned int arg); | |
94 | ||
95 | int arch_syscall_resolve_name(const struct arch_def *arch, const char *name); | |
96 | const char *arch_syscall_resolve_num(const struct arch_def *arch, int num); | |
97 | ||
98 | int arch_syscall_translate(const struct arch_def *arch, int *syscall); | |
99 | int arch_syscall_rewrite(const struct arch_def *arch, bool strict, | |
100 | int *syscall); | |
101 | ||
102 | int arch_filter_rewrite(const struct arch_def *arch, | |
103 | bool strict, int *syscall, struct db_api_arg *chain); | |
104 | ||
105 | #endif |
0 | /** | |
1 | * Enhanced Seccomp Filter DB | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <assert.h> | |
22 | #include <errno.h> | |
23 | #include <inttypes.h> | |
24 | #include <stdlib.h> | |
25 | #include <string.h> | |
26 | #include <stdarg.h> | |
27 | ||
28 | #include <seccomp.h> | |
29 | ||
30 | #include "arch.h" | |
31 | #include "db.h" | |
32 | ||
33 | /* state values */ | |
34 | #define _DB_STA_VALID 0xA1B2C3D4 | |
35 | #define _DB_STA_FREED 0x1A2B3C4D | |
36 | ||
37 | /* the priority field is fairly simple - without any user hints, or in the case | |
38 | * of a hint "tie", we give higher priority to syscalls with less chain nodes | |
39 | * (filter is easier to evaluate) */ | |
40 | #define _DB_PRI_MASK_CHAIN 0x0000FFFF | |
41 | #define _DB_PRI_MASK_USER 0x00FF0000 | |
42 | #define _DB_PRI_USER(x) (((x) << 16) & _DB_PRI_MASK_USER) | |
43 | ||
44 | /* private structure for tracking the state of the sub-tree "pruning" */ | |
45 | struct db_prune_state { | |
46 | bool prefix_exist; | |
47 | bool prefix_new; | |
48 | bool matched; | |
49 | }; | |
50 | ||
51 | static unsigned int _db_tree_free(struct db_arg_chain_tree *tree); | |
52 | ||
53 | /** | |
54 | * Do not call this function directly, use _db_tree_free() instead | |
55 | */ | |
56 | static unsigned int __db_tree_free(struct db_arg_chain_tree *tree) | |
57 | { | |
58 | int cnt; | |
59 | ||
60 | if (tree == NULL || --(tree->refcnt) > 0) | |
61 | return 0; | |
62 | ||
63 | /* we assume the caller has ensured that 'tree->lvl_prv == NULL' */ | |
64 | cnt = __db_tree_free(tree->lvl_nxt); | |
65 | cnt += _db_tree_free(tree->nxt_t); | |
66 | cnt += _db_tree_free(tree->nxt_f); | |
67 | ||
68 | free(tree); | |
69 | return cnt + 1; | |
70 | } | |
71 | ||
72 | /** | |
73 | * Free a syscall filter argument chain tree | |
74 | * @param list the argument chain list | |
75 | * | |
76 | * This function frees a syscall argument chain list and returns the number of | |
77 | * nodes freed. | |
78 | * | |
79 | */ | |
80 | static unsigned int _db_tree_free(struct db_arg_chain_tree *tree) | |
81 | { | |
82 | struct db_arg_chain_tree *iter; | |
83 | ||
84 | if (tree == NULL) | |
85 | return 0; | |
86 | ||
87 | iter = tree; | |
88 | while (iter->lvl_prv != NULL) | |
89 | iter = iter->lvl_prv; | |
90 | ||
91 | return __db_tree_free(iter); | |
92 | } | |
93 | ||
94 | /** | |
95 | * Remove a node from an argument chain tree | |
96 | * @param tree the pointer to the tree | |
97 | * @param node the node to remove | |
98 | * | |
99 | * This function searches the tree looking for the node and removes it once | |
100 | * found. Returns the number of nodes freed. | |
101 | * | |
102 | */ | |
103 | static unsigned int _db_tree_remove(struct db_arg_chain_tree **tree, | |
104 | struct db_arg_chain_tree *node) | |
105 | { | |
106 | int cnt = 0; | |
107 | struct db_arg_chain_tree *c_iter; | |
108 | ||
109 | if (tree == NULL || *tree == NULL || node == NULL) | |
110 | return 0; | |
111 | ||
112 | c_iter = *tree; | |
113 | while (c_iter->lvl_prv != NULL) | |
114 | c_iter = c_iter->lvl_prv; | |
115 | ||
116 | do { | |
117 | if (c_iter == node || db_chain_zombie(c_iter)) { | |
118 | /* remove from the tree */ | |
119 | if (c_iter == *tree) { | |
120 | if (c_iter->lvl_prv != NULL) | |
121 | *tree = c_iter->lvl_prv; | |
122 | else | |
123 | *tree = c_iter->lvl_nxt; | |
124 | } | |
125 | if (c_iter->lvl_prv != NULL) | |
126 | c_iter->lvl_prv->lvl_nxt = c_iter->lvl_nxt; | |
127 | if (c_iter->lvl_nxt != NULL) | |
128 | c_iter->lvl_nxt->lvl_prv = c_iter->lvl_prv; | |
129 | ||
130 | /* free and return */ | |
131 | c_iter->lvl_prv = NULL; | |
132 | c_iter->lvl_nxt = NULL; | |
133 | cnt += _db_tree_free(c_iter); | |
134 | return cnt; | |
135 | } | |
136 | ||
137 | /* check the true/false sub-trees */ | |
138 | cnt += _db_tree_remove(&(c_iter->nxt_t), node); | |
139 | cnt += _db_tree_remove(&(c_iter->nxt_f), node); | |
140 | ||
141 | c_iter = c_iter->lvl_nxt; | |
142 | } while (c_iter != NULL); | |
143 | ||
144 | return cnt; | |
145 | } | |
146 | ||
147 | /** | |
148 | * Traverse a tree checking the action values | |
149 | * @param tree the pointer to the tree | |
150 | * @param action the action | |
151 | * | |
152 | * Traverse the tree inspecting each action to see if it matches the given | |
153 | * action. Returns zero if all actions match the given action, negative values | |
154 | * on failure. | |
155 | * | |
156 | */ | |
157 | static int _db_tree_act_check(struct db_arg_chain_tree *tree, uint32_t action) | |
158 | { | |
159 | int rc; | |
160 | struct db_arg_chain_tree *c_iter; | |
161 | ||
162 | if (tree == NULL) | |
163 | return 0; | |
164 | ||
165 | c_iter = tree; | |
166 | while (c_iter->lvl_prv != NULL) | |
167 | c_iter = c_iter->lvl_prv; | |
168 | ||
169 | do { | |
170 | if (c_iter->act_t_flg && c_iter->act_t != action) | |
171 | return -EEXIST; | |
172 | if (c_iter->act_f_flg && c_iter->act_f != action) | |
173 | return -EEXIST; | |
174 | ||
175 | rc = _db_tree_act_check(c_iter->nxt_t, action); | |
176 | if (rc < 0) | |
177 | return rc; | |
178 | rc = _db_tree_act_check(c_iter->nxt_f, action); | |
179 | if (rc < 0) | |
180 | return rc; | |
181 | ||
182 | c_iter = c_iter->lvl_nxt; | |
183 | } while (c_iter != NULL); | |
184 | ||
185 | return 0; | |
186 | } | |
187 | ||
188 | /** | |
189 | * Checks for a sub-tree match in an existing tree and prunes the tree | |
190 | * @param prev the head of the existing tree or sub-tree | |
191 | * @param existing the starting point into the existing tree | |
192 | * @param new pointer to the new tree | |
193 | * @param state pointer to the pruning state | |
194 | * | |
195 | * This function searches the existing and new trees trying to prune each to | |
196 | * eliminate redundancy. Returns the number of nodes removed from the tree on | |
197 | * success, zero if no changes were made, and negative values if the new tree | |
198 | * should be discarded. | |
199 | * | |
200 | */ | |
201 | static int _db_tree_sub_prune(struct db_arg_chain_tree **prev, | |
202 | struct db_arg_chain_tree *existing, | |
203 | struct db_arg_chain_tree *new, | |
204 | struct db_prune_state *state) | |
205 | { | |
206 | int rc = 0; | |
207 | int rc_tmp; | |
208 | struct db_arg_chain_tree *ec_iter; | |
209 | struct db_arg_chain_tree *ec_iter_tmp; | |
210 | struct db_arg_chain_tree *c_iter; | |
211 | struct db_prune_state state_new; | |
212 | ||
213 | if (!state || !existing || !new) | |
214 | return 0; | |
215 | ||
216 | ec_iter = existing; | |
217 | c_iter = new; | |
218 | do { | |
219 | if (db_chain_eq(ec_iter, c_iter)) { | |
220 | /* equal */ | |
221 | ||
222 | if (db_chain_leaf(c_iter)) { | |
223 | /* leaf */ | |
224 | if (db_chain_eq_result(ec_iter, c_iter)) { | |
225 | /* identical results */ | |
226 | if (prev != NULL) | |
227 | return _db_tree_remove(prev, | |
228 | ec_iter); | |
229 | else | |
230 | return -1; | |
231 | } | |
232 | if (c_iter->act_t_flg && ec_iter->nxt_t) { | |
233 | /* new is shorter (true) */ | |
234 | if (prev == NULL) | |
235 | return -1; | |
236 | rc += _db_tree_remove(&(ec_iter->nxt_t), | |
237 | ec_iter->nxt_t); | |
238 | ec_iter->act_t = c_iter->act_t; | |
239 | ec_iter->act_t_flg = true; | |
240 | } | |
241 | if (c_iter->act_f_flg && ec_iter->nxt_f) { | |
242 | /* new is shorter (false) */ | |
243 | if (prev == NULL) | |
244 | return -1; | |
245 | rc += _db_tree_remove(&(ec_iter->nxt_f), | |
246 | ec_iter->nxt_f); | |
247 | ec_iter->act_f = c_iter->act_f; | |
248 | ec_iter->act_f_flg = true; | |
249 | } | |
250 | ||
251 | return rc; | |
252 | } | |
253 | ||
254 | if (c_iter->nxt_t && ec_iter->act_t_flg) | |
255 | /* existing is shorter (true) */ | |
256 | return -1; | |
257 | if (c_iter->nxt_f && ec_iter->act_f_flg) | |
258 | /* existing is shorter (false) */ | |
259 | return -1; | |
260 | ||
261 | if (c_iter->nxt_t) { | |
262 | state_new = *state; | |
263 | state_new.matched = true; | |
264 | rc_tmp = _db_tree_sub_prune((prev ? | |
265 | &ec_iter : NULL), | |
266 | ec_iter->nxt_t, | |
267 | c_iter->nxt_t, | |
268 | &state_new); | |
269 | rc += (rc_tmp > 0 ? rc_tmp : 0); | |
270 | if (state->prefix_new && rc_tmp < 0) | |
271 | return (rc > 0 ? rc : rc_tmp); | |
272 | } | |
273 | if (c_iter->nxt_f) { | |
274 | state_new = *state; | |
275 | state_new.matched = true; | |
276 | rc_tmp = _db_tree_sub_prune((prev ? | |
277 | &ec_iter : NULL), | |
278 | ec_iter->nxt_f, | |
279 | c_iter->nxt_f, | |
280 | &state_new); | |
281 | rc += (rc_tmp > 0 ? rc_tmp : 0); | |
282 | if (state->prefix_new && rc_tmp < 0) | |
283 | return (rc > 0 ? rc : rc_tmp); | |
284 | } | |
285 | } else if (db_chain_lt(ec_iter, c_iter)) { | |
286 | /* less than */ | |
287 | if (state->matched || state->prefix_new) | |
288 | goto next; | |
289 | state_new = *state; | |
290 | state_new.prefix_exist = true; | |
291 | ||
292 | if (ec_iter->nxt_t) { | |
293 | rc_tmp = _db_tree_sub_prune((prev ? | |
294 | &ec_iter : NULL), | |
295 | ec_iter->nxt_t, | |
296 | c_iter, | |
297 | &state_new); | |
298 | rc += (rc_tmp > 0 ? rc_tmp : 0); | |
299 | } | |
300 | if (ec_iter->nxt_f) { | |
301 | rc_tmp = _db_tree_sub_prune((prev ? | |
302 | &ec_iter : NULL), | |
303 | ec_iter->nxt_f, | |
304 | c_iter, | |
305 | &state_new); | |
306 | rc += (rc_tmp > 0 ? rc_tmp : 0); | |
307 | } | |
308 | } else if (db_chain_gt(ec_iter, c_iter)) { | |
309 | /* greater than */ | |
310 | if (state->matched || state->prefix_exist) | |
311 | goto next; | |
312 | state_new = *state; | |
313 | state_new.prefix_new = true; | |
314 | ||
315 | if (c_iter->nxt_t) { | |
316 | rc_tmp = _db_tree_sub_prune(NULL, | |
317 | ec_iter, | |
318 | c_iter->nxt_t, | |
319 | &state_new); | |
320 | rc += (rc_tmp > 0 ? rc_tmp : 0); | |
321 | if (rc_tmp < 0) | |
322 | return (rc > 0 ? rc : rc_tmp); | |
323 | } | |
324 | if (c_iter->nxt_f) { | |
325 | rc_tmp = _db_tree_sub_prune(NULL, | |
326 | ec_iter, | |
327 | c_iter->nxt_f, | |
328 | &state_new); | |
329 | rc += (rc_tmp > 0 ? rc_tmp : 0); | |
330 | if (rc_tmp < 0) | |
331 | return (rc > 0 ? rc : rc_tmp); | |
332 | } | |
333 | } | |
334 | ||
335 | next: | |
336 | /* re-check current node and advance to the next node */ | |
337 | if (db_chain_zombie(ec_iter)) { | |
338 | ec_iter_tmp = ec_iter->lvl_nxt; | |
339 | rc += _db_tree_remove(prev, ec_iter); | |
340 | ec_iter = ec_iter_tmp; | |
341 | } else | |
342 | ec_iter = ec_iter->lvl_nxt; | |
343 | } while (ec_iter); | |
344 | ||
345 | return rc; | |
346 | } | |
347 | ||
348 | /** | |
349 | * Validate the seccomp action | |
350 | * @param action the seccomp action | |
351 | * | |
352 | * Verify that the given action is a valid seccomp action; return zero if | |
353 | * valid, -EINVAL if invalid. | |
354 | */ | |
355 | int db_action_valid(uint32_t action) | |
356 | { | |
357 | if (action == SCMP_ACT_KILL) | |
358 | return 0; | |
359 | else if (action == SCMP_ACT_TRAP) | |
360 | return 0; | |
361 | else if (action == SCMP_ACT_ERRNO(action & 0x0000ffff)) | |
362 | return 0; | |
363 | else if (action == SCMP_ACT_TRACE(action & 0x0000ffff)) | |
364 | return 0; | |
365 | else if (action == SCMP_ACT_ALLOW) | |
366 | return 0; | |
367 | ||
368 | return -EINVAL; | |
369 | } | |
370 | ||
371 | /** | |
372 | * Free and reset the seccomp filter collection | |
373 | * @param col the seccomp filter collection | |
374 | * @param def_action the default filter action | |
375 | * | |
376 | * This function frees any existing filter DBs and resets the collection to a | |
377 | * default state. | |
378 | * | |
379 | */ | |
380 | void db_col_reset(struct db_filter_col *col, uint32_t def_action) | |
381 | { | |
382 | unsigned int iter; | |
383 | ||
384 | if (col == NULL) | |
385 | return; | |
386 | ||
387 | /* free any filters */ | |
388 | for (iter = 0; iter < col->filter_cnt; iter++) | |
389 | db_release(col->filters[iter]); | |
390 | col->filter_cnt = 0; | |
391 | free(col->filters); | |
392 | col->filters = NULL; | |
393 | ||
394 | /* set the default attribute values */ | |
395 | col->attr.act_default = def_action; | |
396 | col->attr.act_badarch = SCMP_ACT_KILL; | |
397 | col->attr.nnp_enable = 1; | |
398 | ||
399 | /* set the state */ | |
400 | col->state = _DB_STA_VALID; | |
401 | } | |
402 | ||
403 | /** | |
404 | * Intitalize a seccomp filter collection | |
405 | * @param def_action the default filter action | |
406 | * | |
407 | * This function initializes a seccomp filter collection and readies it for | |
408 | * use. Returns a pointer to the collection on success, NULL on failure. | |
409 | * | |
410 | */ | |
411 | struct db_filter_col *db_col_init(uint32_t def_action) | |
412 | { | |
413 | struct db_filter_col *col; | |
414 | ||
415 | col = malloc(sizeof(*col)); | |
416 | if (col == NULL) | |
417 | return NULL; | |
418 | ||
419 | /* clear the buffer for the first time */ | |
420 | memset(col, 0, sizeof(*col)); | |
421 | ||
422 | /* reset the DB to a known state */ | |
423 | db_col_reset(col, def_action); | |
424 | ||
425 | return col; | |
426 | } | |
427 | ||
428 | /** | |
429 | * Destroy a seccomp filter collection | |
430 | * @param col the seccomp filter collection | |
431 | * | |
432 | * This function destroys a seccomp filter collection. After calling this | |
433 | * function, the filter should no longer be referenced. | |
434 | * | |
435 | */ | |
436 | void db_col_release(struct db_filter_col *col) | |
437 | { | |
438 | if (col == NULL) | |
439 | return; | |
440 | ||
441 | /* set the state, just in case */ | |
442 | col->state = _DB_STA_FREED; | |
443 | ||
444 | /* free and reset the DB */ | |
445 | db_col_reset(col, 0); | |
446 | free(col); | |
447 | } | |
448 | ||
449 | /** | |
450 | * Validate a filter collection | |
451 | * @param col the seccomp filter collection | |
452 | * | |
453 | * This function validates a seccomp filter collection. Returns zero if the | |
454 | * collection is valid, negative values on failure. | |
455 | * | |
456 | */ | |
457 | int db_col_valid(struct db_filter_col *col) | |
458 | { | |
459 | if (col != NULL && col->state == _DB_STA_VALID) | |
460 | return 0; | |
461 | return -EINVAL; | |
462 | } | |
463 | ||
464 | /** | |
465 | * Merge two filter collections | |
466 | * @param col_dst the destination filter collection | |
467 | * @param col_src the source filter collection | |
468 | * | |
469 | * This function merges two filter collections into the given destination | |
470 | * collection. The source filter collection is no longer valid if the function | |
471 | * returns successfully. Returns zero on success, negative values on failure. | |
472 | * | |
473 | */ | |
474 | int db_col_merge(struct db_filter_col *col_dst, struct db_filter_col *col_src) | |
475 | { | |
476 | unsigned int iter_a, iter_b; | |
477 | struct db_filter **dbs; | |
478 | ||
479 | /* make sure we don't have any arch/filter collisions */ | |
480 | for (iter_a = 0; iter_a < col_dst->filter_cnt; iter_a++) { | |
481 | for (iter_b = 0; iter_b < col_src->filter_cnt; iter_b++) { | |
482 | if (col_dst->filters[iter_a]->arch->token == | |
483 | col_src->filters[iter_b]->arch->token) | |
484 | return -EEXIST; | |
485 | } | |
486 | } | |
487 | ||
488 | /* expand the destination */ | |
489 | dbs = realloc(col_dst->filters, | |
490 | sizeof(struct db_filter *) * | |
491 | (col_dst->filter_cnt + col_src->filter_cnt)); | |
492 | if (dbs == NULL) | |
493 | return -ENOMEM; | |
494 | col_dst->filters = dbs; | |
495 | ||
496 | /* transfer the architecture filters */ | |
497 | for (iter_a = col_dst->filter_cnt, iter_b = 0; | |
498 | iter_b < col_src->filter_cnt; iter_a++, iter_b++) { | |
499 | col_dst->filters[iter_a] = col_src->filters[iter_b]; | |
500 | col_dst->filter_cnt++; | |
501 | } | |
502 | ||
503 | /* free the source */ | |
504 | col_src->filter_cnt = 0; | |
505 | db_col_release(col_src); | |
506 | ||
507 | return 0; | |
508 | } | |
509 | ||
510 | /** | |
511 | * Check to see if an architecture filter exists in the filter collection | |
512 | * @param col the seccomp filter collection | |
513 | * @param arch_token the architecture token | |
514 | * | |
515 | * Iterate through the given filter collection checking to see if a filter | |
516 | * exists for the specified architecture. Returns -EEXIST if a filter is found, | |
517 | * zero if a matching filter does not exist. | |
518 | * | |
519 | */ | |
520 | int db_col_arch_exist(struct db_filter_col *col, uint32_t arch_token) | |
521 | { | |
522 | unsigned int iter; | |
523 | ||
524 | for (iter = 0; iter < col->filter_cnt; iter++) | |
525 | if (col->filters[iter]->arch->token == arch_token) | |
526 | return -EEXIST; | |
527 | ||
528 | return 0; | |
529 | } | |
530 | ||
531 | /** | |
532 | * Get a filter attribute | |
533 | * @param col the seccomp filter collection | |
534 | * @param attr the filter attribute | |
535 | * @param value the filter attribute value | |
536 | * | |
537 | * Get the requested filter attribute and provide it via @value. Returns zero | |
538 | * on success, negative values on failure. | |
539 | * | |
540 | */ | |
541 | int db_col_attr_get(const struct db_filter_col *col, | |
542 | enum scmp_filter_attr attr, uint32_t *value) | |
543 | { | |
544 | int rc = 0; | |
545 | ||
546 | switch (attr) { | |
547 | case SCMP_FLTATR_ACT_DEFAULT: | |
548 | *value = col->attr.act_default; | |
549 | break; | |
550 | case SCMP_FLTATR_ACT_BADARCH: | |
551 | *value = col->attr.act_badarch; | |
552 | break; | |
553 | case SCMP_FLTATR_CTL_NNP: | |
554 | *value = col->attr.nnp_enable; | |
555 | break; | |
556 | default: | |
557 | rc = -EEXIST; | |
558 | break; | |
559 | } | |
560 | ||
561 | return rc; | |
562 | } | |
563 | ||
564 | /** | |
565 | * Set a filter attribute | |
566 | * @param db the seccomp filter collection | |
567 | * @param attr the filter attribute | |
568 | * @param value the filter attribute value | |
569 | * | |
570 | * Set the requested filter attribute with the given value. Returns zero on | |
571 | * success, negative values on failure. | |
572 | * | |
573 | */ | |
574 | int db_col_attr_set(struct db_filter_col *col, | |
575 | enum scmp_filter_attr attr, uint32_t value) | |
576 | { | |
577 | int rc = 0; | |
578 | ||
579 | switch (attr) { | |
580 | case SCMP_FLTATR_ACT_DEFAULT: | |
581 | /* read only */ | |
582 | return -EACCES; | |
583 | break; | |
584 | case SCMP_FLTATR_ACT_BADARCH: | |
585 | if (db_action_valid(value) == 0) | |
586 | col->attr.act_badarch = value; | |
587 | else | |
588 | return -EINVAL; | |
589 | break; | |
590 | case SCMP_FLTATR_CTL_NNP: | |
591 | col->attr.nnp_enable = (value ? 1 : 0); | |
592 | break; | |
593 | default: | |
594 | rc = -EEXIST; | |
595 | break; | |
596 | } | |
597 | ||
598 | return rc; | |
599 | } | |
600 | ||
601 | /** | |
602 | * Add a new filter DB to a filter collection | |
603 | * @param col the seccomp filter collection | |
604 | * @param db the seccomp filter DB | |
605 | * | |
606 | * This function adds an existing seccomp filter DB to an existing seccomp | |
607 | * filter collection assuming there isn't a filter DB already present with the | |
608 | * same architecture. Returns zero on success, negative values on failure. | |
609 | * | |
610 | */ | |
611 | int db_col_db_add(struct db_filter_col *col, struct db_filter *db) | |
612 | { | |
613 | struct db_filter **dbs; | |
614 | ||
615 | if (db_col_arch_exist(col, db->arch->token)) | |
616 | return -EEXIST; | |
617 | ||
618 | dbs = realloc(col->filters, | |
619 | sizeof(struct db_filter *) * (col->filter_cnt + 1)); | |
620 | if (dbs == NULL) | |
621 | return -ENOMEM; | |
622 | col->filters = dbs; | |
623 | col->filter_cnt++; | |
624 | col->filters[col->filter_cnt - 1] = db; | |
625 | ||
626 | return 0; | |
627 | } | |
628 | ||
629 | /** | |
630 | * Remove a filter DB from a filter collection | |
631 | * @param col the seccomp filter collection | |
632 | * @param arch_token the architecture token | |
633 | * | |
634 | * This function removes an existing seccomp filter DB from an existing seccomp | |
635 | * filter collection. Returns zero on success, negative values on failure. | |
636 | * | |
637 | */ | |
638 | int db_col_db_remove(struct db_filter_col *col, uint32_t arch_token) | |
639 | { | |
640 | unsigned int iter; | |
641 | unsigned int found; | |
642 | struct db_filter **dbs; | |
643 | ||
644 | if ((col->filter_cnt <= 1) || (db_col_arch_exist(col, arch_token) == 0)) | |
645 | return -EINVAL; | |
646 | ||
647 | for (found = 0, iter = 0; iter < col->filter_cnt; iter++) { | |
648 | if (found) | |
649 | col->filters[iter - 1] = col->filters[iter]; | |
650 | else if (col->filters[iter]->arch->token == arch_token) { | |
651 | db_release(col->filters[iter]); | |
652 | found = 1; | |
653 | } | |
654 | } | |
655 | col->filters[--col->filter_cnt] = NULL; | |
656 | ||
657 | /* NOTE: if we can't do the realloc it isn't fatal, we just have some | |
658 | * extra space that will get cleaned up later */ | |
659 | dbs = realloc(col->filters, | |
660 | sizeof(struct db_filter *) * col->filter_cnt); | |
661 | if (dbs != NULL) | |
662 | col->filters = dbs; | |
663 | ||
664 | return 0; | |
665 | } | |
666 | ||
667 | /** | |
668 | * Free and reset the seccomp filter DB | |
669 | * @param db the seccomp filter DB | |
670 | * @param def_action the default filter action | |
671 | * | |
672 | * This function frees any existing filters and resets the filter DB to a | |
673 | * default state; only the DB architecture is preserved. | |
674 | * | |
675 | */ | |
676 | void db_reset(struct db_filter *db) | |
677 | { | |
678 | struct db_sys_list *s_iter; | |
679 | ||
680 | if (db == NULL) | |
681 | return; | |
682 | ||
683 | /* free any filters */ | |
684 | if (db->syscalls != NULL) { | |
685 | s_iter = db->syscalls; | |
686 | while (s_iter != NULL) { | |
687 | db->syscalls = s_iter->next; | |
688 | _db_tree_free(s_iter->chains); | |
689 | free(s_iter); | |
690 | s_iter = db->syscalls; | |
691 | } | |
692 | db->syscalls = NULL; | |
693 | } | |
694 | } | |
695 | ||
696 | /** | |
697 | * Intitalize a seccomp filter DB | |
698 | * @param arch the architecture definition | |
699 | * | |
700 | * This function initializes a seccomp filter DB and readies it for use. | |
701 | * Returns a pointer to the DB on success, NULL on failure. | |
702 | * | |
703 | */ | |
704 | struct db_filter *db_init(const struct arch_def *arch) | |
705 | { | |
706 | struct db_filter *db; | |
707 | ||
708 | db = malloc(sizeof(*db)); | |
709 | if (db == NULL) | |
710 | return NULL; | |
711 | ||
712 | /* clear the buffer for the first time and set the arch */ | |
713 | memset(db, 0, sizeof(*db)); | |
714 | db->arch = arch; | |
715 | ||
716 | /* reset the DB to a known state */ | |
717 | db_reset(db); | |
718 | ||
719 | return db; | |
720 | } | |
721 | ||
722 | /** | |
723 | * Destroy a seccomp filter DB | |
724 | * @param db the seccomp filter DB | |
725 | * | |
726 | * This function destroys a seccomp filter DB. After calling this function, | |
727 | * the filter should no longer be referenced. | |
728 | * | |
729 | */ | |
730 | void db_release(struct db_filter *db) | |
731 | { | |
732 | if (db == NULL) | |
733 | return; | |
734 | ||
735 | /* free and reset the DB */ | |
736 | db_reset(db); | |
737 | free(db); | |
738 | } | |
739 | ||
740 | /** | |
741 | * Update the user specified portion of the syscall priority | |
742 | * @param db the seccomp filter db | |
743 | * @param syscall the syscall number | |
744 | * @param priority the syscall priority | |
745 | * | |
746 | * This function sets, or updates, the syscall priority; the highest priority | |
747 | * value between the existing and specified value becomes the new syscall | |
748 | * priority. If the syscall entry does not already exist, a new phantom | |
749 | * syscall entry is created as a placeholder. Returns zero on success, | |
750 | * negative values on failure. | |
751 | * | |
752 | */ | |
753 | int db_syscall_priority(struct db_filter *db, | |
754 | unsigned int syscall, uint8_t priority) | |
755 | { | |
756 | unsigned int sys_pri = _DB_PRI_USER(priority); | |
757 | struct db_sys_list *s_new, *s_iter, *s_prev = NULL; | |
758 | ||
759 | assert(db != NULL); | |
760 | ||
761 | s_iter = db->syscalls; | |
762 | while (s_iter != NULL && s_iter->num < syscall) { | |
763 | s_prev = s_iter; | |
764 | s_iter = s_iter->next; | |
765 | } | |
766 | ||
767 | /* matched an existing syscall entry */ | |
768 | if (s_iter != NULL && s_iter->num == syscall) { | |
769 | if (sys_pri > (s_iter->priority & _DB_PRI_MASK_USER)) { | |
770 | s_iter->priority &= (~_DB_PRI_MASK_USER); | |
771 | s_iter->priority |= sys_pri; | |
772 | } | |
773 | return 0; | |
774 | } | |
775 | ||
776 | /* no existing syscall entry - create a phantom entry */ | |
777 | s_new = malloc(sizeof(*s_new)); | |
778 | if (s_new == NULL) | |
779 | return -ENOMEM; | |
780 | memset(s_new, 0, sizeof(*s_new)); | |
781 | s_new->num = syscall; | |
782 | s_new->priority = sys_pri; | |
783 | s_new->valid = false; | |
784 | ||
785 | /* add it before s_iter */ | |
786 | if (s_prev != NULL) { | |
787 | s_new->next = s_prev->next; | |
788 | s_prev->next = s_new; | |
789 | } else { | |
790 | s_new->next = db->syscalls; | |
791 | db->syscalls = s_new; | |
792 | } | |
793 | ||
794 | return 0; | |
795 | } | |
796 | ||
797 | /** | |
798 | * Fixup the node based on the op/mask | |
799 | * @param node the chain node | |
800 | * | |
801 | * Apply some simplifications based on the comparison op and mask value. | |
802 | * | |
803 | */ | |
804 | static void _db_node_mask_fixup(struct db_arg_chain_tree *node) | |
805 | { | |
806 | if (node->op == SCMP_CMP_MASKED_EQ && node->mask == 0) { | |
807 | node->op = SCMP_CMP_EQ; | |
808 | node->mask = ARG_MASK_MAX; | |
809 | node->datum = 0; | |
810 | } else | |
811 | node->datum &= node->mask; | |
812 | } | |
813 | ||
814 | /** | |
815 | * Generate a new filter rule for a 64 bit system | |
816 | * @param arch the architecture definition | |
817 | * @param action the filter action | |
818 | * @param syscall the syscall number | |
819 | * @param chain argument filter chain | |
820 | * | |
821 | * This function generates a new syscall filter for a 64 bit system. Returns | |
822 | * zero on success, negative values on failure. | |
823 | * | |
824 | */ | |
825 | static struct db_sys_list *_db_rule_gen_64(const struct arch_def *arch, | |
826 | uint32_t action, | |
827 | unsigned int syscall, | |
828 | struct db_api_arg *chain) | |
829 | { | |
830 | unsigned int iter; | |
831 | int chain_len_max; | |
832 | struct db_sys_list *s_new; | |
833 | struct db_arg_chain_tree *c_iter_hi = NULL, *c_iter_lo = NULL; | |
834 | struct db_arg_chain_tree *c_prev_hi = NULL, *c_prev_lo = NULL; | |
835 | bool tf_flag; | |
836 | ||
837 | s_new = malloc(sizeof(*s_new)); | |
838 | if (s_new == NULL) | |
839 | return NULL; | |
840 | memset(s_new, 0, sizeof(*s_new)); | |
841 | s_new->num = syscall; | |
842 | s_new->valid = true; | |
843 | /* run through the argument chain */ | |
844 | chain_len_max = arch_arg_count_max(arch); | |
845 | for (iter = 0; iter < chain_len_max; iter++) { | |
846 | if (chain[iter].valid == 0) | |
847 | continue; | |
848 | ||
849 | c_iter_hi = malloc(sizeof(*c_iter_hi)); | |
850 | if (c_iter_hi == NULL) | |
851 | goto gen_64_failure; | |
852 | memset(c_iter_hi, 0, sizeof(*c_iter_hi)); | |
853 | c_iter_hi->refcnt = 1; | |
854 | c_iter_lo = malloc(sizeof(*c_iter_lo)); | |
855 | if (c_iter_lo == NULL) { | |
856 | free(c_iter_hi); | |
857 | goto gen_64_failure; | |
858 | } | |
859 | memset(c_iter_lo, 0, sizeof(*c_iter_lo)); | |
860 | c_iter_lo->refcnt = 1; | |
861 | ||
862 | /* link this level to the previous level */ | |
863 | if (c_prev_lo != NULL) { | |
864 | if (!tf_flag) { | |
865 | c_prev_lo->nxt_f = c_iter_hi; | |
866 | c_prev_hi->nxt_f = c_iter_hi; | |
867 | c_iter_hi->refcnt++; | |
868 | } else | |
869 | c_prev_lo->nxt_t = c_iter_hi; | |
870 | } else | |
871 | s_new->chains = c_iter_hi; | |
872 | s_new->node_cnt += 2; | |
873 | ||
874 | /* set the arg, op, and datum fields */ | |
875 | c_iter_hi->arg = chain[iter].arg; | |
876 | c_iter_lo->arg = chain[iter].arg; | |
877 | c_iter_hi->arg_offset = arch_arg_offset_hi(arch, | |
878 | c_iter_hi->arg); | |
879 | c_iter_lo->arg_offset = arch_arg_offset_lo(arch, | |
880 | c_iter_lo->arg); | |
881 | switch (chain[iter].op) { | |
882 | case SCMP_CMP_GT: | |
883 | c_iter_hi->op = SCMP_CMP_GE; | |
884 | c_iter_lo->op = SCMP_CMP_GT; | |
885 | tf_flag = true; | |
886 | break; | |
887 | case SCMP_CMP_NE: | |
888 | c_iter_hi->op = SCMP_CMP_EQ; | |
889 | c_iter_lo->op = SCMP_CMP_EQ; | |
890 | tf_flag = false; | |
891 | break; | |
892 | case SCMP_CMP_LT: | |
893 | c_iter_hi->op = SCMP_CMP_GE; | |
894 | c_iter_lo->op = SCMP_CMP_GE; | |
895 | tf_flag = false; | |
896 | break; | |
897 | case SCMP_CMP_LE: | |
898 | c_iter_hi->op = SCMP_CMP_GE; | |
899 | c_iter_lo->op = SCMP_CMP_GT; | |
900 | tf_flag = false; | |
901 | break; | |
902 | default: | |
903 | c_iter_hi->op = chain[iter].op; | |
904 | c_iter_lo->op = chain[iter].op; | |
905 | tf_flag = true; | |
906 | } | |
907 | c_iter_hi->mask = D64_HI(chain[iter].mask); | |
908 | c_iter_lo->mask = D64_LO(chain[iter].mask); | |
909 | c_iter_hi->datum = D64_HI(chain[iter].datum); | |
910 | c_iter_lo->datum = D64_LO(chain[iter].datum); | |
911 | ||
912 | /* fixup the mask/datum */ | |
913 | _db_node_mask_fixup(c_iter_hi); | |
914 | _db_node_mask_fixup(c_iter_lo); | |
915 | ||
916 | /* link the hi and lo chain nodes */ | |
917 | c_iter_hi->nxt_t = c_iter_lo; | |
918 | ||
919 | c_prev_hi = c_iter_hi; | |
920 | c_prev_lo = c_iter_lo; | |
921 | } | |
922 | if (c_iter_lo != NULL) { | |
923 | /* set the leaf node */ | |
924 | if (!tf_flag) { | |
925 | c_iter_lo->act_f_flg = true; | |
926 | c_iter_lo->act_f = action; | |
927 | c_iter_hi->act_f_flg = true; | |
928 | c_iter_hi->act_f = action; | |
929 | } else { | |
930 | c_iter_lo->act_t_flg = true; | |
931 | c_iter_lo->act_t = action; | |
932 | } | |
933 | } else | |
934 | s_new->action = action; | |
935 | ||
936 | return s_new; | |
937 | ||
938 | gen_64_failure: | |
939 | /* free the new chain and its syscall struct */ | |
940 | _db_tree_free(s_new->chains); | |
941 | free(s_new); | |
942 | return NULL; | |
943 | } | |
944 | ||
945 | /** | |
946 | * Generate a new filter rule for a 32 bit system | |
947 | * @param arch the architecture definition | |
948 | * @param action the filter action | |
949 | * @param syscall the syscall number | |
950 | * @param chain argument filter chain | |
951 | * | |
952 | * This function generates a new syscall filter for a 32 bit system. Returns | |
953 | * zero on success, negative values on failure. | |
954 | * | |
955 | */ | |
956 | static struct db_sys_list *_db_rule_gen_32(const struct arch_def *arch, | |
957 | uint32_t action, | |
958 | unsigned int syscall, | |
959 | struct db_api_arg *chain) | |
960 | { | |
961 | unsigned int iter; | |
962 | int chain_len_max; | |
963 | struct db_sys_list *s_new; | |
964 | struct db_arg_chain_tree *c_iter = NULL, *c_prev = NULL; | |
965 | bool tf_flag; | |
966 | ||
967 | s_new = malloc(sizeof(*s_new)); | |
968 | if (s_new == NULL) | |
969 | return NULL; | |
970 | memset(s_new, 0, sizeof(*s_new)); | |
971 | s_new->num = syscall; | |
972 | s_new->valid = true; | |
973 | /* run through the argument chain */ | |
974 | chain_len_max = arch_arg_count_max(arch); | |
975 | for (iter = 0; iter < chain_len_max; iter++) { | |
976 | if (chain[iter].valid == 0) | |
977 | continue; | |
978 | ||
979 | c_iter = malloc(sizeof(*c_iter)); | |
980 | if (c_iter == NULL) | |
981 | goto gen_32_failure; | |
982 | memset(c_iter, 0, sizeof(*c_iter)); | |
983 | c_iter->refcnt = 1; | |
984 | c_iter->arg = chain[iter].arg; | |
985 | c_iter->arg_offset = arch_arg_offset(c_iter->arg); | |
986 | c_iter->op = chain[iter].op; | |
987 | c_iter->mask = chain[iter].mask; | |
988 | c_iter->datum = chain[iter].datum; | |
989 | ||
990 | /* link in the new node and update the chain */ | |
991 | if (c_prev != NULL) { | |
992 | if (tf_flag) | |
993 | c_prev->nxt_t = c_iter; | |
994 | else | |
995 | c_prev->nxt_f = c_iter; | |
996 | } else | |
997 | s_new->chains = c_iter; | |
998 | s_new->node_cnt++; | |
999 | ||
1000 | /* rewrite the op to reduce the op/datum combos */ | |
1001 | switch (c_iter->op) { | |
1002 | case SCMP_CMP_NE: | |
1003 | c_iter->op = SCMP_CMP_EQ; | |
1004 | tf_flag = false; | |
1005 | break; | |
1006 | case SCMP_CMP_LT: | |
1007 | c_iter->op = SCMP_CMP_GE; | |
1008 | tf_flag = false; | |
1009 | break; | |
1010 | case SCMP_CMP_LE: | |
1011 | c_iter->op = SCMP_CMP_GT; | |
1012 | tf_flag = false; | |
1013 | break; | |
1014 | default: | |
1015 | tf_flag = true; | |
1016 | } | |
1017 | ||
1018 | /* fixup the mask/datum */ | |
1019 | _db_node_mask_fixup(c_iter); | |
1020 | ||
1021 | c_prev = c_iter; | |
1022 | } | |
1023 | if (c_iter != NULL) { | |
1024 | /* set the leaf node */ | |
1025 | if (tf_flag) { | |
1026 | c_iter->act_t_flg = true; | |
1027 | c_iter->act_t = action; | |
1028 | } else { | |
1029 | c_iter->act_f_flg = true; | |
1030 | c_iter->act_f = action; | |
1031 | } | |
1032 | } else | |
1033 | s_new->action = action; | |
1034 | ||
1035 | return s_new; | |
1036 | ||
1037 | gen_32_failure: | |
1038 | /* free the new chain and its syscall struct */ | |
1039 | _db_tree_free(s_new->chains); | |
1040 | free(s_new); | |
1041 | return NULL; | |
1042 | } | |
1043 | ||
1044 | /** | |
1045 | * Add a new rule to the seccomp filter DB | |
1046 | * @param db the seccomp filter db | |
1047 | * @param action the filter action | |
1048 | * @param syscall the syscall number | |
1049 | * @param chain argument filter chain | |
1050 | * | |
1051 | * This function adds a new syscall filter to the seccomp filter DB, adding to | |
1052 | * the existing filters for the syscall, unless no argument specific filters | |
1053 | * are present (filtering only on the syscall). When adding new chains, the | |
1054 | * shortest chain, or most inclusive filter match, will be entered into the | |
1055 | * filter DB. Returns zero on success, negative values on failure. | |
1056 | * | |
1057 | */ | |
1058 | int db_rule_add(struct db_filter *db, uint32_t action, unsigned int syscall, | |
1059 | struct db_api_arg *chain) | |
1060 | { | |
1061 | int rc = -ENOMEM; | |
1062 | struct db_sys_list *s_new, *s_iter, *s_prev = NULL; | |
1063 | struct db_arg_chain_tree *c_iter = NULL, *c_prev = NULL; | |
1064 | struct db_arg_chain_tree *ec_iter; | |
1065 | struct db_prune_state state; | |
1066 | bool rm_flag = false; | |
1067 | unsigned int new_chain_cnt = 0; | |
1068 | unsigned int n_cnt; | |
1069 | ||
1070 | assert(db != NULL); | |
1071 | ||
1072 | /* do all our possible memory allocation up front so we don't have to | |
1073 | * worry about failure once we get to the point where we start updating | |
1074 | * the filter db */ | |
1075 | if (db->arch->size == ARCH_SIZE_64) | |
1076 | s_new = _db_rule_gen_64(db->arch, action, syscall, chain); | |
1077 | else if (db->arch->size == ARCH_SIZE_32) | |
1078 | s_new = _db_rule_gen_32(db->arch, action, syscall, chain); | |
1079 | else | |
1080 | return -EFAULT; | |
1081 | if (s_new == NULL) | |
1082 | return -ENOMEM; | |
1083 | new_chain_cnt = s_new->node_cnt; | |
1084 | ||
1085 | /* no more failures allowed after this point that would result in the | |
1086 | * stored filter being in an inconsistent state */ | |
1087 | ||
1088 | /* find a matching syscall/chain or insert a new one */ | |
1089 | s_iter = db->syscalls; | |
1090 | while (s_iter != NULL && s_iter->num < syscall) { | |
1091 | s_prev = s_iter; | |
1092 | s_iter = s_iter->next; | |
1093 | } | |
1094 | add_reset: | |
1095 | s_new->node_cnt = new_chain_cnt; | |
1096 | s_new->priority = _DB_PRI_MASK_CHAIN - s_new->node_cnt; | |
1097 | c_prev = NULL; | |
1098 | c_iter = s_new->chains; | |
1099 | if (s_iter != NULL) | |
1100 | ec_iter = s_iter->chains; | |
1101 | else | |
1102 | ec_iter = NULL; | |
1103 | if (s_iter == NULL || s_iter->num != syscall) { | |
1104 | /* new syscall, add before s_iter */ | |
1105 | if (s_prev != NULL) { | |
1106 | s_new->next = s_prev->next; | |
1107 | s_prev->next = s_new; | |
1108 | } else { | |
1109 | s_new->next = db->syscalls; | |
1110 | db->syscalls = s_new; | |
1111 | } | |
1112 | return 0; | |
1113 | } else if (s_iter->chains == NULL) { | |
1114 | if (rm_flag || !s_iter->valid) { | |
1115 | /* we are here because our previous pass cleared the | |
1116 | * entire syscall chain when searching for a subtree | |
1117 | * match or the existing syscall entry is a phantom, | |
1118 | * so either way add the new chain */ | |
1119 | s_iter->chains = s_new->chains; | |
1120 | s_iter->action = s_new->action; | |
1121 | s_iter->node_cnt = s_new->node_cnt; | |
1122 | if (s_iter->valid) | |
1123 | s_iter->priority = s_new->priority; | |
1124 | s_iter->valid = true; | |
1125 | free(s_new); | |
1126 | rc = 0; | |
1127 | goto add_priority_update; | |
1128 | } else | |
1129 | /* syscall exists without any chains - existing filter | |
1130 | * is at least as large as the new entry so cleanup and | |
1131 | * exit */ | |
1132 | goto add_free_ok; | |
1133 | } else if (s_iter->chains != NULL && s_new->chains == NULL) { | |
1134 | /* syscall exists with chains but the new filter has no chains | |
1135 | * so we need to clear the existing chains and exit */ | |
1136 | _db_tree_free(s_iter->chains); | |
1137 | s_iter->chains = NULL; | |
1138 | s_iter->node_cnt = 0; | |
1139 | s_iter->action = action; | |
1140 | goto add_free_ok; | |
1141 | } | |
1142 | ||
1143 | /* check for sub-tree matches */ | |
1144 | memset(&state, 0, sizeof(state)); | |
1145 | rc = _db_tree_sub_prune(&(s_iter->chains), ec_iter, c_iter, &state); | |
1146 | if (rc > 0) { | |
1147 | rm_flag = true; | |
1148 | s_iter->node_cnt -= rc; | |
1149 | goto add_reset; | |
1150 | } else if (rc < 0) | |
1151 | goto add_free_ok; | |
1152 | ||
1153 | /* syscall exists and has at least one existing chain - start at the | |
1154 | * top and walk the two chains */ | |
1155 | do { | |
1156 | /* insert the new rule into the existing tree */ | |
1157 | if (db_chain_eq(c_iter, ec_iter)) { | |
1158 | /* found a matching node on this chain level */ | |
1159 | if (db_chain_action(c_iter) && | |
1160 | db_chain_action(ec_iter)) { | |
1161 | /* both are "action" nodes */ | |
1162 | if (c_iter->act_t_flg && ec_iter->act_t_flg) { | |
1163 | if (ec_iter->act_t != action) | |
1164 | goto add_free_exist; | |
1165 | } else if (c_iter->act_t_flg) { | |
1166 | ec_iter->act_t_flg = true; | |
1167 | ec_iter->act_t = action; | |
1168 | } | |
1169 | if (c_iter->act_f_flg && ec_iter->act_f_flg) { | |
1170 | if (ec_iter->act_f != action) | |
1171 | goto add_free_exist; | |
1172 | } else if (c_iter->act_f_flg) { | |
1173 | ec_iter->act_f_flg = true; | |
1174 | ec_iter->act_f = action; | |
1175 | } | |
1176 | if (ec_iter->act_t_flg == ec_iter->act_f_flg && | |
1177 | ec_iter->act_t == ec_iter->act_f) { | |
1178 | n_cnt = _db_tree_remove( | |
1179 | &(s_iter->chains), | |
1180 | ec_iter); | |
1181 | s_iter->node_cnt -= n_cnt; | |
1182 | goto add_free_ok; | |
1183 | } | |
1184 | } else if (db_chain_action(c_iter)) { | |
1185 | /* new is shorter */ | |
1186 | if (c_iter->act_t_flg) { | |
1187 | rc = _db_tree_act_check(ec_iter->nxt_t, | |
1188 | action); | |
1189 | if (rc < 0) | |
1190 | goto add_free; | |
1191 | n_cnt = _db_tree_free(ec_iter->nxt_t); | |
1192 | ec_iter->nxt_t = NULL; | |
1193 | ec_iter->act_t_flg = true; | |
1194 | ec_iter->act_t = action; | |
1195 | } else { | |
1196 | rc = _db_tree_act_check(ec_iter->nxt_f, | |
1197 | action); | |
1198 | if (rc < 0) | |
1199 | goto add_free; | |
1200 | n_cnt = _db_tree_free(ec_iter->nxt_f); | |
1201 | ec_iter->nxt_f = NULL; | |
1202 | ec_iter->act_f_flg = true; | |
1203 | ec_iter->act_f = action; | |
1204 | } | |
1205 | s_iter->node_cnt -= n_cnt; | |
1206 | } | |
1207 | if (c_iter->nxt_t != NULL) { | |
1208 | if (ec_iter->nxt_t != NULL) { | |
1209 | /* jump to the next level */ | |
1210 | c_prev = c_iter; | |
1211 | c_iter = c_iter->nxt_t; | |
1212 | ec_iter = ec_iter->nxt_t; | |
1213 | s_new->node_cnt--; | |
1214 | } else if (ec_iter->act_t_flg) { | |
1215 | /* existing is shorter */ | |
1216 | if (ec_iter->act_t == action) | |
1217 | goto add_free_ok; | |
1218 | goto add_free_exist; | |
1219 | } else { | |
1220 | /* add a new branch */ | |
1221 | c_prev = c_iter; | |
1222 | ec_iter->nxt_t = c_iter->nxt_t; | |
1223 | s_iter->node_cnt += | |
1224 | (s_new->node_cnt - 1); | |
1225 | goto add_free_match; | |
1226 | } | |
1227 | } else if (c_iter->nxt_f != NULL) { | |
1228 | if (ec_iter->nxt_f != NULL) { | |
1229 | /* jump to the next level */ | |
1230 | c_prev = c_iter; | |
1231 | c_iter = c_iter->nxt_f; | |
1232 | ec_iter = ec_iter->nxt_f; | |
1233 | s_new->node_cnt--; | |
1234 | } else if (ec_iter->act_f_flg) { | |
1235 | /* existing is shorter */ | |
1236 | if (ec_iter->act_f == action) | |
1237 | goto add_free_ok; | |
1238 | goto add_free_exist; | |
1239 | } else { | |
1240 | /* add a new branch */ | |
1241 | c_prev = c_iter; | |
1242 | ec_iter->nxt_f = c_iter->nxt_f; | |
1243 | s_iter->node_cnt += | |
1244 | (s_new->node_cnt - 1); | |
1245 | goto add_free_match; | |
1246 | } | |
1247 | } else | |
1248 | goto add_free_ok; | |
1249 | } else { | |
1250 | /* need to check other nodes on this level */ | |
1251 | if (db_chain_lt(c_iter, ec_iter)) { | |
1252 | if (ec_iter->lvl_prv == NULL) { | |
1253 | /* add to the start of the level */ | |
1254 | ec_iter->lvl_prv = c_iter; | |
1255 | c_iter->lvl_nxt = ec_iter; | |
1256 | if (ec_iter == s_iter->chains) | |
1257 | s_iter->chains = c_iter; | |
1258 | s_iter->node_cnt += s_new->node_cnt; | |
1259 | goto add_free_match; | |
1260 | } else | |
1261 | ec_iter = ec_iter->lvl_prv; | |
1262 | } else { | |
1263 | if (ec_iter->lvl_nxt == NULL) { | |
1264 | /* add to the end of the level */ | |
1265 | ec_iter->lvl_nxt = c_iter; | |
1266 | c_iter->lvl_prv = ec_iter; | |
1267 | s_iter->node_cnt += s_new->node_cnt; | |
1268 | goto add_free_match; | |
1269 | } else if (db_chain_lt(c_iter, | |
1270 | ec_iter->lvl_nxt)) { | |
1271 | /* add new chain in between */ | |
1272 | c_iter->lvl_nxt = ec_iter->lvl_nxt; | |
1273 | ec_iter->lvl_nxt->lvl_prv = c_iter; | |
1274 | ec_iter->lvl_nxt = c_iter; | |
1275 | c_iter->lvl_prv = ec_iter; | |
1276 | s_iter->node_cnt += s_new->node_cnt; | |
1277 | goto add_free_match; | |
1278 | } else | |
1279 | ec_iter = ec_iter->lvl_nxt; | |
1280 | } | |
1281 | } | |
1282 | } while ((c_iter != NULL) && (ec_iter != NULL)); | |
1283 | ||
1284 | /* we should never be here! */ | |
1285 | return -EFAULT; | |
1286 | ||
1287 | add_free_exist: | |
1288 | rc = -EEXIST; | |
1289 | goto add_free; | |
1290 | add_free_ok: | |
1291 | rc = 0; | |
1292 | add_free: | |
1293 | /* free the new chain and its syscall struct */ | |
1294 | _db_tree_free(s_new->chains); | |
1295 | free(s_new); | |
1296 | goto add_priority_update; | |
1297 | add_free_match: | |
1298 | /* free the matching portion of new chain */ | |
1299 | if (c_prev != NULL) { | |
1300 | c_prev->nxt_t = NULL; | |
1301 | c_prev->nxt_f = NULL; | |
1302 | _db_tree_free(s_new->chains); | |
1303 | } | |
1304 | free(s_new); | |
1305 | rc = 0; | |
1306 | add_priority_update: | |
1307 | /* update the priority */ | |
1308 | if (s_iter != NULL) { | |
1309 | s_iter->priority &= (~_DB_PRI_MASK_CHAIN); | |
1310 | s_iter->priority |= (_DB_PRI_MASK_CHAIN - s_iter->node_cnt); | |
1311 | } | |
1312 | return rc; | |
1313 | } |
0 | /** | |
1 | * Enhanced Seccomp Filter DB | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #ifndef _FILTER_DB_H | |
22 | #define _FILTER_DB_H | |
23 | ||
24 | #include <inttypes.h> | |
25 | #include <stdbool.h> | |
26 | ||
27 | #include <seccomp.h> | |
28 | ||
29 | #include "arch.h" | |
30 | ||
31 | /* XXX - need to provide doxygen comments for the types here */ | |
32 | ||
33 | struct db_api_arg { | |
34 | unsigned int arg; | |
35 | unsigned int op; | |
36 | scmp_datum_t mask; | |
37 | scmp_datum_t datum; | |
38 | ||
39 | bool valid; | |
40 | }; | |
41 | ||
42 | struct db_arg_chain_tree { | |
43 | /* argument number (a0 = 0, a1 = 1, etc.) */ | |
44 | unsigned int arg; | |
45 | /* argument bpf offset */ | |
46 | unsigned int arg_offset; | |
47 | ||
48 | /* comparison operator */ | |
49 | enum scmp_compare op; | |
50 | /* syscall argument value */ | |
51 | uint32_t mask; | |
52 | uint32_t datum; | |
53 | ||
54 | /* actions */ | |
55 | bool act_t_flg; | |
56 | bool act_f_flg; | |
57 | uint32_t act_t; | |
58 | uint32_t act_f; | |
59 | ||
60 | /* list of nodes on this level */ | |
61 | struct db_arg_chain_tree *lvl_prv, *lvl_nxt; | |
62 | ||
63 | /* next node in the chain */ | |
64 | struct db_arg_chain_tree *nxt_t; | |
65 | struct db_arg_chain_tree *nxt_f; | |
66 | ||
67 | unsigned int refcnt; | |
68 | }; | |
69 | #define ARG_MASK_MAX ((uint32_t)-1) | |
70 | #define db_chain_lt(x,y) \ | |
71 | (((x)->arg < (y)->arg) || \ | |
72 | (((x)->arg == (y)->arg) && \ | |
73 | (((x)->op < (y)->op) || (((x)->mask & (y)->mask) == (y)->mask)))) | |
74 | #define db_chain_eq(x,y) \ | |
75 | (((x)->arg == (y)->arg) && \ | |
76 | ((x)->op == (y)->op) && ((x)->datum == (y)->datum) && \ | |
77 | ((x)->mask == (y)->mask)) | |
78 | #define db_chain_gt(x,y) \ | |
79 | (((x)->arg > (y)->arg) || \ | |
80 | (((x)->arg == (y)->arg) && \ | |
81 | (((x)->op > (y)->op) || (((x)->mask & (y)->mask) != (y)->mask)))) | |
82 | #define db_chain_action(x) \ | |
83 | (((x)->act_t_flg) || ((x)->act_f_flg)) | |
84 | #define db_chain_zombie(x) \ | |
85 | ((x)->nxt_t == NULL && !((x)->act_t_flg) && \ | |
86 | (x)->nxt_f == NULL && !((x)->act_f_flg)) | |
87 | #define db_chain_leaf(x) \ | |
88 | ((x)->nxt_t == NULL && (x)->nxt_f == NULL) | |
89 | #define db_chain_eq_result(x,y) \ | |
90 | ((((x)->nxt_t != NULL && (y)->nxt_t != NULL) || \ | |
91 | ((x)->nxt_t == NULL && (y)->nxt_t == NULL)) && \ | |
92 | (((x)->nxt_f != NULL && (y)->nxt_f != NULL) || \ | |
93 | ((x)->nxt_f == NULL && (y)->nxt_f == NULL)) && \ | |
94 | ((x)->act_t_flg == (y)->act_t_flg) && \ | |
95 | ((x)->act_f_flg == (y)->act_f_flg) && \ | |
96 | (((x)->act_t_flg && (x)->act_t == (y)->act_t) || \ | |
97 | (!((x)->act_t_flg))) && \ | |
98 | (((x)->act_f_flg && (x)->act_f == (y)->act_f) || \ | |
99 | (!((x)->act_f_flg)))) | |
100 | ||
101 | struct db_sys_list { | |
102 | /* native syscall number */ | |
103 | unsigned int num; | |
104 | ||
105 | /* priority - higher is better */ | |
106 | unsigned int priority; | |
107 | ||
108 | /* the argument chain heads */ | |
109 | struct db_arg_chain_tree *chains; | |
110 | unsigned int node_cnt; | |
111 | ||
112 | /* action in the case of no argument chains */ | |
113 | uint32_t action; | |
114 | ||
115 | struct db_sys_list *next; | |
116 | /* temporary use only by the BPF generator */ | |
117 | struct db_sys_list *pri_prv, *pri_nxt; | |
118 | ||
119 | bool valid; | |
120 | }; | |
121 | ||
122 | struct db_filter_attr { | |
123 | /* action to take if we don't match an explicit allow/deny */ | |
124 | uint32_t act_default; | |
125 | /* action to take if we don't match the architecture */ | |
126 | uint32_t act_badarch; | |
127 | /* NO_NEW_PRIVS related attributes */ | |
128 | uint32_t nnp_enable; | |
129 | }; | |
130 | ||
131 | struct db_filter { | |
132 | /* target architecture */ | |
133 | const struct arch_def *arch; | |
134 | ||
135 | /* syscall filters, kept as a sorted single-linked list */ | |
136 | struct db_sys_list *syscalls; | |
137 | }; | |
138 | ||
139 | struct db_filter_col { | |
140 | /* verification / state */ | |
141 | int state; | |
142 | ||
143 | /* attributes */ | |
144 | struct db_filter_attr attr; | |
145 | ||
146 | /* individual filters */ | |
147 | struct db_filter **filters; | |
148 | unsigned int filter_cnt; | |
149 | }; | |
150 | ||
151 | /** | |
152 | * Iterate over each item in the DB list | |
153 | * @param iter the iterator | |
154 | * @param list the list | |
155 | * | |
156 | * This macro acts as for()/while() conditional and iterates the following | |
157 | * statement for each item in the given list. | |
158 | * | |
159 | */ | |
160 | #define db_list_foreach(iter,list) \ | |
161 | for (iter = (list); iter != NULL; iter = iter->next) | |
162 | ||
163 | int db_action_valid(uint32_t action); | |
164 | ||
165 | struct db_filter_col *db_col_init(uint32_t def_action); | |
166 | void db_col_reset(struct db_filter_col *col, uint32_t def_action); | |
167 | void db_col_release(struct db_filter_col *col); | |
168 | ||
169 | int db_col_valid(struct db_filter_col *col); | |
170 | ||
171 | int db_col_merge(struct db_filter_col *col_dst, struct db_filter_col *col_src); | |
172 | ||
173 | int db_col_arch_exist(struct db_filter_col *col, uint32_t arch_token); | |
174 | ||
175 | int db_col_attr_get(const struct db_filter_col *col, | |
176 | enum scmp_filter_attr attr, uint32_t *value); | |
177 | int db_col_attr_set(struct db_filter_col *col, | |
178 | enum scmp_filter_attr attr, uint32_t value); | |
179 | ||
180 | int db_col_db_add(struct db_filter_col *col, struct db_filter *db); | |
181 | int db_col_db_remove(struct db_filter_col *col, uint32_t arch_token); | |
182 | ||
183 | struct db_filter *db_init(const struct arch_def *arch); | |
184 | void db_reset(struct db_filter *db); | |
185 | void db_release(struct db_filter *db); | |
186 | ||
187 | int db_syscall_priority(struct db_filter *db, | |
188 | unsigned int syscall, uint8_t priority); | |
189 | ||
190 | int db_rule_add(struct db_filter *db, uint32_t action, unsigned int syscall, | |
191 | struct db_api_arg *chain); | |
192 | ||
193 | #endif |
0 | /** | |
1 | * Seccomp BPF Translator | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <errno.h> | |
22 | #include <inttypes.h> | |
23 | #include <stdlib.h> | |
24 | #include <stdio.h> | |
25 | #include <string.h> | |
26 | #include <stdbool.h> | |
27 | ||
28 | #include <seccomp.h> | |
29 | ||
30 | #include "arch.h" | |
31 | #include "arch-x32.h" | |
32 | #include "gen_bpf.h" | |
33 | #include "db.h" | |
34 | #include "hash.h" | |
35 | #include "system.h" | |
36 | ||
37 | /* allocation increments */ | |
38 | #define AINC_BLK 2 | |
39 | #define AINC_PROG 64 | |
40 | ||
41 | struct acc_state { | |
42 | int32_t offset; | |
43 | uint32_t mask; | |
44 | }; | |
45 | ||
46 | enum bpf_jump_type { | |
47 | TGT_NONE = 0, | |
48 | TGT_K, /* immediate "k" value */ | |
49 | TGT_NXT, /* fall through to the next block */ | |
50 | TGT_IMM, /* resolved immediate value */ | |
51 | TGT_PTR_DB, /* pointer to part of the filter db */ | |
52 | TGT_PTR_BLK, /* pointer to an instruction block */ | |
53 | TGT_PTR_HSH, /* pointer to a block hash table */ | |
54 | }; | |
55 | ||
56 | struct bpf_jump { | |
57 | union { | |
58 | uint8_t imm_j; | |
59 | uint32_t imm_k; | |
60 | uint64_t hash; | |
61 | struct db_arg_chain_tree *db; | |
62 | struct bpf_blk *blk; | |
63 | unsigned int nxt; | |
64 | } tgt; | |
65 | enum bpf_jump_type type; | |
66 | }; | |
67 | #define _BPF_JMP_NO \ | |
68 | ((struct bpf_jump) { .type = TGT_NONE }) | |
69 | #define _BPF_JMP_NXT(x) \ | |
70 | ((struct bpf_jump) { .type = TGT_NXT, .tgt = { .nxt = (x) } }) | |
71 | #define _BPF_JMP_IMM(x) \ | |
72 | ((struct bpf_jump) { .type = TGT_IMM, .tgt = { .imm_j = (x) } }) | |
73 | #define _BPF_JMP_DB(x) \ | |
74 | ((struct bpf_jump) { .type = TGT_PTR_DB, .tgt = { .db = (x) } }) | |
75 | #define _BPF_JMP_BLK(x) \ | |
76 | ((struct bpf_jump) { .type = TGT_PTR_BLK, .tgt = { .blk = (x) } }) | |
77 | #define _BPF_JMP_HSH(x) \ | |
78 | ((struct bpf_jump) { .type = TGT_PTR_HSH, .tgt = { .hash = (x) } }) | |
79 | #define _BPF_K(x) \ | |
80 | ((struct bpf_jump) { .type = TGT_K, .tgt = { .imm_k = (x) } }) | |
81 | #define _BPF_JMP_MAX 255 | |
82 | #define _BPF_JMP_MAX_RET 255 | |
83 | ||
84 | struct bpf_instr { | |
85 | uint16_t op; | |
86 | struct bpf_jump jt; | |
87 | struct bpf_jump jf; | |
88 | struct bpf_jump k; | |
89 | }; | |
90 | #define _BPF_OFFSET_SYSCALL (offsetof(struct seccomp_data, nr)) | |
91 | #define _BPF_SYSCALL _BPF_K(_BPF_OFFSET_SYSCALL) | |
92 | ||
93 | struct bpf_blk { | |
94 | struct bpf_instr *blks; | |
95 | unsigned int blk_cnt; | |
96 | unsigned int blk_alloc; | |
97 | ||
98 | /* priority - higher is better */ | |
99 | unsigned int priority; | |
100 | ||
101 | /* status flags */ | |
102 | bool flag_hash; /* added to the hash table */ | |
103 | bool flag_dup; /* duplicate block and in use */ | |
104 | bool flag_unique; /* ->blks is unique to this block */ | |
105 | ||
106 | /* original db_arg_chain_tree node */ | |
107 | const struct db_arg_chain_tree *node; | |
108 | ||
109 | /* used during block assembly */ | |
110 | uint64_t hash; | |
111 | struct bpf_blk *hash_nxt; | |
112 | struct bpf_blk *prev, *next; | |
113 | struct bpf_blk *lvl_prv, *lvl_nxt; | |
114 | struct acc_state acc_state; | |
115 | }; | |
116 | #define _BLK_MSZE(x) \ | |
117 | ((x)->blk_cnt * sizeof(*((x)->blks))) | |
118 | ||
119 | struct bpf_hash_bkt { | |
120 | struct bpf_blk *blk; | |
121 | struct bpf_hash_bkt *next; | |
122 | unsigned int found; | |
123 | }; | |
124 | ||
125 | #define _BPF_HASH_BITS 8 | |
126 | #define _BPF_HASH_SIZE (1 << _BPF_HASH_BITS) | |
127 | #define _BPF_HASH_MASK (_BPF_HASH_BITS - 1) | |
128 | struct bpf_state { | |
129 | /* block hash table */ | |
130 | struct bpf_hash_bkt *htbl[_BPF_HASH_SIZE]; | |
131 | ||
132 | /* filter attributes */ | |
133 | const struct db_filter_attr *attr; | |
134 | /* default action */ | |
135 | uint64_t def_hsh; | |
136 | ||
137 | /* target arch - NOTE: be careful, temporary use only! */ | |
138 | const struct arch_def *arch; | |
139 | ||
140 | /* bpf program */ | |
141 | struct bpf_program *bpf; | |
142 | }; | |
143 | ||
144 | /** | |
145 | * Populate a BPF instruction | |
146 | * @param _ins the BPF instruction | |
147 | * @param _op the BPF operand | |
148 | * @param _jt the BPF jt value | |
149 | * @param _jf the BPF jf value | |
150 | * @param _k the BPF k value | |
151 | * | |
152 | * Set the given values on the provided bpf_instr struct. | |
153 | * | |
154 | */ | |
155 | #define _BPF_INSTR(_ins,_op,_jt,_jf,_k) \ | |
156 | do { \ | |
157 | memset(&(_ins), 0, sizeof(_ins)); \ | |
158 | (_ins).op = (_op); \ | |
159 | (_ins).jt = _jt; \ | |
160 | (_ins).jf = _jf; \ | |
161 | (_ins).k = _k; \ | |
162 | } while (0) | |
163 | ||
164 | static struct bpf_blk *_gen_bpf_chain(struct bpf_state *state, | |
165 | const struct db_sys_list *sys, | |
166 | const struct db_arg_chain_tree *chain, | |
167 | const struct bpf_jump *nxt_jump, | |
168 | struct acc_state *a_state); | |
169 | ||
170 | static struct bpf_blk *_hsh_remove(struct bpf_state *state, uint64_t h_val); | |
171 | static struct bpf_blk *_hsh_find(const struct bpf_state *state, uint64_t h_val); | |
172 | ||
173 | /** | |
174 | * Free the BPF instruction block | |
175 | * @param state the BPF state | |
176 | * @param blk the BPF instruction block | |
177 | * | |
178 | * Free the BPF instruction block, any linked blocks are preserved and the hash | |
179 | * table is not modified. In general, you probably want to use _blk_free() | |
180 | * instead. | |
181 | * | |
182 | */ | |
183 | static void __blk_free(struct bpf_state *state, struct bpf_blk *blk) | |
184 | { | |
185 | struct bpf_blk *b_tmp; | |
186 | ||
187 | while (blk->hash_nxt != NULL) { | |
188 | b_tmp = blk->hash_nxt; | |
189 | blk->hash_nxt = b_tmp->hash_nxt; | |
190 | if (!b_tmp->flag_dup) | |
191 | free(b_tmp); | |
192 | } | |
193 | if (blk->blks != NULL && blk->flag_unique) | |
194 | free(blk->blks); | |
195 | free(blk); | |
196 | } | |
197 | ||
198 | /** | |
199 | * Free the BPF instruction block | |
200 | * @param state the BPF state | |
201 | * @param blk the BPF instruction block | |
202 | * | |
203 | * Free the BPF instruction block including any linked blocks. The hash table | |
204 | * is updated to reflect the newly removed block(s). | |
205 | * | |
206 | */ | |
207 | static void _blk_free(struct bpf_state *state, struct bpf_blk *blk) | |
208 | { | |
209 | int iter; | |
210 | struct bpf_blk *b_iter; | |
211 | struct bpf_instr *i_iter; | |
212 | ||
213 | if (blk == NULL) | |
214 | return; | |
215 | ||
216 | /* remove this block from the hash table */ | |
217 | _hsh_remove(state, blk->hash); | |
218 | ||
219 | /* run through the block freeing TGT_PTR_{BLK,HSH} jump targets */ | |
220 | for (iter = 0; iter < blk->blk_cnt; iter++) { | |
221 | i_iter = &blk->blks[iter]; | |
222 | switch (i_iter->jt.type) { | |
223 | case TGT_PTR_BLK: | |
224 | _blk_free(state, i_iter->jt.tgt.blk); | |
225 | break; | |
226 | case TGT_PTR_HSH: | |
227 | b_iter = _hsh_find(state, i_iter->jt.tgt.hash); | |
228 | _blk_free(state, b_iter); | |
229 | break; | |
230 | default: | |
231 | /* do nothing */ | |
232 | break; | |
233 | } | |
234 | switch (i_iter->jf.type) { | |
235 | case TGT_PTR_BLK: | |
236 | _blk_free(state, i_iter->jf.tgt.blk); | |
237 | break; | |
238 | case TGT_PTR_HSH: | |
239 | b_iter = _hsh_find(state, i_iter->jf.tgt.hash); | |
240 | _blk_free(state, b_iter); | |
241 | break; | |
242 | default: | |
243 | /* do nothing */ | |
244 | break; | |
245 | } | |
246 | } | |
247 | __blk_free(state, blk); | |
248 | } | |
249 | ||
250 | /** | |
251 | * Append a new BPF instruction to an instruction block | |
252 | * @param state the BPF state | |
253 | * @param blk the existing instruction block, or NULL | |
254 | * @param instr the new instruction | |
255 | * | |
256 | * Add the new BPF instruction to the end of the give instruction block. If | |
257 | * the given instruction block is NULL, a new block will be allocated. Returns | |
258 | * a pointer to the block on success, NULL on failure, and in the case of | |
259 | * failure the instruction block is free'd. | |
260 | * | |
261 | */ | |
262 | static struct bpf_blk *_blk_append(struct bpf_state *state, | |
263 | struct bpf_blk *blk, | |
264 | const struct bpf_instr *instr) | |
265 | { | |
266 | struct bpf_instr *new; | |
267 | ||
268 | if (blk == NULL) { | |
269 | blk = malloc(sizeof(*blk)); | |
270 | if (blk == NULL) | |
271 | return NULL; | |
272 | memset(blk, 0, sizeof(*blk)); | |
273 | blk->flag_unique = true; | |
274 | } | |
275 | if ((blk->blk_cnt + 1) > blk->blk_alloc) { | |
276 | blk->blk_alloc += AINC_BLK; | |
277 | new = realloc(blk->blks, blk->blk_alloc * sizeof(*(blk->blks))); | |
278 | if (new == NULL) { | |
279 | _blk_free(state, blk); | |
280 | return NULL; | |
281 | } | |
282 | blk->blks = new; | |
283 | } | |
284 | memcpy(&blk->blks[blk->blk_cnt++], instr, sizeof(*instr)); | |
285 | ||
286 | return blk; | |
287 | } | |
288 | ||
289 | /** | |
290 | * Append a block of BPF instructions to the final BPF program | |
291 | * @param prg the BPF program | |
292 | * @param blk the BPF instruction block | |
293 | * | |
294 | * Add the BPF instruction block to the end of the BPF program and perform the | |
295 | * necssary translation. Returns zero on success, negative values on failure | |
296 | * and in the case of failure the BPF program is free'd. | |
297 | * | |
298 | */ | |
299 | static int _bpf_append_blk(struct bpf_program *prg, const struct bpf_blk *blk) | |
300 | { | |
301 | int rc; | |
302 | bpf_instr_raw *i_new; | |
303 | bpf_instr_raw *i_iter; | |
304 | unsigned int old_cnt = prg->blk_cnt; | |
305 | unsigned int iter; | |
306 | ||
307 | /* (re)allocate the program memory */ | |
308 | prg->blk_cnt += blk->blk_cnt; | |
309 | i_new = realloc(prg->blks, BPF_PGM_SIZE(prg)); | |
310 | if (i_new == NULL) { | |
311 | rc = -ENOMEM; | |
312 | goto bpf_append_blk_failure; | |
313 | } | |
314 | prg->blks = i_new; | |
315 | ||
316 | /* transfer and translate the blocks to raw instructions */ | |
317 | for (iter = 0; iter < blk->blk_cnt; iter++) { | |
318 | i_iter = &(prg->blks[old_cnt + iter]); | |
319 | ||
320 | i_iter->code = blk->blks[iter].op; | |
321 | switch (blk->blks[iter].jt.type) { | |
322 | case TGT_NONE: | |
323 | i_iter->jt = 0; | |
324 | break; | |
325 | case TGT_IMM: | |
326 | /* jump to the value specified */ | |
327 | i_iter->jt = blk->blks[iter].jt.tgt.imm_j; | |
328 | break; | |
329 | default: | |
330 | /* fatal error - we should never get here */ | |
331 | rc = -EFAULT; | |
332 | goto bpf_append_blk_failure; | |
333 | } | |
334 | switch (blk->blks[iter].jf.type) { | |
335 | case TGT_NONE: | |
336 | i_iter->jf = 0; | |
337 | break; | |
338 | case TGT_IMM: | |
339 | /* jump to the value specified */ | |
340 | i_iter->jf = blk->blks[iter].jf.tgt.imm_j; | |
341 | break; | |
342 | default: | |
343 | /* fatal error - we should never get here */ | |
344 | rc = -EFAULT; | |
345 | goto bpf_append_blk_failure; | |
346 | } | |
347 | switch (blk->blks[iter].k.type) { | |
348 | case TGT_NONE: | |
349 | i_iter->k = 0; | |
350 | break; | |
351 | case TGT_K: | |
352 | i_iter->k = blk->blks[iter].k.tgt.imm_k; | |
353 | break; | |
354 | default: | |
355 | /* fatal error - we should never get here */ | |
356 | rc = -EFAULT; | |
357 | goto bpf_append_blk_failure; | |
358 | } | |
359 | } | |
360 | ||
361 | return prg->blk_cnt; | |
362 | ||
363 | bpf_append_blk_failure: | |
364 | prg->blk_cnt = 0; | |
365 | free(prg->blks); | |
366 | return rc; | |
367 | } | |
368 | ||
369 | /** | |
370 | * Free the BPF program | |
371 | * @param prg the BPF program | |
372 | * | |
373 | * Free the BPF program. None of the associated BPF state used to generate the | |
374 | * BPF program is released in this function. | |
375 | * | |
376 | */ | |
377 | static void _program_free(struct bpf_program *prg) | |
378 | { | |
379 | if (prg == NULL) | |
380 | return; | |
381 | ||
382 | if (prg->blks != NULL) | |
383 | free(prg->blks); | |
384 | free(prg); | |
385 | } | |
386 | ||
387 | /** | |
388 | * Free the BPF state | |
389 | * @param the BPF state | |
390 | * | |
391 | * Free all of the BPF state, including the BPF program if present. | |
392 | * | |
393 | */ | |
394 | static void _state_release(struct bpf_state *state) | |
395 | { | |
396 | unsigned int bkt; | |
397 | struct bpf_hash_bkt *iter; | |
398 | ||
399 | if (state == NULL) | |
400 | return; | |
401 | ||
402 | /* release all of the hash table entries */ | |
403 | for (bkt = 0; bkt < _BPF_HASH_SIZE; bkt++) { | |
404 | while (state->htbl[bkt]) { | |
405 | iter = state->htbl[bkt]; | |
406 | state->htbl[bkt] = iter->next; | |
407 | __blk_free(state, iter->blk); | |
408 | free(iter); | |
409 | } | |
410 | } | |
411 | _program_free(state->bpf); | |
412 | ||
413 | memset(state, 0, sizeof(*state)); | |
414 | } | |
415 | ||
416 | /** | |
417 | * Add an instruction block to the BPF state hash table | |
418 | * @param state the BPF state | |
419 | * @param blk_p pointer to the BPF instruction block | |
420 | * @param found initial found value (see _hsh_find_once() for description) | |
421 | * | |
422 | * This function adds an instruction block to the hash table, and frees the | |
423 | * block if an identical instruction block already exists, returning a pointer | |
424 | * to the original block in place of the given block. Returns zero on success | |
425 | * and negative values on failure. | |
426 | * | |
427 | */ | |
428 | static int _hsh_add(struct bpf_state *state, struct bpf_blk **blk_p, | |
429 | unsigned int found) | |
430 | { | |
431 | uint64_t h_val; | |
432 | struct bpf_hash_bkt *h_new, *h_iter, *h_prev = NULL; | |
433 | struct bpf_blk *blk = *blk_p; | |
434 | struct bpf_blk *b_iter; | |
435 | ||
436 | if (blk->flag_hash) | |
437 | return 0; | |
438 | ||
439 | h_new = malloc(sizeof(*h_new)); | |
440 | if (h_new == NULL) | |
441 | return -ENOMEM; | |
442 | memset(h_new, 0, sizeof(*h_new)); | |
443 | ||
444 | /* generate the hash */ | |
445 | h_val = jhash(blk->blks, _BLK_MSZE(blk), 0); | |
446 | blk->hash = h_val; | |
447 | blk->flag_hash = true; | |
448 | blk->node = NULL; | |
449 | h_new->blk = blk; | |
450 | h_new->found = (found ? 1 : 0); | |
451 | ||
452 | /* insert the block into the hash table */ | |
453 | h_iter = state->htbl[h_val & _BPF_HASH_MASK]; | |
454 | if (h_iter != NULL) { | |
455 | do { | |
456 | if ((h_iter->blk->hash == h_val) && | |
457 | (_BLK_MSZE(h_iter->blk) == _BLK_MSZE(blk)) && | |
458 | (memcmp(h_iter->blk->blks, blk->blks, | |
459 | _BLK_MSZE(blk)) == 0)) { | |
460 | /* duplicate block */ | |
461 | free(h_new); | |
462 | ||
463 | /* store the duplicate block */ | |
464 | b_iter = h_iter->blk; | |
465 | while (b_iter->hash_nxt != NULL) | |
466 | b_iter = b_iter->hash_nxt; | |
467 | b_iter->hash_nxt = blk; | |
468 | ||
469 | /* in some cases we want to return the | |
470 | * duplicate block */ | |
471 | if (found) { | |
472 | blk->flag_dup = true; | |
473 | return 0; | |
474 | } | |
475 | ||
476 | /* update the priority if needed */ | |
477 | if (h_iter->blk->priority < blk->priority) | |
478 | h_iter->blk->priority = blk->priority; | |
479 | ||
480 | /* try to save some memory */ | |
481 | free(blk->blks); | |
482 | blk->blks = h_iter->blk->blks; | |
483 | blk->flag_unique = false; | |
484 | ||
485 | *blk_p = h_iter->blk; | |
486 | return 0; | |
487 | } else if (h_iter->blk->hash == h_val) { | |
488 | /* hash collision */ | |
489 | if ((h_val >> 32) == 0xffffffff) { | |
490 | /* overflow */ | |
491 | blk->flag_hash = false; | |
492 | blk->hash = 0; | |
493 | return -EFAULT; | |
494 | } | |
495 | h_val += ((uint64_t)1 << 32); | |
496 | h_new->blk->hash = h_val; | |
497 | ||
498 | /* restart at the beginning of the bucket */ | |
499 | h_iter = state->htbl[h_val & _BPF_HASH_MASK]; | |
500 | } else { | |
501 | /* no match, move along */ | |
502 | h_prev = h_iter; | |
503 | h_iter = h_iter->next; | |
504 | } | |
505 | } while (h_iter != NULL); | |
506 | h_prev->next = h_new; | |
507 | } else | |
508 | state->htbl[h_val & _BPF_HASH_MASK] = h_new; | |
509 | ||
510 | return 0; | |
511 | } | |
512 | ||
513 | /** | |
514 | * Remove an entry from the hash table | |
515 | * @param state the BPF state | |
516 | * @param h_val the hash value | |
517 | * | |
518 | * Remove an entry from the hash table and return it to the caller, NULL is | |
519 | * returned if the entry can not be found. | |
520 | * | |
521 | */ | |
522 | static struct bpf_blk *_hsh_remove(struct bpf_state *state, uint64_t h_val) | |
523 | { | |
524 | unsigned int bkt = h_val & _BPF_HASH_MASK; | |
525 | struct bpf_blk *blk; | |
526 | struct bpf_hash_bkt *h_iter, *h_prev = NULL; | |
527 | ||
528 | h_iter = state->htbl[bkt]; | |
529 | while (h_iter != NULL) { | |
530 | if (h_iter->blk->hash == h_val) { | |
531 | if (h_prev != NULL) | |
532 | h_prev->next = h_iter->next; | |
533 | else | |
534 | state->htbl[bkt] = h_iter->next; | |
535 | blk = h_iter->blk; | |
536 | free(h_iter); | |
537 | return blk; | |
538 | } | |
539 | h_prev = h_iter; | |
540 | h_iter = h_iter->next; | |
541 | } | |
542 | ||
543 | return NULL; | |
544 | } | |
545 | ||
546 | /** | |
547 | * Find and return a hash bucket | |
548 | * @param state the BPF state | |
549 | * @param h_val the hash value | |
550 | * | |
551 | * Find the entry associated with the given hash value and return it to the | |
552 | * caller, NULL is returned if the entry can not be found. This function | |
553 | * should not be called directly; use _hsh_find() and _hsh_find_once() instead. | |
554 | * | |
555 | */ | |
556 | static struct bpf_hash_bkt *_hsh_find_bkt(const struct bpf_state *state, | |
557 | uint64_t h_val) | |
558 | { | |
559 | struct bpf_hash_bkt *h_iter; | |
560 | ||
561 | h_iter = state->htbl[h_val & _BPF_HASH_MASK]; | |
562 | while (h_iter != NULL) { | |
563 | if (h_iter->blk->hash == h_val) | |
564 | return h_iter; | |
565 | h_iter = h_iter->next; | |
566 | } | |
567 | ||
568 | return NULL; | |
569 | } | |
570 | ||
571 | /** | |
572 | * Find and only return an entry in the hash table once | |
573 | * @param state the BPF state | |
574 | * @param h_val the hash value | |
575 | * | |
576 | * Find the entry associated with the given hash value and return it to the | |
577 | * caller if it has not be returned previously by this function; returns NULL | |
578 | * if the entry can not be found or has already been returned in a previous | |
579 | * call. | |
580 | * | |
581 | */ | |
582 | static struct bpf_blk *_hsh_find_once(const struct bpf_state *state, | |
583 | uint64_t h_val) | |
584 | { | |
585 | struct bpf_hash_bkt *h_iter; | |
586 | ||
587 | h_iter = _hsh_find_bkt(state, h_val); | |
588 | if (h_iter == NULL || h_iter->found != 0) | |
589 | return NULL; | |
590 | h_iter->found = 1; | |
591 | return h_iter->blk; | |
592 | } | |
593 | ||
594 | /** | |
595 | * Finds an entry in the hash table | |
596 | * @param state the BPF state | |
597 | * @param h_val the hash value | |
598 | * | |
599 | * Find the entry associated with the given hash value and return it to the | |
600 | * caller, NULL is returned if the entry can not be found. | |
601 | * | |
602 | */ | |
603 | static struct bpf_blk *_hsh_find(const struct bpf_state *state, uint64_t h_val) | |
604 | { | |
605 | struct bpf_hash_bkt *h_iter; | |
606 | ||
607 | h_iter = _hsh_find_bkt(state, h_val); | |
608 | if (h_iter == NULL) | |
609 | return NULL; | |
610 | return h_iter->blk; | |
611 | } | |
612 | ||
613 | /** | |
614 | * Generate a BPF action instruction | |
615 | * @param state the BPF state | |
616 | * @param blk the BPF instruction block, or NULL | |
617 | * @param action the desired action | |
618 | * | |
619 | * Generate a BPF action instruction and append it to the given instruction | |
620 | * block. Returns a pointer to the instruction block on success, NULL on | |
621 | * failure. | |
622 | * | |
623 | */ | |
624 | static struct bpf_blk *_gen_bpf_action(struct bpf_state *state, | |
625 | struct bpf_blk *blk, uint32_t action) | |
626 | { | |
627 | struct bpf_instr instr; | |
628 | ||
629 | _BPF_INSTR(instr, BPF_RET, _BPF_JMP_NO, _BPF_JMP_NO, _BPF_K(action)); | |
630 | return _blk_append(state, blk, &instr); | |
631 | } | |
632 | ||
633 | /** | |
634 | * Generate a BPF action instruction and insert it into the hash table | |
635 | * @param state the BPF state | |
636 | * @param action the desired action | |
637 | * | |
638 | * Generate a BPF action instruction and insert it into the hash table. | |
639 | * Returns a pointer to the instruction block on success, NULL on failure. | |
640 | * | |
641 | */ | |
642 | static struct bpf_blk *_gen_bpf_action_hsh(struct bpf_state *state, | |
643 | uint32_t action) | |
644 | { | |
645 | struct bpf_blk *blk; | |
646 | ||
647 | blk = _gen_bpf_action(state, NULL, action); | |
648 | if (blk == NULL) | |
649 | return NULL; | |
650 | if (_hsh_add(state, &blk, 0) < 0) { | |
651 | _blk_free(state, blk); | |
652 | return NULL; | |
653 | } | |
654 | ||
655 | return blk; | |
656 | } | |
657 | ||
658 | /** | |
659 | * Generate a BPF instruction block for a given chain node | |
660 | * @param state the BPF state | |
661 | * @param node the filter chain node | |
662 | * @param a_state the accumulator state | |
663 | * | |
664 | * Generate BPF instructions to execute the filter for the given chain node. | |
665 | * Returns a pointer to the instruction block on success, NULL on failure. | |
666 | * | |
667 | */ | |
668 | static struct bpf_blk *_gen_bpf_node(struct bpf_state *state, | |
669 | const struct db_arg_chain_tree *node, | |
670 | struct acc_state *a_state) | |
671 | { | |
672 | int32_t acc_offset; | |
673 | uint32_t acc_mask; | |
674 | uint64_t act_t_hash = 0, act_f_hash = 0; | |
675 | struct bpf_blk *blk = NULL, *b_act; | |
676 | struct bpf_instr instr; | |
677 | struct acc_state a_state_orig = *a_state; | |
678 | ||
679 | /* generate the action blocks */ | |
680 | if (node->act_t_flg) { | |
681 | b_act = _gen_bpf_action_hsh(state, node->act_t); | |
682 | if (b_act == NULL) | |
683 | goto node_failure; | |
684 | act_t_hash = b_act->hash; | |
685 | } | |
686 | if (node->act_f_flg) { | |
687 | b_act = _gen_bpf_action_hsh(state, node->act_f); | |
688 | if (b_act == NULL) | |
689 | goto node_failure; | |
690 | act_f_hash = b_act->hash; | |
691 | } | |
692 | ||
693 | /* check the accumulator state */ | |
694 | acc_offset = node->arg_offset; | |
695 | acc_mask = node->mask; | |
696 | if (acc_offset < 0) | |
697 | goto node_failure; | |
698 | if ((acc_offset != a_state->offset) || | |
699 | ((acc_mask & a_state->mask) != acc_mask)) { | |
700 | /* reload the accumulator */ | |
701 | a_state->offset = acc_offset; | |
702 | a_state->mask = ARG_MASK_MAX; | |
703 | _BPF_INSTR(instr, BPF_LD + BPF_ABS, | |
704 | _BPF_JMP_NO, _BPF_JMP_NO, _BPF_K(acc_offset)); | |
705 | blk = _blk_append(state, blk, &instr); | |
706 | if (blk == NULL) | |
707 | goto node_failure; | |
708 | } | |
709 | if (acc_mask != a_state->mask) { | |
710 | /* apply the bitmask */ | |
711 | a_state->mask = acc_mask; | |
712 | _BPF_INSTR(instr, BPF_ALU + BPF_AND, | |
713 | _BPF_JMP_NO, _BPF_JMP_NO, _BPF_K(acc_mask)); | |
714 | blk = _blk_append(state, blk, &instr); | |
715 | if (blk == NULL) | |
716 | goto node_failure; | |
717 | } | |
718 | ||
719 | /* check the accumulator against the datum */ | |
720 | switch (node->op) { | |
721 | case SCMP_CMP_MASKED_EQ: | |
722 | case SCMP_CMP_EQ: | |
723 | _BPF_INSTR(instr, BPF_JMP + BPF_JEQ, | |
724 | _BPF_JMP_NO, _BPF_JMP_NO, _BPF_K(node->datum)); | |
725 | break; | |
726 | case SCMP_CMP_GT: | |
727 | _BPF_INSTR(instr, BPF_JMP + BPF_JGT, | |
728 | _BPF_JMP_NO, _BPF_JMP_NO, _BPF_K(node->datum)); | |
729 | break; | |
730 | case SCMP_CMP_GE: | |
731 | _BPF_INSTR(instr, BPF_JMP + BPF_JGE, | |
732 | _BPF_JMP_NO, _BPF_JMP_NO, _BPF_K(node->datum)); | |
733 | break; | |
734 | case SCMP_CMP_NE: | |
735 | case SCMP_CMP_LT: | |
736 | case SCMP_CMP_LE: | |
737 | /* if we hit here it means the filter db isn't correct */ | |
738 | default: | |
739 | /* fatal error, we should never get here */ | |
740 | goto node_failure; | |
741 | } | |
742 | ||
743 | /* fixup the jump targets */ | |
744 | if (node->nxt_t != NULL) | |
745 | instr.jt = _BPF_JMP_DB(node->nxt_t); | |
746 | else if (node->act_t_flg) | |
747 | instr.jt = _BPF_JMP_HSH(act_t_hash); | |
748 | else | |
749 | instr.jt = _BPF_JMP_NXT(0); | |
750 | if (node->nxt_f != NULL) | |
751 | instr.jf = _BPF_JMP_DB(node->nxt_f); | |
752 | else if (node->act_f_flg) | |
753 | instr.jf = _BPF_JMP_HSH(act_f_hash); | |
754 | else | |
755 | instr.jf = _BPF_JMP_NXT(0); | |
756 | blk = _blk_append(state, blk, &instr); | |
757 | if (blk == NULL) | |
758 | goto node_failure; | |
759 | ||
760 | blk->node = node; | |
761 | blk->acc_state = a_state_orig; | |
762 | return blk; | |
763 | ||
764 | node_failure: | |
765 | _blk_free(state, blk); | |
766 | return NULL; | |
767 | } | |
768 | ||
769 | /** | |
770 | * Resolve the jump targets in a BPF instruction block | |
771 | * @param state the BPF state | |
772 | * @param sys the syscall filter | |
773 | * @param blk the BPF instruction block | |
774 | * @param nxt_jump the jump to fallthrough to at the end of the level | |
775 | * | |
776 | * Resolve the jump targets in a BPF instruction block generated by the | |
777 | * _gen_bpf_chain_lvl() function and adds the resulting block to the hash | |
778 | * table. Returns a pointer to the new instruction block on success, NULL on | |
779 | * failure. | |
780 | * | |
781 | */ | |
782 | static struct bpf_blk *_gen_bpf_chain_lvl_res(struct bpf_state *state, | |
783 | const struct db_sys_list *sys, | |
784 | struct bpf_blk *blk, | |
785 | const struct bpf_jump *nxt_jump) | |
786 | { | |
787 | int rc; | |
788 | unsigned int iter; | |
789 | struct bpf_blk *b_new; | |
790 | struct bpf_instr *i_iter; | |
791 | struct db_arg_chain_tree *node; | |
792 | ||
793 | if (blk->flag_hash) | |
794 | return blk; | |
795 | ||
796 | /* convert TGT_PTR_DB to TGT_PTR_HSH references */ | |
797 | for (iter = 0; iter < blk->blk_cnt; iter++) { | |
798 | i_iter = &blk->blks[iter]; | |
799 | switch (i_iter->jt.type) { | |
800 | case TGT_NONE: | |
801 | case TGT_IMM: | |
802 | case TGT_PTR_HSH: | |
803 | /* ignore these jump types */ | |
804 | break; | |
805 | case TGT_PTR_BLK: | |
806 | b_new = _gen_bpf_chain_lvl_res(state, sys, | |
807 | i_iter->jt.tgt.blk, | |
808 | nxt_jump); | |
809 | if (b_new == NULL) | |
810 | return NULL; | |
811 | i_iter->jt = _BPF_JMP_HSH(b_new->hash); | |
812 | break; | |
813 | case TGT_PTR_DB: | |
814 | node = (struct db_arg_chain_tree *)i_iter->jt.tgt.db; | |
815 | b_new = _gen_bpf_chain(state, sys, node, | |
816 | nxt_jump, &blk->acc_state); | |
817 | if (b_new == NULL) | |
818 | return NULL; | |
819 | i_iter->jt = _BPF_JMP_HSH(b_new->hash); | |
820 | break; | |
821 | default: | |
822 | /* we should not be here */ | |
823 | return NULL; | |
824 | } | |
825 | switch (i_iter->jf.type) { | |
826 | case TGT_NONE: | |
827 | case TGT_IMM: | |
828 | case TGT_PTR_HSH: | |
829 | /* ignore these jump types */ | |
830 | break; | |
831 | case TGT_PTR_BLK: | |
832 | b_new = _gen_bpf_chain_lvl_res(state, sys, | |
833 | i_iter->jf.tgt.blk, | |
834 | nxt_jump); | |
835 | if (b_new == NULL) | |
836 | return NULL; | |
837 | i_iter->jf = _BPF_JMP_HSH(b_new->hash); | |
838 | break; | |
839 | case TGT_PTR_DB: | |
840 | node = (struct db_arg_chain_tree *)i_iter->jf.tgt.db; | |
841 | b_new = _gen_bpf_chain(state, sys, node, | |
842 | nxt_jump, &blk->acc_state); | |
843 | if (b_new == NULL) | |
844 | return NULL; | |
845 | i_iter->jf = _BPF_JMP_HSH(b_new->hash); | |
846 | break; | |
847 | default: | |
848 | /* we should not be here */ | |
849 | return NULL; | |
850 | } | |
851 | switch (i_iter->k.type) { | |
852 | case TGT_NONE: | |
853 | case TGT_K: | |
854 | case TGT_PTR_HSH: | |
855 | /* ignore these jump types */ | |
856 | break; | |
857 | default: | |
858 | /* we should not be here */ | |
859 | return NULL; | |
860 | } | |
861 | } | |
862 | ||
863 | /* insert the block into the hash table */ | |
864 | rc = _hsh_add(state, &blk, 0); | |
865 | if (rc < 0) | |
866 | return NULL; | |
867 | ||
868 | return blk; | |
869 | } | |
870 | ||
871 | /** | |
872 | * Generates the BPF instruction blocks for a given filter chain | |
873 | * @param state the BPF state | |
874 | * @param sys the syscall filter | |
875 | * @param chain the filter chain | |
876 | * @param nxt_jump the jump to fallthrough to at the end of the level | |
877 | * @param a_state the accumulator state | |
878 | * | |
879 | * Generate the BPF instruction blocks for the given filter chain and return | |
880 | * a pointer to the first block on success; returns NULL on failure. | |
881 | * | |
882 | */ | |
883 | static struct bpf_blk *_gen_bpf_chain(struct bpf_state *state, | |
884 | const struct db_sys_list *sys, | |
885 | const struct db_arg_chain_tree *chain, | |
886 | const struct bpf_jump *nxt_jump, | |
887 | struct acc_state *a_state) | |
888 | { | |
889 | struct bpf_blk *b_head = NULL, *b_tail = NULL; | |
890 | struct bpf_blk *b_prev, *b_next, *b_iter; | |
891 | struct bpf_instr *i_iter; | |
892 | const struct db_arg_chain_tree *c_iter; | |
893 | unsigned int iter; | |
894 | struct bpf_jump nxt_jump_tmp; | |
895 | ||
896 | if (chain == NULL) { | |
897 | b_head = _gen_bpf_action(state, NULL, sys->action); | |
898 | if (b_head == NULL) | |
899 | goto chain_failure; | |
900 | b_tail = b_head; | |
901 | } else { | |
902 | /* find the starting node of the level */ | |
903 | c_iter = chain; | |
904 | while (c_iter->lvl_prv != NULL) | |
905 | c_iter = c_iter->lvl_prv; | |
906 | ||
907 | /* build all of the blocks for this level */ | |
908 | do { | |
909 | b_iter = _gen_bpf_node(state, c_iter, a_state); | |
910 | if (b_iter == NULL) | |
911 | goto chain_failure; | |
912 | if (b_head != NULL) { | |
913 | b_iter->lvl_prv = b_tail; | |
914 | b_tail->lvl_nxt = b_iter; | |
915 | b_tail = b_iter; | |
916 | } else { | |
917 | b_head = b_iter; | |
918 | b_tail = b_iter; | |
919 | } | |
920 | c_iter = c_iter->lvl_nxt; | |
921 | } while (c_iter != NULL); | |
922 | ||
923 | /* resolve the TGT_NXT jumps */ | |
924 | b_iter = b_head; | |
925 | do { | |
926 | b_next = b_iter->lvl_nxt; | |
927 | for (iter = 0; iter < b_iter->blk_cnt; iter++) { | |
928 | i_iter = &b_iter->blks[iter]; | |
929 | if (i_iter->jt.type == TGT_NXT) { | |
930 | if (i_iter->jt.tgt.nxt != 0) | |
931 | goto chain_failure; | |
932 | if (b_next == NULL) | |
933 | i_iter->jt = *nxt_jump; | |
934 | else | |
935 | i_iter->jt = | |
936 | _BPF_JMP_BLK(b_next); | |
937 | } | |
938 | if (i_iter->jf.type == TGT_NXT) { | |
939 | if (i_iter->jf.tgt.nxt != 0) | |
940 | goto chain_failure; | |
941 | if (b_next == NULL) | |
942 | i_iter->jf = *nxt_jump; | |
943 | else | |
944 | i_iter->jf = | |
945 | _BPF_JMP_BLK(b_next); | |
946 | } | |
947 | } | |
948 | b_iter = b_next; | |
949 | } while (b_iter != NULL); | |
950 | } | |
951 | ||
952 | /* resolve all of the blocks */ | |
953 | memset(&nxt_jump_tmp, 0, sizeof(nxt_jump_tmp)); | |
954 | b_iter = b_tail; | |
955 | do { | |
956 | /* b_iter may change after resolving, so save the linkage */ | |
957 | b_prev = b_iter->lvl_prv; | |
958 | b_next = b_iter->lvl_nxt; | |
959 | ||
960 | nxt_jump_tmp = _BPF_JMP_BLK(b_next); | |
961 | b_iter = _gen_bpf_chain_lvl_res(state, sys, b_iter, | |
962 | (b_next == NULL ? | |
963 | nxt_jump : | |
964 | &nxt_jump_tmp)); | |
965 | if (b_iter == NULL) | |
966 | goto chain_failure; | |
967 | ||
968 | /* restore the block linkage on this level */ | |
969 | if (b_prev != NULL) | |
970 | b_prev->lvl_nxt = b_iter; | |
971 | b_iter->lvl_prv = b_prev; | |
972 | b_iter->lvl_nxt = b_next; | |
973 | if (b_next != NULL) | |
974 | b_next->lvl_prv = b_iter; | |
975 | if (b_iter->lvl_prv == NULL) | |
976 | b_head = b_iter; | |
977 | ||
978 | b_iter = b_prev; | |
979 | } while (b_iter != NULL); | |
980 | ||
981 | return b_head; | |
982 | ||
983 | chain_failure: | |
984 | while (b_head != NULL) { | |
985 | b_iter = b_head; | |
986 | b_head = b_iter->lvl_nxt; | |
987 | _blk_free(state, b_iter); | |
988 | } | |
989 | return NULL; | |
990 | } | |
991 | ||
992 | /** | |
993 | * Generate the BPF instruction blocks for a given syscall | |
994 | * @param state the BPF state | |
995 | * @param sys the syscall filter DB entry | |
996 | * @param nxt_hash the hash value of the next syscall filter DB entry | |
997 | * @param acc_reset accumulator reset flag | |
998 | * | |
999 | * Generate the BPF instruction blocks for the given syscall filter and return | |
1000 | * a pointer to the first block on success; returns NULL on failure. It is | |
1001 | * important to note that the block returned has not been added to the hash | |
1002 | * table, however, any linked/referenced blocks have been added to the hash | |
1003 | * table. | |
1004 | * | |
1005 | */ | |
1006 | static struct bpf_blk *_gen_bpf_syscall(struct bpf_state *state, | |
1007 | const struct db_sys_list *sys, | |
1008 | uint64_t nxt_hash, | |
1009 | bool acc_reset) | |
1010 | { | |
1011 | int rc; | |
1012 | struct bpf_instr instr; | |
1013 | struct bpf_blk *blk_c, *blk_s = NULL; | |
1014 | struct bpf_jump def_jump; | |
1015 | struct acc_state a_state; | |
1016 | ||
1017 | /* we do the memset before the assignment to keep valgrind happy */ | |
1018 | memset(&def_jump, 0, sizeof(def_jump)); | |
1019 | def_jump = _BPF_JMP_HSH(state->def_hsh); | |
1020 | ||
1021 | /* setup the accumulator state */ | |
1022 | if (acc_reset) { | |
1023 | _BPF_INSTR(instr, BPF_LD + BPF_ABS, _BPF_JMP_NO, _BPF_JMP_NO, | |
1024 | _BPF_SYSCALL); | |
1025 | blk_s = _blk_append(state, NULL, &instr); | |
1026 | if (blk_s == NULL) | |
1027 | return NULL; | |
1028 | a_state.offset = _BPF_OFFSET_SYSCALL; | |
1029 | a_state.mask = ARG_MASK_MAX; | |
1030 | } else { | |
1031 | /* set the accumulator state to an unknown value */ | |
1032 | a_state.offset = -1; | |
1033 | a_state.mask = ARG_MASK_MAX; | |
1034 | } | |
1035 | ||
1036 | /* generate the argument chains */ | |
1037 | blk_c = _gen_bpf_chain(state, sys, sys->chains, &def_jump, &a_state); | |
1038 | if (blk_c == NULL) | |
1039 | return NULL; | |
1040 | ||
1041 | /* syscall check */ | |
1042 | _BPF_INSTR(instr, BPF_JMP + BPF_JEQ, | |
1043 | _BPF_JMP_HSH(blk_c->hash), _BPF_JMP_HSH(nxt_hash), | |
1044 | _BPF_K(sys->num)); | |
1045 | blk_s = _blk_append(state, blk_s, &instr); | |
1046 | if (blk_s == NULL) | |
1047 | return NULL; | |
1048 | blk_s->priority = sys->priority; | |
1049 | ||
1050 | /* add to the hash table */ | |
1051 | rc = _hsh_add(state, &blk_s, 1); | |
1052 | if (rc < 0) { | |
1053 | _blk_free(state, blk_s); | |
1054 | return NULL; | |
1055 | } | |
1056 | ||
1057 | return blk_s; | |
1058 | } | |
1059 | ||
1060 | /** | |
1061 | * Generate the BPF instruction blocks for a given filter/architecture | |
1062 | * @param state the BPF state | |
1063 | * @param db the filter DB | |
1064 | * @param db_secondary the secondary DB | |
1065 | * | |
1066 | * Generate the BPF instruction block for the given filter DB(s)/architecture(s) | |
1067 | * and return a pointer to the block on succes, NULL on failure. The resulting | |
1068 | * block assumes that the architecture token has already been loaded into the | |
1069 | * BPF accumulator. | |
1070 | * | |
1071 | */ | |
1072 | static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, | |
1073 | const struct db_filter *db, | |
1074 | const struct db_filter *db_secondary) | |
1075 | { | |
1076 | int rc; | |
1077 | unsigned int blk_cnt = 0; | |
1078 | bool acc_reset; | |
1079 | struct bpf_instr instr; | |
1080 | struct db_sys_list *s_head = NULL, *s_tail = NULL, *s_iter, *s_iter_b; | |
1081 | struct bpf_blk *b_head = NULL, *b_tail = NULL, *b_iter, *b_new; | |
1082 | ||
1083 | state->arch = db->arch; | |
1084 | ||
1085 | /* sort the syscall list */ | |
1086 | db_list_foreach(s_iter, db->syscalls) { | |
1087 | if (s_head != NULL) { | |
1088 | s_iter_b = s_head; | |
1089 | while ((s_iter_b->pri_nxt != NULL) && | |
1090 | (s_iter->priority <= s_iter_b->priority)) | |
1091 | s_iter_b = s_iter_b->pri_nxt; | |
1092 | ||
1093 | if (s_iter->priority > s_iter_b->priority) { | |
1094 | s_iter->pri_prv = s_iter_b->pri_prv; | |
1095 | s_iter->pri_nxt = s_iter_b; | |
1096 | if (s_iter_b == s_head) { | |
1097 | s_head->pri_prv = s_iter; | |
1098 | s_head = s_iter; | |
1099 | } else { | |
1100 | s_iter->pri_prv->pri_nxt = s_iter; | |
1101 | s_iter->pri_nxt->pri_prv = s_iter; | |
1102 | } | |
1103 | } else { | |
1104 | s_iter->pri_prv = s_tail; | |
1105 | s_iter->pri_nxt = NULL; | |
1106 | s_iter->pri_prv->pri_nxt = s_iter; | |
1107 | s_tail = s_iter; | |
1108 | } | |
1109 | } else { | |
1110 | s_head = s_iter; | |
1111 | s_tail = s_iter; | |
1112 | s_head->pri_prv = NULL; | |
1113 | s_head->pri_nxt = NULL; | |
1114 | } | |
1115 | } | |
1116 | if (db_secondary != NULL) { | |
1117 | db_list_foreach(s_iter, db_secondary->syscalls) { | |
1118 | if (s_head != NULL) { | |
1119 | s_iter_b = s_head; | |
1120 | while ((s_iter_b->pri_nxt != NULL) && | |
1121 | (s_iter->priority <= s_iter_b->priority)) | |
1122 | s_iter_b = s_iter_b->pri_nxt; | |
1123 | ||
1124 | if (s_iter->priority > s_iter_b->priority) { | |
1125 | s_iter->pri_prv = s_iter_b->pri_prv; | |
1126 | s_iter->pri_nxt = s_iter_b; | |
1127 | if (s_iter_b == s_head) { | |
1128 | s_head->pri_prv = s_iter; | |
1129 | s_head = s_iter; | |
1130 | } else { | |
1131 | s_iter->pri_prv->pri_nxt = | |
1132 | s_iter; | |
1133 | s_iter->pri_nxt->pri_prv = | |
1134 | s_iter; | |
1135 | } | |
1136 | } else { | |
1137 | s_iter->pri_prv = s_tail; | |
1138 | s_iter->pri_nxt = NULL; | |
1139 | s_iter->pri_prv->pri_nxt = s_iter; | |
1140 | s_tail = s_iter; | |
1141 | } | |
1142 | } else { | |
1143 | s_head = s_iter; | |
1144 | s_tail = s_iter; | |
1145 | s_head->pri_prv = NULL; | |
1146 | s_head->pri_nxt = NULL; | |
1147 | } | |
1148 | } | |
1149 | } | |
1150 | ||
1151 | if ((db->arch->token == SCMP_ARCH_X86_64 || | |
1152 | db->arch->token == SCMP_ARCH_X32) && (db_secondary == NULL)) | |
1153 | acc_reset = false; | |
1154 | else | |
1155 | acc_reset = true; | |
1156 | ||
1157 | /* create the syscall filters and add them to block list group */ | |
1158 | for (s_iter = s_tail; s_iter != NULL; s_iter = s_iter->pri_prv) { | |
1159 | if (!s_iter->valid) | |
1160 | continue; | |
1161 | ||
1162 | /* build the syscall filter */ | |
1163 | b_new = _gen_bpf_syscall(state, s_iter, | |
1164 | (b_head == NULL ? | |
1165 | state->def_hsh : b_head->hash), | |
1166 | (s_iter == s_head ? | |
1167 | acc_reset : false)); | |
1168 | if (b_new == NULL) | |
1169 | goto arch_failure; | |
1170 | ||
1171 | /* add the filter to the list head */ | |
1172 | b_new->prev = NULL; | |
1173 | b_new->next = b_head; | |
1174 | if (b_tail != NULL) { | |
1175 | b_head->prev = b_new; | |
1176 | b_head = b_new; | |
1177 | } else { | |
1178 | b_head = b_new; | |
1179 | b_tail = b_head; | |
1180 | } | |
1181 | ||
1182 | if (b_tail->next != NULL) | |
1183 | b_tail = b_tail->next; | |
1184 | blk_cnt++; | |
1185 | } | |
1186 | ||
1187 | /* additional ABI filtering */ | |
1188 | if ((db->arch->token == SCMP_ARCH_X86_64 || | |
1189 | db->arch->token == SCMP_ARCH_X32) && (db_secondary == NULL)) { | |
1190 | _BPF_INSTR(instr, BPF_LD + BPF_ABS, _BPF_JMP_NO, _BPF_JMP_NO, | |
1191 | _BPF_SYSCALL); | |
1192 | b_new = _blk_append(state, NULL, &instr); | |
1193 | if (b_new == NULL) | |
1194 | goto arch_failure; | |
1195 | if (db->arch->token == SCMP_ARCH_X86_64) { | |
1196 | /* filter out x32 */ | |
1197 | _BPF_INSTR(instr, BPF_JMP + BPF_JGE, | |
1198 | _BPF_JMP_NXT(blk_cnt++), _BPF_JMP_NO, | |
1199 | _BPF_K(X32_SYSCALL_BIT)); | |
1200 | if (b_head != NULL) | |
1201 | instr.jf = _BPF_JMP_HSH(b_head->hash); | |
1202 | else | |
1203 | instr.jf = _BPF_JMP_HSH(state->def_hsh); | |
1204 | } else if (db->arch->token == SCMP_ARCH_X32) { | |
1205 | /* filter out x86_64 */ | |
1206 | _BPF_INSTR(instr, BPF_JMP + BPF_JGE, | |
1207 | _BPF_JMP_NO, _BPF_JMP_NXT(blk_cnt++), | |
1208 | _BPF_K(X32_SYSCALL_BIT)); | |
1209 | if (b_head != NULL) | |
1210 | instr.jt = _BPF_JMP_HSH(b_head->hash); | |
1211 | else | |
1212 | instr.jt = _BPF_JMP_HSH(state->def_hsh); | |
1213 | } else | |
1214 | /* we should never get here */ | |
1215 | goto arch_failure; | |
1216 | b_new = _blk_append(state, b_new, &instr); | |
1217 | if (b_new == NULL) | |
1218 | goto arch_failure; | |
1219 | b_new->next = b_head; | |
1220 | if (b_head != NULL) | |
1221 | b_head->prev = b_new; | |
1222 | b_head = b_new; | |
1223 | rc = _hsh_add(state, &b_head, 1); | |
1224 | if (rc < 0) | |
1225 | goto arch_failure; | |
1226 | } | |
1227 | ||
1228 | /* do the ABI/architecture check */ | |
1229 | _BPF_INSTR(instr, BPF_JMP + BPF_JEQ, | |
1230 | _BPF_JMP_NO, _BPF_JMP_NXT(blk_cnt++), | |
1231 | _BPF_K(db->arch->token_bpf)); | |
1232 | if (b_head != NULL) | |
1233 | instr.jt = _BPF_JMP_HSH(b_head->hash); | |
1234 | else | |
1235 | instr.jt = _BPF_JMP_HSH(state->def_hsh); | |
1236 | b_new = _blk_append(state, NULL, &instr); | |
1237 | if (b_new == NULL) | |
1238 | goto arch_failure; | |
1239 | b_new->next = b_head; | |
1240 | if (b_head != NULL) | |
1241 | b_head->prev = b_new; | |
1242 | b_head = b_new; | |
1243 | rc = _hsh_add(state, &b_head, 1); | |
1244 | if (rc < 0) | |
1245 | goto arch_failure; | |
1246 | ||
1247 | state->arch = NULL; | |
1248 | return b_head; | |
1249 | ||
1250 | arch_failure: | |
1251 | /* NOTE: we do the cleanup here and not just return an error as all of | |
1252 | * the instruction blocks may not be added to the hash table when we | |
1253 | * hit an error */ | |
1254 | state->arch = NULL; | |
1255 | b_iter = b_head; | |
1256 | while (b_iter != NULL) { | |
1257 | b_new = b_iter->next; | |
1258 | _blk_free(state, b_iter); | |
1259 | b_iter = b_new; | |
1260 | } | |
1261 | return NULL; | |
1262 | } | |
1263 | ||
1264 | /** | |
1265 | * Find the target block for the "next" jump | |
1266 | * @param blk the instruction block | |
1267 | * @param nxt the next offset | |
1268 | * | |
1269 | * Find the target block for the TGT_NXT jump using the given offset. Returns | |
1270 | * a pointer to the target block on success or NULL on failure. | |
1271 | * | |
1272 | */ | |
1273 | static struct bpf_blk *_gen_bpf_find_nxt(const struct bpf_blk *blk, | |
1274 | unsigned int nxt) | |
1275 | { | |
1276 | struct bpf_blk *iter = blk->next; | |
1277 | ||
1278 | for (; (iter != NULL) && (nxt > 0); nxt--) | |
1279 | iter = iter->next; | |
1280 | ||
1281 | return iter; | |
1282 | } | |
1283 | ||
1284 | /** | |
1285 | * Manage jumps to return instructions | |
1286 | * @param state the BPF state | |
1287 | * @param blk the instruction block to check | |
1288 | * @param offset the instruction offset into the instruction block | |
1289 | * @param blk_ret the return instruction block | |
1290 | * | |
1291 | * Using the given block and instruction offset, calculate the jump distance | |
1292 | * between the jumping instruction and return instruction block. If the jump | |
1293 | * distance is too great, duplicate the return instruction to reduce the | |
1294 | * distance to the maximum value. Returns 1 if a long jump was added, zero if | |
1295 | * the existing jump is valid, and negative values on failure. | |
1296 | * | |
1297 | */ | |
1298 | static int _gen_bpf_build_jmp_ret(struct bpf_state *state, | |
1299 | struct bpf_blk *blk, unsigned int offset, | |
1300 | struct bpf_blk *blk_ret) | |
1301 | { | |
1302 | unsigned int j_len; | |
1303 | uint64_t tgt_hash = blk_ret->hash; | |
1304 | struct bpf_blk *b_jmp, *b_new; | |
1305 | ||
1306 | /* calculate the jump distance */ | |
1307 | j_len = blk->blk_cnt - (offset + 1); | |
1308 | b_jmp = blk->next; | |
1309 | while (b_jmp != NULL && b_jmp != blk_ret && j_len < _BPF_JMP_MAX_RET) { | |
1310 | j_len += b_jmp->blk_cnt; | |
1311 | b_jmp = b_jmp->next; | |
1312 | } | |
1313 | if (j_len <= _BPF_JMP_MAX_RET && b_jmp == blk_ret) | |
1314 | return 0; | |
1315 | if (b_jmp == NULL) | |
1316 | return -EFAULT; | |
1317 | ||
1318 | /* we need a closer return instruction, see if one already exists */ | |
1319 | j_len = blk->blk_cnt - (offset + 1); | |
1320 | b_jmp = blk->next; | |
1321 | while (b_jmp != NULL && b_jmp->hash != tgt_hash && | |
1322 | j_len < _BPF_JMP_MAX_RET) { | |
1323 | j_len += b_jmp->blk_cnt; | |
1324 | b_jmp = b_jmp->next; | |
1325 | } | |
1326 | if (j_len <= _BPF_JMP_MAX_RET && b_jmp->hash == tgt_hash) | |
1327 | return 0; | |
1328 | if (b_jmp == NULL) | |
1329 | return -EFAULT; | |
1330 | ||
1331 | /* we need to insert a new return instruction - create one */ | |
1332 | b_new = _gen_bpf_action(state, NULL, blk_ret->blks[0].k.tgt.imm_k); | |
1333 | if (b_new == NULL) | |
1334 | return -EFAULT; | |
1335 | ||
1336 | /* NOTE - we need to be careful here, we're giving the block a hash | |
1337 | * value (this is a sneaky way to ensure we leverage the | |
1338 | * inserted long jumps as much as possible) but we never add the | |
1339 | * block to the hash table so it won't get cleaned up | |
1340 | * automatically */ | |
1341 | b_new->hash = tgt_hash; | |
1342 | ||
1343 | /* insert the jump after the current jumping block */ | |
1344 | b_new->prev = blk; | |
1345 | b_new->next = blk->next; | |
1346 | blk->next->prev = b_new; | |
1347 | blk->next = b_new; | |
1348 | ||
1349 | return 1; | |
1350 | } | |
1351 | ||
1352 | /** | |
1353 | * Manage jump lengths by duplicating and adding jumps if needed | |
1354 | * @param state the BPF state | |
1355 | * @param tail the tail of the instruction block list | |
1356 | * @param blk the instruction block to check | |
1357 | * @param offset the instruction offset into the instruction block | |
1358 | * @param tgt_hash the hash of the jump destination block | |
1359 | * | |
1360 | * Using the given block and instruction offset, calculate the jump distance | |
1361 | * between the jumping instruction and the destination. If the jump distance | |
1362 | * is too great, add a long jump instruction to reduce the distance to a legal | |
1363 | * value. Returns 1 if a new instruction was added, zero if the existing jump | |
1364 | * is valid, and negative values on failure. | |
1365 | * | |
1366 | */ | |
1367 | static int _gen_bpf_build_jmp(struct bpf_state *state, | |
1368 | struct bpf_blk *tail, | |
1369 | struct bpf_blk *blk, unsigned int offset, | |
1370 | uint64_t tgt_hash) | |
1371 | { | |
1372 | int rc; | |
1373 | unsigned int jmp_len; | |
1374 | struct bpf_instr instr; | |
1375 | struct bpf_blk *b_new, *b_jmp, *b_tgt; | |
1376 | ||
1377 | /* find the jump target */ | |
1378 | b_tgt = tail; | |
1379 | while (b_tgt != blk && b_tgt->hash != tgt_hash) | |
1380 | b_tgt = b_tgt->prev; | |
1381 | if (b_tgt == blk) | |
1382 | return -EFAULT; | |
1383 | ||
1384 | if (b_tgt->blk_cnt == 1 && b_tgt->blks[0].op == BPF_RET) { | |
1385 | rc = _gen_bpf_build_jmp_ret(state, blk, offset, b_tgt); | |
1386 | if (rc == 1) | |
1387 | return 1; | |
1388 | else if (rc < 0) | |
1389 | return rc; | |
1390 | } | |
1391 | ||
1392 | /* calculate the jump distance */ | |
1393 | jmp_len = blk->blk_cnt - (offset + 1); | |
1394 | b_jmp = blk->next; | |
1395 | while (b_jmp != NULL && b_jmp != b_tgt && jmp_len < _BPF_JMP_MAX) { | |
1396 | jmp_len += b_jmp->blk_cnt; | |
1397 | b_jmp = b_jmp->next; | |
1398 | } | |
1399 | if (jmp_len <= _BPF_JMP_MAX && b_jmp == b_tgt) | |
1400 | return 0; | |
1401 | if (b_jmp == NULL) | |
1402 | return -EFAULT; | |
1403 | ||
1404 | /* we need a long jump, see if one already exists */ | |
1405 | jmp_len = blk->blk_cnt - (offset + 1); | |
1406 | b_jmp = blk->next; | |
1407 | while (b_jmp != NULL && b_jmp->hash != tgt_hash && | |
1408 | jmp_len < _BPF_JMP_MAX) { | |
1409 | jmp_len += b_jmp->blk_cnt; | |
1410 | b_jmp = b_jmp->next; | |
1411 | } | |
1412 | if (jmp_len <= _BPF_JMP_MAX && b_jmp->hash == tgt_hash) | |
1413 | return 0; | |
1414 | if (b_jmp == NULL) | |
1415 | return -EFAULT; | |
1416 | ||
1417 | /* we need to insert a long jump - create one */ | |
1418 | _BPF_INSTR(instr, BPF_JMP + BPF_JA, | |
1419 | _BPF_JMP_NO, _BPF_JMP_NO, _BPF_JMP_HSH(tgt_hash)); | |
1420 | b_new = _blk_append(state, NULL, &instr); | |
1421 | if (b_new == NULL) | |
1422 | return -EFAULT; | |
1423 | ||
1424 | /* NOTE - we need to be careful here, we're giving the block a hash | |
1425 | * value (this is a sneaky way to ensure we leverage the | |
1426 | * inserted long jumps as much as possible) but we never add the | |
1427 | * block to the hash table so it won't get cleaned up | |
1428 | * automatically */ | |
1429 | b_new->hash = tgt_hash; | |
1430 | ||
1431 | /* insert the jump after the current jumping block */ | |
1432 | b_new->prev = blk; | |
1433 | b_new->next = blk->next; | |
1434 | blk->next->prev = b_new; | |
1435 | blk->next = b_new; | |
1436 | ||
1437 | return 1; | |
1438 | } | |
1439 | ||
1440 | /** | |
1441 | * Generate the BPF program for the given filter collection | |
1442 | * @param state the BPF state | |
1443 | * @param col the filter collection | |
1444 | * | |
1445 | * Generate the BPF program for the given filter collection. Returns zero on | |
1446 | * success, negative values on failure. | |
1447 | * | |
1448 | */ | |
1449 | static int _gen_bpf_build_bpf(struct bpf_state *state, | |
1450 | const struct db_filter_col *col) | |
1451 | { | |
1452 | int rc; | |
1453 | int iter; | |
1454 | uint64_t h_val; | |
1455 | unsigned int res_cnt; | |
1456 | unsigned int jmp_len; | |
1457 | int arch_x86_64 = -1, arch_x32 = -1; | |
1458 | struct bpf_instr instr; | |
1459 | struct bpf_instr *i_iter; | |
1460 | struct bpf_blk *b_badarch, *b_default; | |
1461 | struct bpf_blk *b_head = NULL, *b_tail = NULL, *b_iter, *b_new, *b_jmp; | |
1462 | struct db_filter *db_secondary = NULL; | |
1463 | ||
1464 | if (col->filter_cnt == 0) | |
1465 | return -EINVAL; | |
1466 | ||
1467 | /* generate the badarch action */ | |
1468 | b_badarch = _gen_bpf_action(state, NULL, state->attr->act_badarch); | |
1469 | if (b_badarch == NULL) | |
1470 | return -ENOMEM; | |
1471 | rc = _hsh_add(state, &b_badarch, 1); | |
1472 | if (rc < 0) | |
1473 | return rc; | |
1474 | ||
1475 | /* generate the default action */ | |
1476 | b_default = _gen_bpf_action(state, NULL, state->attr->act_default); | |
1477 | if (b_default == NULL) | |
1478 | return -ENOMEM; | |
1479 | rc = _hsh_add(state, &b_default, 0); | |
1480 | if (rc < 0) | |
1481 | return rc; | |
1482 | state->def_hsh = b_default->hash; | |
1483 | ||
1484 | /* load the architecture token/number */ | |
1485 | _BPF_INSTR(instr, BPF_LD + BPF_ABS, _BPF_JMP_NO, _BPF_JMP_NO, | |
1486 | _BPF_K(offsetof(struct seccomp_data, arch))); | |
1487 | b_head = _blk_append(state, NULL, &instr); | |
1488 | if (b_head == NULL) | |
1489 | return -ENOMEM; | |
1490 | rc = _hsh_add(state, &b_head, 1); | |
1491 | if (rc < 0) | |
1492 | return rc; | |
1493 | b_tail = b_head; | |
1494 | ||
1495 | /* generate the per-architecture filters */ | |
1496 | for (iter = 0; iter < col->filter_cnt; iter++) { | |
1497 | if (col->filters[iter]->arch->token == SCMP_ARCH_X86_64) | |
1498 | arch_x86_64 = iter; | |
1499 | if (col->filters[iter]->arch->token == SCMP_ARCH_X32) | |
1500 | arch_x32 = iter; | |
1501 | } | |
1502 | for (iter = 0; iter < col->filter_cnt; iter++) { | |
1503 | /* figure out the secondary arch filter mess */ | |
1504 | if (iter == arch_x86_64) { | |
1505 | if (arch_x32 > iter) | |
1506 | db_secondary = col->filters[arch_x32]; | |
1507 | else if (arch_x32 >= 0) | |
1508 | continue; | |
1509 | } else if (iter == arch_x32) { | |
1510 | if (arch_x86_64 > iter) | |
1511 | db_secondary = col->filters[arch_x86_64]; | |
1512 | else if (arch_x86_64 >= 0) | |
1513 | continue; | |
1514 | } else | |
1515 | db_secondary = NULL; | |
1516 | ||
1517 | /* create the filter for the architecture(s) */ | |
1518 | b_new = _gen_bpf_arch(state, col->filters[iter], db_secondary); | |
1519 | if (b_new == NULL) | |
1520 | return -ENOMEM; | |
1521 | b_new->prev = b_tail; | |
1522 | b_tail->next = b_new; | |
1523 | b_tail = b_new; | |
1524 | while (b_tail->next != NULL) | |
1525 | b_tail = b_tail->next; | |
1526 | } | |
1527 | ||
1528 | /* add a badarch action to the end */ | |
1529 | b_badarch->prev = b_tail; | |
1530 | b_badarch->next = NULL; | |
1531 | b_tail->next = b_badarch; | |
1532 | b_tail = b_badarch; | |
1533 | ||
1534 | /* resolve any TGT_NXT jumps at the top level */ | |
1535 | b_iter = b_head; | |
1536 | do { | |
1537 | for (iter = 0; iter < b_iter->blk_cnt; iter++) { | |
1538 | i_iter = &b_iter->blks[iter]; | |
1539 | if (i_iter->jt.type == TGT_NXT) { | |
1540 | b_jmp = _gen_bpf_find_nxt(b_iter, | |
1541 | i_iter->jt.tgt.nxt); | |
1542 | if (b_jmp == NULL) | |
1543 | return -EFAULT; | |
1544 | i_iter->jt = _BPF_JMP_HSH(b_jmp->hash); | |
1545 | } | |
1546 | if (i_iter->jf.type == TGT_NXT) { | |
1547 | b_jmp = _gen_bpf_find_nxt(b_iter, | |
1548 | i_iter->jf.tgt.nxt); | |
1549 | if (b_jmp == NULL) | |
1550 | return -EFAULT; | |
1551 | i_iter->jf = _BPF_JMP_HSH(b_jmp->hash); | |
1552 | } | |
1553 | /* we shouldn't need to worry about a TGT_NXT in k */ | |
1554 | } | |
1555 | b_iter = b_iter->next; | |
1556 | } while (b_iter != NULL && b_iter->next != NULL); | |
1557 | ||
1558 | /* pull in all of the TGT_PTR_HSH jumps, one layer at a time */ | |
1559 | b_iter = b_tail; | |
1560 | do { | |
1561 | b_jmp = NULL; | |
1562 | /* look for jumps - backwards (shorter jumps) */ | |
1563 | for (iter = b_iter->blk_cnt - 1; | |
1564 | (iter >= 0) && (b_jmp == NULL); | |
1565 | iter--) { | |
1566 | i_iter = &b_iter->blks[iter]; | |
1567 | if (i_iter->jt.type == TGT_PTR_HSH) | |
1568 | b_jmp = _hsh_find_once(state, | |
1569 | i_iter->jt.tgt.hash); | |
1570 | if (b_jmp == NULL && i_iter->jf.type == TGT_PTR_HSH) | |
1571 | b_jmp = _hsh_find_once(state, | |
1572 | i_iter->jf.tgt.hash); | |
1573 | if (b_jmp == NULL && i_iter->k.type == TGT_PTR_HSH) | |
1574 | b_jmp = _hsh_find_once(state, | |
1575 | i_iter->k.tgt.hash); | |
1576 | if (b_jmp != NULL) { | |
1577 | /* insert the new block after this block */ | |
1578 | b_jmp->prev = b_iter; | |
1579 | b_jmp->next = b_iter->next; | |
1580 | b_iter->next = b_jmp; | |
1581 | if (b_jmp->next) | |
1582 | b_jmp->next->prev = b_jmp; | |
1583 | } | |
1584 | } | |
1585 | if (b_jmp != NULL) { | |
1586 | while (b_tail->next != NULL) | |
1587 | b_tail = b_tail->next; | |
1588 | b_iter = b_tail; | |
1589 | } else | |
1590 | b_iter = b_iter->prev; | |
1591 | } while (b_iter != NULL); | |
1592 | ||
1593 | /* NOTE - from here to the end of the function we need to fail via the | |
1594 | * the build_bpf_free_blks label, not just return an error; see | |
1595 | * the _gen_bpf_build_jmp() function for details */ | |
1596 | ||
1597 | /* check for long jumps and insert if necessary, we also verify that | |
1598 | * all our jump targets are valid at this point in the process */ | |
1599 | b_iter = b_tail; | |
1600 | do { | |
1601 | res_cnt = 0; | |
1602 | for (iter = b_iter->blk_cnt - 1; iter >= 0; iter--) { | |
1603 | i_iter = &b_iter->blks[iter]; | |
1604 | switch (i_iter->jt.type) { | |
1605 | case TGT_NONE: | |
1606 | case TGT_IMM: | |
1607 | break; | |
1608 | case TGT_PTR_HSH: | |
1609 | h_val = i_iter->jt.tgt.hash; | |
1610 | rc = _gen_bpf_build_jmp(state, b_tail, | |
1611 | b_iter, iter, | |
1612 | h_val); | |
1613 | if (rc < 0) | |
1614 | goto build_bpf_free_blks; | |
1615 | res_cnt += rc; | |
1616 | break; | |
1617 | default: | |
1618 | /* fatal error */ | |
1619 | goto build_bpf_free_blks; | |
1620 | } | |
1621 | switch (i_iter->jf.type) { | |
1622 | case TGT_NONE: | |
1623 | case TGT_IMM: | |
1624 | break; | |
1625 | case TGT_PTR_HSH: | |
1626 | h_val = i_iter->jf.tgt.hash; | |
1627 | rc = _gen_bpf_build_jmp(state, b_tail, | |
1628 | b_iter, iter, | |
1629 | h_val); | |
1630 | if (rc < 0) | |
1631 | goto build_bpf_free_blks; | |
1632 | res_cnt += rc; | |
1633 | break; | |
1634 | default: | |
1635 | /* fatal error */ | |
1636 | goto build_bpf_free_blks; | |
1637 | } | |
1638 | } | |
1639 | if (res_cnt == 0) | |
1640 | b_iter = b_iter->prev; | |
1641 | } while (b_iter != NULL); | |
1642 | ||
1643 | /* build the bpf program */ | |
1644 | do { | |
1645 | b_iter = b_head; | |
1646 | /* resolve the TGT_PTR_HSH jumps */ | |
1647 | for (iter = 0; iter < b_iter->blk_cnt; iter++) { | |
1648 | i_iter = &b_iter->blks[iter]; | |
1649 | if (i_iter->jt.type == TGT_PTR_HSH) { | |
1650 | h_val = i_iter->jt.tgt.hash; | |
1651 | jmp_len = b_iter->blk_cnt - (iter + 1); | |
1652 | b_jmp = b_iter->next; | |
1653 | while (b_jmp != NULL && b_jmp->hash != h_val) { | |
1654 | jmp_len += b_jmp->blk_cnt; | |
1655 | b_jmp = b_jmp->next; | |
1656 | } | |
1657 | if (b_jmp == NULL || jmp_len > _BPF_JMP_MAX) | |
1658 | goto build_bpf_free_blks; | |
1659 | i_iter->jt = _BPF_JMP_IMM(jmp_len); | |
1660 | } | |
1661 | if (i_iter->jf.type == TGT_PTR_HSH) { | |
1662 | h_val = i_iter->jf.tgt.hash; | |
1663 | jmp_len = b_iter->blk_cnt - (iter + 1); | |
1664 | b_jmp = b_iter->next; | |
1665 | while (b_jmp != NULL && b_jmp->hash != h_val) { | |
1666 | jmp_len += b_jmp->blk_cnt; | |
1667 | b_jmp = b_jmp->next; | |
1668 | } | |
1669 | if (b_jmp == NULL || jmp_len > _BPF_JMP_MAX) | |
1670 | goto build_bpf_free_blks; | |
1671 | i_iter->jf = _BPF_JMP_IMM(jmp_len); | |
1672 | } | |
1673 | if (i_iter->k.type == TGT_PTR_HSH) { | |
1674 | h_val = i_iter->k.tgt.hash; | |
1675 | jmp_len = b_iter->blk_cnt - (iter + 1); | |
1676 | b_jmp = b_tail; | |
1677 | while (b_jmp->hash != h_val) | |
1678 | b_jmp = b_jmp->prev; | |
1679 | b_jmp = b_jmp->prev; | |
1680 | while (b_jmp != b_iter) { | |
1681 | jmp_len += b_jmp->blk_cnt; | |
1682 | b_jmp = b_jmp->prev; | |
1683 | } | |
1684 | if (b_jmp == NULL) | |
1685 | goto build_bpf_free_blks; | |
1686 | i_iter->k = _BPF_K(jmp_len); | |
1687 | } | |
1688 | } | |
1689 | ||
1690 | /* build the bpf program */ | |
1691 | if (_bpf_append_blk(state->bpf, b_iter) < 0) | |
1692 | goto build_bpf_free_blks; | |
1693 | ||
1694 | /* we're done with the block, free it */ | |
1695 | b_head = b_iter->next; | |
1696 | _blk_free(state, b_iter); | |
1697 | } while (b_head != NULL); | |
1698 | ||
1699 | return 0; | |
1700 | ||
1701 | build_bpf_free_blks: | |
1702 | b_iter = b_head; | |
1703 | while (b_iter != NULL) { | |
1704 | b_jmp = b_iter->next; | |
1705 | _hsh_remove(state, b_iter->hash); | |
1706 | __blk_free(state, b_iter); | |
1707 | b_iter = b_jmp; | |
1708 | } | |
1709 | return -EFAULT; | |
1710 | } | |
1711 | ||
1712 | /** | |
1713 | * Generate a BPF representation of the filter DB | |
1714 | * @param col the seccomp filter collection | |
1715 | * | |
1716 | * This function generates a BPF representation of the given filter collection. | |
1717 | * Returns a pointer to a valid bpf_program on success, NULL on failure. | |
1718 | * | |
1719 | */ | |
1720 | struct bpf_program *gen_bpf_generate(const struct db_filter_col *col) | |
1721 | { | |
1722 | int rc; | |
1723 | struct bpf_state state; | |
1724 | ||
1725 | memset(&state, 0, sizeof(state)); | |
1726 | state.attr = &col->attr; | |
1727 | ||
1728 | state.bpf = malloc(sizeof(*(state.bpf))); | |
1729 | if (state.bpf == NULL) | |
1730 | return NULL; | |
1731 | memset(state.bpf, 0, sizeof(*(state.bpf))); | |
1732 | ||
1733 | rc = _gen_bpf_build_bpf(&state, col); | |
1734 | if (rc < 0) | |
1735 | goto bpf_generate_end; | |
1736 | ||
1737 | bpf_generate_end: | |
1738 | if (rc < 0) | |
1739 | _state_release(&state); | |
1740 | return state.bpf; | |
1741 | } | |
1742 | ||
1743 | /** | |
1744 | * Free memory associated with a BPF representation | |
1745 | * @param fprog the BPF representation | |
1746 | * | |
1747 | * Free the memory associated with a BPF representation generated by the | |
1748 | * gen_bpf_generate() function. | |
1749 | * | |
1750 | */ | |
1751 | void gen_bpf_release(struct bpf_program *program) | |
1752 | { | |
1753 | _program_free(program); | |
1754 | } |
0 | /** | |
1 | * Seccomp BPF Translator | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #ifndef _TRANSLATOR_BPF_H | |
22 | #define _TRANSLATOR_BPF_H | |
23 | ||
24 | #include <inttypes.h> | |
25 | ||
26 | #include "arch.h" | |
27 | #include "db.h" | |
28 | #include "system.h" | |
29 | ||
30 | /* NOTE - do not change this structure, it is part of the prctl() API */ | |
31 | struct bpf_program { | |
32 | uint16_t blk_cnt; | |
33 | bpf_instr_raw *blks; | |
34 | }; | |
35 | #define BPF_PGM_SIZE(x) \ | |
36 | ((x)->blk_cnt * sizeof(*((x)->blks))) | |
37 | ||
38 | struct bpf_program *gen_bpf_generate(const struct db_filter_col *col); | |
39 | void gen_bpf_release(struct bpf_program *program); | |
40 | ||
41 | #endif |
0 | /** | |
1 | * Seccomp Pseudo Filter Code (PFC) Generator | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <errno.h> | |
22 | #include <inttypes.h> | |
23 | #include <stdlib.h> | |
24 | #include <stdio.h> | |
25 | #include <string.h> | |
26 | #include <unistd.h> | |
27 | ||
28 | /* NOTE: needed for the arch->token decoding in _pfc_arch() */ | |
29 | #include <linux/audit.h> | |
30 | ||
31 | #include <seccomp.h> | |
32 | ||
33 | #include "arch.h" | |
34 | #include "db.h" | |
35 | #include "gen_pfc.h" | |
36 | ||
37 | struct pfc_sys_list { | |
38 | struct db_sys_list *sys; | |
39 | struct pfc_sys_list *next; | |
40 | }; | |
41 | ||
42 | /* XXX - we should check the fprintf() return values */ | |
43 | ||
44 | /** | |
45 | * Display a string representation of the architecture | |
46 | * @param arch the architecture definition | |
47 | */ | |
48 | static const char *_pfc_arch(const struct arch_def *arch) | |
49 | { | |
50 | switch (arch->token) { | |
51 | case SCMP_ARCH_X86: | |
52 | return "x86"; | |
53 | case SCMP_ARCH_X86_64: | |
54 | return "x86_64"; | |
55 | case SCMP_ARCH_X32: | |
56 | return "x32"; | |
57 | case SCMP_ARCH_ARM: | |
58 | return "arm"; | |
59 | default: | |
60 | return "UNKNOWN"; | |
61 | } | |
62 | } | |
63 | ||
64 | /** | |
65 | * Display a string representation of the node argument | |
66 | * @param fds the file stream to send the output | |
67 | * @param arch the architecture definition | |
68 | * @param node the node | |
69 | */ | |
70 | static void _pfc_arg(FILE *fds, | |
71 | const struct arch_def *arch, | |
72 | const struct db_arg_chain_tree *node) | |
73 | { | |
74 | if (arch->size == ARCH_SIZE_64) { | |
75 | if (arch_arg_offset_hi(arch, node->arg) == node->arg_offset) | |
76 | fprintf(fds, "$a%d.hi32", node->arg); | |
77 | else | |
78 | fprintf(fds, "$a%d.lo32", node->arg); | |
79 | } else | |
80 | fprintf(fds, "$a%d", node->arg); | |
81 | } | |
82 | ||
83 | /** | |
84 | * Display a string representation of the filter action | |
85 | * @param fds the file stream to send the output | |
86 | * @param action the action | |
87 | */ | |
88 | static void _pfc_action(FILE *fds, uint32_t action) | |
89 | { | |
90 | switch (action & 0xffff0000) { | |
91 | case SCMP_ACT_KILL: | |
92 | fprintf(fds, "action KILL;\n"); | |
93 | break; | |
94 | case SCMP_ACT_TRAP: | |
95 | fprintf(fds, "action TRAP;\n"); | |
96 | break; | |
97 | case SCMP_ACT_ERRNO(0): | |
98 | fprintf(fds, "action ERRNO(%u);\n", (action & 0x0000ffff)); | |
99 | break; | |
100 | case SCMP_ACT_TRACE(0): | |
101 | fprintf(fds, "action TRACE(%u);\n", (action & 0x0000ffff)); | |
102 | break; | |
103 | case SCMP_ACT_ALLOW: | |
104 | fprintf(fds, "action ALLOW;\n"); | |
105 | break; | |
106 | default: | |
107 | fprintf(fds, "action 0x%x;\n", action); | |
108 | } | |
109 | } | |
110 | ||
111 | /** | |
112 | * Indent the output stream | |
113 | * @param fds the file stream to send the output | |
114 | * @param lvl the indentation level | |
115 | * | |
116 | * This function indents the output stream with whitespace based on the | |
117 | * requested indentation level. | |
118 | */ | |
119 | static void _indent(FILE *fds, unsigned int lvl) | |
120 | { | |
121 | while (lvl-- > 0) | |
122 | fprintf(fds, " "); | |
123 | } | |
124 | ||
125 | /** | |
126 | * Generate the pseudo filter code for an argument chain | |
127 | * @param arch the architecture definition | |
128 | * @param node the head of the argument chain | |
129 | * @param lvl the indentation level | |
130 | * @param fds the file stream to send the output | |
131 | * | |
132 | * This function generates the pseudo filter code representation of the given | |
133 | * argument chain and writes it to the given output stream. | |
134 | * | |
135 | */ | |
136 | static void _gen_pfc_chain(const struct arch_def *arch, | |
137 | const struct db_arg_chain_tree *node, | |
138 | unsigned int lvl, FILE *fds) | |
139 | { | |
140 | const struct db_arg_chain_tree *c_iter; | |
141 | ||
142 | /* get to the start */ | |
143 | c_iter = node; | |
144 | while (c_iter->lvl_prv != NULL) | |
145 | c_iter = c_iter->lvl_prv; | |
146 | ||
147 | while (c_iter != NULL) { | |
148 | /* comparison operation */ | |
149 | _indent(fds, lvl); | |
150 | fprintf(fds, "if ("); | |
151 | _pfc_arg(fds, arch, c_iter); | |
152 | switch (c_iter->op) { | |
153 | case SCMP_CMP_EQ: | |
154 | fprintf(fds, " == "); | |
155 | break; | |
156 | case SCMP_CMP_GE: | |
157 | fprintf(fds, " >= "); | |
158 | break; | |
159 | case SCMP_CMP_GT: | |
160 | fprintf(fds, " > "); | |
161 | break; | |
162 | case SCMP_CMP_MASKED_EQ: | |
163 | fprintf(fds, " & 0x%.8x == ", c_iter->mask); | |
164 | break; | |
165 | default: | |
166 | fprintf(fds, " ??? "); | |
167 | } | |
168 | fprintf(fds, "%u)\n", c_iter->datum); | |
169 | ||
170 | /* true result */ | |
171 | if (c_iter->act_t_flg) { | |
172 | _indent(fds, lvl + 1); | |
173 | _pfc_action(fds, c_iter->act_t); | |
174 | } else if (c_iter->nxt_t != NULL) | |
175 | _gen_pfc_chain(arch, c_iter->nxt_t, lvl + 1, fds); | |
176 | ||
177 | /* false result */ | |
178 | if (c_iter->act_f_flg) { | |
179 | _indent(fds, lvl); | |
180 | fprintf(fds, "else\n"); | |
181 | _indent(fds, lvl + 1); | |
182 | _pfc_action(fds, c_iter->act_f); | |
183 | } else if (c_iter->nxt_f != NULL) { | |
184 | _indent(fds, lvl); | |
185 | fprintf(fds, "else\n"); | |
186 | _gen_pfc_chain(arch, c_iter->nxt_f, lvl + 1, fds); | |
187 | } | |
188 | ||
189 | c_iter = c_iter->lvl_nxt; | |
190 | } | |
191 | } | |
192 | ||
193 | /** | |
194 | * Generate pseudo filter code for a syscall | |
195 | * @param arch the architecture definition | |
196 | * @param sys the syscall filter | |
197 | * @param fds the file stream to send the output | |
198 | * | |
199 | * This function generates a pseduo filter code representation of the given | |
200 | * syscall filter and writes it to the given output stream. | |
201 | * | |
202 | */ | |
203 | static void _gen_pfc_syscall(const struct arch_def *arch, | |
204 | const struct db_sys_list *sys, FILE *fds) | |
205 | { | |
206 | unsigned int sys_num = sys->num; | |
207 | const char *sys_name = arch_syscall_resolve_num(arch, sys_num); | |
208 | ||
209 | _indent(fds, 1); | |
210 | fprintf(fds, "# filter for syscall \"%s\" (%d) [priority: %d]\n", | |
211 | (sys_name ? sys_name : "UNKNOWN"), sys_num, sys->priority); | |
212 | _indent(fds, 1); | |
213 | fprintf(fds, "if ($syscall == %d)\n", sys_num); | |
214 | if (sys->chains == NULL) { | |
215 | _indent(fds, 2); | |
216 | _pfc_action(fds, sys->action); | |
217 | } else | |
218 | _gen_pfc_chain(arch, sys->chains, 2, fds); | |
219 | } | |
220 | ||
221 | /** | |
222 | * Generate pseudo filter code for an architecture | |
223 | * @param col the seccomp filter collection | |
224 | * @param db the single seccomp filter | |
225 | * @param fds the file stream to send the output | |
226 | * | |
227 | * This function generates a pseudo filter code representation of the given | |
228 | * filter DB and writes it to the given output stream. Returns zero on | |
229 | * success, negative values on failure. | |
230 | * | |
231 | */ | |
232 | static int _gen_pfc_arch(const struct db_filter_col *col, | |
233 | const struct db_filter *db, FILE *fds) | |
234 | { | |
235 | int rc; | |
236 | struct db_sys_list *s_iter; | |
237 | struct pfc_sys_list *p_iter = NULL, *p_new, *p_head = NULL, *p_prev; | |
238 | ||
239 | /* sort the syscall list */ | |
240 | db_list_foreach(s_iter, db->syscalls) { | |
241 | p_new = malloc(sizeof(*p_new)); | |
242 | if (p_new == NULL) { | |
243 | rc = -ENOMEM; | |
244 | goto arch_return; | |
245 | } | |
246 | memset(p_new, 0, sizeof(*p_new)); | |
247 | p_new->sys = s_iter; | |
248 | ||
249 | p_prev = NULL; | |
250 | p_iter = p_head; | |
251 | while (p_iter != NULL && | |
252 | s_iter->priority < p_iter->sys->priority) { | |
253 | p_prev = p_iter; | |
254 | p_iter = p_iter->next; | |
255 | } | |
256 | if (p_head == NULL) | |
257 | p_head = p_new; | |
258 | else if (p_prev == NULL) { | |
259 | p_new->next = p_head; | |
260 | p_head = p_new; | |
261 | } else { | |
262 | p_new->next = p_iter; | |
263 | p_prev->next = p_new; | |
264 | } | |
265 | } | |
266 | ||
267 | fprintf(fds, "# filter for arch %s (%u)\n", | |
268 | _pfc_arch(db->arch), db->arch->token_bpf); | |
269 | fprintf(fds, "if ($arch == %u)\n", db->arch->token_bpf); | |
270 | p_iter = p_head; | |
271 | while (p_iter != NULL) { | |
272 | if (!p_iter->sys->valid) | |
273 | continue; | |
274 | _gen_pfc_syscall(db->arch, p_iter->sys, fds); | |
275 | p_iter = p_iter->next; | |
276 | } | |
277 | _indent(fds, 1); | |
278 | fprintf(fds, "# default action\n"); | |
279 | _indent(fds, 1); | |
280 | _pfc_action(fds, col->attr.act_default); | |
281 | ||
282 | arch_return: | |
283 | while (p_head != NULL) { | |
284 | p_iter = p_head; | |
285 | p_head = p_head->next; | |
286 | free(p_iter); | |
287 | } | |
288 | return rc; | |
289 | } | |
290 | ||
291 | /** | |
292 | * Generate a pseudo filter code string representation | |
293 | * @param col the seccomp filter collection | |
294 | * @param fd the fd to send the output | |
295 | * | |
296 | * This function generates a pseudo filter code representation of the given | |
297 | * filter collection and writes it to the given fd. Returns zero on success, | |
298 | * negative values on failure. | |
299 | * | |
300 | */ | |
301 | int gen_pfc_generate(const struct db_filter_col *col, int fd) | |
302 | { | |
303 | int rc = 0; | |
304 | int newfd; | |
305 | unsigned int iter; | |
306 | FILE *fds; | |
307 | ||
308 | newfd = dup(fd); | |
309 | if (newfd < 0) | |
310 | return errno; | |
311 | fds = fdopen(newfd, "a"); | |
312 | if (fds == NULL) { | |
313 | close(newfd); | |
314 | return errno; | |
315 | } | |
316 | ||
317 | /* generate the pfc */ | |
318 | fprintf(fds, "#\n"); | |
319 | fprintf(fds, "# pseudo filter code start\n"); | |
320 | fprintf(fds, "#\n"); | |
321 | ||
322 | for (iter = 0; iter < col->filter_cnt; iter++) | |
323 | _gen_pfc_arch(col, col->filters[iter], fds); | |
324 | ||
325 | fprintf(fds, "# invalid architecture action\n"); | |
326 | _pfc_action(fds, col->attr.act_badarch); | |
327 | fprintf(fds, "#\n"); | |
328 | fprintf(fds, "# pseudo filter code end\n"); | |
329 | fprintf(fds, "#\n"); | |
330 | ||
331 | fflush(fds); | |
332 | fclose(fds); | |
333 | ||
334 | return rc; | |
335 | } |
0 | /** | |
1 | * Seccomp String Translator | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #ifndef _TRANSLATOR_STR_H | |
22 | #define _TRANSLATOR_STR_H | |
23 | ||
24 | #include "db.h" | |
25 | ||
26 | int gen_pfc_generate(const struct db_filter_col *col, int fd); | |
27 | ||
28 | #endif |
0 | /** | |
1 | * Seccomp Library hash code | |
2 | * | |
3 | * Release under the Public Domain | |
4 | * Author: Bob Jenkins <bob_jenkins@burtleburtle.net> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * lookup3.c, by Bob Jenkins, May 2006, Public Domain. | |
9 | * | |
10 | * These are functions for producing 32-bit hashes for hash table lookup. | |
11 | * jhash_word(), jhash_le(), jhash_be(), mix(), and final() are externally useful | |
12 | * functions. Routines to test the hash are included if SELF_TEST is defined. | |
13 | * You can use this free for any purpose. It's in the public domain. It has | |
14 | * no warranty. | |
15 | * | |
16 | * You probably want to use jhash_le(). jhash_le() and jhash_be() hash byte | |
17 | * arrays. jhash_le() is is faster than jhash_be() on little-endian machines. | |
18 | * Intel and AMD are little-endian machines. | |
19 | * | |
20 | * If you want to find a hash of, say, exactly 7 integers, do | |
21 | * a = i1; b = i2; c = i3; | |
22 | * mix(a,b,c); | |
23 | * a += i4; b += i5; c += i6; | |
24 | * mix(a,b,c); | |
25 | * a += i7; | |
26 | * final(a,b,c); | |
27 | * | |
28 | * then use c as the hash value. If you have a variable length array of | |
29 | * 4-byte integers to hash, use jhash_word(). If you have a byte array (like | |
30 | * a character string), use jhash_le(). If you have several byte arrays, or | |
31 | * a mix of things, see the comments above jhash_le(). | |
32 | * | |
33 | * Why is this so big? I read 12 bytes at a time into 3 4-byte integers, then | |
34 | * mix those integers. This is fast (you can do a lot more thorough mixing | |
35 | * with 12*3 instructions on 3 integers than you can with 3 instructions on 1 | |
36 | * byte), but shoehorning those bytes into integers efficiently is messy. | |
37 | */ | |
38 | ||
39 | #include <stdint.h> | |
40 | ||
41 | #include "arch.h" | |
42 | #include "hash.h" | |
43 | ||
44 | #define hashsize(n) ((uint32_t)1<<(n)) | |
45 | #define hashmask(n) (hashsize(n)-1) | |
46 | #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) | |
47 | ||
48 | /** | |
49 | * Mix 3 32-bit values reversibly | |
50 | * @param a 32-bit value | |
51 | * @param b 32-bit value | |
52 | * @param c 32-bit value | |
53 | * | |
54 | * This is reversible, so any information in (a,b,c) before mix() is still | |
55 | * in (a,b,c) after mix(). | |
56 | * | |
57 | * If four pairs of (a,b,c) inputs are run through mix(), or through mix() in | |
58 | * reverse, there are at least 32 bits of the output that are sometimes the | |
59 | * same for one pair and different for another pair. | |
60 | * | |
61 | * This was tested for: | |
62 | * - pairs that differed by one bit, by two bits, in any combination of top | |
63 | * bits of (a,b,c), or in any combination of bottom bits of (a,b,c). | |
64 | * - "differ" is defined as +, -, ^, or ~^. For + and -, I transformed the | |
65 | * output delta to a Gray code (a^(a>>1)) so a string of 1's (as is commonly | |
66 | * produced by subtraction) look like a single 1-bit difference. | |
67 | * - the base values were pseudorandom, all zero but one bit set, or all zero | |
68 | * plus a counter that starts at zero. | |
69 | * | |
70 | * Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that | |
71 | * satisfy this are | |
72 | * 4 6 8 16 19 4 | |
73 | * 9 15 3 18 27 15 | |
74 | * 14 9 3 7 17 3 | |
75 | * | |
76 | * Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing for "differ" | |
77 | * defined as + with a one-bit base and a two-bit delta. I used | |
78 | * http://burtleburtle.net/bob/hash/avalanche.html to choose the operations, | |
79 | * constants, and arrangements of the variables. | |
80 | * | |
81 | * This does not achieve avalanche. There are input bits of (a,b,c) that fail | |
82 | * to affect some output bits of (a,b,c), especially of a. The most thoroughly | |
83 | * mixed value is c, but it doesn't really even achieve avalanche in c. | |
84 | * | |
85 | * This allows some parallelism. Read-after-writes are good at doubling the | |
86 | * number of bits affected, so the goal of mixing pulls in the opposite | |
87 | * direction as the goal of parallelism. I did what I could. Rotates seem to | |
88 | * cost as much as shifts on every machine I could lay my hands on, and rotates | |
89 | * are much kinder to the top and bottom bits, so I used rotates. | |
90 | * | |
91 | */ | |
92 | #define mix(a,b,c) \ | |
93 | { \ | |
94 | a -= c; a ^= rot(c, 4); c += b; \ | |
95 | b -= a; b ^= rot(a, 6); a += c; \ | |
96 | c -= b; c ^= rot(b, 8); b += a; \ | |
97 | a -= c; a ^= rot(c,16); c += b; \ | |
98 | b -= a; b ^= rot(a,19); a += c; \ | |
99 | c -= b; c ^= rot(b, 4); b += a; \ | |
100 | } | |
101 | ||
102 | /** | |
103 | * Final mixing of 3 32-bit values (a,b,c) into c | |
104 | * @param a 32-bit value | |
105 | * @param b 32-bit value | |
106 | * @param c 32-bit value | |
107 | * | |
108 | * Pairs of (a,b,c) values differing in only a few bits will usually produce | |
109 | * values of c that look totally different. This was tested for: | |
110 | * - pairs that differed by one bit, by two bits, in any combination of top | |
111 | * bits of (a,b,c), or in any combination of bottom bits of (a,b,c). | |
112 | * - "differ" is defined as +, -, ^, or ~^. For + and -, I transformed the | |
113 | * output delta to a Gray code (a^(a>>1)) so a string of 1's (as is commonly | |
114 | * produced by subtraction) look like a single 1-bit difference. | |
115 | * - the base values were pseudorandom, all zero but one bit set, or all zero | |
116 | * plus a counter that starts at zero. | |
117 | * | |
118 | * These constants passed: | |
119 | * 14 11 25 16 4 14 24 | |
120 | * 12 14 25 16 4 14 24 | |
121 | * and these came close: | |
122 | * 4 8 15 26 3 22 24 | |
123 | * 10 8 15 26 3 22 24 | |
124 | * 11 8 15 26 3 22 24 | |
125 | * | |
126 | */ | |
127 | #define final(a,b,c) \ | |
128 | { \ | |
129 | c ^= b; c -= rot(b,14); \ | |
130 | a ^= c; a -= rot(c,11); \ | |
131 | b ^= a; b -= rot(a,25); \ | |
132 | c ^= b; c -= rot(b,16); \ | |
133 | a ^= c; a -= rot(c,4); \ | |
134 | b ^= a; b -= rot(a,14); \ | |
135 | c ^= b; c -= rot(b,24); \ | |
136 | } | |
137 | ||
138 | /** | |
139 | * Hash an array of 32-bit values | |
140 | * @param k the key, an array of uint32_t values | |
141 | * @param length the number of array elements | |
142 | * @param initval the previous hash, or an arbitrary value | |
143 | * | |
144 | * This works on all machines. To be useful, it requires: | |
145 | * - that the key be an array of uint32_t's, and | |
146 | * - that the length be the number of uint32_t's in the key | |
147 | * | |
148 | * The function jhash_word() is identical to jhash_le() on little-endian | |
149 | * machines, and identical to jhash_be() on big-endian machines, except that | |
150 | * the length has to be measured in uint32_ts rather than in bytes. jhash_le() | |
151 | * is more complicated than jhash_word() only because jhash_le() has to dance | |
152 | * around fitting the key bytes into registers. | |
153 | * | |
154 | */ | |
155 | static uint32_t jhash_word(const uint32_t *k, size_t length, uint32_t initval) | |
156 | { | |
157 | uint32_t a, b, c; | |
158 | ||
159 | /* set up the internal state */ | |
160 | a = b = c = 0xdeadbeef + (((uint32_t)length) << 2) + initval; | |
161 | ||
162 | /* handle most of the key */ | |
163 | while (length > 3) { | |
164 | a += k[0]; | |
165 | b += k[1]; | |
166 | c += k[2]; | |
167 | mix(a, b, c); | |
168 | length -= 3; | |
169 | k += 3; | |
170 | } | |
171 | ||
172 | /* handle the last 3 uint32_t's */ | |
173 | switch(length) { | |
174 | case 3 : | |
175 | c += k[2]; | |
176 | case 2 : | |
177 | b += k[1]; | |
178 | case 1 : | |
179 | a += k[0]; | |
180 | final(a, b, c); | |
181 | case 0: | |
182 | /* nothing left to add */ | |
183 | break; | |
184 | } | |
185 | ||
186 | return c; | |
187 | } | |
188 | ||
189 | /** | |
190 | * Hash a variable-length key into a 32-bit value | |
191 | * @param k the key (the unaligned variable-length array of bytes) | |
192 | * @param length the length of the key, counting by bytes | |
193 | * @param initval can be any 4-byte value | |
194 | * | |
195 | * Returns a 32-bit value. Every bit of the key affects every bit of the | |
196 | * return value. Two keys differing by one or two bits will have totally | |
197 | * different hash values. | |
198 | * | |
199 | * The best hash table sizes are powers of 2. There is no need to do mod a | |
200 | * prime (mod is sooo slow!). If you need less than 32 bits, use a bitmask. | |
201 | * For example, if you need only 10 bits, do: | |
202 | * h = (h & hashmask(10)); | |
203 | * In which case, the hash table should have hashsize(10) elements. | |
204 | * | |
205 | * If you are hashing n strings (uint8_t **)k, do it like this: | |
206 | * for (i=0, h=0; i<n; ++i) h = jhash_le( k[i], len[i], h); | |
207 | * | |
208 | */ | |
209 | static uint32_t jhash_le(const void *key, size_t length, uint32_t initval) | |
210 | { | |
211 | uint32_t a, b, c; | |
212 | union { | |
213 | const void *ptr; | |
214 | size_t i; | |
215 | } u; /* needed for Mac Powerbook G4 */ | |
216 | ||
217 | /* set up the internal state */ | |
218 | a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; | |
219 | ||
220 | u.ptr = key; | |
221 | if ((arch_def_native->endian == ARCH_ENDIAN_LITTLE) && | |
222 | ((u.i & 0x3) == 0)) { | |
223 | /* read 32-bit chunks */ | |
224 | const uint32_t *k = (const uint32_t *)key; | |
225 | ||
226 | while (length > 12) { | |
227 | a += k[0]; | |
228 | b += k[1]; | |
229 | c += k[2]; | |
230 | mix(a, b, c); | |
231 | length -= 12; | |
232 | k += 3; | |
233 | } | |
234 | ||
235 | /* "k[2]&0xffffff" actually reads beyond the end of the string, | |
236 | * but then masks off the part it's not allowed to read. | |
237 | * Because the string is aligned, the masked-off tail is in the | |
238 | * same word as the rest of the string. Every machine with | |
239 | * memory protection I've seen does it on word boundaries, so | |
240 | * is OK with this. But VALGRIND will still catch it and | |
241 | * complain. The masking trick does make the hash noticably | |
242 | * faster for short strings (like English words). */ | |
243 | #ifndef VALGRIND | |
244 | ||
245 | switch(length) { | |
246 | case 12: | |
247 | c += k[2]; | |
248 | b += k[1]; | |
249 | a += k[0]; | |
250 | break; | |
251 | case 11: | |
252 | c += k[2] & 0xffffff; | |
253 | b += k[1]; | |
254 | a += k[0]; | |
255 | break; | |
256 | case 10: | |
257 | c += k[2] & 0xffff; | |
258 | b += k[1]; | |
259 | a += k[0]; | |
260 | break; | |
261 | case 9 : | |
262 | c += k[2] & 0xff; | |
263 | b += k[1]; | |
264 | a += k[0]; | |
265 | break; | |
266 | case 8 : | |
267 | b += k[1]; | |
268 | a += k[0]; | |
269 | break; | |
270 | case 7 : | |
271 | b += k[1] & 0xffffff; | |
272 | a += k[0]; | |
273 | break; | |
274 | case 6 : | |
275 | b += k[1] & 0xffff; | |
276 | a += k[0]; | |
277 | break; | |
278 | case 5 : | |
279 | b += k[1] & 0xff; | |
280 | a += k[0]; | |
281 | break; | |
282 | case 4 : | |
283 | a += k[0]; | |
284 | break; | |
285 | case 3 : | |
286 | a += k[0] & 0xffffff; | |
287 | break; | |
288 | case 2 : | |
289 | a += k[0] & 0xffff; | |
290 | break; | |
291 | case 1 : | |
292 | a += k[0] & 0xff; | |
293 | break; | |
294 | case 0 : | |
295 | /* zero length strings require no mixing */ | |
296 | return c; | |
297 | } | |
298 | ||
299 | #else /* make valgrind happy */ | |
300 | ||
301 | k8 = (const uint8_t *)k; | |
302 | switch(length) { | |
303 | case 12: | |
304 | c += k[2]; | |
305 | b += k[1]; | |
306 | a += k[0]; | |
307 | break; | |
308 | case 11: | |
309 | c += ((uint32_t)k8[10]) << 16; | |
310 | case 10: | |
311 | c += ((uint32_t)k8[9]) << 8; | |
312 | case 9 : | |
313 | c += k8[8]; | |
314 | case 8 : | |
315 | b += k[1]; | |
316 | a += k[0]; | |
317 | break; | |
318 | case 7 : | |
319 | b += ((uint32_t)k8[6]) << 16; | |
320 | case 6 : | |
321 | b += ((uint32_t)k8[5]) << 8; | |
322 | case 5 : | |
323 | b += k8[4]; | |
324 | case 4 : | |
325 | a += k[0]; | |
326 | break; | |
327 | case 3 : | |
328 | a += ((uint32_t)k8[2]) << 16; | |
329 | case 2 : | |
330 | a += ((uint32_t)k8[1]) << 8; | |
331 | case 1 : | |
332 | a += k8[0]; | |
333 | break; | |
334 | case 0 : | |
335 | return c; | |
336 | } | |
337 | ||
338 | #endif /* !valgrind */ | |
339 | ||
340 | } else if ((arch_def_native->endian == ARCH_ENDIAN_LITTLE) && | |
341 | ((u.i & 0x1) == 0)) { | |
342 | /* read 16-bit chunks */ | |
343 | const uint16_t *k = (const uint16_t *)key; | |
344 | const uint8_t *k8; | |
345 | ||
346 | while (length > 12) { | |
347 | a += k[0] + (((uint32_t)k[1]) << 16); | |
348 | b += k[2] + (((uint32_t)k[3]) << 16); | |
349 | c += k[4] + (((uint32_t)k[5]) << 16); | |
350 | mix(a, b, c); | |
351 | length -= 12; | |
352 | k += 6; | |
353 | } | |
354 | ||
355 | k8 = (const uint8_t *)k; | |
356 | switch(length) { | |
357 | case 12: | |
358 | c += k[4] + (((uint32_t)k[5]) << 16); | |
359 | b += k[2] + (((uint32_t)k[3]) << 16); | |
360 | a += k[0] + (((uint32_t)k[1]) << 16); | |
361 | break; | |
362 | case 11: | |
363 | c += ((uint32_t)k8[10]) << 16; | |
364 | case 10: | |
365 | c += k[4]; | |
366 | b += k[2] + (((uint32_t)k[3]) << 16); | |
367 | a += k[0] + (((uint32_t)k[1]) << 16); | |
368 | break; | |
369 | case 9 : | |
370 | c += k8[8]; | |
371 | case 8 : | |
372 | b += k[2] + (((uint32_t)k[3]) << 16); | |
373 | a += k[0] + (((uint32_t)k[1]) << 16); | |
374 | break; | |
375 | case 7 : | |
376 | b += ((uint32_t)k8[6]) << 16; | |
377 | case 6 : | |
378 | b += k[2]; | |
379 | a += k[0] + (((uint32_t)k[1]) << 16); | |
380 | break; | |
381 | case 5 : | |
382 | b += k8[4]; | |
383 | case 4 : | |
384 | a += k[0] + (((uint32_t)k[1]) << 16); | |
385 | break; | |
386 | case 3 : | |
387 | a += ((uint32_t)k8[2]) << 16; | |
388 | case 2 : | |
389 | a += k[0]; | |
390 | break; | |
391 | case 1 : | |
392 | a += k8[0]; | |
393 | break; | |
394 | case 0 : | |
395 | /* zero length requires no mixing */ | |
396 | return c; | |
397 | } | |
398 | ||
399 | } else { | |
400 | /* need to read the key one byte at a time */ | |
401 | const uint8_t *k = (const uint8_t *)key; | |
402 | ||
403 | while (length > 12) { | |
404 | a += k[0]; | |
405 | a += ((uint32_t)k[1]) << 8; | |
406 | a += ((uint32_t)k[2]) << 16; | |
407 | a += ((uint32_t)k[3]) << 24; | |
408 | b += k[4]; | |
409 | b += ((uint32_t)k[5]) << 8; | |
410 | b += ((uint32_t)k[6]) << 16; | |
411 | b += ((uint32_t)k[7]) << 24; | |
412 | c += k[8]; | |
413 | c += ((uint32_t)k[9]) << 8; | |
414 | c += ((uint32_t)k[10]) << 16; | |
415 | c += ((uint32_t)k[11]) << 24; | |
416 | mix(a, b, c); | |
417 | length -= 12; | |
418 | k += 12; | |
419 | } | |
420 | ||
421 | switch(length) { | |
422 | case 12: | |
423 | c += ((uint32_t)k[11]) << 24; | |
424 | case 11: | |
425 | c += ((uint32_t)k[10]) << 16; | |
426 | case 10: | |
427 | c += ((uint32_t)k[9]) << 8; | |
428 | case 9 : | |
429 | c += k[8]; | |
430 | case 8 : | |
431 | b += ((uint32_t)k[7]) << 24; | |
432 | case 7 : | |
433 | b += ((uint32_t)k[6]) << 16; | |
434 | case 6 : | |
435 | b += ((uint32_t)k[5]) << 8; | |
436 | case 5 : | |
437 | b += k[4]; | |
438 | case 4 : | |
439 | a += ((uint32_t)k[3]) << 24; | |
440 | case 3 : | |
441 | a += ((uint32_t)k[2]) << 16; | |
442 | case 2 : | |
443 | a += ((uint32_t)k[1]) << 8; | |
444 | case 1 : | |
445 | a += k[0]; | |
446 | break; | |
447 | case 0 : | |
448 | return c; | |
449 | } | |
450 | } | |
451 | ||
452 | final(a, b, c); | |
453 | return c; | |
454 | } | |
455 | ||
456 | /** | |
457 | * Hash a variable-length key into a 32-bit value | |
458 | * @param k the key (the unaligned variable-length array of bytes) | |
459 | * @param length the length of the key, counting by bytes | |
460 | * @param initval can be any 4-byte value | |
461 | * | |
462 | * This is the same as jhash_word() on big-endian machines. It is different | |
463 | * from jhash_le() on all machines. jhash_be() takes advantage of big-endian | |
464 | * byte ordering. | |
465 | * | |
466 | */ | |
467 | static uint32_t jhash_be( const void *key, size_t length, uint32_t initval) | |
468 | { | |
469 | uint32_t a, b, c; | |
470 | union { | |
471 | const void *ptr; | |
472 | size_t i; | |
473 | } u; /* to cast key to (size_t) happily */ | |
474 | ||
475 | /* set up the internal state */ | |
476 | a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; | |
477 | ||
478 | u.ptr = key; | |
479 | if ((arch_def_native->endian == ARCH_ENDIAN_BIG) && | |
480 | ((u.i & 0x3) == 0)) { | |
481 | /* read 32-bit chunks */ | |
482 | const uint32_t *k = (const uint32_t *)key; | |
483 | ||
484 | while (length > 12) { | |
485 | a += k[0]; | |
486 | b += k[1]; | |
487 | c += k[2]; | |
488 | mix(a, b, c); | |
489 | length -= 12; | |
490 | k += 3; | |
491 | } | |
492 | ||
493 | /* "k[2]<<8" actually reads beyond the end of the string, but | |
494 | * then shifts out the part it's not allowed to read. Because | |
495 | * the string is aligned, the illegal read is in the same word | |
496 | * as the rest of the string. Every machine with memory | |
497 | * protection I've seen does it on word boundaries, so is OK | |
498 | * with this. But VALGRIND will still catch it and complain. | |
499 | * The masking trick does make the hash noticably faster for | |
500 | * short strings (like English words). */ | |
501 | #ifndef VALGRIND | |
502 | ||
503 | switch(length) { | |
504 | case 12: | |
505 | c += k[2]; | |
506 | b += k[1]; | |
507 | a += k[0]; | |
508 | break; | |
509 | case 11: | |
510 | c += k[2] & 0xffffff00; | |
511 | b += k[1]; | |
512 | a += k[0]; | |
513 | break; | |
514 | case 10: | |
515 | c += k[2] & 0xffff0000; | |
516 | b += k[1]; | |
517 | a += k[0]; | |
518 | break; | |
519 | case 9 : | |
520 | c += k[2] & 0xff000000; | |
521 | b += k[1]; | |
522 | a += k[0]; | |
523 | break; | |
524 | case 8 : | |
525 | b += k[1]; | |
526 | a += k[0]; | |
527 | break; | |
528 | case 7 : | |
529 | b += k[1] & 0xffffff00; | |
530 | a += k[0]; | |
531 | break; | |
532 | case 6 : | |
533 | b += k[1] & 0xffff0000; | |
534 | a += k[0]; | |
535 | break; | |
536 | case 5 : | |
537 | b += k[1] & 0xff000000; | |
538 | a += k[0]; | |
539 | break; | |
540 | case 4 : | |
541 | a += k[0]; | |
542 | break; | |
543 | case 3 : | |
544 | a += k[0] & 0xffffff00; | |
545 | break; | |
546 | case 2 : | |
547 | a += k[0] & 0xffff0000; | |
548 | break; | |
549 | case 1 : | |
550 | a += k[0] & 0xff000000; | |
551 | break; | |
552 | case 0 : | |
553 | /* zero length strings require no mixing */ | |
554 | return c; | |
555 | } | |
556 | ||
557 | #else /* make valgrind happy */ | |
558 | ||
559 | k8 = (const uint8_t *)k; | |
560 | switch(length) { | |
561 | case 12: | |
562 | c += k[2]; | |
563 | b += k[1]; | |
564 | a += k[0]; | |
565 | break; | |
566 | case 11: | |
567 | c += ((uint32_t)k8[10]) << 8; | |
568 | case 10: | |
569 | c += ((uint32_t)k8[9]) << 16; | |
570 | case 9 : | |
571 | c += ((uint32_t)k8[8]) << 24; | |
572 | case 8 : | |
573 | b += k[1]; | |
574 | a += k[0]; | |
575 | break; | |
576 | case 7 : | |
577 | b += ((uint32_t)k8[6]) << 8; | |
578 | case 6 : | |
579 | b += ((uint32_t)k8[5]) << 16; | |
580 | case 5 : | |
581 | b += ((uint32_t)k8[4]) << 24; | |
582 | case 4 : | |
583 | a += k[0]; | |
584 | break; | |
585 | case 3 : | |
586 | a += ((uint32_t)k8[2]) << 8; | |
587 | case 2 : | |
588 | a += ((uint32_t)k8[1]) << 16; | |
589 | case 1 : | |
590 | a += ((uint32_t)k8[0]) << 24; | |
591 | break; | |
592 | case 0 : | |
593 | return c; | |
594 | } | |
595 | ||
596 | #endif /* !VALGRIND */ | |
597 | ||
598 | } else { | |
599 | /* need to read the key one byte at a time */ | |
600 | const uint8_t *k = (const uint8_t *)key; | |
601 | ||
602 | while (length > 12) { | |
603 | a += ((uint32_t)k[0]) << 24; | |
604 | a += ((uint32_t)k[1]) << 16; | |
605 | a += ((uint32_t)k[2]) << 8; | |
606 | a += ((uint32_t)k[3]); | |
607 | b += ((uint32_t)k[4]) << 24; | |
608 | b += ((uint32_t)k[5]) << 16; | |
609 | b += ((uint32_t)k[6]) << 8; | |
610 | b += ((uint32_t)k[7]); | |
611 | c += ((uint32_t)k[8]) << 24; | |
612 | c += ((uint32_t)k[9]) << 16; | |
613 | c += ((uint32_t)k[10]) << 8; | |
614 | c += ((uint32_t)k[11]); | |
615 | mix(a, b, c); | |
616 | length -= 12; | |
617 | k += 12; | |
618 | } | |
619 | ||
620 | switch(length) { | |
621 | case 12: | |
622 | c += k[11]; | |
623 | case 11: | |
624 | c += ((uint32_t)k[10]) << 8; | |
625 | case 10: | |
626 | c += ((uint32_t)k[9]) << 16; | |
627 | case 9 : | |
628 | c += ((uint32_t)k[8]) << 24; | |
629 | case 8 : | |
630 | b += k[7]; | |
631 | case 7 : | |
632 | b += ((uint32_t)k[6]) << 8; | |
633 | case 6 : | |
634 | b += ((uint32_t)k[5]) << 16; | |
635 | case 5 : | |
636 | b += ((uint32_t)k[4]) << 24; | |
637 | case 4 : | |
638 | a += k[3]; | |
639 | case 3 : | |
640 | a += ((uint32_t)k[2]) << 8; | |
641 | case 2 : | |
642 | a += ((uint32_t)k[1]) << 16; | |
643 | case 1 : | |
644 | a += ((uint32_t)k[0]) << 24; | |
645 | break; | |
646 | case 0 : | |
647 | return c; | |
648 | } | |
649 | } | |
650 | ||
651 | final(a, b, c); | |
652 | return c; | |
653 | } | |
654 | ||
655 | /** | |
656 | * Hash a variable-length key into a 32-bit value | |
657 | * @param k the key (the unaligned variable-length array of bytes) | |
658 | * @param length the length of the key, counting by bytes | |
659 | * @param initval can be any 4-byte value | |
660 | * | |
661 | * A small wrapper function that selects the proper hash function based on the | |
662 | * native machine's byte-ordering. | |
663 | * | |
664 | */ | |
665 | uint32_t jhash(const void *key, size_t length, uint32_t initval) | |
666 | { | |
667 | if (length % sizeof(uint32_t) == 0) | |
668 | return jhash_word(key, (length / sizeof(uint32_t)), initval); | |
669 | else if (arch_def_native->endian == ARCH_ENDIAN_BIG) | |
670 | return jhash_be(key, length, initval); | |
671 | else | |
672 | return jhash_le(key, length, initval); | |
673 | } |
0 | /** | |
1 | * The "lookup3.c" Hash Implementation from Bob Jenkins | |
2 | * | |
3 | * Original Author: Bob Jenkins <bob_jenkins@burtleburtle.net> | |
4 | * Source: http://burtleburtle.net/bob/c/lookup3.c | |
5 | */ | |
6 | ||
7 | /* | |
8 | * Original License: | |
9 | * | |
10 | * These are functions for producing 32-bit hashes for hash table lookup. | |
11 | * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() | |
12 | * are externally useful functions. Routines to test the hash are included | |
13 | * if SELF_TEST is defined. You can use this free for any purpose. It's in | |
14 | * the public domain. It has no warranty. | |
15 | */ | |
16 | ||
17 | #ifndef _HASH_H | |
18 | #define _HASH_H | |
19 | ||
20 | #include <inttypes.h> | |
21 | ||
22 | uint32_t jhash(const void *key, size_t length, uint32_t initval); | |
23 | ||
24 | #endif | |
25 |
0 | # | |
1 | # Enhanced Seccomp Library Python Bindings Makefile | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | # | |
22 | # macros | |
23 | # | |
24 | ||
25 | include ../../macros.mk | |
26 | ||
27 | # | |
28 | # configuration | |
29 | # | |
30 | ||
31 | include $(TOPDIR)/version_info.mk | |
32 | include $(TOPDIR)/configure.mk | |
33 | include $(TOPDIR)/install.mk | |
34 | ||
35 | LIB_STATIC = ../libseccomp.a | |
36 | ||
37 | # | |
38 | # targets | |
39 | # | |
40 | ||
41 | .PHONY: all install clean | |
42 | ||
43 | all: build | |
44 | ||
45 | build: $(LIB_STATIC) libseccomp.pxd seccomp.pyx | |
46 | @$(RM) seccomp.c | |
47 | $(PY_BUILD) && touch build | |
48 | ||
49 | install: build | |
50 | $(PY_INSTALL) install --prefix=$(DESTDIR)/$(INSTALL_PREFIX) | |
51 | ||
52 | clean: | |
53 | $(RM) -rf build seccomp.c |
0 | # | |
1 | # Seccomp Library Python Bindings | |
2 | # | |
3 | # Copyright (c) 2012,2013 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | from libc.stdint cimport uint8_t, uint32_t, uint64_t | |
22 | ||
23 | cdef extern from "seccomp.h": | |
24 | ||
25 | ctypedef void* scmp_filter_ctx | |
26 | ||
27 | cdef enum: | |
28 | SCMP_ARCH_NATIVE | |
29 | SCMP_ARCH_X86 | |
30 | SCMP_ARCH_X86_64 | |
31 | SCMP_ARCH_X32 | |
32 | SCMP_ARCH_ARM | |
33 | ||
34 | cdef enum scmp_filter_attr: | |
35 | SCMP_FLTATR_ACT_DEFAULT | |
36 | SCMP_FLTATR_ACT_BADARCH | |
37 | SCMP_FLTATR_CTL_NNP | |
38 | ||
39 | cdef enum scmp_compare: | |
40 | SCMP_CMP_NE | |
41 | SCMP_CMP_LT | |
42 | SCMP_CMP_LE | |
43 | SCMP_CMP_EQ | |
44 | SCMP_CMP_GE | |
45 | SCMP_CMP_GT | |
46 | SCMP_CMP_MASKED_EQ | |
47 | ||
48 | cdef enum: | |
49 | SCMP_ACT_KILL | |
50 | SCMP_ACT_TRAP | |
51 | SCMP_ACT_ALLOW | |
52 | unsigned int SCMP_ACT_ERRNO(int errno) | |
53 | unsigned int SCMP_ACT_TRACE(int value) | |
54 | ||
55 | ctypedef uint64_t scmp_datum_t | |
56 | ||
57 | cdef struct scmp_arg_cmp: | |
58 | unsigned int arg | |
59 | scmp_compare op | |
60 | scmp_datum_t datum_a | |
61 | scmp_datum_t datum_b | |
62 | ||
63 | scmp_filter_ctx seccomp_init(uint32_t def_action) | |
64 | int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action) | |
65 | void seccomp_release(scmp_filter_ctx ctx) | |
66 | ||
67 | int seccomp_merge(scmp_filter_ctx ctx_dst, scmp_filter_ctx ctx_src) | |
68 | ||
69 | uint32_t seccomp_arch_native() | |
70 | int seccomp_arch_exist(scmp_filter_ctx ctx, uint32_t arch_token) | |
71 | int seccomp_arch_add(scmp_filter_ctx ctx, uint32_t arch_token) | |
72 | int seccomp_arch_remove(scmp_filter_ctx ctx, uint32_t arch_token) | |
73 | ||
74 | int seccomp_load(scmp_filter_ctx ctx) | |
75 | ||
76 | int seccomp_attr_get(scmp_filter_ctx ctx, | |
77 | scmp_filter_attr attr, uint32_t* value) | |
78 | int seccomp_attr_set(scmp_filter_ctx ctx, | |
79 | scmp_filter_attr attr, uint32_t value) | |
80 | ||
81 | char *seccomp_syscall_resolve_num_arch(uint32_t arch_token, int num) | |
82 | int seccomp_syscall_resolve_name_arch(uint32_t arch_token, char *name) | |
83 | int seccomp_syscall_resolve_name(char *name) | |
84 | int seccomp_syscall_priority(scmp_filter_ctx ctx, | |
85 | int syscall, uint8_t priority) | |
86 | ||
87 | int seccomp_rule_add(scmp_filter_ctx ctx, uint32_t action, | |
88 | int syscall, unsigned int arg_cnt, ...) | |
89 | ||
90 | int seccomp_rule_add_exact(scmp_filter_ctx ctx, uint32_t action, | |
91 | int syscall, unsigned int arg_cnt, ...) | |
92 | ||
93 | int seccomp_export_pfc(scmp_filter_ctx ctx, int fd) | |
94 | int seccomp_export_bpf(scmp_filter_ctx ctx, int fd) | |
95 | ||
96 | # kate: syntax python; | |
97 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # Seccomp Library Python Bindings | |
2 | # | |
3 | # Copyright (c) 2012,2013 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | """ Python bindings for the libseccomp library | |
22 | ||
23 | The libseccomp library provides and easy to use, platform independent, | |
24 | interface to the Linux Kernel's syscall filtering mechanism: seccomp. The | |
25 | libseccomp API is designed to abstract away the underlying BPF based | |
26 | syscall filter language and present a more conventional function-call | |
27 | based filtering interface that should be familiar to, and easily adopted | |
28 | by application developers. | |
29 | ||
30 | Filter action values: | |
31 | KILL - kill the process | |
32 | ALLOW - allow the syscall to execute | |
33 | TRAP - a SIGSYS signal will be thrown | |
34 | ERRNO(x) - syscall will return (x) | |
35 | TRACE(x) - if the process is being traced, (x) will be returned to the | |
36 | tracing process via PTRACE_EVENT_SECCOMP and the | |
37 | PTRACE_GETEVENTMSG option | |
38 | ||
39 | Argument comparison values (see the Arg class): | |
40 | ||
41 | NE - arg != datum_a | |
42 | LT - arg < datum_a | |
43 | LE - arg <= datum_a | |
44 | EQ - arg == datum_a | |
45 | GT - arg > datum_a | |
46 | GE - arg >= datum_a | |
47 | MASKED_EQ - (arg & datum_b) == datum_a | |
48 | ||
49 | ||
50 | Example: | |
51 | ||
52 | import sys | |
53 | from seccomp import * | |
54 | ||
55 | # create a filter object with a default KILL action | |
56 | f = SyscallFilter(defaction=KILL) | |
57 | ||
58 | # add syscall filter rules to allow certain syscalls | |
59 | f.add_rule(ALLOW, "open") | |
60 | f.add_rule(ALLOW, "close") | |
61 | f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin)) | |
62 | f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stdout)) | |
63 | f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stderr)) | |
64 | f.add_rule(ALLOW, "rt_sigreturn") | |
65 | ||
66 | # load the filter into the kernel | |
67 | f.load() | |
68 | """ | |
69 | __author__ = 'Paul Moore <paul@paul-moore.com>' | |
70 | __date__ = "7 January 2013" | |
71 | ||
72 | from libc.stdint cimport uint32_t | |
73 | import errno | |
74 | ||
75 | cimport libseccomp | |
76 | ||
77 | KILL = libseccomp.SCMP_ACT_KILL | |
78 | TRAP = libseccomp.SCMP_ACT_TRAP | |
79 | ALLOW = libseccomp.SCMP_ACT_ALLOW | |
80 | def ERRNO(int errno): | |
81 | return libseccomp.SCMP_ACT_ERRNO(errno) | |
82 | def TRACE(int value): | |
83 | return libseccomp.SCMP_ACT_TRACE(value) | |
84 | ||
85 | NE = libseccomp.SCMP_CMP_NE | |
86 | LT = libseccomp.SCMP_CMP_LT | |
87 | LE = libseccomp.SCMP_CMP_LE | |
88 | EQ = libseccomp.SCMP_CMP_EQ | |
89 | GE = libseccomp.SCMP_CMP_GE | |
90 | GT = libseccomp.SCMP_CMP_GT | |
91 | MASKED_EQ = libseccomp.SCMP_CMP_MASKED_EQ | |
92 | ||
93 | def system_arch(): | |
94 | """ Return the system architecture value. | |
95 | ||
96 | Description: | |
97 | Returns the native system architecture value. | |
98 | """ | |
99 | return libseccomp.seccomp_arch_native() | |
100 | ||
101 | def resolve_syscall(arch, syscall): | |
102 | """ Resolve the syscall. | |
103 | ||
104 | Arguments: | |
105 | arch - the architecture value, e.g. Arch.* | |
106 | syscall - the syscall name or number | |
107 | ||
108 | Description: | |
109 | Resolve an architecture's syscall name to the correct number or the | |
110 | syscall number to the correct name. | |
111 | """ | |
112 | if (isinstance(syscall, basestring)): | |
113 | return libseccomp.seccomp_syscall_resolve_name_arch(arch, syscall) | |
114 | elif (isinstance(syscall, int)): | |
115 | return libseccomp.seccomp_syscall_resolve_num_arch(arch, syscall) | |
116 | else: | |
117 | raise TypeError("Syscall must either be an int or str type") | |
118 | ||
119 | cdef class Arch: | |
120 | """ Python object representing the SyscallFilter architecture values. | |
121 | ||
122 | Data values: | |
123 | NATIVE - the native architecture | |
124 | X86 - 32-bit x86 | |
125 | X86_64 - 64-bit x86 | |
126 | X32 - 64-bit x86 using the x32 ABI | |
127 | ARM - ARM | |
128 | """ | |
129 | ||
130 | NATIVE = libseccomp.SCMP_ARCH_NATIVE | |
131 | X86 = libseccomp.SCMP_ARCH_X86 | |
132 | X86_64 = libseccomp.SCMP_ARCH_X86_64 | |
133 | X32 = libseccomp.SCMP_ARCH_X32 | |
134 | ARM = libseccomp.SCMP_ARCH_ARM | |
135 | ||
136 | cdef class Attr: | |
137 | """ Python object representing the SyscallFilter attributes. | |
138 | ||
139 | Data values: | |
140 | ACT_DEFAULT - the filter's default action | |
141 | ACT_BADARCH - the filter's bad architecture action | |
142 | CTL_NNP - the filter's "no new privileges" flag | |
143 | """ | |
144 | ACT_DEFAULT = libseccomp.SCMP_FLTATR_ACT_DEFAULT | |
145 | ACT_BADARCH = libseccomp.SCMP_FLTATR_ACT_BADARCH | |
146 | CTL_NNP = libseccomp.SCMP_FLTATR_CTL_NNP | |
147 | ||
148 | cdef class Arg: | |
149 | """ Python object representing a SyscallFilter syscall argument. | |
150 | """ | |
151 | cdef libseccomp.scmp_arg_cmp _arg | |
152 | ||
153 | def __cinit__(self, arg, op, datum_a, datum_b = 0): | |
154 | """ Initialize the argument comparison. | |
155 | ||
156 | Arguments: | |
157 | arg - the arguement number, starting at 0 | |
158 | op - the argument comparison operator, e.g. {NE,LT,LE,...} | |
159 | datum_a - argument value | |
160 | datum_b - argument value, only valid when op == MASKED_EQ | |
161 | ||
162 | Description: | |
163 | Create an argument comparison object for use with SyscallFilter. | |
164 | """ | |
165 | self._arg.arg = arg | |
166 | self._arg.op = op | |
167 | self._arg.datum_a = datum_a | |
168 | self._arg.datum_b = datum_b | |
169 | ||
170 | def to_c(self): | |
171 | """ Convert the object into a C structure. | |
172 | ||
173 | Description: | |
174 | Helper function which should only be used internally by | |
175 | SyscallFilter objects and exists for the sole purpose of making it | |
176 | easier to deal with the varadic functions of the libseccomp API, | |
177 | e.g. seccomp_rule_add(). | |
178 | """ | |
179 | return self._arg | |
180 | ||
181 | cdef class SyscallFilter: | |
182 | """ Python object representing a seccomp syscall filter. """ | |
183 | cdef int _defaction | |
184 | cdef libseccomp.scmp_filter_ctx _ctx | |
185 | ||
186 | def __cinit__(self, int defaction): | |
187 | self._ctx = libseccomp.seccomp_init(defaction) | |
188 | if self._ctx == NULL: | |
189 | raise RuntimeError("Library error") | |
190 | _defaction = defaction | |
191 | ||
192 | def __init__(self, defaction): | |
193 | """ Initialize the filter state | |
194 | ||
195 | Arguments: | |
196 | defaction - the default filter action | |
197 | ||
198 | Description: | |
199 | Initializes the seccomp filter state to the defaults. | |
200 | """ | |
201 | ||
202 | def __dealloc__(self): | |
203 | """ Destroys the filter state and releases any resources. | |
204 | ||
205 | Description: | |
206 | Destroys the seccomp filter state and releases any resources | |
207 | associated with the filter state. This function does not affect | |
208 | any seccomp filters already loaded into the kernel. | |
209 | """ | |
210 | if self._ctx != NULL: | |
211 | libseccomp.seccomp_release(self._ctx) | |
212 | ||
213 | def reset(self, int defaction = -1): | |
214 | """ Reset the filter state. | |
215 | ||
216 | Arguments: | |
217 | defaction - the default filter action | |
218 | ||
219 | Description: | |
220 | Resets the seccomp filter state to an initial default state, if a | |
221 | default filter action is not specified in the reset call the | |
222 | original action will be reused. This function does not affect any | |
223 | seccomp filters alread loaded into the kernel. | |
224 | """ | |
225 | if defaction == -1: | |
226 | defaction = self._defaction | |
227 | rc = libseccomp.seccomp_reset(self._ctx, defaction) | |
228 | if rc == -errno.EINVAL: | |
229 | raise ValueError("Invalid action") | |
230 | if rc != 0: | |
231 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
232 | _defaction = defaction | |
233 | ||
234 | def merge(self, SyscallFilter filter): | |
235 | """ Merge two existing SyscallFilter objects. | |
236 | ||
237 | Arguments: | |
238 | filter - a valid SyscallFilter object | |
239 | ||
240 | Description: | |
241 | Merges a valid SyscallFilter object with the current SyscallFilter | |
242 | object; the passed filter object will be reset on success. In | |
243 | order to successfully merge two seccomp filters they must have the | |
244 | same attribute values and not share any of the same architectures. | |
245 | """ | |
246 | rc = libseccomp.seccomp_merge(self._ctx, filter._ctx) | |
247 | if rc != 0: | |
248 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
249 | filter._ctx = NULL | |
250 | filter = SyscallFilter(filter._defaction) | |
251 | ||
252 | def exist_arch(self, arch): | |
253 | """ Check if the seccomp filter contains a given architecture. | |
254 | ||
255 | Arguments: | |
256 | arch - the architecture value, e.g. Arch.* | |
257 | ||
258 | Description: | |
259 | Test to see if a given architecture is included in the filter. | |
260 | Return True is the architecture exists, False if it does not | |
261 | exist. | |
262 | """ | |
263 | rc = libseccomp.seccomp_arch_exist(self._ctx, arch) | |
264 | if rc == 0: | |
265 | return True | |
266 | elif rc == -errno.EEXIST: | |
267 | return False | |
268 | elif rc == -errno.EINVAL: | |
269 | raise ValueError("Invalid architecture") | |
270 | else: | |
271 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
272 | ||
273 | def add_arch(self, arch): | |
274 | """ Add an architecture to the filter. | |
275 | ||
276 | Arguments: | |
277 | arch - the architecture value, e.g. Arch.* | |
278 | ||
279 | Description: | |
280 | Add the given architecture to the filter. Any new rules added | |
281 | after this method returns successfully will be added to this new | |
282 | architecture, but any existing rules will not be added to the new | |
283 | architecture. | |
284 | """ | |
285 | rc = libseccomp.seccomp_arch_add(self._ctx, arch) | |
286 | if rc == -errno.EINVAL: | |
287 | raise ValueError("Invalid architecture") | |
288 | elif rc != 0: | |
289 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
290 | ||
291 | def remove_arch(self, arch): | |
292 | """ Remove an architecture from the filter. | |
293 | ||
294 | Arguments: | |
295 | arch - the architecture value, e.g. Arch.* | |
296 | ||
297 | Description: | |
298 | Remove the given architecture from the filter. The filter must | |
299 | always contain at least one architecture, so if only one | |
300 | architecture exists in the filter this method will fail. | |
301 | """ | |
302 | rc = libseccomp.seccomp_arch_remove(self._ctx, arch) | |
303 | if rc == -errno.EINVAL: | |
304 | raise ValueError("Invalid architecture") | |
305 | elif rc != 0: | |
306 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
307 | ||
308 | def load(self): | |
309 | """ Load the filter into the Linux Kernel. | |
310 | ||
311 | Description: | |
312 | Load the current filter into the Linux Kernel. As soon as the | |
313 | method returns the filter will be active and enforcing. | |
314 | """ | |
315 | rc = libseccomp.seccomp_load(self._ctx) | |
316 | if rc != 0: | |
317 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
318 | ||
319 | def get_attr(self, attr): | |
320 | """ Get an attribute value from the filter. | |
321 | ||
322 | Arguments: | |
323 | attr - the attribute, e.g. Attr.* | |
324 | ||
325 | Description: | |
326 | Lookup the given attribute in the filter and return the | |
327 | attribute's value to the caller. | |
328 | """ | |
329 | value = 0 | |
330 | rc = libseccomp.seccomp_attr_get(self._ctx, | |
331 | attr, <uint32_t *>&value) | |
332 | if rc == -errno.EINVAL: | |
333 | raise ValueError("Invalid attribute") | |
334 | elif rc != 0: | |
335 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
336 | return value | |
337 | ||
338 | def set_attr(self, attr, int value): | |
339 | """ Set a filter attribute. | |
340 | ||
341 | Arguments: | |
342 | attr - the attribute, e.g. Attr.* | |
343 | value - the attribute value | |
344 | ||
345 | Description: | |
346 | Lookup the given attribute in the filter and assign it the given | |
347 | value. | |
348 | """ | |
349 | rc = libseccomp.seccomp_attr_set(self._ctx, attr, value) | |
350 | if rc == -errno.EINVAL: | |
351 | raise ValueError("Invalid attribute") | |
352 | elif rc != 0: | |
353 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
354 | ||
355 | def syscall_priority(self, syscall, int priority): | |
356 | """ Set the filter priority of a syscall. | |
357 | ||
358 | Arguments: | |
359 | syscall - the syscall name or number | |
360 | priority - the priority of the syscall | |
361 | ||
362 | Description: | |
363 | Set the filter priority of the given syscall. A syscall with a | |
364 | higher priority will have less overhead in the generated filter | |
365 | code which is loaded into the system. Priority values can range | |
366 | from 0 to 255 inclusive. | |
367 | """ | |
368 | if priority < 0 or priority > 255: | |
369 | raise ValueError("Syscall priority must be between 0 and 255") | |
370 | if isinstance(syscall, str): | |
371 | syscall_str = syscall.encode() | |
372 | syscall_num = libseccomp.seccomp_syscall_resolve_name(syscall_str) | |
373 | elif isinstance(syscall, int): | |
374 | syscall_num = syscall | |
375 | else: | |
376 | raise TypeError("Syscall must either be an int or str type") | |
377 | rc = libseccomp.seccomp_syscall_priority(self._ctx, | |
378 | syscall_num, priority) | |
379 | if rc != 0: | |
380 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
381 | ||
382 | def add_rule(self, int action, syscall, *args): | |
383 | """ Add a new rule to filter. | |
384 | ||
385 | Arguments: | |
386 | action - the rule action: KILL, TRAP, ERRNO(), TRACE(), or ALLOW | |
387 | syscall - the syscall name or number | |
388 | args - variable number of Arg objects | |
389 | ||
390 | Description: | |
391 | Add a new rule to the filter, matching on the given syscall and an | |
392 | optional list of argument comparisons. If the rule is triggered | |
393 | the given action will be taken by the kernel. In order for the | |
394 | rule to trigger, the syscall as well as each argument comparison | |
395 | must be true. | |
396 | ||
397 | In the case where the specific rule is not valid on a specific | |
398 | architecture, e.g. socket() on 32-bit x86, this method rewrites | |
399 | the rule to the best possible match. If you don't want this fule | |
400 | rewriting to take place use add_rule_exactly(). | |
401 | """ | |
402 | cdef libseccomp.scmp_arg_cmp c_arg[6] | |
403 | if isinstance(syscall, str): | |
404 | syscall_str = syscall.encode() | |
405 | syscall_num = libseccomp.seccomp_syscall_resolve_name(syscall_str) | |
406 | elif isinstance(syscall, int): | |
407 | syscall_num = syscall | |
408 | else: | |
409 | raise TypeError("Syscall must either be an int or str type") | |
410 | """ NOTE: the code below exists solely to deal with the varadic | |
411 | nature of seccomp_rule_add() function and the inability of Cython | |
412 | to handle this automatically """ | |
413 | for i, arg in enumerate(args): | |
414 | c_arg[i] = arg.to_c() | |
415 | if len(args) == 0: | |
416 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, 0) | |
417 | elif len(args) == 1: | |
418 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, | |
419 | len(args), | |
420 | c_arg[0]) | |
421 | elif len(args) == 2: | |
422 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, | |
423 | len(args), | |
424 | c_arg[0], | |
425 | c_arg[1]) | |
426 | elif len(args) == 3: | |
427 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, | |
428 | len(args), | |
429 | c_arg[0], | |
430 | c_arg[1], | |
431 | c_arg[2]) | |
432 | elif len(args) == 4: | |
433 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, | |
434 | len(args), | |
435 | c_arg[0], | |
436 | c_arg[1], | |
437 | c_arg[2], | |
438 | c_arg[3]) | |
439 | elif len(args) == 5: | |
440 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, | |
441 | len(args), | |
442 | c_arg[0], | |
443 | c_arg[1], | |
444 | c_arg[2], | |
445 | c_arg[3], | |
446 | c_arg[4]) | |
447 | elif len(args) == 6: | |
448 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, | |
449 | len(args), | |
450 | c_arg[0], | |
451 | c_arg[1], | |
452 | c_arg[2], | |
453 | c_arg[3], | |
454 | c_arg[4], | |
455 | c_arg[5]) | |
456 | else: | |
457 | raise RuntimeError("Maximum number of arguments exceeded") | |
458 | if rc != 0: | |
459 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
460 | ||
461 | def add_rule_exactly(self, int action, syscall, *args): | |
462 | """ Add a new rule to filter. | |
463 | ||
464 | Arguments: | |
465 | action - the rule action: KILL, TRAP, ERRNO(), TRACE(), or ALLOW | |
466 | syscall - the syscall name or number | |
467 | args - variable number of Arg objects | |
468 | ||
469 | Description: | |
470 | Add a new rule to the filter, matching on the given syscall and an | |
471 | optional list of argument comparisons. If the rule is triggered | |
472 | the given action will be taken by the kernel. In order for the | |
473 | rule to trigger, the syscall as well as each argument comparison | |
474 | must be true. | |
475 | ||
476 | This method attempts to add the filter rule exactly as specified | |
477 | which can cause problems on certain architectures, e.g. socket() | |
478 | on 32-bit x86. For a architecture independent version of this | |
479 | method use add_rule(). | |
480 | """ | |
481 | cdef libseccomp.scmp_arg_cmp c_arg[6] | |
482 | if isinstance(syscall, str): | |
483 | syscall_str = syscall.encode() | |
484 | syscall_num = libseccomp.seccomp_syscall_resolve_name(syscall_str) | |
485 | elif isinstance(syscall, int): | |
486 | syscall_num = syscall | |
487 | else: | |
488 | raise TypeError("Syscall must either be an int or str type") | |
489 | """ NOTE: the code below exists solely to deal with the varadic | |
490 | nature of seccomp_rule_add_exact() function and the inability of | |
491 | Cython to handle this automatically """ | |
492 | for i, arg in enumerate(args): | |
493 | c_arg[i] = arg.to_c() | |
494 | if len(args) == 0: | |
495 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
496 | syscall_num, 0) | |
497 | elif len(args) == 1: | |
498 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
499 | syscall_num, len(args), | |
500 | c_arg[0]) | |
501 | elif len(args) == 2: | |
502 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
503 | syscall_num, len(args), | |
504 | c_arg[0], | |
505 | c_arg[1]) | |
506 | elif len(args) == 3: | |
507 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
508 | syscall_num, len(args), | |
509 | c_arg[0], | |
510 | c_arg[1], | |
511 | c_arg[2]) | |
512 | elif len(args) == 4: | |
513 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
514 | syscall_num, len(args), | |
515 | c_arg[0], | |
516 | c_arg[1], | |
517 | c_arg[2], | |
518 | c_arg[3]) | |
519 | elif len(args) == 5: | |
520 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
521 | syscall_num, len(args), | |
522 | c_arg[0], | |
523 | c_arg[1], | |
524 | c_arg[2], | |
525 | c_arg[3], | |
526 | c_arg[4]) | |
527 | elif len(args) == 6: | |
528 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
529 | syscall_num, len(args), | |
530 | c_arg[0], | |
531 | c_arg[1], | |
532 | c_arg[2], | |
533 | c_arg[3], | |
534 | c_arg[4], | |
535 | c_arg[5]) | |
536 | else: | |
537 | raise RuntimeError("Maximum number of arguments exceeded") | |
538 | if rc != 0: | |
539 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
540 | ||
541 | def export_pfc(self, file): | |
542 | """ Export the filter in PFC format. | |
543 | ||
544 | Arguments: | |
545 | file - the output file | |
546 | ||
547 | Description: | |
548 | Output the filter in Pseudo Filter Code (PFC) to the given file. | |
549 | The output is functionally equivalent to the BPF based filter | |
550 | which is loaded into the Linux Kernel. | |
551 | """ | |
552 | rc = libseccomp.seccomp_export_pfc(self._ctx, file.fileno()) | |
553 | if rc != 0: | |
554 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
555 | ||
556 | def export_bpf(self, file): | |
557 | """ Export the filter in BPF format. | |
558 | ||
559 | Arguments: | |
560 | file - the output file | |
561 | ||
562 | Output the filter in Berkley Packet Filter (BPF) to the given | |
563 | file. The output is identical to what is loaded into the | |
564 | Linux Kernel. | |
565 | """ | |
566 | rc = libseccomp.seccomp_export_bpf(self._ctx, file.fileno()) | |
567 | if rc != 0: | |
568 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
569 | ||
570 | # kate: syntax python; | |
571 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Enhanced Seccomp Library Python Module Build Script | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import os | |
24 | ||
25 | from distutils.core import setup | |
26 | from distutils.extension import Extension | |
27 | from Cython.Distutils import build_ext | |
28 | ||
29 | setup( | |
30 | name = "seccomp", | |
31 | version = os.environ["VERSION_RELEASE"], | |
32 | description = "Python binding for libseccomp", | |
33 | long_description = "Python API for the Linux Kernel's syscall filtering capability, seccomp.", | |
34 | url = "http://libseccomp.sf.net", | |
35 | maintainer = "Paul Moore", | |
36 | maintainer_email = "paul@paul-moore.com", | |
37 | license = "LGPLv2.1", | |
38 | platforms = "Linux", | |
39 | cmdclass = {'build_ext': build_ext}, | |
40 | ext_modules = [ | |
41 | Extension("seccomp", ["seccomp.pyx"], | |
42 | extra_objects=["../libseccomp.a"]) | |
43 | ] | |
44 | ) |
0 | /** | |
1 | * Seccomp System Information | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #ifndef _SYSTEM_H | |
22 | #define _SYSTEM_H | |
23 | ||
24 | #include <linux/filter.h> | |
25 | #include <linux/prctl.h> | |
26 | ||
27 | #include <configure.h> | |
28 | ||
29 | #ifdef CONF_SYSINC_SECCOMP | |
30 | ||
31 | /* system header file */ | |
32 | #include <linux/seccomp.h> | |
33 | ||
34 | #else | |
35 | ||
36 | /* NOTE: the definitions below were taken from the Linux Kernel sources */ | |
37 | #include <linux/types.h> | |
38 | ||
39 | /* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */ | |
40 | #define SECCOMP_MODE_DISABLED 0 /* seccomp is not in use. */ | |
41 | #define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */ | |
42 | #define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */ | |
43 | ||
44 | /* | |
45 | * All BPF programs must return a 32-bit value. | |
46 | * The bottom 16-bits are for optional return data. | |
47 | * The upper 16-bits are ordered from least permissive values to most. | |
48 | * | |
49 | * The ordering ensures that a min_t() over composed return values always | |
50 | * selects the least permissive choice. | |
51 | */ | |
52 | #define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */ | |
53 | #define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ | |
54 | #define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ | |
55 | #define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ | |
56 | #define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ | |
57 | ||
58 | /* Masks for the return value sections. */ | |
59 | #define SECCOMP_RET_ACTION 0x7fff0000U | |
60 | #define SECCOMP_RET_DATA 0x0000ffffU | |
61 | ||
62 | /* | |
63 | * struct seccomp_data - the format the BPF program executes over. | |
64 | * @nr: the system call number | |
65 | * @arch: indicates system call convention as an AUDIT_ARCH_* value | |
66 | * as defined in <linux/audit.h>. | |
67 | * @instruction_pointer: at the time of the system call. | |
68 | * @args: up to 6 system call arguments always stored as 64-bit values | |
69 | * regardless of the architecture. | |
70 | */ | |
71 | struct seccomp_data { | |
72 | int nr; | |
73 | __u32 arch; | |
74 | __u64 instruction_pointer; | |
75 | __u64 args[6]; | |
76 | }; | |
77 | ||
78 | #endif /* CONF_SYSINC_SECCOMP */ | |
79 | ||
80 | /* rename some of the socket filter types to make more sense */ | |
81 | typedef struct sock_filter bpf_instr_raw; | |
82 | ||
83 | #ifndef PR_SET_NO_NEW_PRIVS | |
84 | #define PR_SET_NO_NEW_PRIVS 38 | |
85 | #endif /* PR_SET_NO_NEW_PRIVS */ | |
86 | ||
87 | #ifndef PR_GET_NO_NEW_PRIVS | |
88 | #define PR_GET_NO_NEW_PRIVS 39 | |
89 | #endif /* PR_GET_NO_NEW_PRIVS */ | |
90 | ||
91 | #endif |
0 | !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ | |
1 | !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ | |
2 | !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ | |
3 | !_TAG_PROGRAM_NAME Exuberant Ctags // | |
4 | !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ | |
5 | !_TAG_PROGRAM_VERSION 5.8 // | |
6 | ACT_BADARCH src/python/seccomp.pyx /^ ACT_BADARCH = libseccomp.SCMP_FLTATR_ACT_BADARCH$/;" v class:Attr | |
7 | ACT_DEFAULT src/python/seccomp.pyx /^ ACT_DEFAULT = libseccomp.SCMP_FLTATR_ACT_DEFAULT$/;" v class:Attr | |
8 | ADDDEP macros.mk /^ADDDEP = \\$/;" m | |
9 | AINC_BLK src/gen_bpf.c 39;" d file: | |
10 | AINC_PROG src/gen_bpf.c 40;" d file: | |
11 | ALLOW src/python/seccomp.pyx /^ALLOW = libseccomp.SCMP_ACT_ALLOW$/;" v | |
12 | ARCHIVE macros.mk /^ ARCHIVE = @echo " AR $@";$/;" m | |
13 | ARCH_ENDIAN_BIG src/arch.h /^ ARCH_ENDIAN_BIG,$/;" e enum:arch_def::__anon3 | |
14 | ARCH_ENDIAN_LITTLE src/arch.h /^ ARCH_ENDIAN_LITTLE,$/;" e enum:arch_def::__anon3 | |
15 | ARCH_ENDIAN_UNSPEC src/arch.h /^ ARCH_ENDIAN_UNSPEC = 0,$/;" e enum:arch_def::__anon3 | |
16 | ARCH_SIZE_32 src/arch.h /^ ARCH_SIZE_32 = 32,$/;" e enum:arch_def::__anon2 | |
17 | ARCH_SIZE_64 src/arch.h /^ ARCH_SIZE_64 = 64,$/;" e enum:arch_def::__anon2 | |
18 | ARCH_SIZE_UNSPEC src/arch.h /^ ARCH_SIZE_UNSPEC = 0,$/;" e enum:arch_def::__anon2 | |
19 | ARG_COUNT_MAX src/arch.h 76;" d | |
20 | ARG_MASK_MAX src/db.h 70;" d | |
21 | ARM src/python/seccomp.pyx /^ ARM = libseccomp.SCMP_ARCH_ARM$/;" v class:Arch | |
22 | AWK macros.mk /^AWK ?= awk$/;" m | |
23 | Arch src/python/seccomp.pyx /^cdef class Arch:$/;" c | |
24 | Arg src/python/seccomp.pyx /^cdef class Arg:$/;" c | |
25 | Attr src/python/seccomp.pyx /^cdef class Attr:$/;" c | |
26 | BINDINGS src/Makefile /^BINDINGS =$/;" m | |
27 | BPF_A tools/bpf.h 117;" d | |
28 | BPF_ABS tools/bpf.h 87;" d | |
29 | BPF_ADD tools/bpf.h 95;" d | |
30 | BPF_ALU tools/bpf.h 75;" d | |
31 | BPF_AND tools/bpf.h 100;" d | |
32 | BPF_B tools/bpf.h 84;" d | |
33 | BPF_CLASS tools/bpf.h 70;" d | |
34 | BPF_DIV tools/bpf.h 98;" d | |
35 | BPF_H tools/bpf.h 83;" d | |
36 | BPF_IMM tools/bpf.h 86;" d | |
37 | BPF_IND tools/bpf.h 88;" d | |
38 | BPF_JA tools/bpf.h 105;" d | |
39 | BPF_JEQ tools/bpf.h 106;" d | |
40 | BPF_JGE tools/bpf.h 108;" d | |
41 | BPF_JGT tools/bpf.h 107;" d | |
42 | BPF_JMP tools/bpf.h 76;" d | |
43 | BPF_JSET tools/bpf.h 109;" d | |
44 | BPF_K tools/bpf.h 112;" d | |
45 | BPF_LD tools/bpf.h 71;" d | |
46 | BPF_LDX tools/bpf.h 72;" d | |
47 | BPF_LEN tools/bpf.h 90;" d | |
48 | BPF_LSH tools/bpf.h 101;" d | |
49 | BPF_MEM tools/bpf.h 89;" d | |
50 | BPF_MISC tools/bpf.h 78;" d | |
51 | BPF_MISCOP tools/bpf.h 120;" d | |
52 | BPF_MODE tools/bpf.h 85;" d | |
53 | BPF_MSH tools/bpf.h 91;" d | |
54 | BPF_MUL tools/bpf.h 97;" d | |
55 | BPF_NEG tools/bpf.h 103;" d | |
56 | BPF_OP tools/bpf.h 93;" d | |
57 | BPF_OR tools/bpf.h 99;" d | |
58 | BPF_PGM_SIZE src/gen_bpf.h 36;" d | |
59 | BPF_PRG_MAX_LEN tools/scmp_bpf_sim.c 36;" d file: | |
60 | BPF_RET tools/bpf.h 77;" d | |
61 | BPF_RSH tools/bpf.h 102;" d | |
62 | BPF_RVAL tools/bpf.h 116;" d | |
63 | BPF_SCRATCH_SIZE tools/bpf.h 33;" d | |
64 | BPF_SIZE tools/bpf.h 81;" d | |
65 | BPF_SRC tools/bpf.h 111;" d | |
66 | BPF_ST tools/bpf.h 73;" d | |
67 | BPF_STX tools/bpf.h 74;" d | |
68 | BPF_SUB tools/bpf.h 96;" d | |
69 | BPF_SYSCALL_MAX tools/bpf.h 45;" d | |
70 | BPF_SYS_ARG_MAX tools/bpf.h 38;" d | |
71 | BPF_TAX tools/bpf.h 121;" d | |
72 | BPF_TXA tools/bpf.h 122;" d | |
73 | BPF_W tools/bpf.h 82;" d | |
74 | BPF_X tools/bpf.h 113;" d | |
75 | CAT macros.mk /^CAT ?= cat$/;" m | |
76 | CFLAGS macros.mk /^CFLAGS ?= -Wl,-z,relro -Wall -O0 -g$/;" m | |
77 | COMPILE macros.mk /^ COMPILE = @echo " CC $@";$/;" m | |
78 | COMPILE_EXEC macros.mk /^ COMPILE_EXEC = @echo " CC $@";$/;" m | |
79 | CONFIGS Makefile /^CONFIGS = configure.mk configure.h version_info.mk libseccomp.pc$/;" m | |
80 | CONF_BINDINGS_PYTHON configure.h 8;" d | |
81 | CONF_BINDINGS_PYTHON configure.mk /^CONF_BINDINGS_PYTHON = 1$/;" m | |
82 | CONF_INSTALL_LIBDIR configure.mk /^CONF_INSTALL_LIBDIR = "\/usr\/local\/lib"$/;" m | |
83 | CONF_INSTALL_PREFIX configure.mk /^CONF_INSTALL_PREFIX = "\/usr\/local"$/;" m | |
84 | CONF_SYSINC_SECCOMP configure.h 7;" d | |
85 | CONF_SYSINC_SECCOMP configure.mk /^CONF_SYSINC_SECCOMP = 1$/;" m | |
86 | CTL_NNP src/python/seccomp.pyx /^ CTL_NNP = libseccomp.SCMP_FLTATR_CTL_NNP$/;" v class:Attr | |
87 | D64_HI src/arch.h 74;" d | |
88 | D64_LO src/arch.h 73;" d | |
89 | DATUM_MAX src/arch.h 72;" d | |
90 | DEPS src/Makefile /^DEPS = $(OBJS:%.o=%.d)$/;" m | |
91 | DEPS tools/Makefile /^DEPS = $(TOOLS:%=%.d)$/;" m | |
92 | DEPS_OBJS tests/Makefile /^DEPS_OBJS = $(OBJS:%.o=%.d)$/;" m | |
93 | DEPS_TESTS tests/Makefile /^DEPS_TESTS = $(TESTS:%=%.d)$/;" m | |
94 | ECHO macros.mk /^ECHO ?= echo$/;" m | |
95 | ECHO_INFO macros.mk /^ ECHO_INFO ?= $(ECHO) ">> INFO:"$/;" m | |
96 | ECHO_INFO macros.mk /^ ECHO_INFO ?= \/bin\/true || $(ECHO) ">> INFO:"$/;" m | |
97 | EQ src/python/seccomp.pyx /^EQ = libseccomp.SCMP_CMP_EQ$/;" v | |
98 | ERRNO src/python/seccomp.pyx /^def ERRNO(int errno):$/;" f | |
99 | Extension src/python/setup.py /^from distutils.extension import Extension$/;" i | |
100 | GCC macros.mk /^GCC ?= gcc$/;" m | |
101 | GE src/python/seccomp.pyx /^GE = libseccomp.SCMP_CMP_GE$/;" v | |
102 | GT src/python/seccomp.pyx /^GT = libseccomp.SCMP_CMP_GT$/;" v | |
103 | HASH_BIG_ENDIAN src/hash.c 55;" d file: | |
104 | HASH_BIG_ENDIAN src/hash.c 60;" d file: | |
105 | HASH_BIG_ENDIAN src/hash.c 63;" d file: | |
106 | HASH_LITTLE_ENDIAN src/hash.c 54;" d file: | |
107 | HASH_LITTLE_ENDIAN src/hash.c 59;" d file: | |
108 | HASH_LITTLE_ENDIAN src/hash.c 62;" d file: | |
109 | HDR_BUILD include/Makefile /^HDR_BUILD = seccomp.h$/;" m | |
110 | INSTALL macros.mk /^INSTALL ?= install$/;" m | |
111 | INSTALL_BIN_DIR install.mk /^INSTALL_BIN_DIR ?= $(DESTDIR)\/$(INSTALL_PREFIX)\/bin$/;" m | |
112 | INSTALL_BIN_MACRO macros.mk /^ INSTALL_BIN_MACRO = @echo " INSTALL $^ ($(INSTALL_BIN_DIR)\/$^)";$/;" m | |
113 | INSTALL_GROUP install.mk /^INSTALL_GROUP ?= $$(id -g)$/;" m | |
114 | INSTALL_INC_DIR install.mk /^INSTALL_INC_DIR ?= $(DESTDIR)\/$(INSTALL_PREFIX)\/include$/;" m | |
115 | INSTALL_INC_MACRO macros.mk /^ INSTALL_INC_MACRO = @echo " INSTALL $^ ($(INSTALL_INC_DIR))";$/;" m | |
116 | INSTALL_LIB_DIR install.mk /^INSTALL_LIB_DIR ?= $(DESTDIR)\/$(CONF_INSTALL_LIBDIR)$/;" m | |
117 | INSTALL_LIB_MACRO macros.mk /^ INSTALL_LIB_MACRO = @echo " INSTALL $^ ($(INSTALL_LIB_DIR)\/$^)";$/;" m | |
118 | INSTALL_MAN1_MACRO macros.mk /^ INSTALL_MAN1_MACRO = \\$/;" m | |
119 | INSTALL_MAN3_MACRO macros.mk /^ INSTALL_MAN3_MACRO = \\$/;" m | |
120 | INSTALL_MAN_DIR install.mk /^INSTALL_MAN_DIR ?= $(DESTDIR)\/$(INSTALL_PREFIX)\/share\/man$/;" m | |
121 | INSTALL_OWNER install.mk /^INSTALL_OWNER ?= $$(id -u)$/;" m | |
122 | INSTALL_PC_MACRO macros.mk /^ INSTALL_PC_MACRO = \\$/;" m | |
123 | INSTALL_PREFIX install.mk /^INSTALL_PREFIX ?= $(CONF_INSTALL_PREFIX)$/;" m | |
124 | INSTALL_SBIN_DIR install.mk /^INSTALL_SBIN_DIR ?= $(DESTDIR)\/$(INSTALL_PREFIX)\/sbin$/;" m | |
125 | KILL src/python/seccomp.pyx /^KILL = libseccomp.SCMP_ACT_KILL$/;" v | |
126 | LDFLAGS macros.mk /^LDFLAGS ?= -z relro -g$/;" m | |
127 | LDFLAGS tests/Makefile /^LDFLAGS := ..\/src\/libseccomp.a $(OBJS)$/;" m | |
128 | LDFLAGS tools/Makefile /^LDFLAGS := ..\/src\/libseccomp.a$/;" m | |
129 | LE src/python/seccomp.pyx /^LE = libseccomp.SCMP_CMP_LE$/;" v | |
130 | LIBFLAGS macros.mk /^LIBFLAGS =$/;" m | |
131 | LIB_SHARED src/Makefile /^LIB_SHARED = libseccomp.so.$(VERSION_RELEASE)$/;" m | |
132 | LIB_STATIC src/Makefile /^LIB_STATIC = libseccomp.a$/;" m | |
133 | LIB_STATIC src/python/Makefile /^LIB_STATIC = ..\/libseccomp.a$/;" m | |
134 | LINK_EXEC macros.mk /^ LINK_EXEC = @echo " LD $@";$/;" m | |
135 | LINK_LIB macros.mk /^ LINK_LIB = @echo " LD $@" \\$/;" m | |
136 | LN macros.mk /^LN ?= ln$/;" m | |
137 | LT src/python/seccomp.pyx /^LT = libseccomp.SCMP_CMP_LT$/;" v | |
138 | MAKEDEP macros.mk /^MAKEDEP = @$(GCC) $(CPPFLAGS) -MM -MF $(patsubst %.o,%.d,$@) $<;$/;" m | |
139 | MAKEDEP_EXEC macros.mk /^MAKEDEP_EXEC = \\$/;" m | |
140 | MAN1 doc/Makefile /^MAN1 = \\$/;" m | |
141 | MAN3 doc/Makefile /^MAN3 = \\$/;" m | |
142 | MASKED_EQ src/python/seccomp.pyx /^MASKED_EQ = libseccomp.SCMP_CMP_MASKED_EQ$/;" v | |
143 | MKDIR macros.mk /^MKDIR ?= mkdir$/;" m | |
144 | MV macros.mk /^MV ?= mv$/;" m | |
145 | NATIVE src/python/seccomp.pyx /^ NATIVE = libseccomp.SCMP_ARCH_NATIVE$/;" v class:Arch | |
146 | NE src/python/seccomp.pyx /^NE = libseccomp.SCMP_CMP_NE$/;" v | |
147 | OBJS src/Makefile /^OBJS = \\$/;" m | |
148 | OBJS tests/Makefile /^OBJS = util.o$/;" m | |
149 | PR_GET_NO_NEW_PRIVS src/system.h 89;" d | |
150 | PR_SET_NO_NEW_PRIVS src/system.h 85;" d | |
151 | PYTHON macros.mk /^PYTHON ?= \/usr\/bin\/env python$/;" m | |
152 | PY_BUILD macros.mk /^ PY_BUILD = @echo " PYTHON build";$/;" m | |
153 | PY_DISTUTILS macros.mk /^PY_DISTUTILS = \\$/;" m | |
154 | PY_INSTALL macros.mk /^ PY_INSTALL = @echo " PYTHON install";$/;" m | |
155 | SECCOMP_MODE_DISABLED src/system.h 41;" d | |
156 | SECCOMP_MODE_FILTER src/system.h 43;" d | |
157 | SECCOMP_MODE_STRICT src/system.h 42;" d | |
158 | SECCOMP_RET_ACTION src/system.h 60;" d | |
159 | SECCOMP_RET_ACTION tools/bpf.h 59;" d | |
160 | SECCOMP_RET_ALLOW src/system.h 57;" d | |
161 | SECCOMP_RET_ALLOW tools/bpf.h 67;" d | |
162 | SECCOMP_RET_DATA src/system.h 61;" d | |
163 | SECCOMP_RET_DATA tools/bpf.h 60;" d | |
164 | SECCOMP_RET_ERRNO src/system.h 55;" d | |
165 | SECCOMP_RET_ERRNO tools/bpf.h 65;" d | |
166 | SECCOMP_RET_KILL src/system.h 53;" d | |
167 | SECCOMP_RET_KILL tools/bpf.h 63;" d | |
168 | SECCOMP_RET_TRACE src/system.h 56;" d | |
169 | SECCOMP_RET_TRACE tools/bpf.h 66;" d | |
170 | SECCOMP_RET_TRAP src/system.h 54;" d | |
171 | SECCOMP_RET_TRAP tools/bpf.h 64;" d | |
172 | SED macros.mk /^SED ?= sed$/;" m | |
173 | SHELL macros.mk /^SHELL = \/bin\/bash$/;" m | |
174 | SUBDIRS_BUILD Makefile /^SUBDIRS_BUILD = include src tests tools$/;" m | |
175 | SUBDIRS_INSTALL Makefile /^SUBDIRS_INSTALL = include src tools doc$/;" m | |
176 | SyscallFilter src/python/seccomp.pyx /^cdef class SyscallFilter:$/;" c | |
177 | TAR macros.mk /^TAR ?= tar$/;" m | |
178 | TESTS tests/Makefile /^TESTS = 01-sim-allow \\$/;" m | |
179 | TEST_PRIVATE tests/Makefile /^TEST_PRIVATE = 00-test$/;" m | |
180 | TGT_IMM src/gen_bpf.c /^ TGT_IMM, \/* resolved immediate value *\/$/;" e enum:bpf_jump_type file: | |
181 | TGT_K src/gen_bpf.c /^ TGT_K, \/* immediate "k" value *\/$/;" e enum:bpf_jump_type file: | |
182 | TGT_NONE src/gen_bpf.c /^ TGT_NONE = 0,$/;" e enum:bpf_jump_type file: | |
183 | TGT_NXT src/gen_bpf.c /^ TGT_NXT, \/* fall through to the next block *\/$/;" e enum:bpf_jump_type file: | |
184 | TGT_PTR_BLK src/gen_bpf.c /^ TGT_PTR_BLK, \/* pointer to an instruction block *\/$/;" e enum:bpf_jump_type file: | |
185 | TGT_PTR_DB src/gen_bpf.c /^ TGT_PTR_DB, \/* pointer to part of the filter db *\/$/;" e enum:bpf_jump_type file: | |
186 | TGT_PTR_HSH src/gen_bpf.c /^ TGT_PTR_HSH, \/* pointer to a block hash table *\/$/;" e enum:bpf_jump_type file: | |
187 | TOOLS tools/Makefile /^TOOLS = scmp_bpf_disasm \\$/;" m | |
188 | TOOLS_INSTALL tools/Makefile /^TOOLS_INSTALL = scmp_sys_resolver$/;" m | |
189 | TOPDIR macros.mk /^TOPDIR := $(shell \\$/;" m | |
190 | TRACE src/python/seccomp.pyx /^def TRACE(int value):$/;" f | |
191 | TRAP src/python/seccomp.pyx /^TRAP = libseccomp.SCMP_ACT_TRAP$/;" v | |
192 | V macros.mk /^V ?= 0$/;" m | |
193 | VERSION_HDR macros.mk /^VERSION_HDR = version.h$/;" m | |
194 | VERSION_MAJOR version.h 5;" d | |
195 | VERSION_MAJOR version_info.mk /^VERSION_MAJOR=0$/;" m | |
196 | VERSION_MICRO version.h 7;" d | |
197 | VERSION_MICRO version_info.mk /^VERSION_MICRO=0$/;" m | |
198 | VERSION_MINOR version.h 6;" d | |
199 | VERSION_MINOR version_info.mk /^VERSION_MINOR=0$/;" m | |
200 | VERSION_RELEASE version.h 4;" d | |
201 | VERSION_RELEASE version_info.mk /^VERSION_RELEASE=0.0.0$/;" m | |
202 | X32 src/python/seccomp.pyx /^ X32 = libseccomp.SCMP_ARCH_X32$/;" v class:Arch | |
203 | X32_SYSCALL_BIT src/arch-x32.h 30;" d | |
204 | X86 src/python/seccomp.pyx /^ X86 = libseccomp.SCMP_ARCH_X86$/;" v class:Arch | |
205 | X86_64 src/python/seccomp.pyx /^ X86_64 = libseccomp.SCMP_ARCH_X86_64$/;" v class:Arch | |
206 | _ARCH_ARM_H src/arch-arm.h 23;" d | |
207 | _ARCH_H src/arch.h 23;" d | |
208 | _ARCH_X32_H src/arch-x32.h 23;" d | |
209 | _ARCH_X86_H src/arch-x86.h 23;" d | |
210 | _ARCH_x86_64_H src/arch-x86_64.h 23;" d | |
211 | _BLK_MSZE src/gen_bpf.c 117;" d file: | |
212 | _BPF_H tools/bpf.h 23;" d | |
213 | _BPF_HASH_BITS src/gen_bpf.c 126;" d file: | |
214 | _BPF_HASH_MASK src/gen_bpf.c 128;" d file: | |
215 | _BPF_HASH_SIZE src/gen_bpf.c 127;" d file: | |
216 | _BPF_INSTR src/gen_bpf.c 156;" d file: | |
217 | _BPF_JMP_BLK src/gen_bpf.c 76;" d file: | |
218 | _BPF_JMP_DB src/gen_bpf.c 74;" d file: | |
219 | _BPF_JMP_HSH src/gen_bpf.c 78;" d file: | |
220 | _BPF_JMP_IMM src/gen_bpf.c 72;" d file: | |
221 | _BPF_JMP_MAX src/gen_bpf.c 82;" d file: | |
222 | _BPF_JMP_MAX_RET src/gen_bpf.c 83;" d file: | |
223 | _BPF_JMP_NO src/gen_bpf.c 68;" d file: | |
224 | _BPF_JMP_NXT src/gen_bpf.c 70;" d file: | |
225 | _BPF_K src/gen_bpf.c 80;" d file: | |
226 | _BPF_OFFSET_SYSCALL src/gen_bpf.c 91;" d file: | |
227 | _BPF_SYSCALL src/gen_bpf.c 92;" d file: | |
228 | _CONFIGURE_H configure.h 5;" d | |
229 | _DB_PRI_MASK_CHAIN src/db.c 41;" d file: | |
230 | _DB_PRI_MASK_USER src/db.c 42;" d file: | |
231 | _DB_PRI_USER src/db.c 43;" d file: | |
232 | _DB_STA_FREED src/db.c 36;" d file: | |
233 | _DB_STA_VALID src/db.c 35;" d file: | |
234 | _FILTER_DB_H src/db.h 23;" d | |
235 | _HASH_H src/hash.h 19;" d | |
236 | _OP_FMT tools/scmp_bpf_disasm.c 35;" d file: | |
237 | _SYSTEM_H src/system.h 23;" d | |
238 | _TRANSLATOR_BPF_H src/gen_bpf.h 23;" d | |
239 | _TRANSLATOR_STR_H src/gen_pfc.h 23;" d | |
240 | _UTIL_TEST_H tests/util.h 23;" d | |
241 | _VERSION_H version.h 3;" d | |
242 | __NR_OABI_SYSCALL_BASE src/arch-arm-syscalls.c 29;" d file: | |
243 | __NR_SYSCALL_BASE src/arch-arm-syscalls.c 34;" d file: | |
244 | __NR_SYSCALL_BASE src/arch-arm-syscalls.c 36;" d file: | |
245 | __author__ src/python/seccomp.pyx /^__author__ = 'Paul Moore <paul@paul-moore.com>'$/;" v | |
246 | __blk_free src/gen_bpf.c /^static void __blk_free(struct bpf_state *state, struct bpf_blk *blk)$/;" f file: | |
247 | __cinit__ src/python/seccomp.pyx /^ def __cinit__(self, arg, op, datum_a, datum_b = 0):$/;" m class:Arg file: | |
248 | __cinit__ src/python/seccomp.pyx /^ def __cinit__(self, int defaction):$/;" m class:SyscallFilter file: | |
249 | __date__ src/python/seccomp.pyx /^__date__ = "7 January 2013"$/;" v | |
250 | __db_tree_free src/db.c /^static unsigned int __db_tree_free(struct db_arg_chain_tree *tree)$/;" f file: | |
251 | __dealloc__ src/python/seccomp.pyx /^ def __dealloc__(self):$/;" m class:SyscallFilter file: | |
252 | __x86_NR_ipc src/arch-x86.c 31;" d file: | |
253 | __x86_NR_socketcall src/arch-x86.c 30;" d file: | |
254 | _blk_append src/gen_bpf.c /^static struct bpf_blk *_blk_append(struct bpf_state *state,$/;" f file: | |
255 | _blk_free src/gen_bpf.c /^static void _blk_free(struct bpf_state *state, struct bpf_blk *blk)$/;" f file: | |
256 | _bpf_append_blk src/gen_bpf.c /^static int _bpf_append_blk(struct bpf_program *prg, const struct bpf_blk *blk)$/;" f file: | |
257 | _ctx_valid src/api.c /^static int _ctx_valid(const scmp_filter_ctx *ctx)$/;" f file: | |
258 | _db_node_mask_fixup src/db.c /^static void _db_node_mask_fixup(struct db_arg_chain_tree *node)$/;" f file: | |
259 | _db_rule_gen_32 src/db.c /^static struct db_sys_list *_db_rule_gen_32(const struct arch_def *arch,$/;" f file: | |
260 | _db_rule_gen_64 src/db.c /^static struct db_sys_list *_db_rule_gen_64(const struct arch_def *arch,$/;" f file: | |
261 | _db_tree_act_check src/db.c /^static int _db_tree_act_check(struct db_arg_chain_tree *tree, uint32_t action)$/;" f file: | |
262 | _db_tree_free src/db.c /^static unsigned int _db_tree_free(struct db_arg_chain_tree *tree)$/;" f file: | |
263 | _db_tree_remove src/db.c /^static unsigned int _db_tree_remove(struct db_arg_chain_tree **tree,$/;" f file: | |
264 | _db_tree_sub_prune src/db.c /^static int _db_tree_sub_prune(struct db_arg_chain_tree **tree_head,$/;" f file: | |
265 | _gen_bpf_action src/gen_bpf.c /^static struct bpf_blk *_gen_bpf_action(struct bpf_state *state,$/;" f file: | |
266 | _gen_bpf_action_hsh src/gen_bpf.c /^static struct bpf_blk *_gen_bpf_action_hsh(struct bpf_state *state,$/;" f file: | |
267 | _gen_bpf_arch src/gen_bpf.c /^static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state,$/;" f file: | |
268 | _gen_bpf_build_bpf src/gen_bpf.c /^static int _gen_bpf_build_bpf(struct bpf_state *state,$/;" f file: | |
269 | _gen_bpf_build_jmp src/gen_bpf.c /^static int _gen_bpf_build_jmp(struct bpf_state *state,$/;" f file: | |
270 | _gen_bpf_build_jmp_ret src/gen_bpf.c /^static int _gen_bpf_build_jmp_ret(struct bpf_state *state,$/;" f file: | |
271 | _gen_bpf_chain src/gen_bpf.c /^static struct bpf_blk *_gen_bpf_chain(struct bpf_state *state,$/;" f file: | |
272 | _gen_bpf_chain_lvl_res src/gen_bpf.c /^static struct bpf_blk *_gen_bpf_chain_lvl_res(struct bpf_state *state,$/;" f file: | |
273 | _gen_bpf_find_nxt src/gen_bpf.c /^static struct bpf_blk *_gen_bpf_find_nxt(const struct bpf_blk *blk,$/;" f file: | |
274 | _gen_bpf_node src/gen_bpf.c /^static struct bpf_blk *_gen_bpf_node(struct bpf_state *state,$/;" f file: | |
275 | _gen_bpf_syscall src/gen_bpf.c /^static struct bpf_blk *_gen_bpf_syscall(struct bpf_state *state,$/;" f file: | |
276 | _gen_pfc_arch src/gen_pfc.c /^static int _gen_pfc_arch(const struct db_filter_col *col,$/;" f file: | |
277 | _gen_pfc_chain src/gen_pfc.c /^static void _gen_pfc_chain(const struct arch_def *arch,$/;" f file: | |
278 | _gen_pfc_syscall src/gen_pfc.c /^static void _gen_pfc_syscall(const struct arch_def *arch,$/;" f file: | |
279 | _hsh_add src/gen_bpf.c /^static int _hsh_add(struct bpf_state *state, struct bpf_blk **blk_p,$/;" f file: | |
280 | _hsh_find src/gen_bpf.c /^static struct bpf_blk *_hsh_find(const struct bpf_state *state, uint64_t h_val)$/;" f file: | |
281 | _hsh_find_bkt src/gen_bpf.c /^static struct bpf_hash_bkt *_hsh_find_bkt(const struct bpf_state *state,$/;" f file: | |
282 | _hsh_find_once src/gen_bpf.c /^static struct bpf_blk *_hsh_find_once(const struct bpf_state *state,$/;" f file: | |
283 | _hsh_remove src/gen_bpf.c /^static struct bpf_blk *_hsh_remove(struct bpf_state *state, uint64_t h_val)$/;" f file: | |
284 | _indent src/gen_pfc.c /^static void _indent(FILE *fds, unsigned int lvl)$/;" f file: | |
285 | _pfc_action src/gen_pfc.c /^static void _pfc_action(FILE *fds, uint32_t action)$/;" f file: | |
286 | _pfc_arch src/gen_pfc.c /^static const char *_pfc_arch(const struct arch_def *arch)$/;" f file: | |
287 | _pfc_arg src/gen_pfc.c /^static void _pfc_arg(FILE *fds,$/;" f file: | |
288 | _program_free src/gen_bpf.c /^static void _program_free(struct bpf_program *prg)$/;" f file: | |
289 | _seccomp_rule_add src/api.c /^static int _seccomp_rule_add(struct db_filter_col *col,$/;" f file: | |
290 | _state_release src/gen_bpf.c /^static void _state_release(struct bpf_state *state)$/;" f file: | |
291 | _syscall_valid src/api.c /^static int _syscall_valid(int syscall)$/;" f file: | |
292 | _trap_handler tests/util.c /^static void _trap_handler(int signal, siginfo_t *info, void *ctx)$/;" f file: | |
293 | acc tools/scmp_bpf_sim.c /^ uint32_t acc;$/;" m struct:sim_state file: | |
294 | acc_state src/gen_bpf.c /^ struct acc_state acc_state;$/;" m struct:bpf_blk typeref:struct:bpf_blk::acc_state file: | |
295 | acc_state src/gen_bpf.c /^struct acc_state {$/;" s file: | |
296 | act_badarch src/db.h /^ uint32_t act_badarch;$/;" m struct:db_filter_attr | |
297 | act_default src/db.h /^ uint32_t act_default;$/;" m struct:db_filter_attr | |
298 | act_f src/db.h /^ uint32_t act_f;$/;" m struct:db_arg_chain_tree | |
299 | act_f_flg src/db.h /^ bool act_f_flg;$/;" m struct:db_arg_chain_tree | |
300 | act_t src/db.h /^ uint32_t act_t;$/;" m struct:db_arg_chain_tree | |
301 | act_t_flg src/db.h /^ bool act_t_flg;$/;" m struct:db_arg_chain_tree | |
302 | action src/db.h /^ uint32_t action;$/;" m struct:db_sys_list | |
303 | add_arch src/python/seccomp.pyx /^ def add_arch(self, arch):$/;" m class:SyscallFilter | |
304 | add_rule src/python/seccomp.pyx /^ def add_rule(self, int action, syscall, *args):$/;" m class:SyscallFilter | |
305 | add_rule_exactly src/python/seccomp.pyx /^ def add_rule_exactly(self, int action, syscall, *args):$/;" m class:SyscallFilter | |
306 | arch src/db.h /^ const struct arch_def *arch;$/;" m struct:db_filter typeref:struct:db_filter::arch_def | |
307 | arch src/gen_bpf.c /^ const struct arch_def *arch;$/;" m struct:bpf_state typeref:struct:bpf_state::arch_def file: | |
308 | arch src/system.h /^ __u32 arch;$/;" m struct:seccomp_data | |
309 | arch tools/bpf.h /^ uint32_t arch;$/;" m struct:seccomp_data | |
310 | arch_arg_count_max src/arch.c /^int arch_arg_count_max(const struct arch_def *arch)$/;" f | |
311 | arch_arg_offset src/arch.h 91;" d | |
312 | arch_arg_offset_hi src/arch.c /^int arch_arg_offset_hi(const struct arch_def *arch, unsigned int arg)$/;" f | |
313 | arch_arg_offset_lo src/arch.c /^int arch_arg_offset_lo(const struct arch_def *arch, unsigned int arg)$/;" f | |
314 | arch_def src/arch.h /^struct arch_def {$/;" s | |
315 | arch_def_arm src/arch-arm.c /^const struct arch_def arch_def_arm = {$/;" v typeref:struct:arch_def | |
316 | arch_def_lookup src/arch.c /^const struct arch_def *arch_def_lookup(uint32_t token)$/;" f | |
317 | arch_def_native src/arch.c /^const struct arch_def *arch_def_native = &arch_def_arm;$/;" v typeref:struct:arch_def | |
318 | arch_def_native src/arch.c /^const struct arch_def *arch_def_native = &arch_def_x32;$/;" v typeref:struct:arch_def | |
319 | arch_def_native src/arch.c /^const struct arch_def *arch_def_native = &arch_def_x86;$/;" v typeref:struct:arch_def | |
320 | arch_def_native src/arch.c /^const struct arch_def *arch_def_native = &arch_def_x86_64;$/;" v typeref:struct:arch_def | |
321 | arch_def_x32 src/arch-x32.c /^const struct arch_def arch_def_x32 = {$/;" v typeref:struct:arch_def | |
322 | arch_def_x86 src/arch-x86.c /^const struct arch_def arch_def_x86 = {$/;" v typeref:struct:arch_def | |
323 | arch_def_x86_64 src/arch-x86_64.c /^const struct arch_def arch_def_x86_64 = {$/;" v typeref:struct:arch_def | |
324 | arch_filter_rewrite src/arch.c /^int arch_filter_rewrite(const struct arch_def *arch,$/;" f | |
325 | arch_syscall_def src/arch.h /^struct arch_syscall_def {$/;" s | |
326 | arch_syscall_resolve_name src/arch.c /^int arch_syscall_resolve_name(const struct arch_def *arch, const char *name)$/;" f | |
327 | arch_syscall_resolve_num src/arch.c /^const char *arch_syscall_resolve_num(const struct arch_def *arch, int num)$/;" f | |
328 | arch_syscall_rewrite src/arch.c /^int arch_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall)$/;" f | |
329 | arch_syscall_translate src/arch.c /^int arch_syscall_translate(const struct arch_def *arch, int *syscall)$/;" f | |
330 | arch_valid src/arch.c /^int arch_valid(uint32_t arch)$/;" f | |
331 | arg src/db.h /^ unsigned int arg;$/;" m struct:db_api_arg | |
332 | arg src/db.h /^ unsigned int arg;$/;" m struct:db_arg_chain_tree | |
333 | arg_offset src/db.h /^ unsigned int arg_offset;$/;" m struct:db_arg_chain_tree | |
334 | argparse tests/01-sim-allow.py /^import argparse$/;" i | |
335 | argparse tests/02-sim-basic.py /^import argparse$/;" i | |
336 | argparse tests/03-sim-basic_chains.py /^import argparse$/;" i | |
337 | argparse tests/04-sim-multilevel_chains.py /^import argparse$/;" i | |
338 | argparse tests/05-sim-long_jumps.py /^import argparse$/;" i | |
339 | argparse tests/06-sim-actions.py /^import argparse$/;" i | |
340 | argparse tests/07-sim-db_bug_looping.py /^import argparse$/;" i | |
341 | argparse tests/08-sim-subtree_checks.py /^import argparse$/;" i | |
342 | argparse tests/09-sim-syscall_priority_pre.py /^import argparse$/;" i | |
343 | argparse tests/10-sim-syscall_priority_post.py /^import argparse$/;" i | |
344 | argparse tests/11-basic-basic_errors.py /^import argparse$/;" i | |
345 | argparse tests/12-sim-basic_masked_ops.py /^import argparse$/;" i | |
346 | argparse tests/13-basic-attrs.py /^import argparse$/;" i | |
347 | argparse tests/14-sim-reset.py /^import argparse$/;" i | |
348 | argparse tests/15-basic-resolver.py /^import argparse$/;" i | |
349 | argparse tests/16-sim-arch_basic.py /^import argparse$/;" i | |
350 | argparse tests/17-sim-arch_merge.py /^import argparse$/;" i | |
351 | argparse tests/18-sim-basic_whitelist.py /^import argparse$/;" i | |
352 | argparse tests/19-sim-missing_syscalls.py /^import argparse$/;" i | |
353 | argparse tests/20-live-basic_die.py /^import argparse$/;" i | |
354 | argparse tests/21-live-basic_allow.py /^import argparse$/;" i | |
355 | argparse tests/22-sim-basic_chains_array.py /^import argparse$/;" i | |
356 | argparse tests/23-sim-arch_all_basic.py /^import argparse$/;" i | |
357 | argparse tests/24-live-arg_allow.py /^import argparse$/;" i | |
358 | argparse tests/25-sim-multilevel_chains_adv.py /^import argparse$/;" i | |
359 | argparse tests/util.py /^import argparse$/;" i | |
360 | args src/system.h /^ __u64 args[6];$/;" m struct:seccomp_data | |
361 | args tests/01-sim-allow.py /^args = util.get_opt()$/;" v | |
362 | args tests/02-sim-basic.py /^args = util.get_opt()$/;" v | |
363 | args tests/03-sim-basic_chains.py /^args = util.get_opt()$/;" v | |
364 | args tests/04-sim-multilevel_chains.py /^args = util.get_opt()$/;" v | |
365 | args tests/05-sim-long_jumps.py /^args = util.get_opt()$/;" v | |
366 | args tests/06-sim-actions.py /^args = util.get_opt()$/;" v | |
367 | args tests/07-sim-db_bug_looping.py /^args = util.get_opt()$/;" v | |
368 | args tests/08-sim-subtree_checks.py /^args = util.get_opt()$/;" v | |
369 | args tests/09-sim-syscall_priority_pre.py /^args = util.get_opt()$/;" v | |
370 | args tests/10-sim-syscall_priority_post.py /^args = util.get_opt()$/;" v | |
371 | args tests/12-sim-basic_masked_ops.py /^args = util.get_opt()$/;" v | |
372 | args tests/14-sim-reset.py /^args = util.get_opt()$/;" v | |
373 | args tests/16-sim-arch_basic.py /^args = util.get_opt()$/;" v | |
374 | args tests/17-sim-arch_merge.py /^args = util.get_opt()$/;" v | |
375 | args tests/18-sim-basic_whitelist.py /^args = util.get_opt()$/;" v | |
376 | args tests/19-sim-missing_syscalls.py /^args = util.get_opt()$/;" v | |
377 | args tests/22-sim-basic_chains_array.py /^args = util.get_opt()$/;" v | |
378 | args tests/23-sim-arch_all_basic.py /^args = util.get_opt()$/;" v | |
379 | args tests/25-sim-multilevel_chains_adv.py /^args = util.get_opt()$/;" v | |
380 | args tools/bpf.h /^ uint64_t args[BPF_SYS_ARG_MAX];$/;" m struct:seccomp_data | |
381 | arm_arg_count_max src/arch-arm.h 30;" d | |
382 | arm_syscall_resolve_name src/arch-arm-syscalls.c /^int arm_syscall_resolve_name(const char *name)$/;" f | |
383 | arm_syscall_resolve_num src/arch-arm-syscalls.c /^const char *arm_syscall_resolve_num(int num)$/;" f | |
384 | arm_syscall_table src/arch-arm-syscalls.c /^const struct arch_syscall_def arm_syscall_table[] = \\$/;" v typeref:struct:arch_syscall_def | |
385 | attr src/db.h /^ struct db_filter_attr attr;$/;" m struct:db_filter_col typeref:struct:db_filter_col::db_filter_attr | |
386 | attr src/gen_bpf.c /^ const struct db_filter_attr *attr;$/;" m struct:bpf_state typeref:struct:bpf_state::db_filter_attr file: | |
387 | blk src/gen_bpf.c /^ struct bpf_blk *blk;$/;" m union:bpf_jump::__anon1 typeref:struct:bpf_jump::__anon1::bpf_blk file: | |
388 | blk src/gen_bpf.c /^ struct bpf_blk *blk;$/;" m struct:bpf_hash_bkt typeref:struct:bpf_hash_bkt::bpf_blk file: | |
389 | blk_alloc src/gen_bpf.c /^ unsigned int blk_alloc;$/;" m struct:bpf_blk file: | |
390 | blk_cnt src/gen_bpf.c /^ unsigned int blk_cnt;$/;" m struct:bpf_blk file: | |
391 | blk_cnt src/gen_bpf.h /^ uint16_t blk_cnt;$/;" m struct:bpf_program | |
392 | blks src/gen_bpf.c /^ struct bpf_instr *blks;$/;" m struct:bpf_blk typeref:struct:bpf_blk::bpf_instr file: | |
393 | blks src/gen_bpf.h /^ bpf_instr_raw *blks;$/;" m struct:bpf_program | |
394 | bpf src/gen_bpf.c /^ struct bpf_program *bpf;$/;" m struct:bpf_state typeref:struct:bpf_state::bpf_program file: | |
395 | bpf_blk src/gen_bpf.c /^struct bpf_blk {$/;" s file: | |
396 | bpf_decode tools/scmp_bpf_disasm.c /^static int bpf_decode(FILE *file)$/;" f file: | |
397 | bpf_decode_args tools/scmp_bpf_disasm.c /^static void bpf_decode_args(const bpf_instr_raw *bpf, unsigned int line)$/;" f file: | |
398 | bpf_decode_op tools/scmp_bpf_disasm.c /^static void bpf_decode_op(const bpf_instr_raw *bpf)$/;" f file: | |
399 | bpf_execute tools/scmp_bpf_sim.c /^static void bpf_execute(const struct bpf_program *prg,$/;" f file: | |
400 | bpf_flg tests/util.h /^ int bpf_flg;$/;" m struct:util_options | |
401 | bpf_hash_bkt src/gen_bpf.c /^struct bpf_hash_bkt {$/;" s file: | |
402 | bpf_instr src/gen_bpf.c /^struct bpf_instr {$/;" s file: | |
403 | bpf_instr_raw src/system.h /^typedef struct sock_filter bpf_instr_raw;$/;" t typeref:struct:sock_filter | |
404 | bpf_instr_raw tools/bpf.h /^typedef struct sock_filter bpf_instr_raw;$/;" t typeref:struct:sock_filter | |
405 | bpf_jump src/gen_bpf.c /^struct bpf_jump {$/;" s file: | |
406 | bpf_jump_type src/gen_bpf.c /^enum bpf_jump_type {$/;" g file: | |
407 | bpf_program src/gen_bpf.h /^struct bpf_program {$/;" s | |
408 | bpf_program tools/scmp_bpf_sim.c /^struct bpf_program {$/;" s file: | |
409 | bpf_state src/gen_bpf.c /^struct bpf_state {$/;" s file: | |
410 | build_ext src/python/setup.py /^from Cython.Distutils import build_ext$/;" i | |
411 | chains src/db.h /^ struct db_arg_chain_tree *chains;$/;" m struct:db_sys_list typeref:struct:db_sys_list::db_arg_chain_tree | |
412 | cmdclass src/python/setup.py /^ cmdclass = {'build_ext': build_ext},$/;" v | |
413 | cnf_entry configure /^function cnf_entry() {$/;" f | |
414 | cnf_footer configure /^function cnf_footer() {$/;" f | |
415 | cnf_h_entry configure /^function cnf_h_entry() {$/;" f | |
416 | cnf_h_footer configure /^function cnf_h_footer() {$/;" f | |
417 | cnf_h_header configure /^function cnf_h_header() {$/;" f | |
418 | cnf_header configure /^function cnf_header() {$/;" f | |
419 | cnf_mk_entry configure /^function cnf_mk_entry() {$/;" f | |
420 | cnf_mk_footer configure /^function cnf_mk_footer() {$/;" f | |
421 | cnf_mk_header configure /^function cnf_mk_header() {$/;" f | |
422 | cnf_reset configure /^function cnf_reset() {$/;" f | |
423 | code tools/bpf.h /^ uint16_t code;$/;" m struct:sock_filter | |
424 | ctx tests/01-sim-allow.py /^ctx = test(args)$/;" v | |
425 | ctx tests/02-sim-basic.py /^ctx = test(args)$/;" v | |
426 | ctx tests/03-sim-basic_chains.py /^ctx = test(args)$/;" v | |
427 | ctx tests/04-sim-multilevel_chains.py /^ctx = test(args)$/;" v | |
428 | ctx tests/05-sim-long_jumps.py /^ctx = test(args)$/;" v | |
429 | ctx tests/06-sim-actions.py /^ctx = test(args)$/;" v | |
430 | ctx tests/07-sim-db_bug_looping.py /^ctx = test(args)$/;" v | |
431 | ctx tests/08-sim-subtree_checks.py /^ctx = test(args)$/;" v | |
432 | ctx tests/09-sim-syscall_priority_pre.py /^ctx = test(args)$/;" v | |
433 | ctx tests/10-sim-syscall_priority_post.py /^ctx = test(args)$/;" v | |
434 | ctx tests/12-sim-basic_masked_ops.py /^ctx = test(args)$/;" v | |
435 | ctx tests/14-sim-reset.py /^ctx = test(args)$/;" v | |
436 | ctx tests/16-sim-arch_basic.py /^ctx = test(args)$/;" v | |
437 | ctx tests/17-sim-arch_merge.py /^ctx = test(args)$/;" v | |
438 | ctx tests/18-sim-basic_whitelist.py /^ctx = test(args)$/;" v | |
439 | ctx tests/19-sim-missing_syscalls.py /^ctx = test(args)$/;" v | |
440 | ctx tests/22-sim-basic_chains_array.py /^ctx = test(args)$/;" v | |
441 | ctx tests/23-sim-arch_all_basic.py /^ctx = test(args)$/;" v | |
442 | ctx tests/25-sim-multilevel_chains_adv.py /^ctx = test(args)$/;" v | |
443 | datum src/db.h /^ scmp_datum_t datum;$/;" m struct:db_api_arg | |
444 | datum src/db.h /^ uint32_t datum;$/;" m struct:db_arg_chain_tree | |
445 | db src/gen_bpf.c /^ struct db_arg_chain_tree *db;$/;" m union:bpf_jump::__anon1 typeref:struct:bpf_jump::__anon1::db_arg_chain_tree file: | |
446 | db_action_valid src/db.c /^int db_action_valid(uint32_t action)$/;" f | |
447 | db_api_arg src/db.h /^struct db_api_arg {$/;" s | |
448 | db_arg_chain_tree src/db.h /^struct db_arg_chain_tree {$/;" s | |
449 | db_chain_eq src/db.h 75;" d | |
450 | db_chain_eq_result src/db.h 85;" d | |
451 | db_chain_gt src/db.h 79;" d | |
452 | db_chain_leaf src/db.h 83;" d | |
453 | db_chain_lt src/db.h 71;" d | |
454 | db_col_arch_exist src/db.c /^int db_col_arch_exist(struct db_filter_col *col, uint32_t arch_token)$/;" f | |
455 | db_col_attr_get src/db.c /^int db_col_attr_get(const struct db_filter_col *col,$/;" f | |
456 | db_col_attr_set src/db.c /^int db_col_attr_set(struct db_filter_col *col,$/;" f | |
457 | db_col_db_add src/db.c /^int db_col_db_add(struct db_filter_col *col, struct db_filter *db)$/;" f | |
458 | db_col_db_remove src/db.c /^int db_col_db_remove(struct db_filter_col *col, uint32_t arch_token)$/;" f | |
459 | db_col_init src/db.c /^struct db_filter_col *db_col_init(uint32_t def_action)$/;" f | |
460 | db_col_merge src/db.c /^int db_col_merge(struct db_filter_col *col_dst, struct db_filter_col *col_src)$/;" f | |
461 | db_col_release src/db.c /^void db_col_release(struct db_filter_col *col)$/;" f | |
462 | db_col_reset src/db.c /^void db_col_reset(struct db_filter_col *col, uint32_t def_action)$/;" f | |
463 | db_col_valid src/db.c /^int db_col_valid(struct db_filter_col *col)$/;" f | |
464 | db_filter src/db.h /^struct db_filter {$/;" s | |
465 | db_filter_attr src/db.h /^struct db_filter_attr {$/;" s | |
466 | db_filter_col src/db.h /^struct db_filter_col {$/;" s | |
467 | db_init src/db.c /^struct db_filter *db_init(const struct arch_def *arch)$/;" f | |
468 | db_list_foreach src/db.h 156;" d | |
469 | db_release src/db.c /^void db_release(struct db_filter *db)$/;" f | |
470 | db_reset src/db.c /^void db_reset(struct db_filter *db)$/;" f | |
471 | db_rule_add src/db.c /^int db_rule_add(struct db_filter *db, uint32_t action, unsigned int syscall,$/;" f | |
472 | db_sys_list src/db.h /^struct db_sys_list {$/;" s | |
473 | db_syscall_priority src/db.c /^int db_syscall_priority(struct db_filter *db,$/;" f | |
474 | def_hsh src/gen_bpf.c /^ uint64_t def_hsh;$/;" m struct:bpf_state file: | |
475 | description src/python/setup.py /^ description = "Python binding for libseccomp",$/;" v | |
476 | end_action tools/scmp_bpf_sim.c /^static void end_action(uint32_t action, unsigned int line)$/;" f file: | |
477 | endian src/arch.h /^ } endian;$/;" m struct:arch_def typeref:enum:arch_def::__anon3 | |
478 | errno src/python/seccomp.pyx /^import errno$/;" i | |
479 | errno tests/06-sim-actions.py /^import errno$/;" i | |
480 | exist_arch src/python/seccomp.pyx /^ def exist_arch(self, arch):$/;" m class:SyscallFilter | |
481 | exit_error tools/scmp_bpf_sim.c /^static void exit_error(unsigned int rc, unsigned int line)$/;" f file: | |
482 | exit_fault tools/scmp_bpf_sim.c /^static void exit_fault(unsigned int rc)$/;" f file: | |
483 | exit_usage tools/scmp_arch_detect.c /^static void exit_usage(const char *program)$/;" f file: | |
484 | exit_usage tools/scmp_bpf_sim.c /^static void exit_usage(const char *program)$/;" f file: | |
485 | exit_usage tools/scmp_sys_resolver.c /^static void exit_usage(const char *program)$/;" f file: | |
486 | export_bpf src/python/seccomp.pyx /^ def export_bpf(self, file):$/;" m class:SyscallFilter | |
487 | export_pfc src/python/seccomp.pyx /^ def export_pfc(self, file):$/;" m class:SyscallFilter | |
488 | ext_modules src/python/setup.py /^ ext_modules = [$/;" v | |
489 | extra_objects src/python/setup.py /^ extra_objects=["..\/libseccomp.a"])$/;" v | |
490 | filter_cnt src/db.h /^ unsigned int filter_cnt;$/;" m struct:db_filter_col | |
491 | filter_output tests/util.py /^def filter_output(args, ctx):$/;" f | |
492 | filters src/db.h /^ struct db_filter **filters;$/;" m struct:db_filter_col typeref:struct:db_filter_col::db_filter | |
493 | final src/hash.c 149;" d file: | |
494 | flag_dup src/gen_bpf.c /^ bool flag_dup; \/* duplicate block and in use *\/$/;" m struct:bpf_blk file: | |
495 | flag_hash src/gen_bpf.c /^ bool flag_hash; \/* added to the hash table *\/$/;" m struct:bpf_blk file: | |
496 | flag_unique src/gen_bpf.c /^ bool flag_unique; \/* ->blks is unique to this block *\/$/;" m struct:bpf_blk file: | |
497 | found src/gen_bpf.c /^ unsigned int found;$/;" m struct:bpf_hash_bkt file: | |
498 | gen_bpf_generate src/gen_bpf.c /^struct bpf_program *gen_bpf_generate(const struct db_filter_col *col)$/;" f | |
499 | gen_bpf_release src/gen_bpf.c /^void gen_bpf_release(struct bpf_program *program)$/;" f | |
500 | gen_pfc_generate src/gen_pfc.c /^int gen_pfc_generate(const struct db_filter_col *col, int fd)$/;" f | |
501 | generate_random_data tests/regression /^function generate_random_data() {$/;" f | |
502 | generate_test_num tests/regression /^function generate_test_num() {$/;" f | |
503 | get_attr src/python/seccomp.pyx /^ def get_attr(self, attr):$/;" m class:SyscallFilter | |
504 | get_opt tests/util.py /^def get_opt():$/;" f | |
505 | get_range tests/regression /^function get_range() {$/;" f | |
506 | hash src/gen_bpf.c /^ uint64_t hash;$/;" m union:bpf_jump::__anon1 file: | |
507 | hash src/gen_bpf.c /^ uint64_t hash;$/;" m struct:bpf_blk file: | |
508 | hash_nxt src/gen_bpf.c /^ struct bpf_blk *hash_nxt;$/;" m struct:bpf_blk typeref:struct:bpf_blk::bpf_blk file: | |
509 | hashbig src/hash.c /^uint32_t hashbig( const void *key, size_t length, uint32_t initval)$/;" f | |
510 | hashlittle src/hash.c /^uint32_t hashlittle( const void *key, size_t length, uint32_t initval)$/;" f | |
511 | hashlittle src/hash.c 44;" d file: | |
512 | hashlittle2 src/hash.c /^void hashlittle2($/;" f | |
513 | hashmask src/hash.c 67;" d file: | |
514 | hashsize src/hash.c 66;" d file: | |
515 | hashword src/hash.c /^uint32_t hashword($/;" f | |
516 | hashword2 src/hash.c /^void hashword2 ($/;" f | |
517 | htbl src/gen_bpf.c /^ struct bpf_hash_bkt *htbl[_BPF_HASH_SIZE];$/;" m struct:bpf_state typeref:struct:bpf_state::bpf_hash_bkt file: | |
518 | i tools/scmp_bpf_sim.c /^ bpf_instr_raw *i;$/;" m struct:bpf_program file: | |
519 | i_cnt tools/scmp_bpf_sim.c /^ size_t i_cnt;$/;" m struct:bpf_program file: | |
520 | imm_j src/gen_bpf.c /^ uint8_t imm_j;$/;" m union:bpf_jump::__anon1 file: | |
521 | imm_k src/gen_bpf.c /^ uint32_t imm_k;$/;" m union:bpf_jump::__anon1 file: | |
522 | install_trap tests/util.py /^def install_trap():$/;" f | |
523 | instruction_pointer src/system.h /^ __u64 instruction_pointer;$/;" m struct:seccomp_data | |
524 | instruction_pointer tools/bpf.h /^ uint64_t instruction_pointer;$/;" m struct:seccomp_data | |
525 | jf src/gen_bpf.c /^ struct bpf_jump jf;$/;" m struct:bpf_instr typeref:struct:bpf_instr::bpf_jump file: | |
526 | jf tools/bpf.h /^ uint8_t jf;$/;" m struct:sock_filter | |
527 | jt src/gen_bpf.c /^ struct bpf_jump jt;$/;" m struct:bpf_instr typeref:struct:bpf_instr::bpf_jump file: | |
528 | jt tools/bpf.h /^ uint8_t jt;$/;" m struct:sock_filter | |
529 | k src/gen_bpf.c /^ struct bpf_jump k;$/;" m struct:bpf_instr typeref:struct:bpf_instr::bpf_jump file: | |
530 | k tools/bpf.h /^ uint32_t k;$/;" m struct:sock_filter | |
531 | libseccomp src/python/seccomp.pyx /^cimport libseccomp$/;" i | |
532 | license src/python/setup.py /^ license = "LGPLv2.1",$/;" v | |
533 | load src/python/seccomp.pyx /^ def load(self):$/;" m class:SyscallFilter | |
534 | long_description src/python/setup.py /^ long_description = "Python API for the Linux Kernel's syscall filtering capability, seccomp.",$/;" v | |
535 | lvl_nxt src/db.h /^ struct db_arg_chain_tree *lvl_prv, *lvl_nxt;$/;" m struct:db_arg_chain_tree typeref:struct:db_arg_chain_tree:: | |
536 | lvl_nxt src/gen_bpf.c /^ struct bpf_blk *lvl_prv, *lvl_nxt;$/;" m struct:bpf_blk typeref:struct:bpf_blk:: file: | |
537 | lvl_prv src/db.h /^ struct db_arg_chain_tree *lvl_prv, *lvl_nxt;$/;" m struct:db_arg_chain_tree typeref:struct:db_arg_chain_tree::db_arg_chain_tree | |
538 | lvl_prv src/gen_bpf.c /^ struct bpf_blk *lvl_prv, *lvl_nxt;$/;" m struct:bpf_blk typeref:struct:bpf_blk::bpf_blk file: | |
539 | main tests/00-test.c /^int main(void)$/;" f | |
540 | main tests/01-sim-allow.c /^int main(int argc, char *argv[])$/;" f | |
541 | main tests/02-sim-basic.c /^int main(int argc, char *argv[])$/;" f | |
542 | main tests/03-sim-basic_chains.c /^int main(int argc, char *argv[])$/;" f | |
543 | main tests/04-sim-multilevel_chains.c /^int main(int argc, char *argv[])$/;" f | |
544 | main tests/05-sim-long_jumps.c /^int main(int argc, char *argv[])$/;" f | |
545 | main tests/06-sim-actions.c /^int main(int argc, char *argv[])$/;" f | |
546 | main tests/07-sim-db_bug_looping.c /^int main(int argc, char *argv[])$/;" f | |
547 | main tests/08-sim-subtree_checks.c /^int main(int argc, char *argv[])$/;" f | |
548 | main tests/09-sim-syscall_priority_pre.c /^int main(int argc, char *argv[])$/;" f | |
549 | main tests/10-sim-syscall_priority_post.c /^int main(int argc, char *argv[])$/;" f | |
550 | main tests/11-basic-basic_errors.c /^int main(int argc, char *argv[])$/;" f | |
551 | main tests/12-sim-basic_masked_ops.c /^int main(int argc, char *argv[])$/;" f | |
552 | main tests/13-basic-attrs.c /^int main(int argc, char *argv[])$/;" f | |
553 | main tests/14-sim-reset.c /^int main(int argc, char *argv[])$/;" f | |
554 | main tests/15-basic-resolver.c /^int main(int argc, char *argv[])$/;" f | |
555 | main tests/16-sim-arch_basic.c /^int main(int argc, char *argv[])$/;" f | |
556 | main tests/17-sim-arch_merge.c /^int main(int argc, char *argv[])$/;" f | |
557 | main tests/18-sim-basic_whitelist.c /^int main(int argc, char *argv[])$/;" f | |
558 | main tests/19-sim-missing_syscalls.c /^int main(int argc, char *argv[])$/;" f | |
559 | main tests/20-live-basic_die.c /^int main(int argc, char *argv[])$/;" f | |
560 | main tests/21-live-basic_allow.c /^int main(int argc, char *argv[])$/;" f | |
561 | main tests/22-sim-basic_chains_array.c /^int main(int argc, char *argv[])$/;" f | |
562 | main tests/23-sim-arch_all_basic.c /^int main(int argc, char *argv[])$/;" f | |
563 | main tests/24-live-arg_allow.c /^int main(int argc, char *argv[])$/;" f | |
564 | main tests/25-sim-multilevel_chains_adv.c /^int main(int argc, char *argv[])$/;" f | |
565 | main tools/scmp_arch_detect.c /^int main(int argc, char *argv[])$/;" f | |
566 | main tools/scmp_bpf_disasm.c /^int main(int argc, char *argv[])$/;" f | |
567 | main tools/scmp_bpf_sim.c /^int main(int argc, char *argv[])$/;" f | |
568 | main tools/scmp_sys_resolver.c /^int main(int argc, char *argv[])$/;" f | |
569 | maintainer src/python/setup.py /^ maintainer = "Paul Moore",$/;" v | |
570 | maintainer_email src/python/setup.py /^ maintainer_email = "paul@paul-moore.com",$/;" v | |
571 | mask src/db.h /^ scmp_datum_t mask;$/;" m struct:db_api_arg | |
572 | mask src/db.h /^ uint32_t mask;$/;" m struct:db_arg_chain_tree | |
573 | mask src/gen_bpf.c /^ uint32_t mask;$/;" m struct:acc_state file: | |
574 | merge src/python/seccomp.pyx /^ def merge(self, SyscallFilter filter):$/;" m class:SyscallFilter | |
575 | mix src/hash.c 114;" d file: | |
576 | msg_error configure /^function msg_error() {$/;" f | |
577 | msg_summary configure /^function msg_summary() {$/;" f | |
578 | msg_usage configure /^function msg_usage() {$/;" f | |
579 | name src/arch.h /^ const char *name;$/;" m struct:arch_syscall_def | |
580 | name src/python/setup.py /^ name = "seccomp",$/;" v | |
581 | next src/db.h /^ struct db_sys_list *next;$/;" m struct:db_sys_list typeref:struct:db_sys_list::db_sys_list | |
582 | next src/gen_bpf.c /^ struct bpf_blk *prev, *next;$/;" m struct:bpf_blk typeref:struct:bpf_blk:: file: | |
583 | next src/gen_bpf.c /^ struct bpf_hash_bkt *next;$/;" m struct:bpf_hash_bkt typeref:struct:bpf_hash_bkt::bpf_hash_bkt file: | |
584 | next src/gen_pfc.c /^ struct pfc_sys_list *next;$/;" m struct:pfc_sys_list typeref:struct:pfc_sys_list::pfc_sys_list file: | |
585 | nnp_enable src/db.h /^ uint32_t nnp_enable;$/;" m struct:db_filter_attr | |
586 | node src/gen_bpf.c /^ const struct db_arg_chain_tree *node;$/;" m struct:bpf_blk typeref:struct:bpf_blk::db_arg_chain_tree file: | |
587 | node_cnt src/db.h /^ unsigned int node_cnt;$/;" m struct:db_sys_list | |
588 | nr src/system.h /^ int nr;$/;" m struct:seccomp_data | |
589 | nr tools/bpf.h /^ int32_t nr;$/;" m struct:seccomp_data | |
590 | num src/arch.h /^ unsigned int num;$/;" m struct:arch_syscall_def | |
591 | num src/db.h /^ unsigned int num;$/;" m struct:db_sys_list | |
592 | nxt src/gen_bpf.c /^ unsigned int nxt;$/;" m union:bpf_jump::__anon1 file: | |
593 | nxt_f src/db.h /^ struct db_arg_chain_tree *nxt_f;$/;" m struct:db_arg_chain_tree typeref:struct:db_arg_chain_tree::db_arg_chain_tree | |
594 | nxt_t src/db.h /^ struct db_arg_chain_tree *nxt_t;$/;" m struct:db_arg_chain_tree typeref:struct:db_arg_chain_tree::db_arg_chain_tree | |
595 | offset src/gen_bpf.c /^ int32_t offset;$/;" m struct:acc_state file: | |
596 | op src/db.h /^ enum scmp_compare op;$/;" m struct:db_arg_chain_tree typeref:enum:db_arg_chain_tree::scmp_compare | |
597 | op src/db.h /^ unsigned int op;$/;" m struct:db_api_arg | |
598 | op src/gen_bpf.c /^ uint16_t op;$/;" m struct:bpf_instr file: | |
599 | opt_verbose tools/scmp_bpf_sim.c /^static unsigned int opt_verbose = 0;$/;" v file: | |
600 | os src/python/setup.py /^import os$/;" i | |
601 | os tests/24-live-arg_allow.py /^import os$/;" i | |
602 | os tests/util.py /^import os$/;" i | |
603 | parse_action tests/util.py /^def parse_action(action):$/;" f | |
604 | pfc_sys_list src/gen_pfc.c /^struct pfc_sys_list {$/;" s file: | |
605 | platforms src/python/setup.py /^ platforms = "Linux",$/;" v | |
606 | prev src/gen_bpf.c /^ struct bpf_blk *prev, *next;$/;" m struct:bpf_blk typeref:struct:bpf_blk::bpf_blk file: | |
607 | pri_nxt src/db.h /^ struct db_sys_list *pri_prv, *pri_nxt;$/;" m struct:db_sys_list typeref:struct:db_sys_list:: | |
608 | pri_prv src/db.h /^ struct db_sys_list *pri_prv, *pri_nxt;$/;" m struct:db_sys_list typeref:struct:db_sys_list::db_sys_list | |
609 | print_data tests/regression /^function print_data() {$/;" f | |
610 | print_result tests/regression /^function print_result() {$/;" f | |
611 | print_valgrind tests/regression /^function print_valgrind() {$/;" f | |
612 | priority src/db.h /^ unsigned int priority;$/;" m struct:db_sys_list | |
613 | priority src/gen_bpf.c /^ unsigned int priority;$/;" m struct:bpf_blk file: | |
614 | refcnt src/db.h /^ unsigned int refcnt;$/;" m struct:db_arg_chain_tree | |
615 | remove_arch src/python/seccomp.pyx /^ def remove_arch(self, arch):$/;" m class:SyscallFilter | |
616 | reset src/python/seccomp.pyx /^ def reset(self, int defaction = -1):$/;" m class:SyscallFilter | |
617 | resolve_syscall src/python/seccomp.pyx /^def resolve_syscall(arch, syscall):$/;" f | |
618 | rot src/hash.c 68;" d file: | |
619 | run_test tests/regression /^function run_test() {$/;" f | |
620 | run_test_basic tests/regression /^function run_test_basic() {$/;" f | |
621 | run_test_bpf_sim tests/regression /^function run_test_bpf_sim() {$/;" f | |
622 | run_test_bpf_sim_fuzz tests/regression /^function run_test_bpf_sim_fuzz() {$/;" f | |
623 | run_test_command tests/regression /^function run_test_command() {$/;" f | |
624 | run_test_live tests/regression /^function run_test_live() {$/;" f | |
625 | run_tests tests/regression /^function run_tests() {$/;" f | |
626 | seccomp_arch_add src/api.c /^int seccomp_arch_add(scmp_filter_ctx ctx, uint32_t arch_token)$/;" f | |
627 | seccomp_arch_exist src/api.c /^int seccomp_arch_exist(const scmp_filter_ctx ctx, uint32_t arch_token)$/;" f | |
628 | seccomp_arch_native src/api.c /^uint32_t seccomp_arch_native(void)$/;" f | |
629 | seccomp_arch_remove src/api.c /^int seccomp_arch_remove(scmp_filter_ctx ctx, uint32_t arch_token)$/;" f | |
630 | seccomp_attr_get src/api.c /^int seccomp_attr_get(const scmp_filter_ctx ctx,$/;" f | |
631 | seccomp_attr_set src/api.c /^int seccomp_attr_set(scmp_filter_ctx ctx,$/;" f | |
632 | seccomp_data src/system.h /^struct seccomp_data {$/;" s | |
633 | seccomp_data tools/bpf.h /^struct seccomp_data {$/;" s | |
634 | seccomp_export_bpf src/api.c /^int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd)$/;" f | |
635 | seccomp_export_pfc src/api.c /^int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd)$/;" f | |
636 | seccomp_init src/api.c /^scmp_filter_ctx seccomp_init(uint32_t def_action)$/;" f | |
637 | seccomp_load src/api.c /^int seccomp_load(const scmp_filter_ctx ctx)$/;" f | |
638 | seccomp_merge src/api.c /^int seccomp_merge(scmp_filter_ctx ctx_dst, scmp_filter_ctx ctx_src)$/;" f | |
639 | seccomp_release src/api.c /^void seccomp_release(scmp_filter_ctx ctx)$/;" f | |
640 | seccomp_reset src/api.c /^int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action)$/;" f | |
641 | seccomp_rule_add src/api.c /^int seccomp_rule_add(scmp_filter_ctx ctx,$/;" f | |
642 | seccomp_rule_add_array src/api.c /^int seccomp_rule_add_array(scmp_filter_ctx ctx,$/;" f | |
643 | seccomp_rule_add_exact src/api.c /^int seccomp_rule_add_exact(scmp_filter_ctx ctx, uint32_t action,$/;" f | |
644 | seccomp_rule_add_exact_array src/api.c /^int seccomp_rule_add_exact_array(scmp_filter_ctx ctx,$/;" f | |
645 | seccomp_syscall_priority src/api.c /^int seccomp_syscall_priority(scmp_filter_ctx ctx, int syscall, uint8_t priority)$/;" f | |
646 | seccomp_syscall_resolve_name src/api.c /^int seccomp_syscall_resolve_name(const char *name)$/;" f | |
647 | seccomp_syscall_resolve_name_arch src/api.c /^int seccomp_syscall_resolve_name_arch(uint32_t arch_token, const char *name)$/;" f | |
648 | seccomp_syscall_resolve_num_arch src/api.c /^char *seccomp_syscall_resolve_num_arch(uint32_t arch_token, int num)$/;" f | |
649 | set_attr src/python/seccomp.pyx /^ def set_attr(self, attr, int value):$/;" m class:SyscallFilter | |
650 | setup src/python/setup.py /^from distutils.core import setup$/;" i | |
651 | signal tests/util.py /^import signal$/;" i | |
652 | sim_state tools/scmp_bpf_sim.c /^struct sim_state {$/;" s file: | |
653 | size src/arch.h /^ } size;$/;" m struct:arch_def typeref:enum:arch_def::__anon2 | |
654 | sock_filter tools/bpf.h /^struct sock_filter {$/;" s | |
655 | state src/db.h /^ int state;$/;" m struct:db_filter_col | |
656 | sys src/gen_pfc.c /^ struct db_sys_list *sys;$/;" m struct:pfc_sys_list typeref:struct:pfc_sys_list::db_sys_list file: | |
657 | sys tests/01-sim-allow.py /^import sys$/;" i | |
658 | sys tests/02-sim-basic.py /^import sys$/;" i | |
659 | sys tests/03-sim-basic_chains.py /^import sys$/;" i | |
660 | sys tests/04-sim-multilevel_chains.py /^import sys$/;" i | |
661 | sys tests/05-sim-long_jumps.py /^import sys$/;" i | |
662 | sys tests/06-sim-actions.py /^import sys$/;" i | |
663 | sys tests/07-sim-db_bug_looping.py /^import sys$/;" i | |
664 | sys tests/08-sim-subtree_checks.py /^import sys$/;" i | |
665 | sys tests/09-sim-syscall_priority_pre.py /^import sys$/;" i | |
666 | sys tests/10-sim-syscall_priority_post.py /^import sys$/;" i | |
667 | sys tests/11-basic-basic_errors.py /^import sys$/;" i | |
668 | sys tests/12-sim-basic_masked_ops.py /^import sys$/;" i | |
669 | sys tests/13-basic-attrs.py /^import sys$/;" i | |
670 | sys tests/14-sim-reset.py /^import sys$/;" i | |
671 | sys tests/15-basic-resolver.py /^import sys$/;" i | |
672 | sys tests/16-sim-arch_basic.py /^import sys$/;" i | |
673 | sys tests/17-sim-arch_merge.py /^import sys$/;" i | |
674 | sys tests/18-sim-basic_whitelist.py /^import sys$/;" i | |
675 | sys tests/19-sim-missing_syscalls.py /^import sys$/;" i | |
676 | sys tests/20-live-basic_die.py /^import sys$/;" i | |
677 | sys tests/21-live-basic_allow.py /^import sys$/;" i | |
678 | sys tests/22-sim-basic_chains_array.py /^import sys$/;" i | |
679 | sys tests/23-sim-arch_all_basic.py /^import sys$/;" i | |
680 | sys tests/24-live-arg_allow.py /^import sys$/;" i | |
681 | sys tests/25-sim-multilevel_chains_adv.py /^import sys$/;" i | |
682 | sys tests/util.py /^import sys$/;" i | |
683 | syscall_priority src/python/seccomp.pyx /^ def syscall_priority(self, syscall, int priority):$/;" m class:SyscallFilter | |
684 | syscalls src/db.h /^ struct db_sys_list *syscalls;$/;" m struct:db_filter typeref:struct:db_filter::db_sys_list | |
685 | system_arch src/python/seccomp.pyx /^def system_arch():$/;" f | |
686 | temp tools/scmp_bpf_sim.c /^ uint32_t temp[BPF_SCRATCH_SIZE];$/;" m struct:sim_state file: | |
687 | test tests/01-sim-allow.py /^def test(args):$/;" f | |
688 | test tests/02-sim-basic.py /^def test(args):$/;" f | |
689 | test tests/03-sim-basic_chains.py /^def test(args):$/;" f | |
690 | test tests/04-sim-multilevel_chains.py /^def test(args):$/;" f | |
691 | test tests/05-sim-long_jumps.py /^def test(args):$/;" f | |
692 | test tests/06-sim-actions.py /^def test(args):$/;" f | |
693 | test tests/07-sim-db_bug_looping.py /^def test(args):$/;" f | |
694 | test tests/08-sim-subtree_checks.py /^def test(args):$/;" f | |
695 | test tests/09-sim-syscall_priority_pre.py /^def test(args):$/;" f | |
696 | test tests/10-sim-syscall_priority_post.py /^def test(args):$/;" f | |
697 | test tests/11-basic-basic_errors.py /^def test():$/;" f | |
698 | test tests/12-sim-basic_masked_ops.py /^def test(args):$/;" f | |
699 | test tests/13-basic-attrs.py /^def test():$/;" f | |
700 | test tests/14-sim-reset.py /^def test(args):$/;" f | |
701 | test tests/15-basic-resolver.py /^def test():$/;" f | |
702 | test tests/16-sim-arch_basic.py /^def test(args):$/;" f | |
703 | test tests/17-sim-arch_merge.py /^def test(args):$/;" f | |
704 | test tests/18-sim-basic_whitelist.py /^def test(args):$/;" f | |
705 | test tests/19-sim-missing_syscalls.py /^def test(args):$/;" f | |
706 | test tests/20-live-basic_die.py /^def test():$/;" f | |
707 | test tests/21-live-basic_allow.py /^def test():$/;" f | |
708 | test tests/22-sim-basic_chains_array.py /^def test(args):$/;" f | |
709 | test tests/23-sim-arch_all_basic.py /^def test(args):$/;" f | |
710 | test tests/24-live-arg_allow.py /^def test():$/;" f | |
711 | test tests/25-sim-multilevel_chains_adv.py /^def test(args):$/;" f | |
712 | test_deps configure /^function test_deps() {$/;" f | |
713 | tgt src/gen_bpf.c /^ } tgt;$/;" m struct:bpf_jump typeref:union:bpf_jump::__anon1 file: | |
714 | tmpl_filter configure /^function tmpl_filter() {$/;" f | |
715 | to_c src/python/seccomp.pyx /^ def to_c(self):$/;" m class:Arg | |
716 | token src/arch.h /^ uint32_t token;$/;" m struct:arch_def | |
717 | token_bpf src/arch.h /^ uint32_t token_bpf;$/;" m struct:arch_def | |
718 | trap_handler tests/util.py /^def trap_handler(signum, frame):$/;" f | |
719 | type src/gen_bpf.c /^ enum bpf_jump_type type;$/;" m struct:bpf_jump typeref:enum:bpf_jump::bpf_jump_type file: | |
720 | uint32_t src/python/libseccomp.pxd /^from libc.stdint cimport uint8_t, uint32_t, uint64_t$/;" i | |
721 | uint32_t src/python/seccomp.pyx /^from libc.stdint cimport uint32_t$/;" i | |
722 | uint64_t src/python/libseccomp.pxd /^from libc.stdint cimport uint8_t, uint32_t, uint64_t$/;" i | |
723 | uint8_t src/python/libseccomp.pxd /^from libc.stdint cimport uint8_t, uint32_t, uint64_t$/;" i | |
724 | url src/python/setup.py /^ url = "http:\/\/libseccomp.sf.net",$/;" v | |
725 | usage tests/regression /^function usage() {$/;" f | |
726 | util tests/01-sim-allow.py /^import util$/;" i | |
727 | util tests/02-sim-basic.py /^import util$/;" i | |
728 | util tests/03-sim-basic_chains.py /^import util$/;" i | |
729 | util tests/04-sim-multilevel_chains.py /^import util$/;" i | |
730 | util tests/05-sim-long_jumps.py /^import util$/;" i | |
731 | util tests/06-sim-actions.py /^import util$/;" i | |
732 | util tests/07-sim-db_bug_looping.py /^import util$/;" i | |
733 | util tests/08-sim-subtree_checks.py /^import util$/;" i | |
734 | util tests/09-sim-syscall_priority_pre.py /^import util$/;" i | |
735 | util tests/10-sim-syscall_priority_post.py /^import util$/;" i | |
736 | util tests/11-basic-basic_errors.py /^import util$/;" i | |
737 | util tests/12-sim-basic_masked_ops.py /^import util$/;" i | |
738 | util tests/13-basic-attrs.py /^import util$/;" i | |
739 | util tests/14-sim-reset.py /^import util$/;" i | |
740 | util tests/15-basic-resolver.py /^import util$/;" i | |
741 | util tests/16-sim-arch_basic.py /^import util$/;" i | |
742 | util tests/17-sim-arch_merge.py /^import util$/;" i | |
743 | util tests/18-sim-basic_whitelist.py /^import util$/;" i | |
744 | util tests/19-sim-missing_syscalls.py /^import util$/;" i | |
745 | util tests/20-live-basic_die.py /^import util$/;" i | |
746 | util tests/21-live-basic_allow.py /^import util$/;" i | |
747 | util tests/22-sim-basic_chains_array.py /^import util$/;" i | |
748 | util tests/23-sim-arch_all_basic.py /^import util$/;" i | |
749 | util tests/24-live-arg_allow.py /^import util$/;" i | |
750 | util tests/25-sim-multilevel_chains_adv.py /^import util$/;" i | |
751 | util_action_parse tests/util.c /^int util_action_parse(const char *action)$/;" f | |
752 | util_file_write tests/util.c /^int util_file_write(const char *path)$/;" f | |
753 | util_filter_output tests/util.c /^int util_filter_output(const struct util_options *opts,$/;" f | |
754 | util_getopt tests/util.c /^int util_getopt(int argc, char *argv[], struct util_options *opts)$/;" f | |
755 | util_options tests/util.h /^struct util_options {$/;" s | |
756 | util_trap_install tests/util.c /^int util_trap_install(void)$/;" f | |
757 | valid src/db.h /^ bool valid;$/;" m struct:db_api_arg | |
758 | valid src/db.h /^ bool valid;$/;" m struct:db_sys_list | |
759 | verify_deps configure /^function verify_deps() {$/;" f | |
760 | verify_deps tests/regression /^function verify_deps() {$/;" f | |
761 | verify_deps tools/scmp_app_inspector /^function verify_deps() {$/;" f | |
762 | version src/python/setup.py /^ version = os.environ["VERSION_RELEASE"],$/;" v | |
763 | write_file tests/util.py /^def write_file(path):$/;" f | |
764 | x32_arg_count_max src/arch-x32.h 32;" d | |
765 | x32_syscall_resolve_name src/arch-x32-syscalls.c /^int x32_syscall_resolve_name(const char *name)$/;" f | |
766 | x32_syscall_resolve_num src/arch-x32-syscalls.c /^const char *x32_syscall_resolve_num(int num)$/;" f | |
767 | x86_64_arg_count_max src/arch-x86_64.h 30;" d | |
768 | x86_64_arg_offset_hi src/arch-x86_64.h 35;" d | |
769 | x86_64_arg_offset_lo src/arch-x86_64.h 34;" d | |
770 | x86_64_syscall_resolve_name src/arch-x86_64-syscalls.c /^int x86_64_syscall_resolve_name(const char *name)$/;" f | |
771 | x86_64_syscall_resolve_num src/arch-x86_64-syscalls.c /^const char *x86_64_syscall_resolve_num(int num)$/;" f | |
772 | x86_64_syscall_table src/arch-x86_64-syscalls.c /^const struct arch_syscall_def x86_64_syscall_table[] = \\$/;" v typeref:struct:arch_syscall_def | |
773 | x86_arg_count_max src/arch-x86.h 31;" d | |
774 | x86_filter_rewrite src/arch-x86.c /^int x86_filter_rewrite(const struct arch_def *arch, bool strict,$/;" f | |
775 | x86_syscall_resolve_name src/arch-x86-syscalls.c /^int x86_syscall_resolve_name(const char *name)$/;" f | |
776 | x86_syscall_resolve_num src/arch-x86-syscalls.c /^const char *x86_syscall_resolve_num(int num)$/;" f | |
777 | x86_syscall_rewrite src/arch-x86.c /^int x86_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall)$/;" f | |
778 | x86_syscall_table src/arch-x86-syscalls.c /^static const struct arch_syscall_def x86_syscall_table[] = \\$/;" v typeref:struct:arch_syscall_def file: |
0 | ||
1 | /* | |
2 | * This library is free software; you can redistribute it and/or modify it | |
3 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
4 | * published by the Free Software Foundation. | |
5 | * | |
6 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
7 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
8 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
9 | * for more details. | |
10 | * | |
11 | * You should have received a copy of the GNU Lesser General Public License | |
12 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
13 | */ | |
14 | ||
15 | #include <signal.h> | |
16 | #include <stdio.h> | |
17 | #include <unistd.h> | |
18 | ||
19 | #include <seccomp.h> | |
20 | ||
21 | #include "util.h" | |
22 | ||
23 | int main(void) | |
24 | { | |
25 | scmp_filter_ctx ctx; | |
26 | int status; | |
27 | ||
28 | ctx = seccomp_init(SCMP_ACT_KILL); | |
29 | if (ctx == NULL) | |
30 | return 1; | |
31 | ||
32 | status = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl), 0); | |
33 | if (status < 0) | |
34 | return 1; | |
35 | ||
36 | status = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); | |
37 | if (status < 0) | |
38 | return 1; | |
39 | ||
40 | #if 1 | |
41 | status = seccomp_load(ctx); | |
42 | if (status < 0) | |
43 | return 1; | |
44 | #endif | |
45 | ||
46 | status = seccomp_reset(ctx, SCMP_ACT_ALLOW); | |
47 | if (status < 0) | |
48 | return 1; | |
49 | ||
50 | #if 0 | |
51 | status = seccomp_load(ctx); | |
52 | if (status < 0) | |
53 | return 1; | |
54 | #endif | |
55 | ||
56 | write(2, "OK\n", 3); | |
57 | ||
58 | return 0; | |
59 | }⏎ |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | struct util_options opts; | |
31 | scmp_filter_ctx ctx; | |
32 | ||
33 | rc = util_getopt(argc, argv, &opts); | |
34 | if (rc < 0) | |
35 | goto out; | |
36 | ||
37 | ctx = seccomp_init(SCMP_ACT_ALLOW); | |
38 | if (ctx == NULL) | |
39 | goto out; | |
40 | ||
41 | rc = util_filter_output(&opts, ctx); | |
42 | if (rc) | |
43 | goto out; | |
44 | ||
45 | out: | |
46 | seccomp_release(ctx); | |
47 | return (rc < 0 ? -rc : rc); | |
48 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(ALLOW) | |
32 | return f | |
33 | ||
34 | args = util.get_opt() | |
35 | ctx = test(args) | |
36 | util.filter_output(args, ctx) | |
37 | ||
38 | # kate: syntax python; | |
39 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 01-sim-allow all 0-350 N N N N N N ALLOW | |
11 | ||
12 | test type: bpf-sim-fuzz | |
13 | ||
14 | # Testname StressCount | |
15 | 01-sim-allow 50 | |
16 | ||
17 | test type: bpf-valgrind | |
18 | ||
19 | # Testname | |
20 | 01-sim-allow |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | /* | |
22 | * Just like mode 1 seccomp we allow 4 syscalls: | |
23 | * read, write, exit, and rt_sigreturn | |
24 | */ | |
25 | ||
26 | #include <unistd.h> | |
27 | ||
28 | #include <seccomp.h> | |
29 | ||
30 | #include "util.h" | |
31 | ||
32 | int main(int argc, char *argv[]) | |
33 | { | |
34 | int rc; | |
35 | struct util_options opts; | |
36 | scmp_filter_ctx ctx; | |
37 | ||
38 | rc = util_getopt(argc, argv, &opts); | |
39 | if (rc < 0) | |
40 | goto out; | |
41 | ||
42 | ctx = seccomp_init(SCMP_ACT_KILL); | |
43 | if (ctx == NULL) | |
44 | goto out; | |
45 | ||
46 | ||
47 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); | |
48 | if (rc != 0) | |
49 | goto out; | |
50 | ||
51 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0); | |
52 | if (rc != 0) | |
53 | goto out; | |
54 | ||
55 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); | |
56 | if (rc != 0) | |
57 | goto out; | |
58 | ||
59 | rc = seccomp_rule_add_exact(ctx, | |
60 | SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); | |
61 | if (rc != 0) | |
62 | goto out; | |
63 | ||
64 | rc = util_filter_output(&opts, ctx); | |
65 | if (rc) | |
66 | goto out; | |
67 | ||
68 | out: | |
69 | seccomp_release(ctx); | |
70 | return (rc < 0 ? -rc : rc); | |
71 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | f.add_rule_exactly(ALLOW, "read"); | |
33 | f.add_rule_exactly(ALLOW, "write"); | |
34 | f.add_rule_exactly(ALLOW, "close"); | |
35 | f.add_rule_exactly(ALLOW, "rt_sigreturn"); | |
36 | return f | |
37 | ||
38 | args = util.get_opt() | |
39 | ctx = test(args) | |
40 | util.filter_output(args, ctx) | |
41 | ||
42 | # kate: syntax python; | |
43 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 02-sim-basic all read 0 0x856B008 40 N N N ALLOW | |
11 | 02-sim-basic all write 1 0x856B008 40 N N N ALLOW | |
12 | 02-sim-basic all close 4 N N N N N ALLOW | |
13 | 02-sim-basic all rt_sigreturn N N N N N N ALLOW | |
14 | 02-sim-basic all open 0x856B008 4 N N N N KILL | |
15 | 02-sim-basic x86 0-2 N N N N N N KILL | |
16 | 02-sim-basic x86 7-172 N N N N N N KILL | |
17 | 02-sim-basic x86 174-350 N N N N N N KILL | |
18 | 02-sim-basic x86_64 4-14 N N N N N N KILL | |
19 | 02-sim-basic x86_64 16-350 N N N N N N KILL | |
20 | ||
21 | test type: bpf-sim-fuzz | |
22 | ||
23 | # Testname StressCount | |
24 | 02-sim-basic 50 | |
25 | ||
26 | test type: bpf-valgrind | |
27 | ||
28 | # Testname | |
29 | 02-sim-basic |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | struct util_options opts; | |
31 | scmp_filter_ctx ctx; | |
32 | ||
33 | rc = util_getopt(argc, argv, &opts); | |
34 | if (rc < 0) | |
35 | goto out; | |
36 | ||
37 | ctx = seccomp_init(SCMP_ACT_KILL); | |
38 | if (ctx == NULL) | |
39 | goto out; | |
40 | ||
41 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, | |
42 | SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO)); | |
43 | if (rc != 0) | |
44 | goto out; | |
45 | ||
46 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, | |
47 | SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)); | |
48 | if (rc != 0) | |
49 | goto out; | |
50 | ||
51 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, | |
52 | SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO)); | |
53 | if (rc != 0) | |
54 | goto out; | |
55 | ||
56 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); | |
57 | if (rc != 0) | |
58 | goto out; | |
59 | ||
60 | rc = seccomp_rule_add_exact(ctx, | |
61 | SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); | |
62 | if (rc != 0) | |
63 | goto out; | |
64 | ||
65 | rc = util_filter_output(&opts, ctx); | |
66 | if (rc) | |
67 | goto out; | |
68 | ||
69 | out: | |
70 | seccomp_release(ctx); | |
71 | return (rc < 0 ? -rc : rc); | |
72 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | f.add_rule_exactly(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno())); | |
33 | f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno())); | |
34 | f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno())); | |
35 | f.add_rule_exactly(ALLOW, "close"); | |
36 | f.add_rule_exactly(ALLOW, "rt_sigreturn"); | |
37 | return f | |
38 | ||
39 | args = util.get_opt() | |
40 | ctx = test(args) | |
41 | util.filter_output(args, ctx) | |
42 | ||
43 | # kate: syntax python; | |
44 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 03-sim-basic_chains all read 0 0x856B008 10 N N N ALLOW | |
11 | 03-sim-basic_chains all read 1-10 0x856B008 10 N N N KILL | |
12 | 03-sim-basic_chains all write 1-2 0x856B008 10 N N N ALLOW | |
13 | 03-sim-basic_chains all write 3-10 0x856B008 10 N N N KILL | |
14 | 03-sim-basic_chains all close N N N N N N ALLOW | |
15 | 03-sim-basic_chains all rt_sigreturn N N N N N N ALLOW | |
16 | 03-sim-basic_chains all open 0x856B008 4 N N N N KILL | |
17 | 03-sim-basic_chains x86 0-2 N N N N N N KILL | |
18 | 03-sim-basic_chains x86 7-172 N N N N N N KILL | |
19 | 03-sim-basic_chains x86 174-350 N N N N N N KILL | |
20 | 03-sim-basic_chains x86_64 4-14 N N N N N N KILL | |
21 | 03-sim-basic_chains x86_64 16-350 N N N N N N KILL | |
22 | ||
23 | test type: bpf-sim-fuzz | |
24 | ||
25 | # Testname StressCount | |
26 | 03-sim-basic_chains 50 | |
27 | ||
28 | test type: bpf-valgrind | |
29 | ||
30 | # Testname | |
31 | 03-sim-basic_chains |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <limits.h> | |
22 | #include <unistd.h> | |
23 | ||
24 | #include <seccomp.h> | |
25 | ||
26 | #include "util.h" | |
27 | ||
28 | int main(int argc, char *argv[]) | |
29 | { | |
30 | int rc; | |
31 | struct util_options opts; | |
32 | scmp_filter_ctx ctx; | |
33 | ||
34 | rc = util_getopt(argc, argv, &opts); | |
35 | if (rc < 0) | |
36 | goto out; | |
37 | ||
38 | ctx = seccomp_init(SCMP_ACT_KILL); | |
39 | if (ctx == NULL) | |
40 | goto out; | |
41 | ||
42 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0); | |
43 | if (rc != 0) | |
44 | goto out; | |
45 | ||
46 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); | |
47 | if (rc != 0) | |
48 | goto out; | |
49 | ||
50 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 3, | |
51 | SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO), | |
52 | SCMP_A1(SCMP_CMP_NE, 0x0), | |
53 | SCMP_A2(SCMP_CMP_LT, SSIZE_MAX)); | |
54 | if (rc != 0) | |
55 | goto out; | |
56 | ||
57 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 3, | |
58 | SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO), | |
59 | SCMP_A1(SCMP_CMP_NE, 0x0), | |
60 | SCMP_A2(SCMP_CMP_LT, SSIZE_MAX)); | |
61 | if (rc != 0) | |
62 | goto out; | |
63 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 3, | |
64 | SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO), | |
65 | SCMP_A1(SCMP_CMP_NE, 0x0), | |
66 | SCMP_A2(SCMP_CMP_LT, SSIZE_MAX)); | |
67 | if (rc != 0) | |
68 | goto out; | |
69 | ||
70 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); | |
71 | if (rc != 0) | |
72 | goto out; | |
73 | ||
74 | rc = seccomp_rule_add_exact(ctx, | |
75 | SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); | |
76 | if (rc != 0) | |
77 | goto out; | |
78 | ||
79 | rc = util_filter_output(&opts, ctx); | |
80 | if (rc) | |
81 | goto out; | |
82 | ||
83 | out: | |
84 | seccomp_release(ctx); | |
85 | return (rc < 0 ? -rc : rc); | |
86 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | f.add_rule_exactly(ALLOW, "open"); | |
33 | f.add_rule_exactly(ALLOW, "close"); | |
34 | f.add_rule_exactly(ALLOW, "read", | |
35 | Arg(0, EQ, sys.stdin.fileno()), | |
36 | Arg(1, NE, 0), | |
37 | Arg(2, LT, sys.maxsize)); | |
38 | f.add_rule_exactly(ALLOW, "write", | |
39 | Arg(0, EQ, sys.stdout.fileno()), | |
40 | Arg(1, NE, 0), | |
41 | Arg(2, LT, sys.maxsize)); | |
42 | f.add_rule_exactly(ALLOW, "write", | |
43 | Arg(0, EQ, sys.stderr.fileno()), | |
44 | Arg(1, NE, 0), | |
45 | Arg(2, LT, sys.maxsize)); | |
46 | f.add_rule_exactly(ALLOW, "close"); | |
47 | f.add_rule_exactly(ALLOW, "rt_sigreturn"); | |
48 | return f | |
49 | ||
50 | args = util.get_opt() | |
51 | ctx = test(args) | |
52 | util.filter_output(args, ctx) | |
53 | ||
54 | # kate: syntax python; | |
55 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 04-sim-multilevel_chains all open 0x856B008 4 N N N N ALLOW | |
11 | 04-sim-multilevel_chains all close 4 N N N N N ALLOW | |
12 | 04-sim-multilevel_chains x86 read 0 0x856B008 0x7FFFFFFE N N N ALLOW | |
13 | 04-sim-multilevel_chains x86_64 read 0 0x856B008 0x7FFFFFFFFFFFFFFE N N N ALLOW | |
14 | 04-sim-multilevel_chains x86 read 0 0x856B008 0x7FFFFFFF N N N KILL | |
15 | 04-sim-multilevel_chains x86_64 read 0 0x856B008 0x7FFFFFFFFFFFFFFF N N N KILL | |
16 | 04-sim-multilevel_chains x86 read 0 0 0x7FFFFFFE N N N KILL | |
17 | 04-sim-multilevel_chains x86_64 read 0 0 0x7FFFFFFFFFFFFFFE N N N KILL | |
18 | 04-sim-multilevel_chains all read 1-10 0x856B008 0x7FFFFFFE N N N KILL | |
19 | 04-sim-multilevel_chains x86 write 1-2 0x856B008 0x7FFFFFFE N N N ALLOW | |
20 | 04-sim-multilevel_chains x86_64 write 1-2 0x856B008 0x7FFFFFFFFFFFFFFE N N N ALLOW | |
21 | 04-sim-multilevel_chains x86 write 1-2 0 0x7FFFFFFE N N N KILL | |
22 | 04-sim-multilevel_chains x86_64 write 1-2 0 0x7FFFFFFFFFFFFFFE N N N KILL | |
23 | 04-sim-multilevel_chains x86 write 1-2 0x856B008 0x7FFFFFFF N N N KILL | |
24 | 04-sim-multilevel_chains x86_64 write 1-2 0x856B008 0x7FFFFFFFFFFFFFFF N N N KILL | |
25 | 04-sim-multilevel_chains all write 3-10 0x856B008 0x7FFFFFFE N N N KILL | |
26 | 04-sim-multilevel_chains all rt_sigreturn N N N N N N ALLOW | |
27 | 04-sim-multilevel_chains x86 0-2 N N N N N N KILL | |
28 | 04-sim-multilevel_chains x86 7-172 N N N N N N KILL | |
29 | 04-sim-multilevel_chains x86 174-350 N N N N N N KILL | |
30 | 04-sim-multilevel_chains x86_64 4-14 N N N N N N KILL | |
31 | 04-sim-multilevel_chains x86_64 16-350 N N N N N N KILL | |
32 | ||
33 | test type: bpf-sim-fuzz | |
34 | ||
35 | # Testname StressCount | |
36 | 04-sim-multilevel_chains 50 | |
37 | ||
38 | test type: bpf-valgrind | |
39 | ||
40 | # Testname | |
41 | 04-sim-multilevel_chains |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | #include <limits.h> | |
23 | ||
24 | #include <seccomp.h> | |
25 | ||
26 | #include "util.h" | |
27 | ||
28 | int main(int argc, char *argv[]) | |
29 | { | |
30 | int rc; | |
31 | int iter; | |
32 | struct util_options opts; | |
33 | scmp_filter_ctx ctx; | |
34 | ||
35 | rc = util_getopt(argc, argv, &opts); | |
36 | if (rc < 0) | |
37 | goto out; | |
38 | ||
39 | ctx = seccomp_init(SCMP_ACT_KILL); | |
40 | if (ctx == NULL) | |
41 | goto out; | |
42 | ||
43 | /* NOTE - syscalls referenced by number to make the test simpler */ | |
44 | ||
45 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1, 0); | |
46 | if (rc != 0) | |
47 | goto out; | |
48 | ||
49 | /* same syscall, many chains */ | |
50 | for (iter = 0; iter < 100; iter++) { | |
51 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1000, 3, | |
52 | SCMP_A0(SCMP_CMP_EQ, iter), | |
53 | SCMP_A1(SCMP_CMP_NE, 0x0), | |
54 | SCMP_A2(SCMP_CMP_LT, SSIZE_MAX)); | |
55 | if (rc != 0) | |
56 | goto out; | |
57 | } | |
58 | ||
59 | /* many syscalls, same chain */ | |
60 | for (iter = 100; iter < 200; iter++) { | |
61 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, iter, 1, | |
62 | SCMP_A0(SCMP_CMP_NE, 0)); | |
63 | if (rc != 0) | |
64 | goto out; | |
65 | } | |
66 | ||
67 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 4, 0); | |
68 | if (rc != 0) | |
69 | goto out; | |
70 | ||
71 | rc = util_filter_output(&opts, ctx); | |
72 | if (rc) | |
73 | goto out; | |
74 | ||
75 | out: | |
76 | seccomp_release(ctx); | |
77 | return (rc < 0 ? -rc : rc); | |
78 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | # syscalls referenced by number to make the test simpler | |
33 | f.add_rule_exactly(ALLOW, 1) | |
34 | i = 0 | |
35 | while i < 100: | |
36 | f.add_rule_exactly(ALLOW, 1000, | |
37 | Arg(0, EQ, i), | |
38 | Arg(1, NE, 0), | |
39 | Arg(2, LT, sys.maxsize)) | |
40 | i += 1 | |
41 | i = 100 | |
42 | while i < 200: | |
43 | f.add_rule_exactly(ALLOW, i, | |
44 | Arg(0, NE, 0)) | |
45 | i += 1 | |
46 | f.add_rule_exactly(ALLOW, 4) | |
47 | return f | |
48 | ||
49 | args = util.get_opt() | |
50 | ctx = test(args) | |
51 | util.filter_output(args, ctx) | |
52 | ||
53 | # kate: syntax python; | |
54 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; | |
55 |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 05-sim-long_jumps all 1 1 2 3 4 5 6 ALLOW | |
11 | 05-sim-long_jumps all 2 N N N N N N KILL | |
12 | 05-sim-long_jumps all 999 N N N N N N KILL | |
13 | 05-sim-long_jumps x86 1000 0-5 0x856B008 0x7FFFFFFE N N N ALLOW | |
14 | 05-sim-long_jumps x86_64 1000 0-5 0x856B008 0x7FFFFFFFFFFFFFFE N N N ALLOW | |
15 | 05-sim-long_jumps x86 1000 95-99 0x856B008 0x7FFFFFFE N N N ALLOW | |
16 | 05-sim-long_jumps x86_64 1000 95-99 0x856B008 0x7FFFFFFFFFFFFFFE N N N ALLOW | |
17 | 05-sim-long_jumps x86 1000 100 0x856B008 0x7FFFFFFE N N N KILL | |
18 | 05-sim-long_jumps x86_64 1000 100 0x856B008 0x7FFFFFFFFFFFFFFE N N N KILL | |
19 | 05-sim-long_jumps all 1001 N N N N N N KILL | |
20 | 05-sim-long_jumps all 99 1 N N N N N KILL | |
21 | 05-sim-long_jumps all 100-105 1 N N N N N ALLOW | |
22 | 05-sim-long_jumps all 195-199 1 N N N N N ALLOW | |
23 | 05-sim-long_jumps all 200 1 N N N N N KILL | |
24 | 05-sim-long_jumps all 3 N N N N N N KILL | |
25 | 05-sim-long_jumps all 4 1 2 3 4 5 6 ALLOW | |
26 | 05-sim-long_jumps all 5 N N N N N N KILL | |
27 | ||
28 | test type: bpf-sim-fuzz | |
29 | ||
30 | # Testname StressCount | |
31 | 05-sim-long_jumps 50 | |
32 | ||
33 | test type: bpf-valgrind | |
34 | ||
35 | # Testname | |
36 | 05-sim-long_jumps |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <errno.h> | |
22 | #include <unistd.h> | |
23 | ||
24 | #include <seccomp.h> | |
25 | ||
26 | #include "util.h" | |
27 | ||
28 | int main(int argc, char *argv[]) | |
29 | { | |
30 | int rc; | |
31 | struct util_options opts; | |
32 | scmp_filter_ctx ctx; | |
33 | ||
34 | rc = util_getopt(argc, argv, &opts); | |
35 | if (rc < 0) | |
36 | goto out; | |
37 | ||
38 | ctx = seccomp_init(SCMP_ACT_KILL); | |
39 | if (ctx == NULL) | |
40 | goto out; | |
41 | ||
42 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); | |
43 | if (rc != 0) | |
44 | goto out; | |
45 | ||
46 | rc = seccomp_rule_add_exact(ctx, | |
47 | SCMP_ACT_ERRNO(EPERM), SCMP_SYS(write), 0); | |
48 | if (rc != 0) | |
49 | goto out; | |
50 | ||
51 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_TRAP, SCMP_SYS(close), 0); | |
52 | if (rc != 0) | |
53 | goto out; | |
54 | ||
55 | rc = seccomp_rule_add_exact(ctx, | |
56 | SCMP_ACT_TRACE(1234), SCMP_SYS(open), 0); | |
57 | if (rc != 0) | |
58 | goto out; | |
59 | ||
60 | rc = util_filter_output(&opts, ctx); | |
61 | if (rc) | |
62 | goto out; | |
63 | ||
64 | out: | |
65 | seccomp_release(ctx); | |
66 | return (rc < 0 ? -rc : rc); | |
67 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import errno | |
25 | import sys | |
26 | ||
27 | import util | |
28 | ||
29 | from seccomp import * | |
30 | ||
31 | def test(args): | |
32 | f = SyscallFilter(KILL) | |
33 | f.add_rule(ALLOW, "read") | |
34 | f.add_rule(ERRNO(errno.EPERM), "write") | |
35 | f.add_rule(TRAP, "close") | |
36 | f.add_rule(TRACE(1234), "open") | |
37 | return f | |
38 | ||
39 | args = util.get_opt() | |
40 | ctx = test(args) | |
41 | util.filter_output(args, ctx) | |
42 | ||
43 | # kate: syntax python; | |
44 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 06-sim-actions all read 4 0x856B008 80 N N N ALLOW | |
11 | 06-sim-actions all write 1 0x856B008 N N N N ERRNO(1) | |
12 | 06-sim-actions all close 4 N N N N N TRAP | |
13 | 06-sim-actions all open 0x856B008 4 N N N N TRACE(1234) | |
14 | 06-sim-actions x86 0-2 N N N N N N KILL | |
15 | 06-sim-actions x86 7-350 N N N N N N KILL | |
16 | 06-sim-actions x86_64 4-350 N N N N N N KILL | |
17 | ||
18 | test type: bpf-sim-fuzz | |
19 | ||
20 | # Testname StressCount | |
21 | 06-sim-actions 50 | |
22 | ||
23 | test type: bpf-valgrind | |
24 | ||
25 | # Testname | |
26 | 06-sim-actions |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright IBM Corp. 2012 | |
4 | * Author: Ashley Lai <adlai@us.ibm.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | struct util_options opts; | |
31 | scmp_filter_ctx ctx; | |
32 | ||
33 | rc = util_getopt(argc, argv, &opts); | |
34 | if (rc < 0) | |
35 | goto out; | |
36 | ||
37 | ctx = seccomp_init(SCMP_ACT_KILL); | |
38 | if (ctx == NULL) | |
39 | goto out; | |
40 | ||
41 | /* The next three seccomp_rule_add_exact() calls for read must | |
42 | * go together in this order to catch an infinite loop. */ | |
43 | ||
44 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, | |
45 | SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)); | |
46 | if (rc != 0) | |
47 | goto out; | |
48 | ||
49 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, | |
50 | SCMP_A1(SCMP_CMP_EQ, 0x0)); | |
51 | if (rc != 0) | |
52 | goto out; | |
53 | ||
54 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, | |
55 | SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO)); | |
56 | if (rc != 0) | |
57 | goto out; | |
58 | ||
59 | rc = util_filter_output(&opts, ctx); | |
60 | if (rc) | |
61 | goto out; | |
62 | ||
63 | out: | |
64 | seccomp_release(ctx); | |
65 | return (rc < 0 ? -rc : rc); | |
66 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | # the next three seccomp_rule_add_exact() calls for read must go together | |
33 | # in this order to catch an infinite loop. | |
34 | f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdout.fileno())) | |
35 | f.add_rule(ALLOW, "read", Arg(1, EQ, 0)) | |
36 | f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno())) | |
37 | return f | |
38 | ||
39 | args = util.get_opt() | |
40 | ctx = test(args) | |
41 | util.filter_output(args, ctx) | |
42 | ||
43 | # kate: syntax python; | |
44 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 07-sim-db_bug_looping all read 1 0x856B008 10 N N N ALLOW | |
11 | 07-sim-db_bug_looping all read 2-10 0 10 N N N ALLOW | |
12 | 07-sim-db_bug_looping all read 0 0x856B008 10 N N N ALLOW | |
13 | ||
14 | test type: bpf-sim-fuzz | |
15 | ||
16 | # Testname StressCount | |
17 | 07-sim-db_bug_looping 50 | |
18 | ||
19 | test type: bpf-valgrind | |
20 | ||
21 | # Testname | |
22 | 07-sim-db_bug_looping |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | struct util_options opts; | |
31 | scmp_filter_ctx ctx; | |
32 | ||
33 | rc = util_getopt(argc, argv, &opts); | |
34 | if (rc < 0) | |
35 | goto out; | |
36 | ||
37 | ctx = seccomp_init(SCMP_ACT_KILL); | |
38 | if (ctx == NULL) | |
39 | goto out; | |
40 | ||
41 | /* the syscall and argument numbers are all fake to make the test | |
42 | * simpler */ | |
43 | ||
44 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1000, 2, | |
45 | SCMP_A0(SCMP_CMP_EQ, 0), | |
46 | SCMP_A1(SCMP_CMP_EQ, 1)); | |
47 | if (rc != 0) | |
48 | goto out; | |
49 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1000, 1, | |
50 | SCMP_A1(SCMP_CMP_EQ, 1)); | |
51 | if (rc != 0) | |
52 | goto out; | |
53 | ||
54 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1001, 1, | |
55 | SCMP_A1(SCMP_CMP_EQ, 1)); | |
56 | if (rc != 0) | |
57 | goto out; | |
58 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1001, 2, | |
59 | SCMP_A0(SCMP_CMP_EQ, 0), | |
60 | SCMP_A1(SCMP_CMP_EQ, 1)); | |
61 | if (rc != 0) | |
62 | goto out; | |
63 | ||
64 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1002, 4, | |
65 | SCMP_A0(SCMP_CMP_EQ, 0), | |
66 | SCMP_A1(SCMP_CMP_EQ, 1), | |
67 | SCMP_A2(SCMP_CMP_EQ, 2), | |
68 | SCMP_A3(SCMP_CMP_EQ, 3)); | |
69 | if (rc != 0) | |
70 | goto out; | |
71 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1002, 2, | |
72 | SCMP_A1(SCMP_CMP_EQ, 1), | |
73 | SCMP_A2(SCMP_CMP_EQ, 2)); | |
74 | if (rc != 0) | |
75 | goto out; | |
76 | ||
77 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1003, 2, | |
78 | SCMP_A1(SCMP_CMP_EQ, 1), | |
79 | SCMP_A2(SCMP_CMP_EQ, 2)); | |
80 | if (rc != 0) | |
81 | goto out; | |
82 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1003, 4, | |
83 | SCMP_A0(SCMP_CMP_EQ, 0), | |
84 | SCMP_A1(SCMP_CMP_EQ, 1), | |
85 | SCMP_A2(SCMP_CMP_EQ, 2), | |
86 | SCMP_A3(SCMP_CMP_EQ, 3)); | |
87 | if (rc != 0) | |
88 | goto out; | |
89 | ||
90 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1004, 4, | |
91 | SCMP_A0(SCMP_CMP_EQ, 0), | |
92 | SCMP_A1(SCMP_CMP_EQ, 1), | |
93 | SCMP_A2(SCMP_CMP_EQ, 2), | |
94 | SCMP_A3(SCMP_CMP_EQ, 3)); | |
95 | if (rc != 0) | |
96 | goto out; | |
97 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1004, 2, | |
98 | SCMP_A0(SCMP_CMP_EQ, 0), | |
99 | SCMP_A1(SCMP_CMP_EQ, 11)); | |
100 | if (rc != 0) | |
101 | goto out; | |
102 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1004, 4, | |
103 | SCMP_A0(SCMP_CMP_EQ, 0), | |
104 | SCMP_A1(SCMP_CMP_EQ, 1), | |
105 | SCMP_A2(SCMP_CMP_EQ, 2), | |
106 | SCMP_A3(SCMP_CMP_EQ, 33)); | |
107 | if (rc != 0) | |
108 | goto out; | |
109 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1004, 2, | |
110 | SCMP_A1(SCMP_CMP_EQ, 1), | |
111 | SCMP_A2(SCMP_CMP_EQ, 2)); | |
112 | if (rc != 0) | |
113 | goto out; | |
114 | ||
115 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1005, 2, | |
116 | SCMP_A1(SCMP_CMP_EQ, 1), | |
117 | SCMP_A2(SCMP_CMP_EQ, 2)); | |
118 | if (rc != 0) | |
119 | goto out; | |
120 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1005, 4, | |
121 | SCMP_A0(SCMP_CMP_EQ, 0), | |
122 | SCMP_A1(SCMP_CMP_EQ, 1), | |
123 | SCMP_A2(SCMP_CMP_EQ, 2), | |
124 | SCMP_A3(SCMP_CMP_EQ, 3)); | |
125 | if (rc != 0) | |
126 | goto out; | |
127 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1005, 2, | |
128 | SCMP_A0(SCMP_CMP_EQ, 0), | |
129 | SCMP_A1(SCMP_CMP_EQ, 11)); | |
130 | if (rc != 0) | |
131 | goto out; | |
132 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1005, 4, | |
133 | SCMP_A0(SCMP_CMP_EQ, 0), | |
134 | SCMP_A1(SCMP_CMP_EQ, 1), | |
135 | SCMP_A2(SCMP_CMP_EQ, 2), | |
136 | SCMP_A3(SCMP_CMP_EQ, 33)); | |
137 | if (rc != 0) | |
138 | goto out; | |
139 | ||
140 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1006, 2, | |
141 | SCMP_A1(SCMP_CMP_NE, 1), | |
142 | SCMP_A2(SCMP_CMP_EQ, 0)); | |
143 | if (rc != 0) | |
144 | goto out; | |
145 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1006, 2, | |
146 | SCMP_A1(SCMP_CMP_EQ, 1), | |
147 | SCMP_A2(SCMP_CMP_EQ, 2)); | |
148 | if (rc != 0) | |
149 | goto out; | |
150 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1006, 1, | |
151 | SCMP_A1(SCMP_CMP_NE, 1)); | |
152 | if (rc != 0) | |
153 | goto out; | |
154 | ||
155 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_TRAP, 1007, 2, | |
156 | SCMP_A2(SCMP_CMP_EQ, 1), | |
157 | SCMP_A3(SCMP_CMP_EQ, 3)); | |
158 | if (rc != 0) | |
159 | goto out; | |
160 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1007, 2, | |
161 | SCMP_A2(SCMP_CMP_EQ, 1), | |
162 | SCMP_A3(SCMP_CMP_NE, 3)); | |
163 | if (rc != 0) | |
164 | goto out; | |
165 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1007, 1, | |
166 | SCMP_A3(SCMP_CMP_NE, 3)); | |
167 | if (rc != 0) | |
168 | goto out; | |
169 | ||
170 | rc = util_filter_output(&opts, ctx); | |
171 | if (rc) | |
172 | goto out; | |
173 | ||
174 | out: | |
175 | seccomp_release(ctx); | |
176 | return (rc < 0 ? -rc : rc); | |
177 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | # the syscall and argument numbers are all fake to make the test simpler | |
33 | f.add_rule_exactly(ALLOW, 1000, | |
34 | Arg(0, EQ, 0), | |
35 | Arg(1, EQ, 1)) | |
36 | f.add_rule_exactly(ALLOW, 1000, | |
37 | Arg(1, EQ, 1)) | |
38 | ||
39 | f.add_rule_exactly(ALLOW, 1001, | |
40 | Arg(1, EQ, 1)) | |
41 | f.add_rule_exactly(ALLOW, 1001, | |
42 | Arg(0, EQ, 0), | |
43 | Arg(1, EQ, 1)) | |
44 | ||
45 | f.add_rule_exactly(ALLOW, 1002, | |
46 | Arg(0, EQ, 0), | |
47 | Arg(1, EQ, 1), | |
48 | Arg(2, EQ, 2), | |
49 | Arg(3, EQ, 3)) | |
50 | f.add_rule_exactly(ALLOW, 1002, | |
51 | Arg(1, EQ, 1), | |
52 | Arg(2, EQ, 2)) | |
53 | ||
54 | f.add_rule_exactly(ALLOW, 1003, | |
55 | Arg(1, EQ, 1), | |
56 | Arg(2, EQ, 2)) | |
57 | f.add_rule_exactly(ALLOW, 1003, | |
58 | Arg(0, EQ, 0), | |
59 | Arg(1, EQ, 1), | |
60 | Arg(2, EQ, 2), | |
61 | Arg(3, EQ, 3)) | |
62 | ||
63 | f.add_rule_exactly(ALLOW, 1004, | |
64 | Arg(0, EQ, 0), | |
65 | Arg(1, EQ, 1), | |
66 | Arg(2, EQ, 2), | |
67 | Arg(3, EQ, 3)) | |
68 | f.add_rule_exactly(ALLOW, 1004, | |
69 | Arg(0, EQ, 0), | |
70 | Arg(1, EQ, 11)) | |
71 | f.add_rule_exactly(ALLOW, 1004, | |
72 | Arg(0, EQ, 0), | |
73 | Arg(1, EQ, 1), | |
74 | Arg(2, EQ, 2), | |
75 | Arg(3, EQ, 33)) | |
76 | f.add_rule_exactly(ALLOW, 1004, | |
77 | Arg(1, EQ, 1), | |
78 | Arg(2, EQ, 2)) | |
79 | ||
80 | f.add_rule_exactly(ALLOW, 1005, | |
81 | Arg(1, EQ, 1), | |
82 | Arg(2, EQ, 2)) | |
83 | f.add_rule_exactly(ALLOW, 1005, | |
84 | Arg(0, EQ, 0), | |
85 | Arg(1, EQ, 1), | |
86 | Arg(2, EQ, 2), | |
87 | Arg(3, EQ, 3)) | |
88 | f.add_rule_exactly(ALLOW, 1005, | |
89 | Arg(0, EQ, 0), | |
90 | Arg(1, EQ, 11)) | |
91 | f.add_rule_exactly(ALLOW, 1005, | |
92 | Arg(0, EQ, 0), | |
93 | Arg(1, EQ, 1), | |
94 | Arg(2, EQ, 2), | |
95 | Arg(3, EQ, 33)) | |
96 | ||
97 | f.add_rule_exactly(ALLOW, 1006, | |
98 | Arg(1, NE, 1), | |
99 | Arg(2, EQ, 0)) | |
100 | f.add_rule_exactly(ALLOW, 1006, | |
101 | Arg(1, EQ, 1), | |
102 | Arg(2, EQ, 2)) | |
103 | f.add_rule_exactly(ALLOW, 1006, | |
104 | Arg(1, NE, 1)) | |
105 | ||
106 | f.add_rule_exactly(TRAP, 1007, | |
107 | Arg(2, EQ, 1), | |
108 | Arg(3, EQ, 3)) | |
109 | f.add_rule_exactly(ALLOW, 1007, | |
110 | Arg(2, EQ, 1), | |
111 | Arg(3, NE, 3)) | |
112 | f.add_rule_exactly(ALLOW, 1007, | |
113 | Arg(3, NE, 3)) | |
114 | return f | |
115 | ||
116 | args = util.get_opt() | |
117 | ctx = test(args) | |
118 | util.filter_output(args, ctx) | |
119 | ||
120 | # kate: syntax python; | |
121 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 08-sim-subtree_checks all 1000 0-10 1 N N N N ALLOW | |
11 | 08-sim-subtree_checks all 1000 0-10 0 N N N N KILL | |
12 | 08-sim-subtree_checks all 1001 0-10 1 N N N N ALLOW | |
13 | 08-sim-subtree_checks all 1001 0-10 0 N N N N KILL | |
14 | 08-sim-subtree_checks all 1002 0-5 1 2 0-5 N N ALLOW | |
15 | 08-sim-subtree_checks all 1002 0-5 2 1 0-5 N N KILL | |
16 | 08-sim-subtree_checks all 1003 0-5 1 2 0-5 N N ALLOW | |
17 | 08-sim-subtree_checks all 1003 0-5 2 1 0-5 N N KILL | |
18 | 08-sim-subtree_checks all 1004 0 11 5-10 10 10 1-5 ALLOW | |
19 | 08-sim-subtree_checks all 1004 0 1 2 0-5 N N ALLOW | |
20 | 08-sim-subtree_checks all 1004 1-5 1 2 0-5 N N ALLOW | |
21 | 08-sim-subtree_checks all 1004 1-5 1 2 30-35 N N ALLOW | |
22 | 08-sim-subtree_checks all 1004 1-5 2 1 30-35 N N KILL | |
23 | 08-sim-subtree_checks all 1005 0 11 5-10 10 10 1-5 ALLOW | |
24 | 08-sim-subtree_checks all 1005 0 1 2 0-5 N N ALLOW | |
25 | 08-sim-subtree_checks all 1005 1-5 1 2 0-5 N N ALLOW | |
26 | 08-sim-subtree_checks all 1005 1-5 1 2 30-35 N N ALLOW | |
27 | 08-sim-subtree_checks all 1005 1-5 2 1 30-35 N N KILL | |
28 | 08-sim-subtree_checks all 1006 0-10 1 2 N N N ALLOW | |
29 | 08-sim-subtree_checks all 1006 0-10 1 3 N N N KILL | |
30 | 08-sim-subtree_checks all 1006 10 2-100 2 N N N ALLOW | |
31 | 08-sim-subtree_checks all 1007 0 0 1 3 N N TRAP | |
32 | 08-sim-subtree_checks all 1007 1 1 1 0-2 1 1 ALLOW | |
33 | 08-sim-subtree_checks all 1007 1 1 2 0-2 1 1 ALLOW | |
34 | 08-sim-subtree_checks all 1007 1 1 2 4-6 1 1 ALLOW | |
35 | 08-sim-subtree_checks all 1007 1 1 0 3 1 1 KILL | |
36 | ||
37 | test type: bpf-sim-fuzz | |
38 | ||
39 | # Testname StressCount | |
40 | 08-sim-subtree_checks 50 | |
41 | ||
42 | ||
43 | test type: bpf-valgrind | |
44 | ||
45 | # Testname | |
46 | 08-sim-subtree_checks |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | struct util_options opts; | |
31 | scmp_filter_ctx ctx; | |
32 | ||
33 | rc = util_getopt(argc, argv, &opts); | |
34 | if (rc < 0) | |
35 | goto out; | |
36 | ||
37 | ctx = seccomp_init(SCMP_ACT_KILL); | |
38 | if (ctx == NULL) | |
39 | goto out; | |
40 | ||
41 | /* the syscall and argument numbers are all fake to make the test | |
42 | * simpler */ | |
43 | ||
44 | rc = seccomp_syscall_priority(ctx, 1000, 3); | |
45 | if (rc != 0) | |
46 | goto out; | |
47 | rc = seccomp_syscall_priority(ctx, 1001, 2); | |
48 | if (rc != 0) | |
49 | goto out; | |
50 | rc = seccomp_syscall_priority(ctx, 1002, 1); | |
51 | if (rc != 0) | |
52 | goto out; | |
53 | ||
54 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1000, 2, | |
55 | SCMP_A0(SCMP_CMP_EQ, 0), | |
56 | SCMP_A1(SCMP_CMP_EQ, 1)); | |
57 | if (rc != 0) | |
58 | goto out; | |
59 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1001, 1, | |
60 | SCMP_A0(SCMP_CMP_EQ, 0)); | |
61 | if (rc != 0) | |
62 | goto out; | |
63 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1002, 0); | |
64 | if (rc != 0) | |
65 | goto out; | |
66 | ||
67 | rc = util_filter_output(&opts, ctx); | |
68 | if (rc) | |
69 | goto out; | |
70 | ||
71 | out: | |
72 | seccomp_release(ctx); | |
73 | return (rc < 0 ? -rc : rc); | |
74 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | # the syscall and argument numbers are all fake to make the test simpler | |
33 | f.syscall_priority(1000, 3) | |
34 | f.syscall_priority(1001, 2) | |
35 | f.syscall_priority(1002, 1) | |
36 | f.add_rule_exactly(ALLOW, 1000, Arg(0, EQ, 0), Arg(1, EQ, 1)) | |
37 | f.add_rule_exactly(ALLOW, 1001, Arg(0, EQ, 0)) | |
38 | f.add_rule_exactly(ALLOW, 1002) | |
39 | return f | |
40 | ||
41 | args = util.get_opt() | |
42 | ctx = test(args) | |
43 | util.filter_output(args, ctx) | |
44 | ||
45 | # kate: syntax python; | |
46 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 09-sim-syscall_priority_pre all 999 N N N N N N KILL | |
11 | 09-sim-syscall_priority_pre all 1000-1002 0 1 N N N N ALLOW | |
12 | 09-sim-syscall_priority_pre all 1000 0 2 N N N N KILL | |
13 | 09-sim-syscall_priority_pre all 1001-1002 0 2 N N N N ALLOW | |
14 | 09-sim-syscall_priority_pre all 1000-1001 1 1 N N N N KILL | |
15 | 09-sim-syscall_priority_pre all 1003 N N N N N N KILL | |
16 | ||
17 | test type: bpf-sim-fuzz | |
18 | ||
19 | # Testname StressCount | |
20 | 09-sim-syscall_priority_pre 50 | |
21 | ||
22 | test type: bpf-valgrind | |
23 | ||
24 | # Testname | |
25 | 09-sim-syscall_priority_pre |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | struct util_options opts; | |
31 | scmp_filter_ctx ctx; | |
32 | ||
33 | rc = util_getopt(argc, argv, &opts); | |
34 | if (rc < 0) | |
35 | goto out; | |
36 | ||
37 | ctx = seccomp_init(SCMP_ACT_KILL); | |
38 | if (ctx == NULL) | |
39 | goto out; | |
40 | ||
41 | /* the syscall and argument numbers are all fake to make the test | |
42 | * simpler */ | |
43 | ||
44 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1000, 2, | |
45 | SCMP_A0(SCMP_CMP_EQ, 0), | |
46 | SCMP_A1(SCMP_CMP_EQ, 1)); | |
47 | if (rc != 0) | |
48 | goto out; | |
49 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1001, 1, | |
50 | SCMP_A0(SCMP_CMP_EQ, 0)); | |
51 | if (rc != 0) | |
52 | goto out; | |
53 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1002, 0); | |
54 | if (rc != 0) | |
55 | goto out; | |
56 | ||
57 | rc = seccomp_syscall_priority(ctx, 1000, 3); | |
58 | if (rc != 0) | |
59 | goto out; | |
60 | rc = seccomp_syscall_priority(ctx, 1001, 2); | |
61 | if (rc != 0) | |
62 | goto out; | |
63 | rc = seccomp_syscall_priority(ctx, 1002, 1); | |
64 | if (rc != 0) | |
65 | goto out; | |
66 | ||
67 | rc = util_filter_output(&opts, ctx); | |
68 | if (rc) | |
69 | goto out; | |
70 | ||
71 | out: | |
72 | seccomp_release(ctx); | |
73 | return (rc < 0 ? -rc : rc); | |
74 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | # the syscall and argument numbers are all fake to make the test simpler | |
33 | f.add_rule_exactly(ALLOW, 1000, Arg(0, EQ, 0), Arg(1, EQ, 1)) | |
34 | f.add_rule_exactly(ALLOW, 1001, Arg(0, EQ, 0)) | |
35 | f.add_rule_exactly(ALLOW, 1002) | |
36 | f.syscall_priority(1000, 3) | |
37 | f.syscall_priority(1001, 2) | |
38 | f.syscall_priority(1002, 1) | |
39 | return f | |
40 | ||
41 | args = util.get_opt() | |
42 | ctx = test(args) | |
43 | util.filter_output(args, ctx) | |
44 | ||
45 | # kate: syntax python; | |
46 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 10-sim-syscall_priority_post all 999 N N N N N N KILL | |
11 | 10-sim-syscall_priority_post all 1000-1002 0 1 N N N N ALLOW | |
12 | 10-sim-syscall_priority_post all 1000 0 2 N N N N KILL | |
13 | 10-sim-syscall_priority_post all 1001-1002 0 2 N N N N ALLOW | |
14 | 10-sim-syscall_priority_post all 1000-1001 1 1 N N N N KILL | |
15 | 10-sim-syscall_priority_post all 1003 N N N N N N KILL | |
16 | ||
17 | test type: bpf-sim-fuzz | |
18 | ||
19 | # Testname StressCount | |
20 | 10-sim-syscall_priority_post 50 | |
21 | ||
22 | test type: bpf-valgrind | |
23 | ||
24 | # Testname | |
25 | 10-sim-syscall_priority_post |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright IBM Corp. 2012 | |
4 | * Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | #include <errno.h> | |
23 | ||
24 | #include <seccomp.h> | |
25 | ||
26 | int main(int argc, char *argv[]) | |
27 | { | |
28 | int rc; | |
29 | scmp_filter_ctx ctx; | |
30 | ||
31 | /* seccomp_init errors */ | |
32 | ctx = seccomp_init(SCMP_ACT_ALLOW + 1); | |
33 | if (ctx != NULL) | |
34 | return -1; | |
35 | ||
36 | ctx = seccomp_init(SCMP_ACT_ALLOW); | |
37 | if (ctx == NULL) | |
38 | return -1; | |
39 | seccomp_release(ctx); | |
40 | ctx = NULL; | |
41 | ||
42 | /* seccomp_reset error */ | |
43 | rc = seccomp_reset(ctx, SCMP_ACT_KILL + 1); | |
44 | if (rc != -EINVAL) | |
45 | return -1; | |
46 | rc = seccomp_reset(ctx, SCMP_ACT_KILL); | |
47 | if (rc != -EINVAL) | |
48 | return -1; | |
49 | ||
50 | /* seccomp_load error */ | |
51 | rc = seccomp_load(ctx); | |
52 | if (rc != -EINVAL) | |
53 | return -1; | |
54 | ||
55 | /* seccomp_syscall_priority errors */ | |
56 | rc = seccomp_syscall_priority(ctx, SCMP_SYS(read), 1); | |
57 | if (rc != -EINVAL) | |
58 | return -1; | |
59 | ||
60 | ctx = seccomp_init(SCMP_ACT_ALLOW); | |
61 | if (ctx == NULL) | |
62 | return -1; | |
63 | else { | |
64 | rc = seccomp_syscall_priority(ctx, -10, 1); | |
65 | if (rc != -EINVAL) | |
66 | return -1; | |
67 | } | |
68 | seccomp_release(ctx); | |
69 | ctx = NULL; | |
70 | ||
71 | /* seccomp_rule_add errors */ | |
72 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, | |
73 | SCMP_A0(SCMP_CMP_EQ, 0)); | |
74 | if (rc != -EINVAL) | |
75 | return -1; | |
76 | ||
77 | ctx = seccomp_init(SCMP_ACT_ALLOW); | |
78 | if (ctx == NULL) | |
79 | return -1; | |
80 | else { | |
81 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); | |
82 | if (rc != -EPERM) | |
83 | return -1; | |
84 | rc = seccomp_rule_add(ctx, SCMP_ACT_KILL - 1, SCMP_SYS(read), 0); | |
85 | if (rc != -EINVAL) | |
86 | return -1; | |
87 | rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(read), 6); | |
88 | if (rc != -EINVAL) | |
89 | return -1; | |
90 | rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(read), 7, | |
91 | SCMP_A0(SCMP_CMP_EQ, 0), | |
92 | SCMP_A1(SCMP_CMP_EQ, 0), | |
93 | SCMP_A2(SCMP_CMP_EQ, 0), | |
94 | SCMP_A3(SCMP_CMP_EQ, 0), | |
95 | SCMP_A4(SCMP_CMP_EQ, 0), | |
96 | SCMP_A5(SCMP_CMP_EQ, 0), | |
97 | SCMP_CMP(6, SCMP_CMP_EQ, 0)); | |
98 | if (rc != -EINVAL) | |
99 | return -1; | |
100 | rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(read), 1, | |
101 | SCMP_A0(_SCMP_CMP_MIN, 0)); | |
102 | if (rc != -EINVAL) | |
103 | return -1; | |
104 | rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(read), 1, | |
105 | SCMP_A0(_SCMP_CMP_MAX, 0)); | |
106 | if (rc != -EINVAL) | |
107 | return -1; | |
108 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, -10001, 0); | |
109 | if (rc != -EDOM) | |
110 | return -1; | |
111 | } | |
112 | seccomp_release(ctx); | |
113 | ctx = NULL; | |
114 | ||
115 | /* seccomp_rule_add_exact error */ | |
116 | ctx = seccomp_init(SCMP_ACT_ALLOW); | |
117 | if (ctx == NULL) | |
118 | return -1; | |
119 | if (seccomp_arch_native() != SCMP_ARCH_X86) { | |
120 | rc = seccomp_arch_add(ctx, SCMP_ARCH_X86); | |
121 | if (rc != 0) | |
122 | return -1; | |
123 | rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE); | |
124 | if (rc != 0) | |
125 | return -1; | |
126 | } | |
127 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, SCMP_SYS(socket), 1, | |
128 | SCMP_A0(SCMP_CMP_EQ, 2)); | |
129 | if (rc != -EINVAL) | |
130 | return -1; | |
131 | seccomp_release(ctx); | |
132 | ctx = NULL; | |
133 | ||
134 | /* seccomp_export_pfc errors */ | |
135 | rc = seccomp_export_pfc(ctx, STDOUT_FILENO); | |
136 | if (rc != -EINVAL) | |
137 | return -1; | |
138 | ||
139 | ctx = seccomp_init(SCMP_ACT_ALLOW); | |
140 | if (ctx == NULL) | |
141 | return -1; | |
142 | else { | |
143 | rc = seccomp_export_pfc(ctx, sysconf(_SC_OPEN_MAX) - 1); | |
144 | if (rc != EBADF) | |
145 | return -1; | |
146 | } | |
147 | seccomp_release(ctx); | |
148 | ctx = NULL; | |
149 | ||
150 | /* seccomp_export_bpf errors */ | |
151 | rc = seccomp_export_bpf(ctx, STDOUT_FILENO); | |
152 | if (rc != -EINVAL) | |
153 | return -1; | |
154 | ||
155 | ctx = seccomp_init(SCMP_ACT_ALLOW); | |
156 | if (ctx == NULL) | |
157 | return -1; | |
158 | else { | |
159 | rc = seccomp_export_bpf(ctx, sysconf(_SC_OPEN_MAX) - 1); | |
160 | if (rc != -EBADF) | |
161 | return -1; | |
162 | } | |
163 | seccomp_release(ctx); | |
164 | ctx = NULL; | |
165 | ||
166 | return 0; | |
167 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(): | |
31 | # this test differs from the native test for obvious reasons | |
32 | try: | |
33 | f = SyscallFilter(ALLOW + 1) | |
34 | except RuntimeError: | |
35 | pass | |
36 | ||
37 | f = SyscallFilter(ALLOW) | |
38 | try: | |
39 | f.reset(KILL + 1) | |
40 | except ValueError: | |
41 | pass | |
42 | ||
43 | f = SyscallFilter(ALLOW) | |
44 | try: | |
45 | f.syscall_priority(-10000, 1) | |
46 | except RuntimeError: | |
47 | pass | |
48 | ||
49 | f = SyscallFilter(ALLOW) | |
50 | try: | |
51 | f.add_rule(ALLOW, "read") | |
52 | except RuntimeError: | |
53 | pass | |
54 | try: | |
55 | f.add_rule(KILL - 1, "read") | |
56 | except RuntimeError: | |
57 | pass | |
58 | try: | |
59 | f.add_rule(KILL, "read", | |
60 | Arg(0, EQ, 0), | |
61 | Arg(1, EQ, 1), | |
62 | Arg(2, EQ, 2), | |
63 | Arg(3, EQ, 3), | |
64 | Arg(4, EQ, 4), | |
65 | Arg(5, EQ, 5), | |
66 | Arg(6, EQ, 6), | |
67 | Arg(7, EQ, 7)) | |
68 | except RuntimeError: | |
69 | pass | |
70 | try: | |
71 | f.add_rule(KILL, -1001) | |
72 | except RuntimeError: | |
73 | pass | |
74 | ||
75 | f = SyscallFilter(ALLOW) | |
76 | if not f.exist_arch(Arch.X86): | |
77 | f.add_arch(Arch.X86) | |
78 | f.remove_arch(Arch.NATIVE) | |
79 | try: | |
80 | f.add_rule_exactly(KILL, "socket", Arg(0, EQ, 2)) | |
81 | except RuntimeError: | |
82 | pass | |
83 | ||
84 | test() | |
85 | ||
86 | # kate: syntax python; | |
87 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: basic | |
8 | ||
9 | # Test command | |
10 | 11-basic-basic_errors |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | struct util_options opts; | |
31 | scmp_filter_ctx ctx; | |
32 | ||
33 | rc = util_getopt(argc, argv, &opts); | |
34 | if (rc < 0) | |
35 | goto out; | |
36 | ||
37 | ctx = seccomp_init(SCMP_ACT_KILL); | |
38 | if (ctx == NULL) | |
39 | goto out; | |
40 | ||
41 | /* the syscall and argument numbers are all fake to make the test | |
42 | * simpler */ | |
43 | ||
44 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1000, 3, | |
45 | SCMP_A0(SCMP_CMP_EQ, 0), | |
46 | SCMP_A1(SCMP_CMP_EQ, 1), | |
47 | SCMP_A2(SCMP_CMP_EQ, 2)); | |
48 | if (rc != 0) | |
49 | goto out; | |
50 | ||
51 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1000, 3, | |
52 | SCMP_A0(SCMP_CMP_EQ, 0), | |
53 | SCMP_A1(SCMP_CMP_MASKED_EQ, 0x00ff, 1), | |
54 | SCMP_A2(SCMP_CMP_EQ, 2)); | |
55 | if (rc != 0) | |
56 | goto out; | |
57 | ||
58 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1000, 3, | |
59 | SCMP_A0(SCMP_CMP_EQ, 0), | |
60 | SCMP_A1(SCMP_CMP_MASKED_EQ, 0xffff, 11), | |
61 | SCMP_A2(SCMP_CMP_EQ, 2)); | |
62 | if (rc != 0) | |
63 | goto out; | |
64 | ||
65 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1000, 3, | |
66 | SCMP_A0(SCMP_CMP_EQ, 0), | |
67 | SCMP_A1(SCMP_CMP_MASKED_EQ, 0xffff, 111), | |
68 | SCMP_A2(SCMP_CMP_EQ, 2)); | |
69 | if (rc != 0) | |
70 | goto out; | |
71 | ||
72 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1000, 3, | |
73 | SCMP_A0(SCMP_CMP_EQ, 0), | |
74 | SCMP_A1(SCMP_CMP_MASKED_EQ, 0xff00, 1000), | |
75 | SCMP_A2(SCMP_CMP_EQ, 2)); | |
76 | if (rc != 0) | |
77 | goto out; | |
78 | ||
79 | rc = util_filter_output(&opts, ctx); | |
80 | if (rc) | |
81 | goto out; | |
82 | ||
83 | out: | |
84 | seccomp_release(ctx); | |
85 | return (rc < 0 ? -rc : rc); | |
86 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | # the syscall and argument numbers are all fake to make the test simpler | |
33 | f.add_rule_exactly(ALLOW, 1000, | |
34 | Arg(0, EQ, 0), | |
35 | Arg(1, EQ, 1), | |
36 | Arg(2, EQ, 2)) | |
37 | f.add_rule_exactly(ALLOW, 1000, | |
38 | Arg(0, EQ, 0), | |
39 | Arg(1, MASKED_EQ, 0x00ff, 1), | |
40 | Arg(2, EQ, 2)) | |
41 | f.add_rule_exactly(ALLOW, 1000, | |
42 | Arg(0, EQ, 0), | |
43 | Arg(1, MASKED_EQ, 0xffff, 11), | |
44 | Arg(2, EQ, 2)) | |
45 | f.add_rule_exactly(ALLOW, 1000, | |
46 | Arg(0, EQ, 0), | |
47 | Arg(1, MASKED_EQ, 0xffff, 111), | |
48 | Arg(2, EQ, 2)) | |
49 | f.add_rule_exactly(ALLOW, 1000, | |
50 | Arg(0, EQ, 0), | |
51 | Arg(1, MASKED_EQ, 0xff00, 1000), | |
52 | Arg(2, EQ, 2)) | |
53 | return f | |
54 | ||
55 | args = util.get_opt() | |
56 | ctx = test(args) | |
57 | util.filter_output(args, ctx) | |
58 | ||
59 | # kate: syntax python; | |
60 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 12-sim-basic_masked_ops all 1000 0 1 2 N N N ALLOW | |
11 | 12-sim-basic_masked_ops all 1000 0 0x01 2 N N N ALLOW | |
12 | 12-sim-basic_masked_ops all 1000 0 0x02-0x0A 2 N N N KILL | |
13 | 12-sim-basic_masked_ops all 1000 0 0x101 2 N N N ALLOW | |
14 | 12-sim-basic_masked_ops all 1000 0 11 2 N N N ALLOW | |
15 | 12-sim-basic_masked_ops all 1000 0 0x0B 2 N N N ALLOW | |
16 | 12-sim-basic_masked_ops all 1000 0 0x0C-0x6E 2 N N N KILL | |
17 | 12-sim-basic_masked_ops all 1000 0 0x1000B 2 N N N ALLOW | |
18 | 12-sim-basic_masked_ops all 1000 0 111 2 N N N ALLOW | |
19 | 12-sim-basic_masked_ops all 1000 0 0x6F 2 N N N ALLOW | |
20 | 12-sim-basic_masked_ops all 1000 0 0x70-0x100 2 N N N KILL | |
21 | 12-sim-basic_masked_ops all 1000 0 0x102-0x200 2 N N N KILL | |
22 | 12-sim-basic_masked_ops all 1000 0 0x10002-0x1000A 2 N N N KILL | |
23 | 12-sim-basic_masked_ops all 1000 0 0x1000C-0x1006E 2 N N N KILL | |
24 | 12-sim-basic_masked_ops all 1000 0 0x1006F 2 N N N ALLOW | |
25 | 12-sim-basic_masked_ops all 1000 0 1000 2 N N N ALLOW | |
26 | 12-sim-basic_masked_ops all 1000 0 0x3E8 2 N N N ALLOW | |
27 | 12-sim-basic_masked_ops all 1000 0 0x2FF 2 N N N KILL | |
28 | 12-sim-basic_masked_ops all 1000 0 0x300-0x3FF 2 N N N ALLOW | |
29 | 12-sim-basic_masked_ops all 1000 0 0x400 2 N N N KILL | |
30 | 12-sim-basic_masked_ops all 1000 0 0x402-0x4FF 2 N N N KILL | |
31 | 12-sim-basic_masked_ops all 1000 0 0x10300-0x103FF 2 N N N ALLOW | |
32 | ||
33 | test type: bpf-sim-fuzz | |
34 | ||
35 | # Testname StressCount | |
36 | 12-sim-basic_masked_ops 50 | |
37 | ||
38 | test type: bpf-valgrind | |
39 | ||
40 | # Testname | |
41 | 12-sim-basic_masked_ops |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <errno.h> | |
22 | #include <unistd.h> | |
23 | ||
24 | #include <seccomp.h> | |
25 | ||
26 | #include "util.h" | |
27 | ||
28 | int main(int argc, char *argv[]) | |
29 | { | |
30 | int rc; | |
31 | uint32_t val = (uint32_t)(-1); | |
32 | scmp_filter_ctx ctx; | |
33 | ||
34 | ctx = seccomp_init(SCMP_ACT_ALLOW); | |
35 | if (ctx == NULL) | |
36 | goto out; | |
37 | ||
38 | rc = seccomp_attr_get(ctx, SCMP_FLTATR_ACT_DEFAULT, &val); | |
39 | if (rc != 0) | |
40 | goto out; | |
41 | if (val != SCMP_ACT_ALLOW) { | |
42 | rc = -1; | |
43 | goto out; | |
44 | } | |
45 | rc = seccomp_attr_set(ctx, SCMP_FLTATR_ACT_DEFAULT, val); | |
46 | if (rc != -EACCES) { | |
47 | rc = -1; | |
48 | goto out; | |
49 | } | |
50 | ||
51 | rc = seccomp_attr_set(ctx, SCMP_FLTATR_ACT_BADARCH, SCMP_ACT_ALLOW); | |
52 | if (rc != 0) | |
53 | goto out; | |
54 | rc = seccomp_attr_get(ctx, SCMP_FLTATR_ACT_BADARCH, &val); | |
55 | if (rc != 0) | |
56 | goto out; | |
57 | if (val != SCMP_ACT_ALLOW) { | |
58 | rc = -1; | |
59 | goto out; | |
60 | } | |
61 | ||
62 | rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, 0); | |
63 | if (rc != 0) | |
64 | goto out; | |
65 | rc = seccomp_attr_get(ctx, SCMP_FLTATR_CTL_NNP, &val); | |
66 | if (rc != 0) | |
67 | goto out; | |
68 | if (val != 0) { | |
69 | rc = -1; | |
70 | goto out; | |
71 | } | |
72 | ||
73 | rc = 0; | |
74 | out: | |
75 | seccomp_release(ctx); | |
76 | return (rc < 0 ? -rc : rc); | |
77 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(): | |
31 | f = SyscallFilter(ALLOW) | |
32 | if f.get_attr(Attr.ACT_DEFAULT) != ALLOW: | |
33 | raise RuntimeError("Failed getting Attr.ACT_DEFAULT") | |
34 | try: | |
35 | f.set_attr(Attr.ACT_DEFAULT, ALLOW) | |
36 | except RuntimeError: | |
37 | pass | |
38 | f.set_attr(Attr.ACT_BADARCH, ALLOW) | |
39 | if f.get_attr(Attr.ACT_BADARCH) != ALLOW: | |
40 | raise RuntimeError("Failed getting Attr.ACT_BADARCH") | |
41 | f.set_attr(Attr.CTL_NNP, 0) | |
42 | if f.get_attr(Attr.CTL_NNP) != 0: | |
43 | raise RuntimeError("Failed getting Attr.CTL_NNP") | |
44 | ||
45 | test() | |
46 | ||
47 | # kate: syntax python; | |
48 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright IBM Corp. 2012 | |
4 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | # | |
6 | ||
7 | test type: basic | |
8 | ||
9 | # Test command | |
10 | 13-basic-attrs |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | struct util_options opts; | |
31 | scmp_filter_ctx ctx; | |
32 | ||
33 | rc = util_getopt(argc, argv, &opts); | |
34 | if (rc < 0) | |
35 | goto out; | |
36 | ||
37 | ctx = seccomp_init(SCMP_ACT_KILL); | |
38 | if (ctx == NULL) | |
39 | goto out; | |
40 | ||
41 | ||
42 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); | |
43 | if (rc != 0) | |
44 | goto out; | |
45 | ||
46 | rc = seccomp_reset(ctx, SCMP_ACT_KILL); | |
47 | if (rc != 0) | |
48 | goto out; | |
49 | ||
50 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0); | |
51 | if (rc != 0) | |
52 | goto out; | |
53 | ||
54 | rc = util_filter_output(&opts, ctx); | |
55 | if (rc) | |
56 | goto out; | |
57 | ||
58 | out: | |
59 | seccomp_release(ctx); | |
60 | return (rc < 0 ? -rc : rc); | |
61 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | f.add_rule(ALLOW, "read") | |
33 | f.reset() | |
34 | f.add_rule(ALLOW, "write") | |
35 | return f | |
36 | ||
37 | args = util.get_opt() | |
38 | ctx = test(args) | |
39 | util.filter_output(args, ctx) | |
40 | ||
41 | # kate: syntax python; | |
42 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 14-sim-reset all read 0 0x856B008 40 N N N KILL | |
11 | 14-sim-reset all write 1 0x856B008 40 N N N ALLOW | |
12 | 14-sim-reset all close 4 N N N N N KILL | |
13 | 14-sim-reset all rt_sigreturn N N N N N N KILL | |
14 | 14-sim-reset all open 0x856B008 4 N N N N KILL | |
15 | 14-sim-reset x86 0-3 N N N N N N KILL | |
16 | 14-sim-reset x86 5-360 N N N N N N KILL | |
17 | 14-sim-reset x86_64 0 N N N N N N KILL | |
18 | 14-sim-reset x86_64 2-360 N N N N N N KILL | |
19 | ||
20 | test type: bpf-sim-fuzz | |
21 | ||
22 | # Testname StressCount | |
23 | 14-sim-reset 50 | |
24 | ||
25 | test type: bpf-valgrind | |
26 | ||
27 | # Testname | |
28 | 14-sim-reset |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <string.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | int main(int argc, char *argv[]) | |
26 | { | |
27 | char *name; | |
28 | ||
29 | if (seccomp_syscall_resolve_name("open") != __NR_open) | |
30 | return 1; | |
31 | if (seccomp_syscall_resolve_name("socket") != __NR_socket) | |
32 | return 1; | |
33 | if (seccomp_syscall_resolve_name("INVALID") != __NR_SCMP_ERROR) | |
34 | return 1; | |
35 | ||
36 | if (seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE, | |
37 | "open") != __NR_open) | |
38 | return 1; | |
39 | if (seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE, | |
40 | "socket") != __NR_socket) | |
41 | return 1; | |
42 | if (seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE, | |
43 | "INVALID") != __NR_SCMP_ERROR) | |
44 | return 1; | |
45 | ||
46 | name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, __NR_open); | |
47 | if (name == NULL || strcmp(name, "open") != 0) | |
48 | return 1; | |
49 | name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, __NR_socket); | |
50 | if (name == NULL || strcmp(name, "socket") != 0) | |
51 | return 1; | |
52 | name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, | |
53 | __NR_SCMP_ERROR); | |
54 | if (name != NULL) | |
55 | return 1; | |
56 | ||
57 | return 0; | |
58 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(): | |
31 | f = SyscallFilter(KILL) | |
32 | # this differs from the native test as we don't support the syscall | |
33 | # resolution functions by themselves | |
34 | f.add_rule(ALLOW, "open") | |
35 | f.add_rule(ALLOW, "socket") | |
36 | try: | |
37 | f.add_rule(ALLOW, "INVALID") | |
38 | except RuntimeError: | |
39 | pass | |
40 | ||
41 | sys_num = resolve_syscall(Arch.NATIVE, "open") | |
42 | sys_name = resolve_syscall(Arch.NATIVE, sys_num) | |
43 | if (sys_name != "open"): | |
44 | raise RuntimeError("Test failure") | |
45 | sys_num = resolve_syscall(Arch.NATIVE, "socket") | |
46 | sys_name = resolve_syscall(Arch.NATIVE, sys_num) | |
47 | if (sys_name != "socket"): | |
48 | raise RuntimeError("Test failure") | |
49 | ||
50 | test() | |
51 | ||
52 | # kate: syntax python; | |
53 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | test type: basic | |
8 | ||
9 | # Test command | |
10 | 15-basic-resolver |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | #include <errno.h> | |
23 | ||
24 | #include <seccomp.h> | |
25 | ||
26 | #include "util.h" | |
27 | ||
28 | int main(int argc, char *argv[]) | |
29 | { | |
30 | int rc; | |
31 | struct util_options opts; | |
32 | scmp_filter_ctx ctx; | |
33 | ||
34 | rc = util_getopt(argc, argv, &opts); | |
35 | if (rc < 0) | |
36 | goto out; | |
37 | ||
38 | ctx = seccomp_init(SCMP_ACT_KILL); | |
39 | if (ctx == NULL) | |
40 | goto out; | |
41 | ||
42 | if (seccomp_arch_exist(ctx, SCMP_ARCH_X86)) { | |
43 | rc = seccomp_arch_add(ctx, SCMP_ARCH_X86); | |
44 | if (rc != 0) | |
45 | goto out; | |
46 | } | |
47 | if (seccomp_arch_exist(ctx, SCMP_ARCH_X86_64)) { | |
48 | rc = seccomp_arch_add(ctx, SCMP_ARCH_X86_64); | |
49 | if (rc != 0) | |
50 | goto out; | |
51 | } | |
52 | if (seccomp_arch_exist(ctx, SCMP_ARCH_X32)) { | |
53 | rc = seccomp_arch_add(ctx, SCMP_ARCH_X32); | |
54 | if (rc != 0) | |
55 | goto out; | |
56 | } | |
57 | if (seccomp_arch_exist(ctx, SCMP_ARCH_ARM)) { | |
58 | rc = seccomp_arch_add(ctx, SCMP_ARCH_ARM); | |
59 | if (rc != 0) | |
60 | goto out; | |
61 | } | |
62 | ||
63 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, | |
64 | SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO)); | |
65 | if (rc != 0) | |
66 | goto out; | |
67 | ||
68 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, | |
69 | SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)); | |
70 | if (rc != 0) | |
71 | goto out; | |
72 | ||
73 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, | |
74 | SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO)); | |
75 | if (rc != 0) | |
76 | goto out; | |
77 | ||
78 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); | |
79 | if (rc != 0) | |
80 | goto out; | |
81 | ||
82 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 0); | |
83 | if (rc != 0) | |
84 | goto out; | |
85 | ||
86 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(connect), 0); | |
87 | if (rc != 0) | |
88 | goto out; | |
89 | ||
90 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(shutdown), 0); | |
91 | if (rc != 0) | |
92 | goto out; | |
93 | ||
94 | rc = util_filter_output(&opts, ctx); | |
95 | if (rc) | |
96 | goto out; | |
97 | ||
98 | out: | |
99 | seccomp_release(ctx); | |
100 | return (rc < 0 ? -rc : rc); | |
101 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | if not f.exist_arch(Arch.X86): | |
33 | f.add_arch(Arch.X86) | |
34 | if not f.exist_arch(Arch.X86_64): | |
35 | f.add_arch(Arch.X86_64) | |
36 | if not f.exist_arch(Arch.X32): | |
37 | f.add_arch(Arch.X32) | |
38 | if not f.exist_arch(Arch.ARM): | |
39 | f.add_arch(Arch.ARM) | |
40 | f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno())) | |
41 | f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno())) | |
42 | f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno())) | |
43 | f.add_rule(ALLOW, "close") | |
44 | f.add_rule(ALLOW, "socket") | |
45 | f.add_rule(ALLOW, "connect") | |
46 | f.add_rule(ALLOW, "shutdown") | |
47 | return f | |
48 | ||
49 | args = util.get_opt() | |
50 | ctx = test(args) | |
51 | util.filter_output(args, ctx) | |
52 | ||
53 | # kate: syntax python; | |
54 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 16-sim-arch_basic +all read 0 0x856B008 10 N N N ALLOW | |
11 | 16-sim-arch_basic +all read 1-10 0x856B008 10 N N N KILL | |
12 | 16-sim-arch_basic +all write 1-2 0x856B008 10 N N N ALLOW | |
13 | 16-sim-arch_basic +all write 3-10 0x856B008 10 N N N KILL | |
14 | 16-sim-arch_basic +all close N N N N N N ALLOW | |
15 | 16-sim-arch_basic +all open 0x856B008 4 N N N N KILL | |
16 | 16-sim-arch_basic +x86 socket 1 N N N N N ALLOW | |
17 | 16-sim-arch_basic +x86 connect 3 N N N N N ALLOW | |
18 | 16-sim-arch_basic +x86 shutdown 13 N N N N N ALLOW | |
19 | 16-sim-arch_basic +x86_64 socket 0 1 2 N N N ALLOW | |
20 | 16-sim-arch_basic +x86_64 connect 0 1 2 N N N ALLOW | |
21 | 16-sim-arch_basic +x86_64 shutdown 0 1 2 N N N ALLOW | |
22 | ||
23 | test type: bpf-sim-fuzz | |
24 | ||
25 | # Testname StressCount | |
26 | 16-sim-arch_basic 50 | |
27 | ||
28 | test type: bpf-valgrind | |
29 | ||
30 | # Testname | |
31 | 16-sim-arch_basic |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | #include <errno.h> | |
23 | ||
24 | #include <seccomp.h> | |
25 | ||
26 | #include "util.h" | |
27 | ||
28 | int main(int argc, char *argv[]) | |
29 | { | |
30 | int rc; | |
31 | struct util_options opts; | |
32 | scmp_filter_ctx ctx_64, ctx_32; | |
33 | ||
34 | rc = util_getopt(argc, argv, &opts); | |
35 | if (rc < 0) | |
36 | goto out_all; | |
37 | ||
38 | ctx_32 = seccomp_init(SCMP_ACT_KILL); | |
39 | if (ctx_32 == NULL) | |
40 | goto out_all; | |
41 | ctx_64 = seccomp_init(SCMP_ACT_KILL); | |
42 | if (ctx_64 == NULL) | |
43 | goto out_all; | |
44 | ||
45 | if (seccomp_arch_exist(ctx_32, SCMP_ARCH_X86) == -EEXIST) { | |
46 | rc = seccomp_arch_add(ctx_32, SCMP_ARCH_X86); | |
47 | if (rc != 0) | |
48 | goto out_all; | |
49 | rc = seccomp_arch_remove(ctx_32, SCMP_ARCH_NATIVE); | |
50 | if (rc != 0) | |
51 | goto out_all; | |
52 | } | |
53 | if (seccomp_arch_exist(ctx_64, SCMP_ARCH_X86_64) == -EEXIST) { | |
54 | rc = seccomp_arch_add(ctx_64, SCMP_ARCH_X86_64); | |
55 | if (rc != 0) | |
56 | goto out_all; | |
57 | rc = seccomp_arch_remove(ctx_64, SCMP_ARCH_NATIVE); | |
58 | if (rc != 0) | |
59 | goto out_all; | |
60 | } | |
61 | ||
62 | rc = seccomp_rule_add(ctx_32, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, | |
63 | SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO)); | |
64 | if (rc != 0) | |
65 | goto out_all; | |
66 | ||
67 | rc = seccomp_rule_add(ctx_32, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, | |
68 | SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)); | |
69 | if (rc != 0) | |
70 | goto out_all; | |
71 | ||
72 | rc = seccomp_rule_add(ctx_32, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, | |
73 | SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO)); | |
74 | if (rc != 0) | |
75 | goto out_all; | |
76 | ||
77 | rc = seccomp_rule_add(ctx_32, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); | |
78 | if (rc != 0) | |
79 | goto out_all; | |
80 | ||
81 | rc = seccomp_rule_add(ctx_64, SCMP_ACT_ALLOW, SCMP_SYS(socket), 0); | |
82 | if (rc != 0) | |
83 | goto out_all; | |
84 | ||
85 | rc = seccomp_rule_add(ctx_64, SCMP_ACT_ALLOW, SCMP_SYS(connect), 0); | |
86 | if (rc != 0) | |
87 | goto out_all; | |
88 | ||
89 | rc = seccomp_rule_add(ctx_64, SCMP_ACT_ALLOW, SCMP_SYS(shutdown), 0); | |
90 | if (rc != 0) | |
91 | goto out_all; | |
92 | ||
93 | rc = seccomp_merge(ctx_64, ctx_32); | |
94 | if (rc != 0) | |
95 | goto out_all; | |
96 | ||
97 | /* NOTE: ctx_32 is no longer valid at this point */ | |
98 | ||
99 | rc = util_filter_output(&opts, ctx_64); | |
100 | if (rc) | |
101 | goto out; | |
102 | ||
103 | out: | |
104 | seccomp_release(ctx_64); | |
105 | return (rc < 0 ? -rc : rc); | |
106 | out_all: | |
107 | seccomp_release(ctx_32); | |
108 | goto out; | |
109 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f32 = SyscallFilter(KILL) | |
32 | f64 = SyscallFilter(KILL) | |
33 | if not f32.exist_arch(Arch.X86): | |
34 | f32.add_arch(Arch.X86) | |
35 | f32.remove_arch(Arch.NATIVE) | |
36 | if not f64.exist_arch(Arch.X86_64): | |
37 | f64.add_arch(Arch.X86_64) | |
38 | f64.remove_arch(Arch.NATIVE) | |
39 | f32.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno())) | |
40 | f32.add_rule(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno())) | |
41 | f32.add_rule(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno())) | |
42 | f32.add_rule(ALLOW, "close") | |
43 | f64.add_rule(ALLOW, "socket") | |
44 | f64.add_rule(ALLOW, "connect") | |
45 | f64.add_rule(ALLOW, "shutdown") | |
46 | f64.merge(f32) | |
47 | return f64 | |
48 | ||
49 | args = util.get_opt() | |
50 | ctx = test(args) | |
51 | util.filter_output(args, ctx) | |
52 | ||
53 | # kate: syntax python; | |
54 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 17-sim-arch_merge +x86 read 0 0x856B008 10 N N N ALLOW | |
11 | 17-sim-arch_merge +x86 read 1-10 0x856B008 10 N N N KILL | |
12 | 17-sim-arch_merge +x86 write 1-2 0x856B008 10 N N N ALLOW | |
13 | 17-sim-arch_merge +x86 write 3-10 0x856B008 10 N N N KILL | |
14 | 17-sim-arch_merge +x86 close N N N N N N ALLOW | |
15 | 17-sim-arch_merge +x86 open 0x856B008 4 N N N N KILL | |
16 | 17-sim-arch_merge +x86_64 socket 0 1 2 N N N ALLOW | |
17 | 17-sim-arch_merge +x86_64 connect 0 1 2 N N N ALLOW | |
18 | 17-sim-arch_merge +x86_64 shutdown 0 1 2 N N N ALLOW | |
19 | ||
20 | test type: bpf-sim-fuzz | |
21 | ||
22 | # Testname StressCount | |
23 | 17-sim-arch_merge 50 | |
24 | ||
25 | test type: bpf-valgrind | |
26 | ||
27 | # Testname | |
28 | 17-sim-arch_merge |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | struct util_options opts; | |
31 | scmp_filter_ctx ctx; | |
32 | ||
33 | rc = util_getopt(argc, argv, &opts); | |
34 | if (rc < 0) | |
35 | goto out; | |
36 | ||
37 | ctx = seccomp_init(SCMP_ACT_ALLOW); | |
38 | if (ctx == NULL) | |
39 | goto out; | |
40 | ||
41 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, SCMP_SYS(read), 1, | |
42 | SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO)); | |
43 | if (rc != 0) | |
44 | goto out; | |
45 | ||
46 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, SCMP_SYS(write), 1, | |
47 | SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)); | |
48 | if (rc != 0) | |
49 | goto out; | |
50 | ||
51 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, SCMP_SYS(write), 1, | |
52 | SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO)); | |
53 | if (rc != 0) | |
54 | goto out; | |
55 | ||
56 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, SCMP_SYS(close), 0); | |
57 | if (rc != 0) | |
58 | goto out; | |
59 | ||
60 | rc = seccomp_rule_add_exact(ctx, | |
61 | SCMP_ACT_KILL, SCMP_SYS(rt_sigreturn), 0); | |
62 | if (rc != 0) | |
63 | goto out; | |
64 | ||
65 | rc = util_filter_output(&opts, ctx); | |
66 | if (rc) | |
67 | goto out; | |
68 | ||
69 | out: | |
70 | seccomp_release(ctx); | |
71 | return (rc < 0 ? -rc : rc); | |
72 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(ALLOW) | |
32 | f.add_rule_exactly(KILL, "read", Arg(0, EQ, sys.stdin.fileno())); | |
33 | f.add_rule_exactly(KILL, "write", Arg(0, EQ, sys.stdout.fileno())); | |
34 | f.add_rule_exactly(KILL, "write", Arg(0, EQ, sys.stderr.fileno())); | |
35 | f.add_rule_exactly(KILL, "close"); | |
36 | f.add_rule_exactly(KILL, "rt_sigreturn"); | |
37 | return f | |
38 | ||
39 | args = util.get_opt() | |
40 | ctx = test(args) | |
41 | util.filter_output(args, ctx) | |
42 | ||
43 | # kate: syntax python; | |
44 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 18-sim-basic_whitelist all read 0 0x856B008 10 N N N KILL | |
11 | 18-sim-basic_whitelist all read 1-10 0x856B008 10 N N N ALLOW | |
12 | 18-sim-basic_whitelist all write 1-2 0x856B008 10 N N N KILL | |
13 | 18-sim-basic_whitelist all write 3-10 0x856B008 10 N N N ALLOW | |
14 | 18-sim-basic_whitelist all close N N N N N N KILL | |
15 | 18-sim-basic_whitelist all rt_sigreturn N N N N N N KILL | |
16 | 18-sim-basic_whitelist all open 0x856B008 4 N N N N ALLOW | |
17 | 18-sim-basic_whitelist x86 0-2 N N N N N N ALLOW | |
18 | 18-sim-basic_whitelist x86 7-172 N N N N N N ALLOW | |
19 | 18-sim-basic_whitelist x86 174-350 N N N N N N ALLOW | |
20 | 18-sim-basic_whitelist x86_64 4-14 N N N N N N ALLOW | |
21 | 18-sim-basic_whitelist x86_64 16-350 N N N N N N ALLOW | |
22 | ||
23 | test type: bpf-sim-fuzz | |
24 | ||
25 | # Testname StressCount | |
26 | 18-sim-basic_whitelist 50 | |
27 | ||
28 | test type: bpf-valgrind | |
29 | ||
30 | # Testname | |
31 | 18-sim-basic_whitelist |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <errno.h> | |
22 | #include <unistd.h> | |
23 | ||
24 | #include <seccomp.h> | |
25 | ||
26 | #include "util.h" | |
27 | ||
28 | int main(int argc, char *argv[]) | |
29 | { | |
30 | int rc; | |
31 | struct util_options opts; | |
32 | scmp_filter_ctx ctx; | |
33 | ||
34 | rc = util_getopt(argc, argv, &opts); | |
35 | if (rc < 0) | |
36 | goto out; | |
37 | ||
38 | ctx = seccomp_init(SCMP_ACT_KILL); | |
39 | if (ctx == NULL) | |
40 | goto out; | |
41 | ||
42 | if (seccomp_arch_native() != SCMP_ARCH_X86) { | |
43 | rc = seccomp_arch_add(ctx, SCMP_ARCH_X86); | |
44 | if (rc != 0) | |
45 | goto out; | |
46 | rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE); | |
47 | if (rc != 0) | |
48 | goto out; | |
49 | } | |
50 | ||
51 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(tuxcall), 0); | |
52 | if (rc != 0) | |
53 | goto out; | |
54 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(tuxcall), 0); | |
55 | if (rc != -EDOM) | |
56 | goto out; | |
57 | ||
58 | rc = util_filter_output(&opts, ctx); | |
59 | if (rc) | |
60 | goto out; | |
61 | ||
62 | out: | |
63 | seccomp_release(ctx); | |
64 | return (rc < 0 ? -rc : rc); | |
65 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | if not system_arch() == Arch.X86: | |
33 | f.add_arch(Arch.X86) | |
34 | f.remove_arch(Arch.NATIVE) | |
35 | f.add_rule(ALLOW, "tuxcall") | |
36 | try: | |
37 | f.add_rule_exactly(ALLOW, "tuxcall") | |
38 | except RuntimeError: | |
39 | pass | |
40 | return f | |
41 | ||
42 | args = util.get_opt() | |
43 | ctx = test(args) | |
44 | util.filter_output(args, ctx) | |
45 | ||
46 | # kate: syntax python; | |
47 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 19-sim-missing_syscalls +x86 0-350 N N N N N N KILL | |
11 | ||
12 | test type: bpf-sim-fuzz | |
13 | ||
14 | # Testname StressCount | |
15 | 19-sim-missing_syscalls 50 | |
16 | ||
17 | test type: bpf-valgrind | |
18 | ||
19 | # Testname | |
20 | 19-sim-missing_syscalls |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | int action; | |
31 | scmp_filter_ctx ctx; | |
32 | ||
33 | rc = util_action_parse(argv[1]); | |
34 | if (rc == -1) | |
35 | goto out; | |
36 | action = rc; | |
37 | ||
38 | if (action == SCMP_ACT_TRAP) { | |
39 | rc = util_trap_install(); | |
40 | if (rc != 0) | |
41 | goto out; | |
42 | } | |
43 | ||
44 | ctx = seccomp_init(action); | |
45 | if (ctx == NULL) | |
46 | goto out; | |
47 | rc = seccomp_rule_add_exact(ctx, | |
48 | SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); | |
49 | if (rc != 0) | |
50 | goto out; | |
51 | rc = seccomp_rule_add_exact(ctx, | |
52 | SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); | |
53 | if (rc != 0) | |
54 | goto out; | |
55 | rc = seccomp_load(ctx); | |
56 | if (rc != 0) | |
57 | goto out; | |
58 | ||
59 | rc = util_file_write("/dev/null"); | |
60 | if (rc != 0) | |
61 | goto out; | |
62 | ||
63 | rc = 160; | |
64 | ||
65 | out: | |
66 | seccomp_release(ctx); | |
67 | return (rc < 0 ? -rc : rc); | |
68 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(): | |
31 | action = util.parse_action(sys.argv[1]) | |
32 | if action == TRAP: | |
33 | util.install_trap() | |
34 | f = SyscallFilter(action) | |
35 | f.add_rule_exactly(ALLOW, "rt_sigreturn") | |
36 | f.add_rule_exactly(ALLOW, "exit_group") | |
37 | f.load() | |
38 | try: | |
39 | util.write_file("/dev/null") | |
40 | except OSError as ex: | |
41 | quit(ex.errno) | |
42 | quit(160) | |
43 | ||
44 | test() | |
45 | ||
46 | # kate: syntax python; | |
47 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com | |
5 | # | |
6 | ||
7 | test type: live | |
8 | ||
9 | # Testname Result | |
10 | 20-live-basic_die KILL | |
11 | 20-live-basic_die TRAP | |
12 | 20-live-basic_die ERRNO |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | scmp_filter_ctx ctx; | |
31 | ||
32 | rc = util_action_parse(argv[1]); | |
33 | if (rc != SCMP_ACT_ALLOW) { | |
34 | rc = 1; | |
35 | goto out; | |
36 | } | |
37 | ||
38 | rc = util_trap_install(); | |
39 | if (rc != 0) | |
40 | goto out; | |
41 | ||
42 | ctx = seccomp_init(SCMP_ACT_TRAP); | |
43 | if (ctx == NULL) | |
44 | goto out; | |
45 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0); | |
46 | if (rc != 0) | |
47 | goto out; | |
48 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0); | |
49 | if (rc != 0) | |
50 | goto out; | |
51 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); | |
52 | if (rc != 0) | |
53 | goto out; | |
54 | rc = seccomp_rule_add_exact(ctx, | |
55 | SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); | |
56 | if (rc != 0) | |
57 | goto out; | |
58 | rc = seccomp_rule_add_exact(ctx, | |
59 | SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); | |
60 | if (rc != 0) | |
61 | goto out; | |
62 | rc = seccomp_load(ctx); | |
63 | if (rc != 0) | |
64 | goto out; | |
65 | ||
66 | rc = util_file_write("/dev/null"); | |
67 | if (rc != 0) | |
68 | goto out; | |
69 | ||
70 | rc = 160; | |
71 | ||
72 | out: | |
73 | seccomp_release(ctx); | |
74 | return (rc < 0 ? -rc : rc); | |
75 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(): | |
31 | action = util.parse_action(sys.argv[1]) | |
32 | if not action == ALLOW: | |
33 | quit(1) | |
34 | util.install_trap() | |
35 | f = SyscallFilter(TRAP) | |
36 | # NOTE: additional syscalls required for python | |
37 | f.add_rule_exactly(ALLOW, "stat") | |
38 | f.add_rule_exactly(ALLOW, "fstat") | |
39 | f.add_rule_exactly(ALLOW, "open") | |
40 | f.add_rule_exactly(ALLOW, "mmap") | |
41 | f.add_rule_exactly(ALLOW, "munmap") | |
42 | f.add_rule_exactly(ALLOW, "read") | |
43 | f.add_rule_exactly(ALLOW, "write") | |
44 | f.add_rule_exactly(ALLOW, "close") | |
45 | f.add_rule_exactly(ALLOW, "rt_sigaction") | |
46 | f.add_rule_exactly(ALLOW, "rt_sigreturn") | |
47 | f.add_rule_exactly(ALLOW, "exit_group") | |
48 | f.load() | |
49 | try: | |
50 | util.write_file("/dev/null") | |
51 | except OSError as ex: | |
52 | quit(ex.errno) | |
53 | quit(160) | |
54 | ||
55 | test() | |
56 | ||
57 | # kate: syntax python; | |
58 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com | |
5 | # | |
6 | ||
7 | test type: live | |
8 | ||
9 | # Testname Result | |
10 | 21-live-basic_allow ALLOW |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Author: Paul Moore <pmoore@redhat.com>, Vitaly Shukela <vi0oss@gmail.com> | |
4 | */ | |
5 | ||
6 | /* | |
7 | * This library is free software; you can redistribute it and/or modify it | |
8 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
9 | * published by the Free Software Foundation. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
14 | * for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public License | |
17 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
18 | */ | |
19 | ||
20 | #include <unistd.h> | |
21 | ||
22 | #include <seccomp.h> | |
23 | ||
24 | #include "util.h" | |
25 | ||
26 | int main(int argc, char *argv[]) | |
27 | { | |
28 | int rc; | |
29 | struct util_options opts; | |
30 | scmp_filter_ctx ctx; | |
31 | struct scmp_arg_cmp arg_cmp; | |
32 | ||
33 | rc = util_getopt(argc, argv, &opts); | |
34 | if (rc < 0) | |
35 | goto out; | |
36 | ||
37 | ctx = seccomp_init(SCMP_ACT_KILL); | |
38 | if (ctx == NULL) | |
39 | goto out; | |
40 | ||
41 | arg_cmp = SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO); | |
42 | rc = seccomp_rule_add_exact_array(ctx, SCMP_ACT_ALLOW, | |
43 | SCMP_SYS(read), 1, &arg_cmp); | |
44 | if (rc != 0) | |
45 | goto out; | |
46 | ||
47 | arg_cmp = SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO); | |
48 | rc = seccomp_rule_add_exact_array(ctx, SCMP_ACT_ALLOW, | |
49 | SCMP_SYS(write), 1, &arg_cmp); | |
50 | if (rc != 0) | |
51 | goto out; | |
52 | ||
53 | arg_cmp = SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO); | |
54 | rc = seccomp_rule_add_exact_array(ctx, SCMP_ACT_ALLOW, | |
55 | SCMP_SYS(write), 1, &arg_cmp); | |
56 | if (rc != 0) | |
57 | goto out; | |
58 | ||
59 | rc = seccomp_rule_add_exact_array(ctx, SCMP_ACT_ALLOW, | |
60 | SCMP_SYS(close), 0, NULL); | |
61 | if (rc != 0) | |
62 | goto out; | |
63 | ||
64 | rc = seccomp_rule_add_exact_array(ctx, SCMP_ACT_ALLOW, | |
65 | SCMP_SYS(rt_sigreturn), 0, NULL); | |
66 | if (rc != 0) | |
67 | goto out; | |
68 | ||
69 | rc = util_filter_output(&opts, ctx); | |
70 | if (rc) | |
71 | goto out; | |
72 | ||
73 | out: | |
74 | seccomp_release(ctx); | |
75 | return (rc < 0 ? -rc : rc); | |
76 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | # NOTE: this is identical to 03-sim-basic_chains.py but is here to satisfy the | |
24 | # need for an equivalent Python test for each native C test | |
25 | ||
26 | import argparse | |
27 | import sys | |
28 | ||
29 | import util | |
30 | ||
31 | from seccomp import * | |
32 | ||
33 | def test(args): | |
34 | f = SyscallFilter(KILL) | |
35 | f.add_rule_exactly(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno())); | |
36 | f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno())); | |
37 | f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno())); | |
38 | f.add_rule_exactly(ALLOW, "close"); | |
39 | f.add_rule_exactly(ALLOW, "rt_sigreturn"); | |
40 | return f | |
41 | ||
42 | args = util.get_opt() | |
43 | ctx = test(args) | |
44 | util.filter_output(args, ctx) | |
45 | ||
46 | # kate: syntax python; | |
47 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Author: Vitaly Shukela <vi0oss@gmail.com> | |
4 | # | |
5 | ||
6 | test type: bpf-sim | |
7 | ||
8 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
9 | 22-sim-basic_chains_array all read 0 0x856B008 10 N N N ALLOW | |
10 | 22-sim-basic_chains_array all read 1-10 0x856B008 10 N N N KILL | |
11 | 22-sim-basic_chains_array all write 1-2 0x856B008 10 N N N ALLOW | |
12 | 22-sim-basic_chains_array all write 3-10 0x856B008 10 N N N KILL | |
13 | 22-sim-basic_chains_array all close N N N N N N ALLOW | |
14 | 22-sim-basic_chains_array all rt_sigreturn N N N N N N ALLOW | |
15 | 22-sim-basic_chains_array all open 0x856B008 4 N N N N KILL | |
16 | 22-sim-basic_chains_array x86 0-2 N N N N N N KILL | |
17 | 22-sim-basic_chains_array x86 7-172 N N N N N N KILL | |
18 | 22-sim-basic_chains_array x86 174-350 N N N N N N KILL | |
19 | 22-sim-basic_chains_array x86_64 4-14 N N N N N N KILL | |
20 | 22-sim-basic_chains_array x86_64 16-350 N N N N N N KILL | |
21 | ||
22 | test type: bpf-sim-fuzz | |
23 | ||
24 | # Testname StressCount | |
25 | 22-sim-basic_chains_array 50 | |
26 | ||
27 | test type: bpf-valgrind | |
28 | ||
29 | # Testname | |
30 | 22-sim-basic_chains_array |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <unistd.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | struct util_options opts; | |
31 | scmp_filter_ctx ctx; | |
32 | ||
33 | rc = util_getopt(argc, argv, &opts); | |
34 | if (rc < 0) | |
35 | goto out; | |
36 | ||
37 | ctx = seccomp_init(SCMP_ACT_KILL); | |
38 | if (ctx == NULL) | |
39 | goto out; | |
40 | ||
41 | if (seccomp_arch_exist(ctx, SCMP_ARCH_X86)) { | |
42 | rc = seccomp_arch_add(ctx, SCMP_ARCH_X86); | |
43 | if (rc != 0) | |
44 | goto out; | |
45 | } | |
46 | if (seccomp_arch_exist(ctx, SCMP_ARCH_X86_64)) { | |
47 | rc = seccomp_arch_add(ctx, SCMP_ARCH_X86_64); | |
48 | if (rc != 0) | |
49 | goto out; | |
50 | } | |
51 | if (seccomp_arch_exist(ctx, SCMP_ARCH_X32)) { | |
52 | rc = seccomp_arch_add(ctx, SCMP_ARCH_X32); | |
53 | if (rc != 0) | |
54 | goto out; | |
55 | } | |
56 | if (seccomp_arch_exist(ctx, SCMP_ARCH_ARM)) { | |
57 | rc = seccomp_arch_add(ctx, SCMP_ARCH_ARM); | |
58 | if (rc != 0) | |
59 | goto out; | |
60 | } | |
61 | ||
62 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, | |
63 | SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO)); | |
64 | if (rc != 0) | |
65 | goto out; | |
66 | ||
67 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, | |
68 | SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)); | |
69 | if (rc != 0) | |
70 | goto out; | |
71 | ||
72 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, | |
73 | SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO)); | |
74 | if (rc != 0) | |
75 | goto out; | |
76 | ||
77 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); | |
78 | if (rc != 0) | |
79 | goto out; | |
80 | ||
81 | rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); | |
82 | if (rc != 0) | |
83 | goto out; | |
84 | ||
85 | rc = util_filter_output(&opts, ctx); | |
86 | if (rc) | |
87 | goto out; | |
88 | ||
89 | out: | |
90 | seccomp_release(ctx); | |
91 | return (rc < 0 ? -rc : rc); | |
92 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | if not f.exist_arch(Arch.X86): | |
33 | f.add_arch(Arch.X86) | |
34 | if not f.exist_arch(Arch.X86_64): | |
35 | f.add_arch(Arch.X86_64) | |
36 | if not f.exist_arch(Arch.X32): | |
37 | f.add_arch(Arch.X32) | |
38 | if not f.exist_arch(Arch.ARM): | |
39 | f.add_arch(Arch.ARM) | |
40 | f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno())) | |
41 | f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno())) | |
42 | f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno())) | |
43 | f.add_rule(ALLOW, "close") | |
44 | f.add_rule(ALLOW, "rt_sigreturn") | |
45 | return f | |
46 | ||
47 | args = util.get_opt() | |
48 | ctx = test(args) | |
49 | util.filter_output(args, ctx) | |
50 | ||
51 | # kate: syntax python; | |
52 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # | |
4 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
5 | # Author: Paul Moore <pmoore@redhat.com | |
6 | # | |
7 | ||
8 | test type: bpf-sim | |
9 | ||
10 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
11 | 23-sim-arch_all_basic +all read 0 0x856B008 10 N N N ALLOW | |
12 | 23-sim-arch_all_basic +all read 1-10 0x856B008 10 N N N KILL | |
13 | 23-sim-arch_all_basic +all write 1-2 0x856B008 10 N N N ALLOW | |
14 | 23-sim-arch_all_basic +all write 3-10 0x856B008 10 N N N KILL | |
15 | 23-sim-arch_all_basic +all close N N N N N N ALLOW | |
16 | 23-sim-arch_all_basic +all rt_sigreturn N N N N N N ALLOW | |
17 | 23-sim-arch_all_basic +all open 0x856B008 4 N N N N KILL | |
18 | ||
19 | test type: bpf-sim-fuzz | |
20 | ||
21 | # Testname StressCount | |
22 | 23-sim-arch_all_basic 50 | |
23 | ||
24 | test type: bpf-valgrind | |
25 | ||
26 | # Testname | |
27 | 23-sim-arch_all_basic |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <errno.h> | |
22 | #include <fcntl.h> | |
23 | #include <string.h> | |
24 | #include <unistd.h> | |
25 | #include <sys/types.h> | |
26 | #include <sys/stat.h> | |
27 | ||
28 | #include <seccomp.h> | |
29 | ||
30 | #include "util.h" | |
31 | ||
32 | int main(int argc, char *argv[]) | |
33 | { | |
34 | int rc; | |
35 | int fd; | |
36 | scmp_filter_ctx ctx; | |
37 | const char buf[] = "testing"; | |
38 | ssize_t buf_len = strlen(buf); | |
39 | ||
40 | rc = util_action_parse(argv[1]); | |
41 | if (rc != SCMP_ACT_ALLOW) { | |
42 | rc = 1; | |
43 | goto out; | |
44 | } | |
45 | ||
46 | rc = util_trap_install(); | |
47 | if (rc != 0) | |
48 | goto out; | |
49 | ||
50 | fd = open("/dev/null", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); | |
51 | if (fd < 0) { | |
52 | rc = errno; | |
53 | goto out; | |
54 | } | |
55 | ||
56 | ctx = seccomp_init(SCMP_ACT_TRAP); | |
57 | if (ctx == NULL) | |
58 | goto out; | |
59 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, | |
60 | SCMP_A0(SCMP_CMP_EQ, fd)); | |
61 | if (rc != 0) | |
62 | goto out; | |
63 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); | |
64 | if (rc != 0) | |
65 | goto out; | |
66 | rc = seccomp_rule_add_exact(ctx, | |
67 | SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); | |
68 | if (rc != 0) | |
69 | goto out; | |
70 | rc = seccomp_rule_add_exact(ctx, | |
71 | SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); | |
72 | if (rc != 0) | |
73 | goto out; | |
74 | rc = seccomp_load(ctx); | |
75 | if (rc != 0) | |
76 | goto out; | |
77 | ||
78 | if (write(fd, buf, buf_len) < buf_len) { | |
79 | rc = errno; | |
80 | goto out; | |
81 | } | |
82 | if (close(fd) < 0) { | |
83 | rc = errno; | |
84 | goto out; | |
85 | } | |
86 | ||
87 | rc = 160; | |
88 | ||
89 | out: | |
90 | seccomp_release(ctx); | |
91 | return (rc < 0 ? -rc : rc); | |
92 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import os | |
25 | import sys | |
26 | ||
27 | import util | |
28 | ||
29 | from seccomp import * | |
30 | ||
31 | def test(): | |
32 | action = util.parse_action(sys.argv[1]) | |
33 | if not action == ALLOW: | |
34 | quit(1) | |
35 | util.install_trap() | |
36 | ||
37 | fd = os.open("/dev/null", os.O_WRONLY|os.O_CREAT, 0600) | |
38 | ||
39 | f = SyscallFilter(TRAP) | |
40 | # NOTE: additional syscalls required for python | |
41 | f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, fd)) | |
42 | f.add_rule_exactly(ALLOW, "close") | |
43 | f.add_rule_exactly(ALLOW, "rt_sigaction") | |
44 | f.add_rule_exactly(ALLOW, "rt_sigreturn") | |
45 | f.add_rule_exactly(ALLOW, "exit_group") | |
46 | f.load() | |
47 | ||
48 | try: | |
49 | if not os.write(fd, "testing") == len("testing"): | |
50 | raise IOError("failed to write the full test string") | |
51 | quit(160) | |
52 | except OSError as ex: | |
53 | quit(ex.errno) | |
54 | os.close(fd) | |
55 | ||
56 | test() | |
57 | ||
58 | # kate: syntax python; | |
59 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com | |
5 | # | |
6 | ||
7 | test type: live | |
8 | ||
9 | # Testname Result | |
10 | 24-live-arg_allow ALLOW |
0 | /** | |
1 | * Seccomp Library test program | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <stdlib.h> | |
22 | ||
23 | #include <seccomp.h> | |
24 | ||
25 | #include "util.h" | |
26 | ||
27 | int main(int argc, char *argv[]) | |
28 | { | |
29 | int rc; | |
30 | struct util_options opts; | |
31 | scmp_filter_ctx ctx; | |
32 | ||
33 | rc = util_getopt(argc, argv, &opts); | |
34 | if (rc < 0) | |
35 | goto out; | |
36 | ||
37 | ctx = seccomp_init(SCMP_ACT_KILL); | |
38 | if (ctx == NULL) | |
39 | goto out; | |
40 | ||
41 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 10, 2, | |
42 | SCMP_A0(SCMP_CMP_EQ, 11), | |
43 | SCMP_A1(SCMP_CMP_NE, 12)); | |
44 | if (rc != 0) | |
45 | goto out; | |
46 | ||
47 | rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 20, 3, | |
48 | SCMP_A0(SCMP_CMP_EQ, 21), | |
49 | SCMP_A1(SCMP_CMP_NE, 22), | |
50 | SCMP_A2(SCMP_CMP_EQ, 23)); | |
51 | if (rc != 0) | |
52 | goto out; | |
53 | ||
54 | rc = util_filter_output(&opts, ctx); | |
55 | if (rc) | |
56 | goto out; | |
57 | ||
58 | out: | |
59 | seccomp_release(ctx); | |
60 | return (rc < 0 ? -rc : rc); | |
61 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | # | |
3 | # Seccomp Library test program | |
4 | # | |
5 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | import argparse | |
24 | import sys | |
25 | ||
26 | import util | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def test(args): | |
31 | f = SyscallFilter(KILL) | |
32 | f.add_rule_exactly(ALLOW, 10, | |
33 | Arg(0, EQ, 11), | |
34 | Arg(1, NE, 12)); | |
35 | f.add_rule_exactly(ALLOW, 20, | |
36 | Arg(0, EQ, 21), | |
37 | Arg(1, NE, 22), | |
38 | Arg(2, EQ, 23)); | |
39 | return f | |
40 | ||
41 | args = util.get_opt() | |
42 | ctx = test(args) | |
43 | util.filter_output(args, ctx) | |
44 | ||
45 | # kate: syntax python; | |
46 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # libseccomp regression test automation data | |
2 | # | |
3 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com | |
5 | # | |
6 | ||
7 | test type: bpf-sim | |
8 | ||
9 | # Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result | |
10 | 25-sim-multilevel_chains_adv all 0-9 N N N N N N KILL | |
11 | 25-sim-multilevel_chains_adv all 10 0x0000000b 0x00000000 N N N N ALLOW | |
12 | 25-sim-multilevel_chains_adv x86_64 10 0x10000000b 0x00000000 N N N N KILL | |
13 | 25-sim-multilevel_chains_adv x86_64 10 0x0000000b 0x10000000c N N N N ALLOW | |
14 | 25-sim-multilevel_chains_adv all 11-19 N N N N N N KILL | |
15 | 25-sim-multilevel_chains_adv all 20 0x00000015 0x00000000 0x00000017 N N N ALLOW | |
16 | 25-sim-multilevel_chains_adv all 20 0x00000015 0x00000016 0x00000017 N N N KILL | |
17 | 25-sim-multilevel_chains_adv x86_64 20 0x100000015 0x00000000 0x00000017 N N N KILL | |
18 | 25-sim-multilevel_chains_adv x86_64 20 0x00000015 0x00000000 0x100000017 N N N KILL | |
19 | 25-sim-multilevel_chains_adv all 21-30 N N N N N N KILL | |
20 | ||
21 | test type: bpf-sim-fuzz | |
22 | ||
23 | # Testname StressCount | |
24 | 25-sim-multilevel_chains_adv 50 | |
25 | ||
26 | test type: bpf-valgrind | |
27 | ||
28 | # Testname | |
29 | 25-sim-multilevel_chains_adv |
0 | # | |
1 | # Enhanced Seccomp Library Makefile | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | # | |
22 | # macros | |
23 | # | |
24 | ||
25 | include ../macros.mk | |
26 | ||
27 | # | |
28 | # configuration | |
29 | # | |
30 | ||
31 | include $(TOPDIR)/version_info.mk | |
32 | include $(TOPDIR)/configure.mk | |
33 | ||
34 | OBJS = util.o | |
35 | ||
36 | LDFLAGS := ../src/libseccomp.a $(OBJS) | |
37 | ||
38 | TEST_PRIVATE = 00-test | |
39 | ||
40 | TESTS = 01-sim-allow \ | |
41 | 02-sim-basic \ | |
42 | 03-sim-basic_chains \ | |
43 | 04-sim-multilevel_chains \ | |
44 | 05-sim-long_jumps \ | |
45 | 06-sim-actions \ | |
46 | 07-sim-db_bug_looping \ | |
47 | 08-sim-subtree_checks \ | |
48 | 09-sim-syscall_priority_pre \ | |
49 | 10-sim-syscall_priority_post \ | |
50 | 11-basic-basic_errors \ | |
51 | 12-sim-basic_masked_ops \ | |
52 | 13-basic-attrs \ | |
53 | 14-sim-reset \ | |
54 | 15-basic-resolver \ | |
55 | 16-sim-arch_basic \ | |
56 | 17-sim-arch_merge \ | |
57 | 18-sim-basic_whitelist \ | |
58 | 19-sim-missing_syscalls \ | |
59 | 20-live-basic_die \ | |
60 | 21-live-basic_allow \ | |
61 | 22-sim-basic_chains_array \ | |
62 | 23-sim-arch_all_basic \ | |
63 | 24-live-arg_allow \ | |
64 | 25-sim-multilevel_chains_adv | |
65 | ||
66 | DEPS_OBJS = $(OBJS:%.o=%.d) | |
67 | DEPS_TESTS = $(TESTS:%=%.d) | |
68 | ||
69 | # | |
70 | # targets | |
71 | # | |
72 | ||
73 | .PHONY: check clean | |
74 | ||
75 | all: $(TESTS) $(OBJS) | |
76 | ||
77 | -include $(DEPS_TESTS) $(DEPS_OBJS) | |
78 | ||
79 | $(DEPS_TESTS): | |
80 | $(MAKEDEP_EXEC) | |
81 | $(ADDDEP) $@ ../src/libseccomp.a | |
82 | $(ADDDEP) $@ $(OBJS) | |
83 | ||
84 | $(TESTS): | |
85 | $(COMPILE_EXEC) | |
86 | ||
87 | $(TEST_PRIVATE): 00-test.c $(OBJS) ../src/libseccomp.a | |
88 | $(COMPILE_EXEC) | |
89 | ||
90 | check: $(TESTS) | |
91 | ./regression | |
92 | ||
93 | clean: | |
94 | $(RM) $(DEPS_TESTS) $(DEPS_OBJS) $(TESTS) $(TEST_PRIVATE) $(OBJS) *.pyc |
0 | #!/bin/bash | |
1 | ||
2 | # | |
3 | # libseccomp regression test automation script | |
4 | # | |
5 | # Copyright IBM Corp. 2012 | |
6 | # Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | GLBL_ARCH_SUPPORT="x86 x86_64 x32 arm" | |
24 | ||
25 | GLBL_SYS_ARCH="../tools/scmp_arch_detect" | |
26 | GLBL_SYS_RESOLVER="../tools/scmp_sys_resolver" | |
27 | GLBL_SYS_SIM="../tools/scmp_bpf_sim" | |
28 | ||
29 | #### | |
30 | # functions | |
31 | ||
32 | # | |
33 | # Dependency check | |
34 | # | |
35 | # Arguments: | |
36 | # 1 Dependency to check for | |
37 | # | |
38 | function check_deps() { | |
39 | [[ -z "$1" ]] && return | |
40 | which "$1" >& /dev/null | |
41 | return $? | |
42 | } | |
43 | ||
44 | # | |
45 | # Dependency verification | |
46 | # | |
47 | # Arguments: | |
48 | # 1 Dependency to check for | |
49 | # | |
50 | function verify_deps() { | |
51 | [[ -z "$1" ]] && return | |
52 | if ! check_deps "$1"; then | |
53 | echo "error: install \"$1\" and include it in your \$PATH" | |
54 | exit 1 | |
55 | fi | |
56 | } | |
57 | ||
58 | # | |
59 | # Print out script usage details | |
60 | # | |
61 | function usage() { | |
62 | cat << EOF | |
63 | usage: regression [-h] [-v] [-m MODE] [-a] [-b BATCH_NAME] [-l <LOG>] | |
64 | [-s SINGLE_TEST] [-t <TEMP_DIR>] [-T <TEST_TYPE>] | |
65 | ||
66 | libseccomp regression test automation script | |
67 | optional arguments: | |
68 | -h show this help message and exit | |
69 | -m MODE specified the test mode [c (default), python] | |
70 | -a specifies all tests are to be run | |
71 | -b BATCH_NAME specifies batch of tests to be run | |
72 | -l [LOG] specifies log file to write test results to | |
73 | -s SINGLE_TEST specifies individual test number to be run | |
74 | -t [TEMP_DIR] specifies directory to create temporary files in | |
75 | -T [TEST_TYPE] only run tests matching the specified type | |
76 | -v specifies that verbose output be provided | |
77 | EOF | |
78 | } | |
79 | ||
80 | # | |
81 | # Generate a string representing the test number | |
82 | # | |
83 | # Arguments: | |
84 | # 1 string containing the batch name | |
85 | # 2 value of the test number from the input test data file | |
86 | # 3 value of the subtest number that corresponds to argument 1 | |
87 | # | |
88 | # The actual test number from the input test data file is 1 for the first | |
89 | # test found in the file, 2 for the second, etc. | |
90 | # | |
91 | # The subtest number is useful for batches that generate multiple tests based | |
92 | # on a single line of input from the test data file. The subtest number | |
93 | # should be set to zero if the corresponding test data is actual test data | |
94 | # that was read from the input file, and should be set to a value greater than | |
95 | # zero if the corresponding test data is generated. | |
96 | # | |
97 | function generate_test_num() { | |
98 | local testnumstr=$(printf '%s%%%%%03d-%05d' "$1" $2 $3) | |
99 | echo "$testnumstr" | |
100 | } | |
101 | ||
102 | # | |
103 | # Print the test data to the log file | |
104 | # | |
105 | # Arguments: | |
106 | # 1 string containing generated test number | |
107 | # 2 string containing line of test data | |
108 | # | |
109 | function print_data() { | |
110 | if [[ -n $verbose ]]; then | |
111 | printf "Test %s data: %s\n" "$1" "$2" >&$logfd | |
112 | fi | |
113 | } | |
114 | ||
115 | # | |
116 | # Print the test result to the log file | |
117 | # | |
118 | # Arguments: | |
119 | # 1 string containing generated test number | |
120 | # 2 string containing the test result (INFO, SUCCESS, ERROR, or FAILURE) | |
121 | # 3 string containing addition details | |
122 | # | |
123 | function print_result() { | |
124 | if [[ $2 == "INFO" && -z $verbose ]]; then | |
125 | return | |
126 | fi | |
127 | if [[ $3 == "" ]]; then | |
128 | printf "Test %s result: %s\n" "$1" "$2" >&$logfd | |
129 | else | |
130 | printf "Test %s result: %s %s\n" "$1" "$2" "$3" >&$logfd | |
131 | fi | |
132 | } | |
133 | ||
134 | # | |
135 | # Print the valgrind header to the log file | |
136 | # | |
137 | # Arguments: | |
138 | # 1 string containing generated test number | |
139 | # | |
140 | function print_valgrind() { | |
141 | if [[ -n $verbose ]]; then | |
142 | printf "Test %s valgrind output\n" "$1" >&$logfd | |
143 | fi | |
144 | } | |
145 | ||
146 | # | |
147 | # Get the low or high range value from a range specification | |
148 | # | |
149 | # Arguments: | |
150 | # 1 value specifying range value to retrieve: low (1) or high (2) | |
151 | # 2 string containing dash-separated range or a single value | |
152 | # | |
153 | function get_range() { | |
154 | if [[ $2 =~ ^[0-9a-fA-Fx]+-[0-9a-fA-Fx]+$ ]]; then | |
155 | # if there's a dash, get the low or high range value | |
156 | range_val=$(echo "$2" | cut -d'-' -f "$1") | |
157 | else | |
158 | # otherwise there should just be a single value | |
159 | range_val="$2" | |
160 | fi | |
161 | echo "$range_val" | |
162 | } | |
163 | ||
164 | # | |
165 | # Run the specified test command (with valgrind if requested) | |
166 | # | |
167 | # Arguments: | |
168 | # 1 string containing generated test number | |
169 | # 2 string containing command name | |
170 | # 3 string containing command options | |
171 | # 4 number for the stdout fd | |
172 | # 5 number for the stderr fd | |
173 | # | |
174 | function run_test_command() { | |
175 | local cmd | |
176 | ||
177 | if [[ $mode == "python" ]]; then | |
178 | cmd="PYTHONPATH=$PYTHONPATH" | |
179 | cmd="$cmd:$(cd $(pwd)/../src/python/build/lib.*; pwd)" | |
180 | cmd="$cmd /usr/bin/env python $2.py $3" | |
181 | else | |
182 | cmd="$2 $3" | |
183 | fi | |
184 | ||
185 | # setup the stdout/stderr redirects | |
186 | local stdout=$4 | |
187 | local stderr=$5 | |
188 | [[ -z $stdout ]] && stdout=$logfd | |
189 | [[ -z $stderr ]] && stderr=$logfd | |
190 | ||
191 | # run the command | |
192 | eval "$cmd" 1>&$stdout 2>&$stderr | |
193 | ||
194 | # return the command's return code | |
195 | return $? | |
196 | } | |
197 | ||
198 | # | |
199 | # Generate pseudo-random string of alphanumeric characters | |
200 | # | |
201 | # The generated string will be no larger than the corresponding | |
202 | # architecture's register size. | |
203 | # | |
204 | function generate_random_data() { | |
205 | local rcount | |
206 | local rdata | |
207 | if [[ $arch == "x86_64" ]]; then | |
208 | rcount=$[ ($RANDOM % 16) + 1 ] | |
209 | else | |
210 | rcount=$[ ($RANDOM % 8) + 1 ] | |
211 | fi | |
212 | rdata=$(echo $(</dev/urandom tr -dc A-Za-z0-9 | head -c"$rcount")) | |
213 | echo "$rdata" | |
214 | } | |
215 | ||
216 | # | |
217 | # Run the specified "bpf-sim-fuzz" test | |
218 | # | |
219 | # Tests that belong to the "bpf-sim-fuzz" test type generate a BPF filter and | |
220 | # then run a simulated system call test with pseudo-random fuzz data for the | |
221 | # syscall and argument values. Tests that belong to this test type provide the | |
222 | # following data on a single line in the input batch file: | |
223 | # | |
224 | # Testname - The executable test name (e.g. 01-allow, 02-basic, etc.) | |
225 | # StressCount - The number of fuzz tests to run against the filter | |
226 | # | |
227 | # The following test data is output to the logfile for each generated test: | |
228 | # | |
229 | # Testname - The executable test name (e.g. 01-allow, 02-basic, etc.) | |
230 | # Syscall - The fuzzed syscall value to be simulated against the filter | |
231 | # Arg0-5 - The fuzzed syscall arg values to be simulated against the filter | |
232 | # | |
233 | # Arguments: | |
234 | # 1 string containing the batch name | |
235 | # 2 value of test number from batch file | |
236 | # 3 string containing line of test data from batch file | |
237 | # | |
238 | function run_test_bpf_sim_fuzz() { | |
239 | local rc | |
240 | ||
241 | # begin splitting the test data from the line into individual variables | |
242 | local line=($3) | |
243 | local testname=${line[0]} | |
244 | local stress_count=${line[1]} | |
245 | ||
246 | for i in $(seq 1 $stress_count); do | |
247 | local sys=$(generate_random_data) | |
248 | local -a arg=($(generate_random_data) $(generate_random_data) \ | |
249 | $(generate_random_data) $(generate_random_data) \ | |
250 | $(generate_random_data) $(generate_random_data)) | |
251 | ||
252 | # get the generated sub-test num string | |
253 | local testnumstr=$(generate_test_num "$1" $2 $i) | |
254 | ||
255 | # set up log file test data line for this individual test, | |
256 | # spacing is added to align the output in the correct columns | |
257 | local -a COL_WIDTH=(26 17 17 17 17 17 17) | |
258 | local testdata=$(printf "%-${COL_WIDTH[0]}s" $testname) | |
259 | testdata+=$(printf "%-${COL_WIDTH[1]}s" $sys) | |
260 | testdata+=$(printf "%-${COL_WIDTH[2]}s" ${arg[0]}) | |
261 | testdata+=$(printf "%-${COL_WIDTH[3]}s" ${arg[1]}) | |
262 | testdata+=$(printf "%-${COL_WIDTH[4]}s" ${arg[2]}) | |
263 | testdata+=$(printf "%-${COL_WIDTH[5]}s" ${arg[3]}) | |
264 | testdata+=$(printf "%-${COL_WIDTH[6]}s" ${arg[4]}) | |
265 | testdata+=$(printf "%s" ${arg[5]}) | |
266 | ||
267 | # print out the generated test data to the log file | |
268 | print_data "$testnumstr" "$testdata" | |
269 | ||
270 | # set up the syscall argument values to be passed to bpf_sim | |
271 | for i in {0..5}; do | |
272 | arg[$i]=" -$i ${arg[$i]} " | |
273 | done | |
274 | ||
275 | # run the test command and put the BPF filter in a temp file | |
276 | exec 4>$tmpfile | |
277 | run_test_command "$testnumstr" "./$testname" "-b" 4 "" | |
278 | rc=$? | |
279 | exec 4>&- | |
280 | if [[ $rc -ne 0 ]]; then | |
281 | print_result $testnumstr "ERROR" "$testname rc=$rc" | |
282 | stats_error=$(($stats_error+1)) | |
283 | return | |
284 | fi | |
285 | ||
286 | # simulate the fuzzed syscall data against the BPF filter, we | |
287 | # don't verify the resulting action since we're just testing for | |
288 | # stability | |
289 | allow=$($GLBL_SYS_SIM -f $tmpfile -s $sys \ | |
290 | ${arg[0]} ${arg[1]} ${arg[2]} ${arg[3]} ${arg[4]} \ | |
291 | ${arg[5]}) | |
292 | rc=$? | |
293 | if [[ $rc -ne 0 ]]; then | |
294 | print_result $testnumstr "ERROR" "bpf_sim rc=$rc" | |
295 | stats_error=$(($stats_error+1)) | |
296 | else | |
297 | print_result $testnumstr "SUCCESS" "" | |
298 | stats_success=$(($stats_success+1)) | |
299 | fi | |
300 | stats_all=$(($stats_all+1)) | |
301 | done | |
302 | } | |
303 | ||
304 | # | |
305 | # Run the specified "bpf-sim" test | |
306 | # | |
307 | # Tests that belong to the "bpf-sim" test type generate a BPF filter and then | |
308 | # run a simulated system call test to validate the filter. Tests that belong to | |
309 | # this test type provide the following data on a single line in the input batch | |
310 | # file: | |
311 | # | |
312 | # Testname - The executable test name (e.g. 01-allow, 02-basic, etc.) | |
313 | # Arch - The architecture that the test should be run on (all, x86, x86_64) | |
314 | # Syscall - The syscall to simulate against the generated filter | |
315 | # Arg0-5 - The syscall arguments to simulate against the generated filter | |
316 | # Result - The expected simulation result (ALLOW, KILL, etc.) | |
317 | # | |
318 | # If a range of syscall or argument values are specified (e.g. 1-9), a test is | |
319 | # generated for every combination of range values. Otherwise, the individual | |
320 | # test is run. | |
321 | # | |
322 | # Arguments: | |
323 | # 1 string containing the batch name | |
324 | # 2 value of test number from batch file | |
325 | # 3 string containing line of test data from batch file | |
326 | # | |
327 | function run_test_bpf_sim() { | |
328 | local rc | |
329 | local LOW=1 | |
330 | local HIGH=2 | |
331 | local -a arg_empty=(false false false false false false) | |
332 | ||
333 | # begin splitting the test data from the line into individual variables | |
334 | local line=($3) | |
335 | local testname=${line[0]} | |
336 | local testarch=${line[1]} | |
337 | local low_syscall #line[2] | |
338 | local high_syscall #line[2] | |
339 | local -a low_arg #line[3-8] | |
340 | local -a high_arg #line[3-8] | |
341 | local result=${line[9]} | |
342 | ||
343 | if [[ "${testarch:0:1}" == "+" ]]; then | |
344 | # run the tests on the specified architecture(s) | |
345 | simarch_list="${testarch:1}" | |
346 | if [[ "$simarch_list" == "all" ]]; then | |
347 | simarch_list="$GLBL_ARCH_SUPPORT" | |
348 | fi | |
349 | elif [[ "$testarch" != "all" ]] && [[ "$testarch" != "$arch" ]]; then | |
350 | # only run tests that match the current architecture | |
351 | print_result $(generate_test_num "$1" $2 1) "INFO" \ | |
352 | "Test skipped due to test/system architecture difference" | |
353 | stats_skipped=$(($stats_skipped+1)) | |
354 | return | |
355 | else | |
356 | # run the tests on the native architecture | |
357 | simarch_list="$arch" | |
358 | fi | |
359 | ||
360 | # get low and high range arg values | |
361 | line_i=3 | |
362 | for arg_i in {0..5}; do | |
363 | low_arg[$arg_i]=$(get_range $LOW "${line[$line_i]}") | |
364 | high_arg[$arg_i]=$(get_range $HIGH "${line[$line_i]}") | |
365 | ||
366 | # fix up empty arg values so the nested loops work | |
367 | if [[ ${low_arg[$arg_i]} == "N" ]]; then | |
368 | arg_empty[$arg_i]=true | |
369 | low_arg[$arg_i]=0 | |
370 | high_arg[$arg_i]=0 | |
371 | fi | |
372 | ||
373 | line_i=$(($line_i+1)) | |
374 | done | |
375 | ||
376 | # loop through the selected architectures | |
377 | for simarch in $simarch_list; do | |
378 | # print architecture header if necessary | |
379 | if [[ $simarch != $simarch_list ]]; then | |
380 | echo " test arch: $simarch" >&$logfd | |
381 | fi | |
382 | ||
383 | # reset the subtest number | |
384 | local subtestnum=1 | |
385 | ||
386 | # get low and high syscall values and convert them to numbers | |
387 | low_syscall=$(get_range $LOW "${line[2]}") | |
388 | if [[ ! $low_syscall =~ ^[0-9]+$ ]]; then | |
389 | low_syscall=$($GLBL_SYS_RESOLVER -a $simarch -t \ | |
390 | $low_syscall) | |
391 | if [[ $? -ne 0 ]]; then | |
392 | print_result $(generate_test_num "$1" $2 1) \ | |
393 | "ERROR" "sys_resolver rc=$?" | |
394 | stats_error=$(($stats_error+1)) | |
395 | return | |
396 | fi | |
397 | fi | |
398 | high_syscall=$(get_range $HIGH "${line[2]}") | |
399 | if [[ ! $high_syscall =~ ^[0-9]+$ ]]; then | |
400 | high_syscall=$($GLBL_SYS_RESOLVER -a $simarch -t \ | |
401 | $high_syscall) | |
402 | if [[ $? -ne 0 ]]; then | |
403 | print_result $(generate_test_num "$1" $2 1) \ | |
404 | "ERROR" "sys_resolver rc=$?" | |
405 | stats_error=$(($stats_error+1)) | |
406 | return | |
407 | fi | |
408 | fi | |
409 | ||
410 | # if ranges exist, the following will loop through all syscall | |
411 | # and arg ranges and generate/run every combination of requested | |
412 | # tests; if no ranges were specifed, then the single test is | |
413 | # run | |
414 | for sys in $(seq -f "%1.0f" $low_syscall $high_syscall); do | |
415 | for arg0 in $(seq -f "%1.0f" ${low_arg[0]} ${high_arg[0]}); do | |
416 | for arg1 in $(seq -f "%1.0f" ${low_arg[1]} ${high_arg[1]}); do | |
417 | for arg2 in $(seq -f "%1.0f" ${low_arg[2]} ${high_arg[2]}); do | |
418 | for arg3 in $(seq -f "%1.0f" ${low_arg[3]} ${high_arg[3]}); do | |
419 | for arg4 in $(seq -f "%1.0f" ${low_arg[4]} ${high_arg[4]}); do | |
420 | for arg5 in $(seq -f "%1.0f" ${low_arg[5]} ${high_arg[5]}); do | |
421 | local -a arg=($arg0 $arg1 $arg2 $arg3 $arg4 $arg5) | |
422 | ||
423 | # Get the generated sub-test num string | |
424 | local testnumstr=$(generate_test_num "$1" $2 \ | |
425 | $subtestnum) | |
426 | ||
427 | # format any empty args to print to log file | |
428 | for i in {0..5}; do | |
429 | if ${arg_empty[$i]}; then | |
430 | arg[$i]="N" | |
431 | fi | |
432 | done | |
433 | ||
434 | # set up log file test data line for this | |
435 | # individual test, spacing is added to align | |
436 | # the output in the correct columns | |
437 | local -a COL_WIDTH=(26 08 14 11 17 21 09 06 06) | |
438 | local testdata=$(printf "%-${COL_WIDTH[0]}s" $testname) | |
439 | testdata+=$(printf "%-${COL_WIDTH[1]}s" $simarch) | |
440 | testdata+=$(printf "%-${COL_WIDTH[2]}s" $sys) | |
441 | testdata+=$(printf "%-${COL_WIDTH[3]}s" ${arg[0]}) | |
442 | testdata+=$(printf "%-${COL_WIDTH[4]}s" ${arg[1]}) | |
443 | testdata+=$(printf "%-${COL_WIDTH[5]}s" ${arg[2]}) | |
444 | testdata+=$(printf "%-${COL_WIDTH[6]}s" ${arg[3]}) | |
445 | testdata+=$(printf "%-${COL_WIDTH[7]}s" ${arg[4]}) | |
446 | testdata+=$(printf "%-${COL_WIDTH[8]}s" ${arg[5]}) | |
447 | testdata+=$(printf "%-${COL_WIDTH[9]}s" $result) | |
448 | ||
449 | # print out the test data to the log file | |
450 | print_data "$testnumstr" "$testdata" | |
451 | ||
452 | # set up the syscall arguments to be passed to bpf_sim | |
453 | for i in {0..5}; do | |
454 | if ${arg_empty[$i]}; then | |
455 | arg[$i]="" | |
456 | else | |
457 | arg[$i]=" -$i ${arg[$i]} " | |
458 | fi | |
459 | done | |
460 | ||
461 | # run the test command and put the BPF in a temp file | |
462 | exec 4>$tmpfile | |
463 | run_test_command "$testnumstr" "./$testname" "-b" 4 "" | |
464 | rc=$? | |
465 | exec 4>&- | |
466 | if [[ $rc -ne 0 ]]; then | |
467 | print_result $testnumstr \ | |
468 | "ERROR" "$testname rc=$rc" | |
469 | stats_error=$(($stats_error+1)) | |
470 | return | |
471 | fi | |
472 | ||
473 | # simulate the specifed syscall against the BPF filter | |
474 | # and verify the results | |
475 | action=$($GLBL_SYS_SIM -a $simarch -f $tmpfile \ | |
476 | -s $sys ${arg[0]} ${arg[1]} ${arg[2]} \ | |
477 | ${arg[3]} ${arg[4]} ${arg[5]}) | |
478 | rc=$? | |
479 | if [[ $rc -ne 0 ]]; then | |
480 | print_result $testnumstr \ | |
481 | "ERROR" "bpf_sim rc=$rc" | |
482 | stats_error=$(($stats_error+1)) | |
483 | elif [[ "$action" != "$result" ]]; then | |
484 | print_result $testnumstr "FAILURE" \ | |
485 | "bpf_sim resulted in $action" | |
486 | stats_failure=$(($stats_failure+1)) | |
487 | else | |
488 | print_result $testnumstr "SUCCESS" "" | |
489 | stats_success=$(($stats_success+1)) | |
490 | fi | |
491 | stats_all=$(($stats_all+1)) | |
492 | ||
493 | subtestnum=$(($subtestnum+1)) | |
494 | done # syscall | |
495 | done # arg0 | |
496 | done # arg1 | |
497 | done # arg2 | |
498 | done # arg3 | |
499 | done # arg4 | |
500 | done # arg5 | |
501 | done # architecture | |
502 | } | |
503 | ||
504 | # | |
505 | # Run the specified "basic" test | |
506 | # | |
507 | # Tests that belong to the "basic" test type will simply have the command | |
508 | # specified in the input batch file. The command must return zero for success | |
509 | # and non-zero for failure. | |
510 | # | |
511 | # Arguments: | |
512 | # 1 value of test number from batch file | |
513 | # 2 string containing line of test data from batch file | |
514 | # | |
515 | function run_test_basic() { | |
516 | local rc | |
517 | ||
518 | # print out the input test data to the log file | |
519 | print_data "$1" "$2" | |
520 | ||
521 | # run the command | |
522 | run_test_command "$1" "./$2" "" "" "" | |
523 | rc=$? | |
524 | if [[ $rc -ne 0 ]]; then | |
525 | print_result $1 "FAILURE" "$2 rc=$rc" | |
526 | stats_failure=$(($stats_failure+1)) | |
527 | else | |
528 | print_result $1 "SUCCESS" "" | |
529 | stats_success=$(($stats_success+1)) | |
530 | fi | |
531 | stats_all=$(($stats_all+1)) | |
532 | } | |
533 | ||
534 | # | |
535 | # Run the specified "bpf-valgrind" test | |
536 | # | |
537 | # Tests that belong to the "bpf-valgrind" test type generate a BPF filter | |
538 | # while running under valgrind to detect any memory errors. | |
539 | # | |
540 | # Arguments: | |
541 | # 1 value of test number from batch file | |
542 | # 2 string containing line of test data from batch file | |
543 | # | |
544 | function run_test_bpf_valgrind() { | |
545 | local rc | |
546 | local testcmd | |
547 | ||
548 | # we only support the native/c test mode here | |
549 | if [[ $mode != "c" ]]; then | |
550 | stats_skipped=$(($stats_skipped+1)) | |
551 | return | |
552 | fi | |
553 | ||
554 | # print out the input test data to the log file | |
555 | print_data "$1" "$2" | |
556 | ||
557 | # build the command | |
558 | testcmd="$2" | |
559 | testvalgrind="valgrind \ | |
560 | --tool=memcheck \ | |
561 | --error-exitcode=1 \ | |
562 | --leak-check=full \ | |
563 | --read-var-info=yes \ | |
564 | --track-origins=yes" | |
565 | if [[ -n $logfile ]]; then | |
566 | testvalgrind+=" --log-fd=$logfd" | |
567 | fi | |
568 | if [[ -z $verbose ]]; then | |
569 | testvalgrind+=" --quiet --log-fd=4" | |
570 | fi | |
571 | ||
572 | # run the command | |
573 | exec 4>/dev/null | |
574 | print_valgrind "$1" | |
575 | run_test_command "$1" "$testvalgrind --" "./$testcmd -b" 4 2 | |
576 | rc=$? | |
577 | exec 4>&- | |
578 | if [[ $rc -ne 0 ]]; then | |
579 | print_result $1 "FAILURE" "$2 rc=$rc" | |
580 | stats_failure=$(($stats_failure+1)) | |
581 | else | |
582 | print_result $1 "SUCCESS" "" | |
583 | stats_success=$(($stats_success+1)) | |
584 | fi | |
585 | stats_all=$(($stats_all+1)) | |
586 | } | |
587 | ||
588 | # | |
589 | # Run the specified "live" test | |
590 | # | |
591 | # Tests that belong to the "live" test type will attempt to run a live test | |
592 | # of the libseccomp library on the host system; for obvious reasons the host | |
593 | # system must support seccomp mode 2 for this to work correctly. | |
594 | # | |
595 | # Arguments: | |
596 | # 1 value of test number from batch file | |
597 | # 2 string containing line of test data from batch file | |
598 | # | |
599 | function run_test_live() { | |
600 | local rc | |
601 | local line=($2) | |
602 | ||
603 | # parse the test line | |
604 | line_cmd=${line[0]} | |
605 | line_act=${line[1]} | |
606 | line_test="$line_cmd $line_act" | |
607 | ||
608 | # print out the input test data to the log file | |
609 | print_data "$1" "$2" | |
610 | ||
611 | # run the command | |
612 | exec 4>/dev/null | |
613 | run_test_command "$1" "./$line_cmd" "$line_act" "" 4 | |
614 | rc=$? | |
615 | exec 4>&- | |
616 | ||
617 | # return value codes for this test type: | |
618 | # 159: KILL | |
619 | # 160: ALLOW | |
620 | # 161: TRAP | |
621 | # 162: TRACE (currently unsupported) | |
622 | # 163: ERRNO | |
623 | if [[ $line_act == "KILL" && $rc -eq 159 ]]; then | |
624 | print_result $1 "SUCCESS" "" | |
625 | stats_success=$(($stats_success+1)) | |
626 | elif [[ $line_act == "ALLOW" && $rc -eq 160 ]]; then | |
627 | print_result $1 "SUCCESS" "" | |
628 | stats_success=$(($stats_success+1)) | |
629 | elif [[ $line_act == "TRAP" && $rc -eq 161 ]]; then | |
630 | print_result $1 "SUCCESS" "" | |
631 | stats_success=$(($stats_success+1)) | |
632 | elif [[ $line_act == "TRACE" ]]; then | |
633 | print_result $1 "ERROR" "unsupported action \"$line_act\"" | |
634 | stats_error=$(($stats_error+1)) | |
635 | elif [[ $line_act == "ERRNO" && $rc -eq 163 ]]; then | |
636 | print_result $1 "SUCCESS" "" | |
637 | stats_success=$(($stats_success+1)) | |
638 | else | |
639 | print_result $1 "FAILURE" "$line_test rc=$rc" | |
640 | stats_failure=$(($stats_failure+1)) | |
641 | fi | |
642 | stats_all=$(($stats_all+1)) | |
643 | } | |
644 | ||
645 | # | |
646 | # Run a single test from the specified batch | |
647 | # | |
648 | # Arguments: | |
649 | # 1 string containing the batch name | |
650 | # 2 value of test number from batch file | |
651 | # 3 string containing line of test data from batch file | |
652 | # 4 string containing test type that this test belongs to | |
653 | # | |
654 | function run_test() { | |
655 | # generate the test number string for the line of batch test data | |
656 | local testnumstr=$(generate_test_num "$1" $2 1) | |
657 | ||
658 | # ensure we only run tests which match the specified type | |
659 | [[ -n $type && "$4" != "$type" ]] && return | |
660 | ||
661 | # execute the function corresponding to the test type | |
662 | if [[ "$4" == "basic" ]]; then | |
663 | run_test_basic "$testnumstr" "$3" | |
664 | elif [[ "$4" == "bpf-sim" ]]; then | |
665 | run_test_bpf_sim "$1" $2 "$3" | |
666 | elif [[ "$4" == "bpf-sim-fuzz" ]]; then | |
667 | run_test_bpf_sim_fuzz "$1" $2 "$3" | |
668 | elif [[ "$4" == "bpf-valgrind" ]]; then | |
669 | # only run this test if valgrind is installed | |
670 | if check_deps valgrind; then | |
671 | run_test_bpf_valgrind "$testnumstr" "$3" | |
672 | else | |
673 | stats_skipped=$(($stats_skipped+1)) | |
674 | fi | |
675 | elif [[ "$4" == "live" ]]; then | |
676 | # only run this test if explicitly requested | |
677 | if [[ -n $type ]]; then | |
678 | run_test_live "$testnumstr" "$3" | |
679 | else | |
680 | stats_skipped=$(($stats_skipped+1)) | |
681 | fi | |
682 | else | |
683 | print_result $testnumstr "ERROR" "test type $4 not supported" | |
684 | stats_error=$(($stats_error+1)) | |
685 | fi | |
686 | } | |
687 | ||
688 | # | |
689 | # Run the requested tests | |
690 | # | |
691 | function run_tests() { | |
692 | # loop through all test files | |
693 | for file in *.tests; do | |
694 | local testnum=1 | |
695 | local batch_requested=false | |
696 | local batch_name="" | |
697 | ||
698 | # extract the batch name from the file name | |
699 | batch_name=$(basename $file .tests) | |
700 | ||
701 | # check if this batch was requested | |
702 | if [[ ${batch_list[@]} ]]; then | |
703 | for b in ${batch_list[@]}; do | |
704 | if [[ $b == $batch_name ]]; then | |
705 | batch_requested=true | |
706 | break | |
707 | fi | |
708 | done | |
709 | if ! $batch_requested; then | |
710 | continue | |
711 | fi | |
712 | fi | |
713 | ||
714 | # print a test batch header | |
715 | echo " batch name: $batch_name" >&$logfd | |
716 | ||
717 | # loop through each line and run the requested tests | |
718 | while read line; do | |
719 | # strip whitespace, comments, and blank lines | |
720 | line=$(echo "$line" | \ | |
721 | sed -e 's/^[\t ]*//;s/[\t ]*$//;' | \ | |
722 | sed -e '/^[#].*$/d;/^$/d') | |
723 | if [[ -z $line ]]; then | |
724 | continue | |
725 | fi | |
726 | ||
727 | if [[ $line =~ ^"test type": ]]; then | |
728 | test_type=$(echo "$line" | \ | |
729 | sed -e 's/^test type: //;') | |
730 | # print a test mode and type header | |
731 | echo " test mode: $mode" >&$logfd | |
732 | echo " test type: $test_type" >&$logfd | |
733 | continue | |
734 | fi | |
735 | ||
736 | if [[ ${single_list[@]} ]]; then | |
737 | for i in ${single_list[@]}; do | |
738 | if [ $i -eq $testnum ]; then | |
739 | # we're running a single test | |
740 | run_test "$batch_name" \ | |
741 | $testnum "$line" \ | |
742 | "$test_type" | |
743 | fi | |
744 | done | |
745 | else | |
746 | # we're running a test from a batch | |
747 | run_test "$batch_name" \ | |
748 | $testnum "$line" "$test_type" | |
749 | fi | |
750 | testnum=$(($testnum+1)) | |
751 | done < "$file" | |
752 | done | |
753 | } | |
754 | ||
755 | #### | |
756 | # main | |
757 | ||
758 | # verify general script dependencies | |
759 | verify_deps head | |
760 | verify_deps sed | |
761 | verify_deps seq | |
762 | verify_deps tr | |
763 | ||
764 | # global variables | |
765 | declare -a batch_list | |
766 | declare -a single_list | |
767 | arch= | |
768 | batch_count=0 | |
769 | logfile= | |
770 | logfd= | |
771 | mode_list="" | |
772 | runall= | |
773 | singlecount=0 | |
774 | tmpfile="" | |
775 | tmpdir="" | |
776 | type= | |
777 | verbose= | |
778 | stats_all=0 | |
779 | stats_skipped=0 | |
780 | stats_success=0 | |
781 | stats_failure=0 | |
782 | stats_error=0 | |
783 | ||
784 | while getopts "ab:gl:m:s:t:T:vh" opt; do | |
785 | case $opt in | |
786 | a) | |
787 | runall=1 | |
788 | ;; | |
789 | b) | |
790 | batch_list[batch_count]="$OPTARG" | |
791 | batch_count=$(($batch_count+1)) | |
792 | ;; | |
793 | l) | |
794 | logfile="$OPTARG" | |
795 | ;; | |
796 | m) | |
797 | case $OPTARG in | |
798 | c) | |
799 | mode_list="$mode_list c" | |
800 | ;; | |
801 | python) | |
802 | verify_deps python | |
803 | mode_list="$mode_list python" | |
804 | ;; | |
805 | *) | |
806 | usage | |
807 | exit 1 | |
808 | esac | |
809 | ;; | |
810 | s) | |
811 | single_list[single_count]=$OPTARG | |
812 | single_count=$(($single_count+1)) | |
813 | ;; | |
814 | t) | |
815 | tmpdir="$OPTARG" | |
816 | ;; | |
817 | T) | |
818 | type="$OPTARG" | |
819 | ;; | |
820 | v) | |
821 | verbose=1 | |
822 | ;; | |
823 | h|*) | |
824 | usage | |
825 | exit 1 | |
826 | ;; | |
827 | esac | |
828 | done | |
829 | ||
830 | # default to running the C tests | |
831 | if [[ -z $mode_list ]]; then | |
832 | mode_list="c" | |
833 | fi | |
834 | ||
835 | # default to all tests if batch or single tests not requested | |
836 | if [[ -z $batch_list ]] && [[ -z $single_list ]]; then | |
837 | runall=1 | |
838 | fi | |
839 | ||
840 | # drop any requested batch and single tests if all tests were requested | |
841 | if [[ -n $runall ]]; then | |
842 | batch_list=() | |
843 | single_list=() | |
844 | fi | |
845 | ||
846 | # open log file for append (default to stdout) | |
847 | if [[ -n $logfile ]]; then | |
848 | logfd=3 | |
849 | exec 3>>"$logfile" | |
850 | else | |
851 | logfd=1 | |
852 | fi | |
853 | ||
854 | # open temporary file | |
855 | if [[ -n $tmpdir ]]; then | |
856 | tmpfile=$(mktemp -t regression_XXXXXX --tmpdir=$tmpdir) | |
857 | else | |
858 | tmpfile=$(mktemp -t regression_XXXXXX) | |
859 | fi | |
860 | ||
861 | # determine the current system's architecture | |
862 | arch=$($GLBL_SYS_ARCH) | |
863 | ||
864 | # display the test output and run the requested tests | |
865 | echo "=============== $(date) ===============" >&$logfd | |
866 | echo "Regression Test Report (\"regression $*\")" >&$logfd | |
867 | for mode in $mode_list; do | |
868 | run_tests | |
869 | done | |
870 | echo "Regression Test Summary" >&$logfd | |
871 | echo " tests run: $stats_all" >&$logfd | |
872 | echo " tests skipped: $stats_skipped" >&$logfd | |
873 | echo " tests passed: $stats_success" >&$logfd | |
874 | echo " tests failed: $stats_failure" >&$logfd | |
875 | echo " tests errored: $stats_error" >&$logfd | |
876 | echo "============================================================" >&$logfd | |
877 | ||
878 | # cleanup and exit | |
879 | rm -f $tmpfile | |
880 | rc=0 | |
881 | [[ $stats_failure -gt 0 ]] && rc=$(($rc + 2)) | |
882 | [[ $stats_error -gt 0 ]] && rc=$(($rc + 4)) | |
883 | ||
884 | exit $rc |
0 | #!/bin/bash | |
1 | ||
2 | # | |
3 | # libseccomp test diff generator | |
4 | # | |
5 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | #### | |
24 | # functions | |
25 | ||
26 | # | |
27 | # Print out script usage details | |
28 | # | |
29 | function usage() { | |
30 | cat << EOF | |
31 | usage: regression [-h] LABEL_1 LABEL_2 | |
32 | ||
33 | libseccomp test diff generator script | |
34 | optional arguments: | |
35 | -h show this help message and exit | |
36 | EOF | |
37 | } | |
38 | ||
39 | # | |
40 | # Print the test header | |
41 | # | |
42 | # Arguments: | |
43 | # 1 string containing generated test number | |
44 | # | |
45 | function print_test() { | |
46 | printf "Test %s comparison:\n" "$1" | |
47 | } | |
48 | ||
49 | # | |
50 | # Compare the tests | |
51 | # | |
52 | # Arguments: | |
53 | # 1 string containing first test label | |
54 | # 2 string containing second test label | |
55 | # | |
56 | function diff_tests() { | |
57 | local batch_name | |
58 | local label_a | |
59 | local label_b | |
60 | local file_a | |
61 | local file_b | |
62 | ||
63 | if [[ -n $1 ]]; then | |
64 | label_a=".$1" | |
65 | else | |
66 | label_a="" | |
67 | fi | |
68 | ||
69 | if [[ -n $2 ]]; then | |
70 | label_b=".$2" | |
71 | else | |
72 | label_b="" | |
73 | fi | |
74 | ||
75 | for file in *-sim-*.tests; do | |
76 | # extract the batch name from the file name | |
77 | batch_name=$(basename $file .tests) | |
78 | ||
79 | print_test "$batch_name" | |
80 | ||
81 | file_a="${batch_name}${label_a}" | |
82 | file_b="${batch_name}${label_b}" | |
83 | ||
84 | if [[ -r "$file_a.pfc" && -r "$file_b.pfc" ]]; then | |
85 | diff -pu "$file_a.pfc" "$file_b.pfc" | |
86 | fi | |
87 | ||
88 | if [[ -r "$file_a.bpf" && -r "$file_b.bpf" ]]; then | |
89 | diff -pu "$file_a.bpf" "$file_b.bpf" | |
90 | fi | |
91 | ||
92 | if [[ -r "$file_a.bpfd" && -r "$file_b.bpfd" ]]; then | |
93 | diff -pu "$file_a.bpfd" "$file_b.bpfd" | |
94 | fi | |
95 | done | |
96 | ||
97 | return | |
98 | } | |
99 | ||
100 | #### | |
101 | # main | |
102 | ||
103 | opt_label= | |
104 | opt_disasm=0 | |
105 | ||
106 | while getopts "h" opt; do | |
107 | case $opt in | |
108 | h|*) | |
109 | usage | |
110 | exit 1 | |
111 | ;; | |
112 | esac | |
113 | done | |
114 | ||
115 | stats_all=0 | |
116 | stats_failure=0 | |
117 | ||
118 | # display the test output and run the requested tests | |
119 | echo "=============== $(date) ===============" | |
120 | echo "Comparing Test Output (\"testdiff $*\")" | |
121 | diff_tests "$1" "$2" | |
122 | echo "============================================================" | |
123 | ||
124 | # exit | |
125 | exit 0 |
0 | #!/bin/bash | |
1 | ||
2 | # | |
3 | # libseccomp test output generator | |
4 | # | |
5 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | #### | |
24 | # functions | |
25 | ||
26 | # | |
27 | # Dependency verification | |
28 | # | |
29 | # Arguments: | |
30 | # 1 Dependency to check for | |
31 | # | |
32 | function verify_deps() { | |
33 | [[ -z "$1" ]] && return | |
34 | if ! which "$1" >& /dev/null; then | |
35 | echo "error: install \"$1\" and include it in your \$PATH" | |
36 | exit 1 | |
37 | fi | |
38 | } | |
39 | ||
40 | # | |
41 | # Print out script usage details | |
42 | # | |
43 | function usage() { | |
44 | cat << EOF | |
45 | usage: regression [-h] [-d] [-l LABEL] | |
46 | ||
47 | libseccomp test output generator script | |
48 | optional arguments: | |
49 | -h show this help message and exit | |
50 | -b generate BPF output | |
51 | -d generate disassembled BPF output | |
52 | -p generate PFC output | |
53 | -v perform valgrind checks | |
54 | -l [LABEL] specifies label for the test output | |
55 | EOF | |
56 | } | |
57 | ||
58 | # | |
59 | # Print the test result | |
60 | # | |
61 | # Arguments: | |
62 | # 1 string containing generated test number | |
63 | # 2 string containing the test result | |
64 | # | |
65 | function print_result() { | |
66 | printf "Test %s result: %s\n" "$1" "$2" | |
67 | } | |
68 | ||
69 | # | |
70 | # Run the tests | |
71 | # | |
72 | # Arguments: | |
73 | # 1 string containing output label | |
74 | # | |
75 | function run_tests() { | |
76 | local batch_name | |
77 | local label | |
78 | local rc | |
79 | ||
80 | if [[ -n $1 ]]; then | |
81 | label=".$1" | |
82 | else | |
83 | label="" | |
84 | fi | |
85 | ||
86 | for file in *-sim-*.tests; do | |
87 | # extract the batch name from the file name | |
88 | batch_name=$(basename $file .tests) | |
89 | ||
90 | if [[ -x "$batch_name" ]]; then | |
91 | if [[ $opt_pfc -eq 1 ]]; then | |
92 | ./$batch_name > ${batch_name}${label}.pfc | |
93 | rc=$? | |
94 | stats_all=$(($stats_all + 1)) | |
95 | if [[ $rc -eq 0 ]]; then | |
96 | print_result "$batch_name [pfc]" "SUCCESS" | |
97 | else | |
98 | stats_failure=$(($stats_failure + 1)) | |
99 | print_result "$batch_name [pfc]" "FAILURE" | |
100 | fi | |
101 | fi | |
102 | ||
103 | if [[ $opt_bpf -eq 1 ]]; then | |
104 | ./$batch_name -b > ${batch_name}${label}.bpf | |
105 | rc=$? | |
106 | stats_all=$(($stats_all + 1)) | |
107 | if [[ $rc -eq 0 ]]; then | |
108 | print_result "$batch_name [bpf]" "SUCCESS" | |
109 | else | |
110 | stats_failure=$(($stats_failure + 1)) | |
111 | print_result "$batch_name [bpf]" "FAILURE" | |
112 | fi | |
113 | fi | |
114 | ||
115 | if [[ $opt_disasm -eq 1 ]]; then | |
116 | ./$batch_name -b | \ | |
117 | ../tools/scmp_bpf_disasm > ${batch_name}${label}.bpfd | |
118 | rc=$? | |
119 | stats_all=$(($stats_all + 1)) | |
120 | if [[ $rc -eq 0 ]]; then | |
121 | print_result "$batch_name [bpfd]" "SUCCESS" | |
122 | else | |
123 | stats_failure=$(($stats_failure + 1)) | |
124 | print_result "$batch_name [bpfd]" "FAILURE" | |
125 | fi | |
126 | fi | |
127 | ||
128 | if [[ $opt_valgrind -eq 1 ]]; then | |
129 | valgrind --tool=memcheck \ | |
130 | --quiet --error-exitcode=1 \ | |
131 | --leak-check=full \ | |
132 | --read-var-info=yes \ | |
133 | --track-origins=yes \ | |
134 | -- ./$batch_name -b > /dev/null | |
135 | rc=$? | |
136 | stats_all=$(($stats_all + 1)) | |
137 | if [[ $rc -eq 0 ]]; then | |
138 | print_result "$batch_name [valgrind]" "SUCCESS" | |
139 | else | |
140 | stats_failure=$(($stats_failure + 1)) | |
141 | print_result "$batch_name [valgrind]" "FAILURE" | |
142 | fi | |
143 | fi | |
144 | else | |
145 | stats_failure=$(($stats_failure + 1)) | |
146 | print_result "$batch_name" "FAILURE" | |
147 | fi | |
148 | done | |
149 | ||
150 | return | |
151 | } | |
152 | ||
153 | #### | |
154 | # main | |
155 | ||
156 | opt_label= | |
157 | opt_bpf=0 | |
158 | opt_disasm=0 | |
159 | opt_pfc=0 | |
160 | opt_valgrind=0 | |
161 | ||
162 | while getopts "bphdl:v" opt; do | |
163 | case $opt in | |
164 | b) | |
165 | opt_bpf=1 | |
166 | ;; | |
167 | d) | |
168 | opt_disasm=1 | |
169 | ;; | |
170 | l) | |
171 | opt_label="$OPTARG" | |
172 | ;; | |
173 | p) | |
174 | opt_pfc=1 | |
175 | ;; | |
176 | v) | |
177 | opt_valgrind=1 | |
178 | ;; | |
179 | h|*) | |
180 | usage | |
181 | exit 1 | |
182 | ;; | |
183 | esac | |
184 | done | |
185 | ||
186 | # verify valgrind | |
187 | [[ $opt_valgrind -eq 1 ]] && verify_deps valgrind | |
188 | ||
189 | stats_all=0 | |
190 | stats_failure=0 | |
191 | ||
192 | # display the test output and run the requested tests | |
193 | echo "=============== $(date) ===============" | |
194 | echo "Collecting Test Output (\"testgen $*\")" | |
195 | run_tests "$opt_label" | |
196 | echo "Test Summary" | |
197 | echo " tests run: $stats_all" | |
198 | echo " tests failed: $stats_failure" | |
199 | echo "============================================================" | |
200 | ||
201 | # cleanup and exit | |
202 | rc=0 | |
203 | [[ $stats_failure -gt 0 ]] && rc=$(($rc + 2)) | |
204 | ||
205 | exit $rc |
0 | /** | |
1 | * Seccomp Library utility code for tests | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <eparis@redhat.com> | |
4 | * Author: Eric Paris <eparis@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <errno.h> | |
22 | #include <fcntl.h> | |
23 | #include <getopt.h> | |
24 | #include <signal.h> | |
25 | #include <stdio.h> | |
26 | #include <string.h> | |
27 | #include <unistd.h> | |
28 | #include <sys/types.h> | |
29 | #include <sys/stat.h> | |
30 | ||
31 | #include <seccomp.h> | |
32 | ||
33 | #include "util.h" | |
34 | ||
35 | /** | |
36 | * SIGSYS signal handler | |
37 | * @param nr the signal number | |
38 | * @param info siginfo_t pointer | |
39 | * @param void_context handler context | |
40 | * | |
41 | * Simple signal handler for SIGSYS which exits with error code 161. | |
42 | * | |
43 | */ | |
44 | static void _trap_handler(int signal, siginfo_t *info, void *ctx) | |
45 | { | |
46 | _exit(161); | |
47 | } | |
48 | ||
49 | /** | |
50 | * Parse the arguments passed to main | |
51 | * @param argc the argument count | |
52 | * @param argv the argument pointer | |
53 | * @param opts the options structure | |
54 | * | |
55 | * This function parses the arguments passed to the test from the command line. | |
56 | * Returns zero on success and negative values on failure. | |
57 | * | |
58 | */ | |
59 | int util_getopt(int argc, char *argv[], struct util_options *opts) | |
60 | { | |
61 | int rc = 0; | |
62 | ||
63 | if (opts == NULL) | |
64 | return -EFAULT; | |
65 | ||
66 | memset(opts, 0, sizeof(*opts)); | |
67 | while (1) { | |
68 | int c, option_index = 0; | |
69 | const struct option long_options[] = { | |
70 | {"bpf", no_argument, &(opts->bpf_flg), 1}, | |
71 | {"pfc", no_argument, &(opts->bpf_flg), 0}, | |
72 | {0, 0, 0, 0}, | |
73 | }; | |
74 | ||
75 | c = getopt_long(argc, argv, "bp", | |
76 | long_options, &option_index); | |
77 | if (c == -1) | |
78 | break; | |
79 | ||
80 | switch (c) { | |
81 | case 0: | |
82 | break; | |
83 | case 'b': | |
84 | opts->bpf_flg = 1; | |
85 | break; | |
86 | case 'p': | |
87 | opts->bpf_flg = 0; | |
88 | break; | |
89 | default: | |
90 | rc = -EINVAL; | |
91 | break; | |
92 | } | |
93 | } | |
94 | ||
95 | if (rc == -EINVAL || optind < argc) { | |
96 | fprintf(stderr, "usage %s: [--bpf,-b] [--pfc,-p]\n", argv[0]); | |
97 | rc = -EINVAL; | |
98 | } | |
99 | ||
100 | return rc; | |
101 | } | |
102 | ||
103 | /** | |
104 | * Output the filter in either BPF or PFC | |
105 | * @param opts the options structure | |
106 | * @param ctx the filter context | |
107 | * | |
108 | * This function outputs the seccomp filter to stdout in either BPF or PFC | |
109 | * format depending on the test paramaeters supplied by @opts. | |
110 | * | |
111 | */ | |
112 | int util_filter_output(const struct util_options *opts, | |
113 | const scmp_filter_ctx ctx) | |
114 | { | |
115 | int rc; | |
116 | ||
117 | if (opts == NULL) | |
118 | return -EFAULT; | |
119 | ||
120 | if (opts->bpf_flg) | |
121 | rc = seccomp_export_bpf(ctx, STDOUT_FILENO); | |
122 | else | |
123 | rc = seccomp_export_pfc(ctx, STDOUT_FILENO); | |
124 | ||
125 | return rc; | |
126 | } | |
127 | ||
128 | /** | |
129 | * Install a TRAP action signal handler | |
130 | * | |
131 | * This function installs the TRAP action signal handler and is based on | |
132 | * examples from Will Drewry and Kees Cook. Returns zero on success, negative | |
133 | * values on failure. | |
134 | * | |
135 | */ | |
136 | int util_trap_install(void) | |
137 | { | |
138 | struct sigaction signal_handler; | |
139 | sigset_t signal_mask; | |
140 | ||
141 | memset(&signal_handler, 0, sizeof(signal_handler)); | |
142 | sigemptyset(&signal_mask); | |
143 | sigaddset(&signal_mask, SIGSYS); | |
144 | ||
145 | signal_handler.sa_sigaction = &_trap_handler; | |
146 | signal_handler.sa_flags = SA_SIGINFO; | |
147 | if (sigaction(SIGSYS, &signal_handler, NULL) < 0) | |
148 | return -errno; | |
149 | if (sigprocmask(SIG_UNBLOCK, &signal_mask, NULL)) | |
150 | return -errno; | |
151 | ||
152 | return 0; | |
153 | } | |
154 | ||
155 | /** | |
156 | * Parse a filter action string into an action value | |
157 | * @param action the action string | |
158 | * | |
159 | * Parse a seccomp action string into the associated integer value. Returns | |
160 | * the correct value on success, -1 on failure. | |
161 | * | |
162 | */ | |
163 | int util_action_parse(const char *action) | |
164 | { | |
165 | if (action == NULL) | |
166 | return -1; | |
167 | ||
168 | if (strcasecmp(action, "KILL") == 0) | |
169 | return SCMP_ACT_KILL; | |
170 | else if (strcasecmp(action, "TRAP") == 0) | |
171 | return SCMP_ACT_TRAP; | |
172 | else if (strcasecmp(action, "ERRNO") == 0) | |
173 | return SCMP_ACT_ERRNO(163); | |
174 | else if (strcasecmp(action, "TRACE") == 0) | |
175 | return -1; /* not yet supported */ | |
176 | else if (strcasecmp(action, "ALLOW") == 0) | |
177 | return SCMP_ACT_ALLOW; | |
178 | ||
179 | return -1; | |
180 | } | |
181 | ||
182 | /** | |
183 | * Write a string to a file | |
184 | * @param path the file path | |
185 | * | |
186 | * Open the specified file, write a string to the file, and close the file. | |
187 | * Return zero on success, negative values on error. | |
188 | * | |
189 | */ | |
190 | int util_file_write(const char *path) | |
191 | { | |
192 | int fd; | |
193 | const char buf[] = "testing"; | |
194 | ssize_t buf_len = strlen(buf); | |
195 | ||
196 | fd = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); | |
197 | if (fd < 0) | |
198 | return errno; | |
199 | if (write(fd, buf, buf_len) < buf_len) { | |
200 | int rc = errno; | |
201 | close(fd); | |
202 | return rc; | |
203 | } | |
204 | if (close(fd) < 0) | |
205 | return errno; | |
206 | ||
207 | return 0; | |
208 | } |
0 | /** | |
1 | * Seccomp Library utility code for tests | |
2 | * | |
3 | * Copyright IBM Corp. 2012 | |
4 | * Author: Corey Bryant <coreyb@linux.vnet.ibm.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #ifndef _UTIL_TEST_H | |
22 | #define _UTIL_TEST_H | |
23 | ||
24 | struct util_options { | |
25 | int bpf_flg; | |
26 | }; | |
27 | ||
28 | int util_getopt(int argc, char *argv[], struct util_options *opts); | |
29 | ||
30 | int util_filter_output(const struct util_options *opts, | |
31 | const scmp_filter_ctx ctx); | |
32 | ||
33 | int util_trap_install(void); | |
34 | ||
35 | int util_action_parse(const char *action); | |
36 | ||
37 | int util_file_write(const char *path); | |
38 | ||
39 | #endif |
0 | # | |
1 | # Seccomp Library utility code for tests | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | """ Python utility code for the libseccomp test suite """ | |
22 | ||
23 | import argparse | |
24 | import os | |
25 | import sys | |
26 | import signal | |
27 | ||
28 | from seccomp import * | |
29 | ||
30 | def trap_handler(signum, frame): | |
31 | """ SIGSYS signal handler, internal use only | |
32 | """ | |
33 | os._exit(161) | |
34 | ||
35 | def get_opt(): | |
36 | """ Parse the arguments passed to main | |
37 | ||
38 | Description: | |
39 | Parse the arguments passed to the test from the command line. Returns | |
40 | a parsed argparse object. | |
41 | """ | |
42 | parser = argparse.ArgumentParser() | |
43 | parser.add_argument("-b", "--bpf", action="store_true") | |
44 | parser.add_argument("-p", "--pfc", action="store_true") | |
45 | return parser.parse_args() | |
46 | ||
47 | def filter_output(args, ctx): | |
48 | """ Output the filter in either BPF or PFC | |
49 | ||
50 | Arguments: | |
51 | args - an argparse object from UtilGetOpt() | |
52 | ctx - a seccomp SyscallFilter object | |
53 | ||
54 | Description: | |
55 | Output the SyscallFilter to stdout in either BPF or PFC format depending | |
56 | on the test's command line arguments. | |
57 | """ | |
58 | if (args.bpf): | |
59 | ctx.export_bpf(sys.stdout) | |
60 | else: | |
61 | ctx.export_pfc(sys.stdout) | |
62 | ||
63 | def install_trap(): | |
64 | """ Install a TRAP action signal handler | |
65 | ||
66 | Description: | |
67 | Install the TRAP action signal handler. | |
68 | """ | |
69 | signal.signal(signal.SIGSYS, trap_handler) | |
70 | ||
71 | def parse_action(action): | |
72 | """ Parse a filter action string into an action value | |
73 | ||
74 | Arguments: | |
75 | action - the action string | |
76 | ||
77 | Description: | |
78 | Parse a seccomp action string into the associated integer value. | |
79 | """ | |
80 | if action == "KILL": | |
81 | return KILL | |
82 | elif action == "TRAP": | |
83 | return TRAP | |
84 | elif action == "ERRNO": | |
85 | return ERRNO(163) | |
86 | elif action == "TRACE": | |
87 | raise RuntimeError("the TRACE action is not currently supported") | |
88 | elif action == "ALLOW": | |
89 | return ALLOW | |
90 | raise RuntimeError("invalid action string") | |
91 | ||
92 | ||
93 | def write_file(path): | |
94 | """ Write a string to a file | |
95 | ||
96 | Arguments: | |
97 | path - the file path | |
98 | ||
99 | Description: | |
100 | Open the specified file, write a string to the file, and close the file. | |
101 | """ | |
102 | fd = os.open(path, os.O_WRONLY|os.O_CREAT, 0600) | |
103 | if not os.write(fd, "testing") == len("testing"): | |
104 | raise IOError("failed to write the full test string in write_file()") | |
105 | os.close(fd) | |
106 | ||
107 | # kate: syntax python; | |
108 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |
0 | # | |
1 | # Enhanced Seccomp Library Makefile | |
2 | # | |
3 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | # Author: Paul Moore <pmoore@redhat.com> | |
5 | # | |
6 | ||
7 | # | |
8 | # This library is free software; you can redistribute it and/or modify it | |
9 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | # published by the Free Software Foundation. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | # for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public License | |
18 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | # | |
20 | ||
21 | # | |
22 | # macros | |
23 | # | |
24 | ||
25 | include ../macros.mk | |
26 | ||
27 | # | |
28 | # configuration | |
29 | # | |
30 | ||
31 | include $(TOPDIR)/configure.mk | |
32 | include $(TOPDIR)/install.mk | |
33 | ||
34 | LDFLAGS := ../src/libseccomp.a | |
35 | ||
36 | TOOLS = scmp_bpf_disasm \ | |
37 | scmp_bpf_sim \ | |
38 | scmp_sys_resolver \ | |
39 | scmp_arch_detect | |
40 | ||
41 | TOOLS_INSTALL = scmp_sys_resolver | |
42 | ||
43 | DEPS = $(TOOLS:%=%.d) | |
44 | ||
45 | # | |
46 | # targets | |
47 | # | |
48 | ||
49 | .PHONY: install clean | |
50 | ||
51 | all: $(TOOLS) | |
52 | ||
53 | -include $(DEPS) | |
54 | ||
55 | $(DEPS): | |
56 | $(MAKEDEP_EXEC) | |
57 | ||
58 | $(TOOLS): | |
59 | $(COMPILE_EXEC) | |
60 | ||
61 | install: $(TOOLS_INSTALL) | |
62 | $(INSTALL_BIN_MACRO) | |
63 | ||
64 | clean: | |
65 | $(RM) $(DEPS) $(TOOLS) |
0 | /** | |
1 | * BPF Language Definitions | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #ifndef _BPF_H | |
22 | #define _BPF_H | |
23 | ||
24 | #include <inttypes.h> | |
25 | #include <stddef.h> | |
26 | ||
27 | /* most of these structures and values are designed to match the Linux Kernel's | |
28 | * BPF interface (see /usr/include/linux/{filter,seccomp}.h), but we define our | |
29 | * own here so that we can function independent of the host OS */ | |
30 | ||
31 | /* XXX - need to verify these values */ | |
32 | #define BPF_SCRATCH_SIZE 6 | |
33 | ||
34 | /** | |
35 | * Syscall record data format used by seccomp | |
36 | */ | |
37 | #define BPF_SYS_ARG_MAX 6 | |
38 | struct seccomp_data { | |
39 | int32_t nr; | |
40 | uint32_t arch; | |
41 | uint64_t instruction_pointer; | |
42 | uint64_t args[BPF_SYS_ARG_MAX]; | |
43 | }; | |
44 | #define BPF_SYSCALL_MAX (sizeof(struct seccomp_data)) | |
45 | ||
46 | /** | |
47 | * BPF instruction format | |
48 | */ | |
49 | struct sock_filter { | |
50 | uint16_t code; | |
51 | uint8_t jt; | |
52 | uint8_t jf; | |
53 | uint32_t k; | |
54 | } __attribute__ ((packed)); | |
55 | typedef struct sock_filter bpf_instr_raw; | |
56 | ||
57 | /* seccomp return masks */ | |
58 | #define SECCOMP_RET_ACTION 0x7fff0000U | |
59 | #define SECCOMP_RET_DATA 0x0000ffffU | |
60 | ||
61 | /* seccomp action values */ | |
62 | #define SECCOMP_RET_KILL 0x00000000U | |
63 | #define SECCOMP_RET_TRAP 0x00030000U | |
64 | #define SECCOMP_RET_ERRNO 0x00050000U | |
65 | #define SECCOMP_RET_TRACE 0x7ff00000U | |
66 | #define SECCOMP_RET_ALLOW 0x7fff0000U | |
67 | ||
68 | /* bpf command classes */ | |
69 | #define BPF_CLASS(code) ((code) & 0x07) | |
70 | #define BPF_LD 0x00 | |
71 | #define BPF_LDX 0x01 | |
72 | #define BPF_ST 0x02 | |
73 | #define BPF_STX 0x03 | |
74 | #define BPF_ALU 0x04 | |
75 | #define BPF_JMP 0x05 | |
76 | #define BPF_RET 0x06 | |
77 | #define BPF_MISC 0x07 | |
78 | ||
79 | /* BPF_LD and BPF_LDX */ | |
80 | #define BPF_SIZE(code) ((code) & 0x18) | |
81 | #define BPF_W 0x00 | |
82 | #define BPF_H 0x08 | |
83 | #define BPF_B 0x10 | |
84 | #define BPF_MODE(code) ((code) & 0xe0) | |
85 | #define BPF_IMM 0x00 | |
86 | #define BPF_ABS 0x20 | |
87 | #define BPF_IND 0x40 | |
88 | #define BPF_MEM 0x60 | |
89 | #define BPF_LEN 0x80 | |
90 | #define BPF_MSH 0xa0 | |
91 | ||
92 | #define BPF_OP(code) ((code) & 0xf0) | |
93 | /* BPF_ALU */ | |
94 | #define BPF_ADD 0x00 | |
95 | #define BPF_SUB 0x10 | |
96 | #define BPF_MUL 0x20 | |
97 | #define BPF_DIV 0x30 | |
98 | #define BPF_OR 0x40 | |
99 | #define BPF_AND 0x50 | |
100 | #define BPF_LSH 0x60 | |
101 | #define BPF_RSH 0x70 | |
102 | #define BPF_NEG 0x80 | |
103 | /* BPF_JMP */ | |
104 | #define BPF_JA 0x00 | |
105 | #define BPF_JEQ 0x10 | |
106 | #define BPF_JGT 0x20 | |
107 | #define BPF_JGE 0x30 | |
108 | #define BPF_JSET 0x40 | |
109 | ||
110 | #define BPF_SRC(code) ((code) & 0x08) | |
111 | #define BPF_K 0x00 | |
112 | #define BPF_X 0x08 | |
113 | ||
114 | /* BPF_RET (BPF_K and BPF_X also apply) */ | |
115 | #define BPF_RVAL(code) ((code) & 0x18) | |
116 | #define BPF_A 0x10 | |
117 | ||
118 | /* BPF_MISC */ | |
119 | #define BPF_MISCOP(code) ((code) & 0xf8) | |
120 | #define BPF_TAX 0x00 | |
121 | #define BPF_TXA 0x80 | |
122 | ||
123 | #endif |
0 | #!/bin/bash | |
1 | ||
2 | # | |
3 | # libseccomp code syntax checking tool | |
4 | # | |
5 | # Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | CHK_C_LIST="include/seccomp.h.in \ | |
24 | src/*.c src/*.h \ | |
25 | tests/*.c tests/*.h \ | |
26 | tools/*.c tools/*.h" | |
27 | CHK_C_EXCLUDE="" | |
28 | ||
29 | #### | |
30 | # functions | |
31 | ||
32 | # | |
33 | # Dependency verification | |
34 | # | |
35 | # Arguments: | |
36 | # 1 Dependency to check for | |
37 | # | |
38 | function verify_deps() { | |
39 | [[ -z "$1" ]] && return | |
40 | if ! which "$1" >& /dev/null; then | |
41 | echo "error: install \"$1\" and include it in your \$PATH" | |
42 | exit 1 | |
43 | fi | |
44 | } | |
45 | ||
46 | # | |
47 | # Print out script usage details | |
48 | # | |
49 | function usage() { | |
50 | cat << EOF | |
51 | usage: check-syntax [-h] | |
52 | ||
53 | libseccomp code syntax checking tool | |
54 | optional arguments: | |
55 | -h show this help message and exit | |
56 | EOF | |
57 | } | |
58 | ||
59 | # | |
60 | # Check the formatting on a C source/header file | |
61 | # | |
62 | # Arguments: | |
63 | # 1 File to check | |
64 | # | |
65 | function tool_c_style() { | |
66 | [[ -z "$1" || ! -r "$1" ]] && return | |
67 | ||
68 | astyle --options=none --lineend=linux --mode=c \ | |
69 | --style=linux \ | |
70 | --indent=force-tab=8 \ | |
71 | --indent-preprocessor \ | |
72 | --indent-col1-comments \ | |
73 | --min-conditional-indent=0 \ | |
74 | --max-instatement-indent=80 \ | |
75 | --pad-oper \ | |
76 | --align-pointer=name \ | |
77 | --align-reference=name \ | |
78 | --max-code-length=80 \ | |
79 | --break-after-logical < "$1" \ | |
80 | | diff -pu --label="$1" "$1" --label="$1 [CORRECTED]" - | |
81 | } | |
82 | ||
83 | # | |
84 | # Perform all known syntax checks for the configured C sources/headers | |
85 | # | |
86 | function check_c() { | |
87 | for i in $CHK_C_LIST; do | |
88 | echo "$CHK_C_EXCLUDE" | grep -q "$i" && continue | |
89 | echo "Differences for $i" | |
90 | tool_c_style "$i" | |
91 | done | |
92 | } | |
93 | ||
94 | #### | |
95 | # main | |
96 | ||
97 | verify_deps astyle | |
98 | ||
99 | while getopts "h" opt; do | |
100 | case $opt in | |
101 | h|*) | |
102 | usage | |
103 | exit 1 | |
104 | ;; | |
105 | esac | |
106 | done | |
107 | ||
108 | # display the results | |
109 | echo "=============== $(date) ===============" | |
110 | echo "Code Syntax Check Results (\"check-syntax $*\")" | |
111 | check_c | |
112 | echo "============================================================" | |
113 | ||
114 | # exit | |
115 | exit 0 |
0 | #!/bin/bash | |
1 | ||
2 | # | |
3 | # Runtime syscall inspector | |
4 | # | |
5 | # Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
6 | # Author: Paul Moore <pmoore@redhat.com> | |
7 | # | |
8 | ||
9 | # | |
10 | # This library is free software; you can redistribute it and/or modify it | |
11 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
12 | # published by the Free Software Foundation. | |
13 | # | |
14 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
17 | # for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU Lesser General Public License | |
20 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
21 | # | |
22 | ||
23 | #### | |
24 | # functions | |
25 | ||
26 | function verify_deps() { | |
27 | [[ -z "$1" ]] && return | |
28 | if ! which "$1" >& /dev/null; then | |
29 | echo "error: install \"$1\" and include it in your \$PATH" | |
30 | exit 1 | |
31 | fi | |
32 | } | |
33 | ||
34 | #### | |
35 | # main | |
36 | ||
37 | # verify script dependencies | |
38 | verify_deps strace | |
39 | verify_deps sed | |
40 | verify_deps sort | |
41 | verify_deps uniq | |
42 | ||
43 | # get the command line arguments | |
44 | opt_freq=0 | |
45 | opt_args=0 | |
46 | opt_out="/proc/self/fd/1" | |
47 | while getopts "afo:h" opt; do | |
48 | case $opt in | |
49 | a) | |
50 | opt_args=1 | |
51 | ;; | |
52 | f) | |
53 | opt_freq=1 | |
54 | ;; | |
55 | o) | |
56 | opt_out="$OPTARG" | |
57 | ;; | |
58 | h|*) | |
59 | echo "usage $0 [-f] [-a] [-o <file>] <command> [<args>]" | |
60 | exit 1 | |
61 | esac | |
62 | done | |
63 | shift $(expr $OPTIND - 1) | |
64 | ||
65 | # generate a temporary output file | |
66 | raw=$(mktemp -t strace-raw_XXXXXX) | |
67 | out="$raw-out" | |
68 | ||
69 | # capture the strace output | |
70 | strace -o $raw -- $* | |
71 | ||
72 | # filter the raw strace | |
73 | if [[ $opt_args -eq 0 ]]; then | |
74 | if [[ $opt_freq -eq 0 ]]; then | |
75 | cat $raw | sed -e 's/(.*//' | sort -u > $out | |
76 | else | |
77 | cat $raw | sed -e 's/(.*//' | sort | uniq -c | sort -nr > $out | |
78 | fi | |
79 | else | |
80 | if [[ $opt_freq -eq 0 ]]; then | |
81 | cat $raw | sed -e 's/)[ \t]*=.*$/)/' \ | |
82 | | sed -e 's/".*,/"...",/g;s/\/\*.*\*\//.../g' \ | |
83 | | sed -e 's/0x[a-f0-9]\+/.../g' \ | |
84 | | sort -u > $out | |
85 | else | |
86 | cat $raw | sed -e 's/)[ \t]*=.*$/)/' \ | |
87 | | sed -e 's/".*,/"...",/g;s/\/\*.*\*\//.../g' \ | |
88 | | sed -e 's/0x[a-f0-9]\+/.../g' \ | |
89 | | sort | uniq -c | sort -nr > $out | |
90 | fi | |
91 | fi | |
92 | ||
93 | # display the output | |
94 | echo "============================================================" > $opt_out | |
95 | echo "Syscall Report (\"$*\")" >> $opt_out | |
96 | [[ $opt_freq -eq 1 ]] && echo " freq syscall" >> $opt_out | |
97 | echo "============================================================" >> $opt_out | |
98 | cat $out >> $opt_out | |
99 | ||
100 | # cleanup and exit | |
101 | rm -f $raw $out | |
102 | exit 0 |
0 | /** | |
1 | * Architecture Detector | |
2 | * | |
3 | * Copyright (c) 2013 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <errno.h> | |
22 | #include <stdlib.h> | |
23 | #include <stdio.h> | |
24 | #include <unistd.h> | |
25 | ||
26 | #include <seccomp.h> | |
27 | ||
28 | /** | |
29 | * Print the usage information to stderr and exit | |
30 | * @param program the name of the current program being invoked | |
31 | * | |
32 | * Print the usage information and exit with EINVAL. | |
33 | * | |
34 | */ | |
35 | static void exit_usage(const char *program) | |
36 | { | |
37 | fprintf(stderr, | |
38 | "usage: %s [-h] [-t]\n", | |
39 | program); | |
40 | exit(EINVAL); | |
41 | } | |
42 | ||
43 | /** | |
44 | * main | |
45 | */ | |
46 | int main(int argc, char *argv[]) | |
47 | { | |
48 | int opt; | |
49 | int token = 0; | |
50 | uint32_t arch; | |
51 | ||
52 | /* parse the command line */ | |
53 | while ((opt = getopt(argc, argv, "ht")) > 0) { | |
54 | switch (opt) { | |
55 | case 't': | |
56 | token = 1; | |
57 | break; | |
58 | case 'h': | |
59 | default: | |
60 | /* usage information */ | |
61 | exit_usage(argv[0]); | |
62 | } | |
63 | } | |
64 | ||
65 | arch = seccomp_arch_native(); | |
66 | if (token == 0) { | |
67 | switch (arch) { | |
68 | case SCMP_ARCH_X86: | |
69 | printf("x86\n"); | |
70 | break; | |
71 | case SCMP_ARCH_X86_64: | |
72 | printf("x86_64\n"); | |
73 | break; | |
74 | case SCMP_ARCH_X32: | |
75 | printf("x32\n"); | |
76 | break; | |
77 | case SCMP_ARCH_ARM: | |
78 | printf("arm\n"); | |
79 | break; | |
80 | default: | |
81 | printf("unknown\n"); | |
82 | } | |
83 | } else | |
84 | printf("%d\n", arch); | |
85 | ||
86 | return 0; | |
87 | } |
0 | /** | |
1 | * BPF Disassembler | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <errno.h> | |
22 | #include <fcntl.h> | |
23 | #include <inttypes.h> | |
24 | #include <limits.h> | |
25 | #include <stdlib.h> | |
26 | #include <stdio.h> | |
27 | #include <string.h> | |
28 | #include <unistd.h> | |
29 | #include <sys/types.h> | |
30 | #include <sys/stat.h> | |
31 | ||
32 | #include "bpf.h" | |
33 | ||
34 | #define _OP_FMT "%-3s" | |
35 | ||
36 | /** | |
37 | * Decode the BPF operand | |
38 | * @param bpf the BPF instruction | |
39 | * | |
40 | * Decode the BPF operand and print it to stdout. | |
41 | * | |
42 | */ | |
43 | static void bpf_decode_op(const bpf_instr_raw *bpf) | |
44 | { | |
45 | switch (bpf->code) { | |
46 | case BPF_LD+BPF_W+BPF_IMM: | |
47 | case BPF_LD+BPF_W+BPF_ABS: | |
48 | case BPF_LD+BPF_W+BPF_IND: | |
49 | case BPF_LD+BPF_W+BPF_MEM: | |
50 | case BPF_LD+BPF_W+BPF_LEN: | |
51 | case BPF_LD+BPF_W+BPF_MSH: | |
52 | printf(_OP_FMT, "ld"); | |
53 | break; | |
54 | case BPF_LD+BPF_H+BPF_IMM: | |
55 | case BPF_LD+BPF_H+BPF_ABS: | |
56 | case BPF_LD+BPF_H+BPF_IND: | |
57 | case BPF_LD+BPF_H+BPF_MEM: | |
58 | case BPF_LD+BPF_H+BPF_LEN: | |
59 | case BPF_LD+BPF_H+BPF_MSH: | |
60 | printf(_OP_FMT, "ldh"); | |
61 | break; | |
62 | case BPF_LD+BPF_B+BPF_IMM: | |
63 | case BPF_LD+BPF_B+BPF_ABS: | |
64 | case BPF_LD+BPF_B+BPF_IND: | |
65 | case BPF_LD+BPF_B+BPF_MEM: | |
66 | case BPF_LD+BPF_B+BPF_LEN: | |
67 | case BPF_LD+BPF_B+BPF_MSH: | |
68 | printf(_OP_FMT, "ldb"); | |
69 | break; | |
70 | case BPF_LDX+BPF_W+BPF_IMM: | |
71 | case BPF_LDX+BPF_W+BPF_ABS: | |
72 | case BPF_LDX+BPF_W+BPF_IND: | |
73 | case BPF_LDX+BPF_W+BPF_MEM: | |
74 | case BPF_LDX+BPF_W+BPF_LEN: | |
75 | case BPF_LDX+BPF_W+BPF_MSH: | |
76 | case BPF_LDX+BPF_H+BPF_IMM: | |
77 | case BPF_LDX+BPF_H+BPF_ABS: | |
78 | case BPF_LDX+BPF_H+BPF_IND: | |
79 | case BPF_LDX+BPF_H+BPF_MEM: | |
80 | case BPF_LDX+BPF_H+BPF_LEN: | |
81 | case BPF_LDX+BPF_H+BPF_MSH: | |
82 | case BPF_LDX+BPF_B+BPF_IMM: | |
83 | case BPF_LDX+BPF_B+BPF_ABS: | |
84 | case BPF_LDX+BPF_B+BPF_IND: | |
85 | case BPF_LDX+BPF_B+BPF_MEM: | |
86 | case BPF_LDX+BPF_B+BPF_LEN: | |
87 | case BPF_LDX+BPF_B+BPF_MSH: | |
88 | printf(_OP_FMT, "ldx"); | |
89 | break; | |
90 | case BPF_ST: | |
91 | printf(_OP_FMT, "st"); | |
92 | break; | |
93 | case BPF_STX: | |
94 | printf(_OP_FMT, "stx"); | |
95 | break; | |
96 | case BPF_ALU+BPF_ADD+BPF_K: | |
97 | case BPF_ALU+BPF_ADD+BPF_X: | |
98 | printf(_OP_FMT, "add"); | |
99 | break; | |
100 | case BPF_ALU+BPF_SUB+BPF_K: | |
101 | case BPF_ALU+BPF_SUB+BPF_X: | |
102 | printf(_OP_FMT, "sub"); | |
103 | break; | |
104 | case BPF_ALU+BPF_MUL+BPF_K: | |
105 | case BPF_ALU+BPF_MUL+BPF_X: | |
106 | printf(_OP_FMT, "mul"); | |
107 | break; | |
108 | case BPF_ALU+BPF_DIV+BPF_K: | |
109 | case BPF_ALU+BPF_DIV+BPF_X: | |
110 | printf(_OP_FMT, "div"); | |
111 | break; | |
112 | case BPF_ALU+BPF_OR+BPF_K: | |
113 | case BPF_ALU+BPF_OR+BPF_X: | |
114 | printf(_OP_FMT, "or"); | |
115 | break; | |
116 | case BPF_ALU+BPF_AND+BPF_K: | |
117 | case BPF_ALU+BPF_AND+BPF_X: | |
118 | printf(_OP_FMT, "and"); | |
119 | break; | |
120 | case BPF_ALU+BPF_LSH+BPF_K: | |
121 | case BPF_ALU+BPF_LSH+BPF_X: | |
122 | printf(_OP_FMT, "lsh"); | |
123 | break; | |
124 | case BPF_ALU+BPF_RSH+BPF_K: | |
125 | case BPF_ALU+BPF_RSH+BPF_X: | |
126 | printf(_OP_FMT, "rsh"); | |
127 | break; | |
128 | case BPF_ALU+BPF_NEG+BPF_K: | |
129 | case BPF_ALU+BPF_NEG+BPF_X: | |
130 | printf(_OP_FMT, "neg"); | |
131 | break; | |
132 | case BPF_JMP+BPF_JA+BPF_K: | |
133 | case BPF_JMP+BPF_JA+BPF_X: | |
134 | printf(_OP_FMT, "jmp"); | |
135 | break; | |
136 | case BPF_JMP+BPF_JEQ+BPF_K: | |
137 | case BPF_JMP+BPF_JEQ+BPF_X: | |
138 | printf(_OP_FMT, "jeq"); | |
139 | break; | |
140 | case BPF_JMP+BPF_JGT+BPF_K: | |
141 | case BPF_JMP+BPF_JGT+BPF_X: | |
142 | printf(_OP_FMT, "jgt"); | |
143 | break; | |
144 | case BPF_JMP+BPF_JGE+BPF_K: | |
145 | case BPF_JMP+BPF_JGE+BPF_X: | |
146 | printf(_OP_FMT, "jge"); | |
147 | break; | |
148 | case BPF_JMP+BPF_JSET+BPF_K: | |
149 | case BPF_JMP+BPF_JSET+BPF_X: | |
150 | printf(_OP_FMT, "jset"); | |
151 | break; | |
152 | case BPF_RET+BPF_K: | |
153 | case BPF_RET+BPF_X: | |
154 | case BPF_RET+BPF_A: | |
155 | printf(_OP_FMT, "ret"); | |
156 | break; | |
157 | case BPF_MISC+BPF_TAX: | |
158 | printf(_OP_FMT, "tax"); | |
159 | break; | |
160 | case BPF_MISC+BPF_TXA: | |
161 | printf(_OP_FMT, "txa"); | |
162 | break; | |
163 | default: | |
164 | printf(_OP_FMT, "???"); | |
165 | } | |
166 | } | |
167 | ||
168 | /** | |
169 | * Decode the BPF arguments (JT, JF, and K) | |
170 | * @param bpf the BPF instruction | |
171 | * @param line the current line number | |
172 | * | |
173 | * Decode the BPF arguments (JT, JF, and K) and print the relevant information | |
174 | * to stdout based on the operand. | |
175 | * | |
176 | */ | |
177 | static void bpf_decode_args(const bpf_instr_raw *bpf, unsigned int line) | |
178 | { | |
179 | switch (BPF_CLASS(bpf->code)) { | |
180 | case BPF_LD: | |
181 | case BPF_LDX: | |
182 | switch (BPF_MODE(bpf->code)) { | |
183 | case BPF_ABS: | |
184 | printf("$data[%u]", bpf->k); | |
185 | break; | |
186 | case BPF_MEM: | |
187 | printf("$temp[%u]", bpf->k); | |
188 | break; | |
189 | } | |
190 | break; | |
191 | case BPF_ST: | |
192 | case BPF_STX: | |
193 | printf("$temp[%u]", bpf->k); | |
194 | break; | |
195 | case BPF_ALU: | |
196 | if (BPF_SRC(bpf->code) == BPF_K) { | |
197 | switch (BPF_OP(bpf->code)) { | |
198 | case BPF_OR: | |
199 | case BPF_AND: | |
200 | printf("0x%.8x", bpf->k); | |
201 | break; | |
202 | default: | |
203 | printf("%u", bpf->k); | |
204 | } | |
205 | } else | |
206 | printf("%u", bpf->k); | |
207 | break; | |
208 | case BPF_JMP: | |
209 | if (BPF_OP(bpf->code) == BPF_JA) { | |
210 | printf("%.4u", (line + 1) + bpf->k); | |
211 | } else { | |
212 | printf("%-4u true:%.4u false:%.4u", | |
213 | bpf->k, | |
214 | (line + 1) + bpf->jt, | |
215 | (line + 1) + bpf->jf); | |
216 | } | |
217 | break; | |
218 | case BPF_RET: | |
219 | if (BPF_RVAL(bpf->code) == BPF_A) { | |
220 | /* XXX - accumulator? */ | |
221 | printf("$acc"); | |
222 | } else if (BPF_SRC(bpf->code) == BPF_K) { | |
223 | uint32_t act = bpf->k & SECCOMP_RET_ACTION; | |
224 | uint32_t data = bpf->k & SECCOMP_RET_DATA; | |
225 | ||
226 | switch (act) { | |
227 | case SECCOMP_RET_KILL: | |
228 | printf("KILL"); | |
229 | break; | |
230 | case SECCOMP_RET_TRAP: | |
231 | printf("TRAP"); | |
232 | break; | |
233 | case SECCOMP_RET_ERRNO: | |
234 | printf("ERRNO(%u)", data); | |
235 | break; | |
236 | case SECCOMP_RET_TRACE: | |
237 | printf("TRACE(%u)", data); | |
238 | break; | |
239 | case SECCOMP_RET_ALLOW: | |
240 | printf("ALLOW"); | |
241 | break; | |
242 | default: | |
243 | printf("0x%.8x", bpf->k); | |
244 | } | |
245 | } else if (BPF_SRC(bpf->code) == BPF_X) { | |
246 | /* XXX - any idea? */ | |
247 | printf("???"); | |
248 | } | |
249 | break; | |
250 | case BPF_MISC: | |
251 | break; | |
252 | default: | |
253 | printf("???"); | |
254 | } | |
255 | } | |
256 | ||
257 | /** | |
258 | * Perform a simple decoding of the BPF program | |
259 | * @param file the BPF program | |
260 | * | |
261 | * Read the BPF program and display the instructions. Returns zero on success, | |
262 | * negative values on failure. | |
263 | * | |
264 | */ | |
265 | static int bpf_decode(FILE *file) | |
266 | { | |
267 | unsigned int line = 0; | |
268 | size_t len; | |
269 | bpf_instr_raw bpf; | |
270 | ||
271 | /* header */ | |
272 | printf(" line OP JT JF K\n"); | |
273 | printf("=================================\n"); | |
274 | ||
275 | while ((len = fread(&bpf, sizeof(bpf), 1, file))) { | |
276 | printf(" %.4u: 0x%.2x 0x%.2x 0x%.2x 0x%.8x", | |
277 | line, bpf.code, bpf.jt, bpf.jf, bpf.k); | |
278 | ||
279 | printf(" "); | |
280 | bpf_decode_op(&bpf); | |
281 | printf(" "); | |
282 | bpf_decode_args(&bpf, line); | |
283 | printf("\n"); | |
284 | ||
285 | line++; | |
286 | } | |
287 | ||
288 | if (ferror(file)) | |
289 | return errno; | |
290 | return 0; | |
291 | } | |
292 | ||
293 | /** | |
294 | * main | |
295 | */ | |
296 | int main(int argc, char *argv[]) | |
297 | { | |
298 | int rc; | |
299 | FILE *file; | |
300 | ||
301 | if (argc > 2) { | |
302 | fprintf(stderr, "usage: %s [<bpf_file>]\n", argv[0]); | |
303 | return EINVAL; | |
304 | } | |
305 | ||
306 | if (argc == 2) { | |
307 | file = fopen(argv[1], "r"); | |
308 | if (file == NULL) { | |
309 | fprintf(stderr, "error: unable to open \"%s\" (%s)\n", | |
310 | argv[1], strerror(errno)); | |
311 | return errno; | |
312 | } | |
313 | } else | |
314 | file = stdin; | |
315 | ||
316 | rc = bpf_decode(file); | |
317 | fclose(file); | |
318 | ||
319 | return rc; | |
320 | } | |
321 |
0 | /** | |
1 | * BPF Simulator | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <elf.h> | |
22 | #include <errno.h> | |
23 | #include <fcntl.h> | |
24 | #include <inttypes.h> | |
25 | #include <stdlib.h> | |
26 | #include <stdio.h> | |
27 | #include <string.h> | |
28 | #include <unistd.h> | |
29 | #include <linux/audit.h> | |
30 | #include <sys/types.h> | |
31 | #include <sys/stat.h> | |
32 | ||
33 | #include "bpf.h" | |
34 | ||
35 | #define BPF_PRG_MAX_LEN 4096 | |
36 | ||
37 | /** | |
38 | * BPF simulator machine state | |
39 | */ | |
40 | struct sim_state { | |
41 | uint32_t acc; | |
42 | uint32_t temp[BPF_SCRATCH_SIZE]; | |
43 | }; | |
44 | ||
45 | struct bpf_program { | |
46 | size_t i_cnt; | |
47 | bpf_instr_raw *i; | |
48 | }; | |
49 | ||
50 | static unsigned int opt_verbose = 0; | |
51 | ||
52 | /** | |
53 | * Print the usage information to stderr and exit | |
54 | * @param program the name of the current program being invoked | |
55 | * | |
56 | * Print the usage information and exit with EINVAL. | |
57 | * | |
58 | */ | |
59 | static void exit_usage(const char *program) | |
60 | { | |
61 | fprintf(stderr, | |
62 | "usage: %s -f <bpf_file> [-v]" | |
63 | " -a <arch> -s <syscall_num> [-0 <a0>] ... [-5 <a5>]\n", | |
64 | program); | |
65 | exit(EINVAL); | |
66 | } | |
67 | ||
68 | /** | |
69 | * Handle a simulator fault | |
70 | * @param rc the error or return code | |
71 | * | |
72 | * Print a "FAULT" to stderr to indicate a simulator fault, and an errno value | |
73 | * if the simulator is running in verbose mode, then exit with EFAULT. | |
74 | * | |
75 | */ | |
76 | static void exit_fault(unsigned int rc) | |
77 | { | |
78 | if (opt_verbose) | |
79 | fprintf(stderr, "FAULT: errno = %d\n", rc); | |
80 | else | |
81 | fprintf(stderr, "FAULT\n"); | |
82 | exit(EFAULT); | |
83 | } | |
84 | ||
85 | /** | |
86 | * Handle a BPF program error | |
87 | * @param rc the error or return code | |
88 | * @param line the line number | |
89 | * | |
90 | * Print an "ERROR" to stderr to indicate a program error, and an errno value | |
91 | * if the simulator is running in verbose mode, then exit with ENOEXEC. | |
92 | * | |
93 | */ | |
94 | static void exit_error(unsigned int rc, unsigned int line) | |
95 | { | |
96 | if (opt_verbose) | |
97 | fprintf(stderr, "ERROR: errno = %d, line = %d\n", rc, line); | |
98 | else | |
99 | fprintf(stderr, "ERROR\n"); | |
100 | exit(ENOEXEC); | |
101 | } | |
102 | ||
103 | /** | |
104 | * Handle a simulator return/action | |
105 | * @param action the return value | |
106 | * @param line the line number | |
107 | * | |
108 | * Display the action to stdout and exit with 0. | |
109 | * | |
110 | */ | |
111 | static void end_action(uint32_t action, unsigned int line) | |
112 | { | |
113 | uint32_t act = action & SECCOMP_RET_ACTION; | |
114 | uint32_t data = action & SECCOMP_RET_DATA; | |
115 | ||
116 | switch (act) { | |
117 | case SECCOMP_RET_KILL: | |
118 | fprintf(stdout, "KILL\n"); | |
119 | break; | |
120 | case SECCOMP_RET_TRAP: | |
121 | fprintf(stdout, "TRAP\n"); | |
122 | break; | |
123 | case SECCOMP_RET_ERRNO: | |
124 | fprintf(stdout, "ERRNO(%u)\n", data); | |
125 | break; | |
126 | case SECCOMP_RET_TRACE: | |
127 | fprintf(stdout, "TRACE(%u)\n", data); | |
128 | break; | |
129 | case SECCOMP_RET_ALLOW: | |
130 | fprintf(stdout, "ALLOW\n"); | |
131 | break; | |
132 | default: | |
133 | exit_error(EDOM, line); | |
134 | } | |
135 | ||
136 | exit(0); | |
137 | } | |
138 | ||
139 | /** | |
140 | * Execute a BPF program | |
141 | * @param prg the loaded BPF program | |
142 | * @param sys_data the syscall record being tested | |
143 | * | |
144 | * Simulate the BPF program with the given syscall record. | |
145 | * | |
146 | */ | |
147 | static void bpf_execute(const struct bpf_program *prg, | |
148 | const struct seccomp_data *sys_data) | |
149 | { | |
150 | unsigned int ip, ip_c; | |
151 | struct sim_state state; | |
152 | bpf_instr_raw *bpf; | |
153 | unsigned char *sys_data_b = (unsigned char *)sys_data; | |
154 | ||
155 | /* initialize the machine state */ | |
156 | ip_c = 0; | |
157 | ip = 0; | |
158 | memset(&state, 0, sizeof(state)); | |
159 | ||
160 | while (ip < prg->i_cnt) { | |
161 | /* get the instruction and bump the ip */ | |
162 | ip_c = ip; | |
163 | bpf = &prg->i[ip++]; | |
164 | ||
165 | switch (bpf->code) { | |
166 | case BPF_LD+BPF_W+BPF_ABS: | |
167 | if (bpf->k < BPF_SYSCALL_MAX) | |
168 | state.acc = *((uint32_t *)&sys_data_b[bpf->k]); | |
169 | else | |
170 | exit_error(ERANGE, ip_c); | |
171 | break; | |
172 | case BPF_ALU+BPF_OR+BPF_K: | |
173 | state.acc |= bpf->k; | |
174 | break; | |
175 | case BPF_ALU+BPF_AND+BPF_K: | |
176 | state.acc &= bpf->k; | |
177 | break; | |
178 | case BPF_JMP+BPF_JA: | |
179 | ip += bpf->k; | |
180 | break; | |
181 | case BPF_JMP+BPF_JEQ+BPF_K: | |
182 | if (state.acc == bpf->k) | |
183 | ip += bpf->jt; | |
184 | else | |
185 | ip += bpf->jf; | |
186 | break; | |
187 | case BPF_JMP+BPF_JGT+BPF_K: | |
188 | if (state.acc > bpf->k) | |
189 | ip += bpf->jt; | |
190 | else | |
191 | ip += bpf->jf; | |
192 | break; | |
193 | case BPF_JMP+BPF_JGE+BPF_K: | |
194 | if (state.acc >= bpf->k) | |
195 | ip += bpf->jt; | |
196 | else | |
197 | ip += bpf->jf; | |
198 | break; | |
199 | case BPF_RET+BPF_K: | |
200 | end_action(bpf->k, ip_c); | |
201 | break; | |
202 | default: | |
203 | /* since we don't support the full bpf language just | |
204 | * yet, this could be either a fault or an error, we'll | |
205 | * treat it as a fault until we provide full support */ | |
206 | exit_fault(EOPNOTSUPP); | |
207 | } | |
208 | } | |
209 | ||
210 | /* if we've reached here there is a problem with the program */ | |
211 | exit_error(ERANGE, ip_c); | |
212 | } | |
213 | ||
214 | /** | |
215 | * main | |
216 | */ | |
217 | int main(int argc, char *argv[]) | |
218 | { | |
219 | int opt; | |
220 | char *opt_file = NULL; | |
221 | FILE *file; | |
222 | size_t file_read_len; | |
223 | struct seccomp_data sys_data; | |
224 | struct bpf_program bpf_prg; | |
225 | ||
226 | /* clear the syscall record */ | |
227 | memset(&sys_data, 0, sizeof(sys_data)); | |
228 | ||
229 | /* parse the command line */ | |
230 | while ((opt = getopt(argc, argv, "a:f:h:s:v0:1:2:3:4:5:")) > 0) { | |
231 | switch (opt) { | |
232 | case 'a': | |
233 | if (strcmp(optarg, "x86") == 0) | |
234 | sys_data.arch = AUDIT_ARCH_I386; | |
235 | else if (strcmp(optarg, "x86_64") == 0) | |
236 | sys_data.arch = AUDIT_ARCH_X86_64; | |
237 | else if (strcmp(optarg, "x32") == 0) | |
238 | sys_data.arch = AUDIT_ARCH_X86_64; | |
239 | else if (strcmp(optarg, "arm") == 0) | |
240 | sys_data.arch = AUDIT_ARCH_ARM; | |
241 | else | |
242 | exit_fault(EINVAL); | |
243 | break; | |
244 | case 'f': | |
245 | opt_file = strdup(optarg); | |
246 | if (opt_file == NULL) | |
247 | exit_fault(ENOMEM); | |
248 | break; | |
249 | case 's': | |
250 | sys_data.nr = strtol(optarg, NULL, 0); | |
251 | break; | |
252 | case 'v': | |
253 | opt_verbose = 1; | |
254 | break; | |
255 | case '0': | |
256 | sys_data.args[0] = strtoull(optarg, NULL, 0); | |
257 | break; | |
258 | case '1': | |
259 | sys_data.args[1] = strtoull(optarg, NULL, 0); | |
260 | break; | |
261 | case '2': | |
262 | sys_data.args[2] = strtoull(optarg, NULL, 0); | |
263 | break; | |
264 | case '3': | |
265 | sys_data.args[3] = strtoull(optarg, NULL, 0); | |
266 | break; | |
267 | case '4': | |
268 | sys_data.args[4] = strtoull(optarg, NULL, 0); | |
269 | break; | |
270 | case '5': | |
271 | sys_data.args[5] = strtoull(optarg, NULL, 0); | |
272 | break; | |
273 | case 'h': | |
274 | default: | |
275 | /* usage information */ | |
276 | exit_usage(argv[0]); | |
277 | } | |
278 | } | |
279 | ||
280 | /* allocate space for the bpf program */ | |
281 | /* XXX - we should make this dynamic */ | |
282 | bpf_prg.i_cnt = 0; | |
283 | bpf_prg.i = calloc(BPF_PRG_MAX_LEN, sizeof(*bpf_prg.i)); | |
284 | if (bpf_prg.i == NULL) | |
285 | exit_fault(ENOMEM); | |
286 | ||
287 | /* load the bpf program */ | |
288 | file = fopen(opt_file, "r"); | |
289 | if (file == NULL) | |
290 | exit_fault(errno); | |
291 | do { | |
292 | file_read_len = fread(&(bpf_prg.i[bpf_prg.i_cnt]), | |
293 | sizeof(*bpf_prg.i), 1, file); | |
294 | if (file_read_len == 1) | |
295 | bpf_prg.i_cnt++; | |
296 | ||
297 | /* check the size */ | |
298 | if (bpf_prg.i_cnt == BPF_PRG_MAX_LEN) | |
299 | exit_fault(E2BIG); | |
300 | } while (file_read_len > 0); | |
301 | fclose(file); | |
302 | ||
303 | /* execute the bpf program */ | |
304 | bpf_execute(&bpf_prg, &sys_data); | |
305 | ||
306 | /* we should never reach here */ | |
307 | exit_fault(EFAULT); | |
308 | return 0; | |
309 | } |
0 | /** | |
1 | * Syscall resolver | |
2 | * | |
3 | * Copyright (c) 2012 Red Hat <pmoore@redhat.com> | |
4 | * Author: Paul Moore <pmoore@redhat.com> | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2.1 of the GNU Lesser General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
15 | * for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with this library; if not, see <http://www.gnu.org/licenses>. | |
19 | */ | |
20 | ||
21 | #include <errno.h> | |
22 | #include <stdlib.h> | |
23 | #include <stdio.h> | |
24 | #include <ctype.h> | |
25 | #include <string.h> | |
26 | #include <unistd.h> | |
27 | ||
28 | #include "../src/arch.h" | |
29 | #include "../src/arch-x86.h" | |
30 | #include "../src/arch-x86_64.h" | |
31 | #include "../src/arch-x32.h" | |
32 | #include "../src/arch-arm.h" | |
33 | ||
34 | /** | |
35 | * Print the usage information to stderr and exit | |
36 | * @param program the name of the current program being invoked | |
37 | * | |
38 | * Print the usage information and exit with EINVAL. | |
39 | * | |
40 | */ | |
41 | static void exit_usage(const char *program) | |
42 | { | |
43 | fprintf(stderr, | |
44 | "usage: %s [-h] [-a <arch>] [-t] <name>|<number>\n", | |
45 | program); | |
46 | exit(EINVAL); | |
47 | } | |
48 | ||
49 | /** | |
50 | * main | |
51 | */ | |
52 | int main(int argc, char *argv[]) | |
53 | { | |
54 | int opt; | |
55 | int translate = 0; | |
56 | const struct arch_def *arch = arch_def_native; | |
57 | int sys_num; | |
58 | const char *sys_name; | |
59 | ||
60 | /* parse the command line */ | |
61 | while ((opt = getopt(argc, argv, "a:ht")) > 0) { | |
62 | switch (opt) { | |
63 | case 'a': | |
64 | if (strcmp(optarg, "x86") == 0) | |
65 | arch = &arch_def_x86; | |
66 | else if (strcmp(optarg, "x86_64") == 0) | |
67 | arch = &arch_def_x86_64; | |
68 | else if (strcmp(optarg, "x32") == 0) | |
69 | arch = &arch_def_x32; | |
70 | else if (strcmp(optarg, "arm") == 0) | |
71 | arch = &arch_def_arm; | |
72 | else | |
73 | exit_usage(argv[0]); | |
74 | break; | |
75 | case 't': | |
76 | translate = 1; | |
77 | break; | |
78 | case 'h': | |
79 | default: | |
80 | /* usage information */ | |
81 | exit_usage(argv[0]); | |
82 | } | |
83 | } | |
84 | ||
85 | /* sanity checks */ | |
86 | if (optind >= argc) | |
87 | exit_usage(argv[0]); | |
88 | ||
89 | /* perform the syscall lookup */ | |
90 | if (isdigit(argv[optind][0]) || argv[optind][0] == '-') { | |
91 | sys_num = atoi(argv[optind]); | |
92 | sys_name = arch_syscall_resolve_num(arch, sys_num); | |
93 | printf("%s\n", sys_name); | |
94 | } else { | |
95 | sys_num = arch_syscall_resolve_name(arch, argv[optind]); | |
96 | if (translate != 0) | |
97 | /* ignore errors and just output the resolved number */ | |
98 | arch_syscall_rewrite(arch, 0, &sys_num); | |
99 | printf("%d\n", sys_num); | |
100 | } | |
101 | ||
102 | return 0; | |
103 | } |